亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: awk、sed 這些工具如何修改二進(jìn)制文件中的某些字節(jié)? [打印本頁(yè)]

作者: Calvin00    時(shí)間: 2012-08-10 22:34
標(biāo)題: awk、sed 這些工具如何修改二進(jìn)制文件中的某些字節(jié)?
本帖最后由 Calvin00 于 2012-08-10 22:37 編輯

我要批量修改一堆編譯出來(lái)的二進(jìn)制可執(zhí)行文件,要修改二進(jìn)制文件中的一些字節(jié),相當(dāng)于對(duì)二進(jìn)制文件打patch做一些細(xì)微修改,修改后仍然可以執(zhí)行。可否用 awk、sed 這些流編輯器實(shí)現(xiàn)?

附件(psxy)是一個(gè)樣本,為 Mac OS X 下編譯出來(lái)的 Mach-O 64-bit executable x86_64 可執(zhí)行文件(linux下的二進(jìn)制可執(zhí)行文件為 ELF 格式,不過(guò)道理相同)。
  1. CalvintekiMacBook-Pro:~ calvin$ otool -L psxy
  2. psxy:
  3.         /opt/local/lib/gmt4/lib/libgmtps.4.dylib (compatibility version 4.0.0, current version 4.5.8)
  4.         /opt/local/lib/gmt4/lib/libgmt.4.dylib (compatibility version 4.0.0, current version 4.5.8)
  5.         /opt/local/lib/gmt4/lib/libpsl.4.dylib (compatibility version 4.0.0, current version 4.5.8)
  6.         /opt/local/lib/libnetcdf.7.dylib (compatibility version 10.0.0, current version 10.0.0)
  7.         /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
復(fù)制代碼
(Mac OS X 下的 otool -L 功能相當(dāng)于 linux 下的 ldd )

現(xiàn)在,我想批量地把這堆二進(jìn)制文件的動(dòng)態(tài)鏈接庫(kù)路徑修改掉,/opt/local/ 統(tǒng)統(tǒng)修改為 /usr/local/ 。我們知道可以用 ghex 等工具一個(gè)一個(gè)地手工打開(kāi),查找,修改。不過(guò)現(xiàn)在我有一大堆這些待改的文件,用ghex這些工具一個(gè)個(gè)該很費(fèi)勁,所以希望寫(xiě)一個(gè)shell腳本,用 awk、sed 等流編輯工具批量地搜索這對(duì)二進(jìn)制文件,把凡是 /opt/local/ 這樣的動(dòng)態(tài)鏈接庫(kù)路徑全部批量修改成 /usr/local/ 。我試了很多次,不知道怎樣輸出回二進(jìn)制文件格式。

下面是一些實(shí)驗(yàn):
  1. CalvintekiMacBook-Pro:~ calvin$ head -c 16 psxy > test

  2. CalvintekiMacBook-Pro:~ calvin$ file test
  3. test: Mach-O 64-bit executable x86_64

  4. CalvintekiMacBook-Pro:~ calvin$ od -An -tx1 test | sed 's/           //g' | sed 's/  //g'
  5. cffaedfe070000010300008002000000

  6. CalvintekiMacBook-Pro:~ calvin$ od -An -tx1 test | sed 's/           //g' | sed 's/  //g' | od -An -tx1
  7.            63  66  66  61  65  64  66  65  30  37  30  30  30  30  30  31
  8.            30  33  30  30  30  30  38  30  30  32  30  30  30  30  30  30
  9.            0a  0a                                                        

  10. 現(xiàn)在,我怎樣把 cffaedfe070000010300008002000000 還原并輸出成跟文件 test 一樣的二進(jìn)制文件? 解決了這個(gè)問(wèn)題的話,我想用 awk 和 sed 批量 patch 二進(jìn)制可執(zhí)行文件就很容易了。
復(fù)制代碼
求高手和大神們幫助。

