[Mac 10.7.1 Lion Intel-based x64 gcc4.2.1]
Q: 有的時候,記得在某個目錄下寫過某個變數或者其它什麼文本形式的東西,但是後來忘記寫在哪個檔案裡了,怎麼找到?
A: 這個就需要用到grep命令了。它很強大,尤其對於開發或者尋找某個東西在哪裡的時候。舉個例子,有個目錄裡面有一些檔案:
而且,有一些檔案裡面含有main字串,現在需要把它們找出來:
很可惜,在mac10.7.1下面,grep的一個參數-r似乎無效,不能遞迴到子目錄下搜尋;不過在cygwin裡面是ok的;bug列表中沒有找到,但是實踐確實無效,也許是個bug吧。
上面測試用的grep版本是2.5.1.
當然,它還支援很多參數,比如-i忽略大小寫,-E進行egrep擴充等等。
Q: 經常會遇到,建立一個進程,但是後來想把它關閉,ps -ax命令得到一堆進程,不便於尋找,怎麼快速能定位它?
A: 同樣可以使用上面的grep命令。例如,需要尋找系統是否啟動了httpd進程:
Q: 有時,需要分析一個產生的可執行檔的內部結構,怎麼辦?
A: 使用otool命令,它異常的強大。它支援很多參數,幫您將可執行檔,也包括中間檔案、庫等檔案的內部展示地一覽無餘。
Q: 我需要查看一個可執行檔的mach頭,怎麼辦?
A: 可以使用-h參數。如下,寫一個簡單的代碼,儲存為hello.c:
#include <stdio.h>int main(){ int i = 2; printf("%d\n", i); return 0;}
使用gcc -o hello hello.c編譯得到hello.它將對hello進行分析:
用它和系統的mach header標頭檔結構對應,就可以得到它的具體含義。同理,使用-l命令可以得到mach-o格式檔案的load commands.
Q: 我想得到某個可執行檔依賴哪些動態庫,怎麼辦?
A: 可以使用otool命令的-L參數即可。同上使用上面的hello檔案,
Q: 我想知道一個可執行檔它的程式碼片段,怎麼辦?
A: 可以使用otool命令的-t參數。同樣使用上面的可執行檔hello,
不過,它是二進位形式的。
Q: 怎麼才能顯示上面的二進位形式的彙編形式代碼?
A: 可以配合-V命令或者-v命令(二者有一定區別)。
xichenMac:c_simple xichen$ otool -Vt hellohello:(__TEXT,__text) sectionstart:0000000100000eb0pushq$0x000000000100000eb2movq%rsp,%rbp0000000100000eb5andq$0xf0,%rsp0000000100000eb9movq0x08(%rbp),%rdi0000000100000ebdleaq0x10(%rbp),%rsi0000000100000ec1movl%edi,%edx0000000100000ec3addl$0x01,%edx0000000100000ec6shll$0x03,%edx0000000100000ec9addq%rsi,%rdx0000000100000eccmovq%rdx,%rcx0000000100000ecfjmp0x100000ed50000000100000ed1addq$0x08,%rcx0000000100000ed5cmpq$0x00,(%rcx)0000000100000ed9jne0x100000ed10000000100000edbaddq$0x08,%rcx0000000100000edfcallq_main0000000100000ee4movl%eax,%edi0000000100000ee6callq0x100000f2e; symbol stub for: _exit0000000100000eebhlt0000000100000eecnop0000000100000eednop0000000100000eeenop0000000100000eefnop_main:0000000100000ef0pushq%rbp0000000100000ef1movq%rsp,%rbp0000000100000ef4subq$0x10,%rsp0000000100000ef8movl$0x00000002,0xf4(%rbp)0000000100000effmovl0xf4(%rbp),%eax0000000100000f02xorb%cl,%cl0000000100000f04leaq0x00000055(%rip),%rdx0000000100000f0bmovq%rdx,%rdi0000000100000f0emovl%eax,%esi0000000100000f10movb%cl,%al0000000100000f12callq0x100000f34; symbol stub for: _printf0000000100000f17movl$0x00000000,0xf8(%rbp)0000000100000f1emovl0xf8(%rbp),%eax0000000100000f21movl%eax,0xfc(%rbp)0000000100000f24movl0xfc(%rbp),%eax0000000100000f27addq$0x10,%rsp0000000100000f2bpopq%rbp0000000100000f2cretxichenMac:c_simple xichen$
可以看到,對應的彙編已經出來了。
Q: 我想查看__TEXT段的字串字面量,怎麼查看?
A: 可以使用-sv __TEXT __cstring參數來得到。修改hello.c, 如下:
#include <stdio.h>int g_i = 0xAA;const int g_j = 0xBB;char *str = "hello";int main(){ int i = 2; printf("%d\n", i); return 0;}
編譯成hello.
可以看到,全域的str對應的hello\0和printf輸出的%d\n\0字串被顯示了
Q: 我想查看資料區__DATA裡面的資料(__data),怎麼辦?
A: 可以使用-sv __DATA __data參數來得到。使用上面的hello,
可以看到前4個位元組對應的全域變數g_i在此被顯示。如果使用otool -d hello會查看hello的__DATA區的資料。
Q: 我想查看全域const變數g_i對應的資料,怎麼查看?
A: 可以使用-sv __TEXT __const參數來查看。
可以看到0xBB變數的資料在此展示了。
Q: 我只想查看某個函數的彙編形式,怎麼辦?
A: 可以使用-p參數來指定查看的函數。如下:
上面查看了hello中的main函數的彙編形式(注意,雖然代碼中是main函數,但是在可執行檔的符號表中,可能會被改變,這依賴編譯器).
Q: 有的可執行檔支援不止一種硬體架構的代碼,如何查看包含哪些?
A: 可以使用file命令查看。如上,查看上面的hello檔案的資訊:
可以看到它是64位運行於x64平台上的可執行檔。
Q: 如何編譯得到一個可執行檔,它是通用的,可以包含幾種架構代碼的?
A: 使用gcc的-arch參數功能來實現。依然使用上面的hello.c代碼:
再運行file命令:
可以看到,檔案包含了兩種架構體系代碼。
Q: 看到很多逆向工具,可以修改特定的目標檔案實現特定的目的,是否可以修改hello檔案來得到希望的執行效果?
A: 是的。我並不善於修改彙編代碼,我們可以修改資料區段來查看效果。
修改上面的hello.c代碼如下:
#include <stdio.h>int g_i = 0xAA;const int g_j = 0xBB;char *str = "hello";int main(){ int i = 2; printf("%s %d\n", str, i); return 0;}
編譯成hello.並查看執行效果:
下面就使用vi來修改可執行檔的hello字串為iello, 最後查看執行效果。使用vi開啟hello檔案,定位到hello字串的位置:
修改hello的h為i:
儲存,然後執行hello:
可以看到,執行結果已經變了。
Q: 有時,需要查看一個目標檔案中各個段的大小,如何查看?
A: 可以使用size命令。
Q: 有時,需要查看目標檔案中可列印的字串有哪些,如何查看?
A: 可以使用strings命令。
Q: 很多編譯好的程式,裡麵包含了符號表或者一些調試資訊,如何去除它們?
A: 可以使用strip命令。
使用strip命令後:
可以看到,符號資訊確實少了。
Q: 上面提到的nm命令,它是做什麼的?
A: 它是可以查看目標檔案中包含的符號資訊的。
xichen
2012-5-25 12:50:52