(接上篇)反編譯兩種可執行檔案
上篇地址:http://blog.csdn.net/eliot_shao/article/details/78648314
上篇主要內容回顧:
上篇內容介紹了靜態編譯生成靜態庫,然後連結靜態庫生成可執行檔案的過程;也對比介紹了動態編譯生成動態庫然後連結動態庫生成可執行檔案的過程。我們也得出了結論:
連結靜態庫生成的可執行檔案main執行不依賴與靜態庫是否存在,而連結動態庫生成的可執行檔案main2是依賴於動態庫的存在的。
下面我們使用反編譯手段分析上面的結論。
1:連結靜態連結庫,生成可執行檔案
gcc main.c -static -L. -lstruct -o main
反編譯可執行檔案 objdump -D main > static_obj.txt
2:連結動態連結庫,生成可執行檔案
gcc main.c -L. -lstruct -o main2
反編譯可執行檔案 objdump -D main > shard_obj.txt
對比大圖:
連結靜態庫(該庫只有hello函式)生成的可執行檔案反編譯結果:
連結動態庫(該庫只有hello函式)生成的可執行檔案反編譯結果,分三步查詢:
查詢過程1、2、3可以通過博文http://blog.csdn.net/eliot_shao/article/details/78549247中的一張圖反映。最終還是依賴於解析器將動態庫載入到記憶體,找到動態庫對應符號(hello)的位置,然後跳轉到hello,執行權利交接,hello函式得以執行!
.so本質和可執行檔案一樣也是elf,elf一種。.a則不是elf檔案,這裡沒深入研究。見下圖。
結論;通過反編譯兩個可執行檔案,我們會發現二者主要區別是動態連結過程,前者已經把靜態庫的內容連結到可執行檔案內部,不需要額外的定位庫檔案,而後者則需要“解析器”去通過PLT和GOT去載入動態庫檔案(.so)到記憶體然後在去定位要訪問函式的位置。