psxy.zip (16.94 KB, 下載次數(shù): 45)
作者: hbmhalley    時(shí)間: 2012-08-10 23:19
od -An -w1 -tu1 | ... | awk '{printf("%c",$0)}'
作者: ziyunfei    時(shí)間: 2012-08-10 23:30
awk一個(gè)就夠了
作者: Calvin00    時(shí)間: 2012-08-11 01:22
回復(fù) 2# hbmhalley

Mac OS X 下的 od 不支持你這種用法:
  1. CalvintekiMacBook-Pro:~ calvin$ od -An -w1 -tu1 psxy
  2. od: illegal option -- w
  3. usage: od [-aBbcDdeFfHhIiLlOosvXx] [-A base] [-j skip] [-N length] [-t type]
  4.           [[+]offset[.][Bb]] [file ...]
復(fù)制代碼

作者: hbmhalley    時(shí)間: 2012-08-11 02:02
回復(fù) 4# Calvin00


    od -An -tu1 | ... | awk '{for (i=1;i<=NF;++i) printf("%c",$i)}'
作者: Calvin00    時(shí)間: 2012-08-11 04:38
本帖最后由 Calvin00 于 2012-08-11 04:44 編輯

回復(fù) 5# hbmhalley
這是不行的。你自己試試便知。

我們只需要做一個(gè)小實(shí)驗(yàn)便可驗(yàn)證:

CalvintekiMacBook-Pro:~ calvin$ file psxy
psxy: Mach-O 64-bit executable x86_64

CalvintekiMacBook-Pro:~ calvin$ head -c 16 psxy >test

CalvintekiMacBook-Pro:~ calvin$ file test
test: Mach-O 64-bit executable x86_64

CalvintekiMacBook-Pro:~ calvin$ od -An -tx1 test
          cf  fa  ed  fe  07  00  00  01  03  00  00  80  02  00  00  00
(這里還輸出了一個(gè)空行)

CalvintekiMacBook-Pro:~ calvin$ od -An -tx1 test | sed 's/           //g' | awk '{if($0){print $0}}'
cf  fa  ed  fe  07  00  00  01  03  00  00  80  02  00  00  00

CalvintekiMacBook-Pro:~ calvin$ od -An -tx1 test | sed 's/           //g' | awk '{if($0){print $0}}' | awk '{for(i=1;i<=NF;i++){printf ("%c",$i)}}' > output

CalvintekiMacBook-Pro:~ calvin$ file output
output: data

CalvintekiMacBook-Pro:~ calvin$ od -An -tx1 test | sed 's/           //g' | awk '{if($0){print $0}}' | awk '{for(i=1;i<=NF;i++){printf ("%c",$i)}}' | od -An -tx1
           63  66  65  66  07  00  00  01  03  00  00  50  02  00  00  00
(這里還輸出了一個(gè)空行)

前后對(duì)比,輸出顯然沒(méi)有還原回跟 test 一樣的二進(jìn)制文件。
作者: Calvin00    時(shí)間: 2012-08-11 04:52
回復(fù) 3# ziyunfei


    你試試把串 “cf  fa  ed  fe  07  00  00  01  03  00  00  80  02  00  00  00” 用 awk 輸出到一個(gè)文件中,用 file 檢查文件類型是 Mach-O 64-bit executable x86_64 ,并且用 od -An -tx1 查看你得到的文件,輸出仍然是串 “cf  fa  ed  fe  07  00  00  01  03  00  00  80  02  00  00  00” ?

單單 awk 似乎不行。
作者: Calvin00    時(shí)間: 2012-08-11 05:49
本帖最后由 Calvin00 于 2012-08-11 05:50 編輯

以下命令似乎可以將從 psxy 開(kāi)頭拿出來(lái)的16個(gè)字節(jié)還原回去:
head -c 16 psxy | od -An -tu1 | awk '{for(i=1;i<=NF;i++){printf ("%c",$i)}}' > header

file header 輸出結(jié)果為 Mach-O 64-bit executable x86_64
od -An -tx1 header 輸出結(jié)果為 cf  fa  ed  fe  07  00  00  01  03  00  00  80  02  00  00  00

