Linux下二進位代碼的閱讀

來源:互聯網
上載者:User

大多數時候,我們研究的是如何閱讀原始碼。但在一些情況下,比如原始碼不公開或得到原始碼的代價很高的情況下,我們又不得不需要瞭解程式的行為,這時閱讀二進位檔案就非常重要。假設現在有一個二進位可執行檔,我們木有原始碼,但要瞭解它的實現,這裡僅簡單列出一些常用的工具。 閱讀方式可分為兩個方面:靜態閱讀和動態閱讀。

靜態閱讀

首先,file命令可以查看可執行檔的大體資訊。比如是哪種格式的,哪個體繫結構的,有沒有調試資訊等。這些決定了需要用哪個版本的工具進行進一步查看。比如如果是arm體系的可執行檔就可用arm toolchain裡的工具,如arm-eabi-objdump,arm-eabi-gdb等。

眾所周知,GNU Binutils提供了一系列解析和操作二進位檔案的工具,最常用的如objdump,其最主要的功能之一是反組譯碼:
objdump -d libxxx.so
其它常用選項包括:
-x  列印所有頭資訊
-s 列印所有段的內容
-S 將反組譯碼和原始碼一起列印
-r   列印重定位表
-R 列印動態重定位表
-D 列印所有段,即不止程式碼片段
-t   列印符號表,和nm的功能類似,但格式不一樣
-T  只列印動態連結的符號表項
等等。

readelf命令主要用於查看elf檔案的元資訊(如段資訊等)。如查看可執行檔的頭資訊:
readelf -h libxxx.so
其它常用選項包括:
-s 列印符號表
-r 列印重定位表
-l 列印裝載屬性
-S 列印段表
等等。

除了以上兩個用得最多的,其它一些協助工具輔助有時也必不可少:

nm      列印符號表
c++filt 把c++符號unmangle
strip    把調試資訊刪除
strings 看檔案中的字串
ldd:    查看依賴關係
等等

 
動態閱讀

要瞭解可程式的行為,最可靠的還是看二進位檔案跑起來時的樣子。很多時候,由於運行環境複雜,特別是多線程情況下,動態閱讀能發現很多靜態閱讀所不可能發現的東西。
首先,在/proc/pid(pid為進程號)下記錄了二進位檔案跑起來後的很多資訊,如通過/proc/pid/maps可以知道該程式連結了哪些庫,分別被載入在了什麼地方(這樣,知道了錯誤地址,理論上就可以找到相應庫的對應反組譯碼代碼。),/proc/pid/mem是進程所用的記憶體鏡像,/proc/pid/stat則記錄了中斷統計資訊等。/proc/pid/cmdline則記錄了啟動程式的命令列。

其次,通過trace(strace,lstrace)可以看程式有哪些系統調用。strace用於跟蹤系統調用,ltrace用於跟蹤動態庫調用。
如對於在/proc/pid/maps中看到的一些匿名記憶體映射,想要看它們是在什麼時候或是在哪被建立可以用:
strace -f -p 3742 -e trace=mmap2,open,mprotect |tee tmp.trace
 其中3742為進程ID。這裡只過濾出關於記憶體映射的函數。

最後,指令級動態閱讀的神器還屬gdb。
在gdb中查看寄存器資訊可用:
(gdb) i r

在調試過程中列印出反組譯碼代碼可用

(gdb) disass addr
或者
(gdb) x/10i addr
然後就可以和objdump出來的反組譯碼結合著看了。如GOT表之類的資訊在靜態閱讀時是無意義的,只有這時才能看。

各種break point能讓我們迅速定位到我們關注的地方:
watch point 在指定資料被訪問時程式停止。
break point 在指定代碼被執行時程式停止。 因為很多時候庫不帶symbol,所以得直接設在地址上 break *addr。
catch point 在指定事件發生時程式停止,如進程建立,動態連結程式庫載入及異常。
條件斷點有時很有用:break ... if <condition>,但這玩意一旦設上不是一般的慢啊。。。

gdb中的bt和info frame命令常用來看堆棧資訊和函數調用關係。但有時因為bug棧被寫壞了,但如果不是被寫得很壞,查看棧的內容常通常能找到一些線索:
(gdb) x/40x $sp
該命令是查看$sp指向地區的40個byte的記憶體內容。該命令也可用來查看任意指定地址的記憶體內容。

關於gdb常用的功能:http://wiki.ubuntu.org.cn/%E7%94%A8GDB%E8%B0%83%E8%AF%95%E7%A8%8B%E5%BA%8F
其它的一些gdb使用備忘:http://blog.csdn.net/ariesjzj/article/details/6913671 

一些相關資料

http://www.linuxforums.org/articles/understanding-elf-using-readelf-and-objdump_125.html

http://bbs.chinaunix.net/thread-1972423-1-1.html

elfutils-0.148: http://www.linux.it/~rubini/docs/binfmt/binfmt.html

GNU binutils & libbfd: http://www.gnu.org/software/binutils/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.