看來(lái) awk 的 printf %c 只能將 unsigned decimal 轉(zhuǎn)換成單個(gè)字符,如果是十六進(jìn)制就會(huì)轉(zhuǎn)換成不正確的結(jié)果。

貌似正確了,問(wèn)題貌似解決了。
不過(guò),還不能高興得太早。當(dāng)把這條命令應(yīng)用到整個(gè)完整的 psxy 文件時(shí),得到的結(jié)果文件仍然跟原來(lái)的 psxy 不同,而且不能運(yùn)行。

od -An -tu1 psxy | awk '{for(i=1;i<=NF;i++){printf ("%c",$i)}}' > psxy-new

CalvintekiMacBook-Pro:~ calvin$ ls -l psxy
-rwxr-xr-x  1 calvin  staff  44184  8 10 16:38 psxy

CalvintekiMacBook-Pro:~ calvin$ file psxy
psxy: Mach-O 64-bit executable x86_64

CalvintekiMacBook-Pro:~ calvin$ ls -l psxy-new
-rw-r--r--  1 calvin  staff  39822  8 11 05:41 psxy-new

CalvintekiMacBook-Pro:~ calvin$ file psxy-new
psxy-new: Mach-O 64-bit executable x86_64

得到的 psxy-new 大小跟原來(lái)的 psxy 不一致,加上可執(zhí)行權(quán)限后試運(yùn)行之,不能運(yùn)行:

CalvintekiMacBook-Pro:~ calvin$ chmod +x psxy-new
CalvintekiMacBook-Pro:~ calvin$ ./psxy-new
-bash: ./psxy-new: Malformed Mach-o file

(提示 psxy-new 為畸形的 Mach-o 文件)

還是不行!
求高手指點(diǎn)迷津。如果你使用 linux ,可以隨便到 /usr/bin 下拿一個(gè)二進(jìn)制可執(zhí)行文件來(lái)做試驗(yàn),看看結(jié)果怎么樣。
作者: Calvin00    時(shí)間: 2012-08-11 07:15
本帖最后由 Calvin00 于 2012-08-11 14:16 編輯

我在 linux 下拿 /bin/pwd 來(lái)做試驗(yàn),同樣得到的新文件不能運(yùn)行。

仔細(xì)對(duì)比了一下原始 /bin/pwd 跟經(jīng)過(guò) od -An -tu1 /bin/pwd | awk '{for(i=1;i<=NF;i++){printf ("%c",$i)}}'  > ~/pwd-new 得到的 pwd-new 文件,發(fā)現(xiàn) awk 在轉(zhuǎn)換某些 ASCII 碼為字符時(shí)出現(xiàn)錯(cuò)誤(大多數(shù)轉(zhuǎn)換正確,中間夾雜一些錯(cuò)誤)。

有幾個(gè)轉(zhuǎn)換錯(cuò)誤的被我抓了出來(lái):

echo 248 | awk '{printf("%c",$0)}' | od -An -tu1 不能得到希望的 248 而會(huì)得到 195 184
echo 131 | awk '{printf("%c",$0)}' | od -An -tu1 不能得到希望的 131 而會(huì)得到 194 131


問(wèn)題就出現(xiàn)在類似 248、131 這些碼上,導(dǎo)致整個(gè)出來(lái)的二進(jìn)制文件畸形、損壞,不能運(yùn)行。

這是咋回事呢????

嗯,在 debian linux 下,小于或等于 127 的 ascii 碼, awk '{printf("%c",$0)}' | od -An -tu1 可以得到跟原來(lái)一樣的碼;
大于127小于或等于191的ascii碼,awk '{printf("%c",$0)}' | od -An -tu1 會(huì)得到 194 + 原來(lái)的碼;
大于或等于192小于255的 ascii 碼,awk '{printf("%c",$0)}' | od -An -tu1 可以得 195 +從128開(kāi)始的編碼。

是說(shuō) linux 下的 gawk %c 打印大于127的擴(kuò)展ascii有問(wèn)題?

但是,在 Mac OS X 下,awk printf %c 輸出大于 127 的ASCII碼又沒(méi)有問(wèn)題:

echo 248 | awk '{printf("%c",$0)}' | od -An -tu1 能得到希望的 248
echo 131 | awk '{printf("%c",$0)}' | od -An -tu1 能得到希望的 131


真是奇怪,linux 下跟 Mac OS X 下還不同。linux 下的是 gawk ,估計(jì)有bug?
作者: personball    時(shí)間: 2012-08-11 08:37
回復(fù) 1# Calvin00


        這個(gè)需求有難度丫
給lz一個(gè)曲線救國(guó)的建議:在/opt/local對(duì)應(yīng)目錄下建立鏈接至/usr/local對(duì)應(yīng)的文件試試。。。
作者: hbmhalley    時(shí)間: 2012-08-11 11:30
本帖最后由 hbmhalley 于 2012-08-11 11:34 編輯

回復(fù) 6# Calvin00


    我試試 ..
作者: r2007    時(shí)間: 2012-08-11 13:59
patch前后文件大小會(huì)有變化嗎?沒(méi)有的話建議用echo+dd,有的話麻煩一些,不過(guò)也可用dd。
作者: r2007    時(shí)間: 2012-08-11 14:31
本帖最后由 r2007 于 2012-08-11 14:34 編輯

od的-w參數(shù)在lion中有效,不知道你的mac啥版本

訂正,我測(cè)的窗口是ssh到了一個(gè)linux主機(jī),lion也不支持-w參數(shù)
作者: Calvin00    時(shí)間: 2012-08-11 15:37
r2007 發(fā)表于 2012-08-11 14:31
od的-w參數(shù)在lion中有效,不知道你的mac啥版本

訂正,我測(cè)的窗口是ssh到了一個(gè)linux主機(jī),lion也不支持- ...

我的是 Mac OS X 10.8 Mountain Lion

經(jīng)過(guò) awk 一遍后,輸出的新的二進(jìn)制文件損壞,大小也跟原來(lái)的不一致。
我用 UtralEdit 打開(kāi)對(duì)比發(fā)現(xiàn)原二進(jìn)制文件跟 awk 輸出的二進(jìn)制文件在偏移量 00000730h 處開(kāi)始出現(xiàn)差異,在此偏移量之前兩者的全部字節(jié)都一致。
作者: r2007    時(shí)間: 2012-08-11 16:35
特定的比如你要的路徑替換,直接sed就可以,指定地址的可以用dd。通用的,要用xxd ...|script|xxd -r ...

作者: Calvin00    時(shí)間: 2012-08-11 18:44
r2007 發(fā)表于 2012-08-11 16:35
特定的比如你要的路徑替換,直接sed就可以,指定地址的可以用dd。通用的,要用xxd ...|script|xxd -r ...


太棒了,試了一下,這個(gè)能行!
  1. xxd psxy | sed 's/2f6f 7074/2f75 7372/g' | xxd -r > psxy-new
復(fù)制代碼

作者: lizhaoyu    時(shí)間: 2012-08-11 20:30
本帖最后由 lizhaoyu 于 2012-08-11 20:31 編輯

用vi或者ex是不是更方便一點(diǎn)啊。。。你的可以這么搞,文件列表你可以用各種方式獲得,我隨便放了個(gè)array,你參考:):
  1. #!/bin/bash
  2. file_list=(psxy)                                                                                                                              
  3. for x in ${file_list[@]}; do                                                                                                                  
  4.     vim $x <<EOF                                                                                                                              
  5. :%s/opt\/local/usr\/local/g                                                                                                                  
  6. ^[                                                                                                                                            
  7. ZZ                                                                                                                                            
  8. EOF                                                                                                                                          
  9. done               
復(fù)制代碼

作者: rdcwayx    時(shí)間: 2012-08-13 12:49
Calvin00 發(fā)表于 2012-08-11 20:44
太棒了,試了一下,這個(gè)能行!

mark一下,以后或許有用




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2