计算机系统实验六:程序的链接
參考教材:計算機系統基礎 第二版 袁春風 機械工業出版社
參考慕課:計算機系統基礎(四):編程與調試實踐 https://www.icourse163.org/learn/NJU-1449521162
計算機系統實驗導航
實驗一:環境安裝 https://blog.csdn.net/weixin_46291251/article/details/122477054
實驗二:數據的存儲與運算 https://blog.csdn.net/weixin_46291251/article/details/122478255
實驗三:程序的機器級表示 https://blog.csdn.net/weixin_46291251/article/details/122478979
實驗四:二進制程序逆向工程 https://blog.csdn.net/weixin_46291251/article/details/122479554
實驗五:緩沖區溢出攻擊 https://blog.csdn.net/weixin_46291251/article/details/122479798
實驗六:程序的鏈接 https://blog.csdn.net/weixin_46291251/article/details/122480049
實驗源碼: xxx
準備
實驗內容:
1 鏈接與 ELF 實驗的內容、方法和基本步驟;
2 程序鏈接的作用與過程、ELF 文件格式組成等知識的回顧與應用。
實驗目標:
1 加深對程序鏈接中符號解析、重定位等基本概念、位置無關代碼和 ELF 文件的基本組成等方面知識的理解和掌握;
2 掌握計算機系統思維,理解高級語言中數據、運算、過程調用和 I/O 操作等在計算機系統
中的實現方法,將程序設計、匯編語言、系統結構、操作系統、編譯鏈接中的重要概念貫穿起來。能夠對計算機系統復雜工程問題制定解決方案
3 掌握各種開源的編譯調試工具,能夠對分析優化程序設計,提高在代碼調試、性能提升、軟件移植和魯棒性等方面的能力。
實驗任務:
1 學習 MOOC 內容
https://www.icourse163.org/learn/NJU-1449521162
第七周 程序的鏈接
第 1 講 鏈接與 ELF 實驗:概述
第 2 講 鏈接與 ELF 實驗:靜態數據與 ELF 數據節
第 3 講 鏈接與 ELF 實驗:指令與 ELF 代碼節及課后實驗
2 完成作業
2.1修改二進制可重定位目標文件“phase1.o”的數據節內容(不允許修改 其他節),使其與main.o鏈接后運行時輸出自己的學號:
2.2實驗內容:修改二進制可重定位目標文件“phase2.o”的代碼節內容(不允許修改 其它節),使其與main.o鏈接后運行輸出自己的學號:
phase1:靜態數據對象與 ELF 數據節
第一步.
使用objdump工具獲得目標文件的匯編代碼,使用readelf工具獲得其重定位記錄。
首先對程序進行鏈接并執行,查看輸出結果:
然后用objdump對phase1.o進行反匯編,查看輸出結果:
分析反匯編后的文件:
選中的兩行實現了對常數0x9a進行壓棧操作。
然后用readelf -r 查看phase.o對應的信息
然后分析phase1.o中出現的重定位記錄:
R_386_PC32PC絕對地址重定位方式下,重定位后的引用地址=符號定義地址-符號引用所在地址+重定位前引用處的初始值
第二步.
結合并分析匯編代碼與重定位信息,定位輸出函數的調用參數在目標 文件中的存儲地址
使用readelf工具查看.data節中相應偏移量(0x29)處的字符串內容,并與未修改的phase1.o模塊鏈接生成的程序輸出的字符串比較,確定該字符串為修改的目標。
利用readelf -x .data phase1.o獲得模塊1指定節的內容:
上述在data節中對應0x9a偏移量地址對應的字符串與前面執行程序輸出的字符串一致,可見輸出字符串對應的地址確實是data節中的0x9a
第三步.
使用hexedit工具,對phase1.o模塊的數據節中相應字節進行修改。
下面使用hexedit工具對目標模塊phase1.o中輸出字符串內容進行修改:
首先利用readeif -S phase1.o 查看data節的偏移量
由上圖可知,data節在文件中的偏移量為0x60.
所以輸出字符串在文件中的偏移量為0x60 + 0x9a = 0xfa
然后利用hexedit工具打開phase1.o模塊
定位到偏移量為0xfa的字節處:
現在把輸出字符串從第一個字節開始,依次替換為需要輸出的學號對應的字符串,1對應的編碼為31后面依次類推,輸入完學號后,最后加上00作為字符串結束的標志。然后ctrl+x保存退出即可。
以上就完成了對phase1.o的修改。
第四步.
重新鏈接phase1.o模塊和main.o模塊,運行生成的可執行程序,驗證修改是否完成了實驗的目標。
驗證了前面對字符串的修改,達到了實驗目標。
phase2:指令與 ELF 代碼節
第一步.
使用objdump工具獲得phase2.o目標模塊的匯編代碼,使用readelf工具獲得其重定位記錄和符號表。
首先對程序進行鏈接,然后運行查看結果:
由以上結果可知,默認phase2不輸出任何信息。
然乎利用objdump對phase2進行反匯編,并查看代碼:
然乎利用readelf查看phase2中出現的重定位記錄:
第二步.
分析匯編代碼并結合重定位信息、符號表,推斷phase2.o模塊中各函數的功能作用,定位出其中負責輸出的函數。
在獲得了phase2.o目標模塊的匯編代碼和重定位記錄知之后,進一步分析該模塊中各個函數的功能。
首先在phase2.o代碼節中找到包含有類似puts輸出函數調用的函數
利用less工具查看反匯編代碼phase2.o,利用其查找功能查找call指令出現的位置:
然后查找重定位表
發現其對應puts函數。
所以調用puts語句的函數即為輸出字符串的函數這里是(00000061 :)
然后就可以在phase2模塊的dophase函數中調用kfSvKnbh函數以實現字符串的輸出
下面從符號表中獲得目標函數在.text節中的偏移量(這里是0x61)
利用readelf查看phase2的符號表
可以看出這個函數對應編號為1的節,大小為48。
然后利用readelf查看得到編號為1的節是text節。
所以目標函數位于text節中偏移量為0x61的位置上。
kfSvKnbh函數具有LOCAL鏈接綁定屬性,故調用該函數可通過相對于PC值的偏移量來進行跳轉,不需要構造相應的重定位記錄進行配合。
第三步.
構造調用輸出函數的指令代碼。
分析目標函數kfSvKnbh的執行邏輯:
查看第一個call語句的重定位記錄可知其調用的是strcmp函數,strcmp函數比較傳遞給它的兩個字符串參數的內容是否相同,如果相同的話將返回0,如不同則返回非0的一個數。
當存放于EAX寄存器中的、strcmp函數的返回值等于0,即兩個字符串相同時,將執行jne跳轉指令后的參數壓棧指令和調用puts函數的另一call指令。這個call對應的就是puts輸出函數,被輸出的、傳遞給puts函數的參數字符串地址就是傳遞給kfSvKnbh函數的第二個參數。
綜上所述:
為了正確調用ecRIvzPzKN函數完成學號字符串的輸出,需要完成兩個任務:
1.確保ecRIvzPzKN函數中傳遞給strcmp函數的兩個參數字符串,在內容上相同。
2.結合重定位記錄確定用于strcmp函數進行字符串比較的內置字符串在phase2.o中的存放位置,進一步獲得字符串內容。
可以看到先壓入棧的偏移量的位置對應一個重定位記錄如下:
結合重定位記錄確定內置字符串在phase2.o中的存放位置,進一步使用readelf工具輸出模塊中 .rodata節的內容:
獲得其內容為“MSLuleX.” ?
內置字符串地址 = .rodata節起始地址 + 引用處的初始值0x2
然后在棧中構造與內置字符串和學號字符串內容相同的局部字符串變量,并將其地址作為實參壓入棧中 。
構造在do phase函數中,調用kfSvKnbh函數的機器指令代碼
指令內容:在棧中構造和初始化兩個字符串局部變量,使其內容相同于程序內置的比較字符串"MSLuleX"和待輸出的學號字符串“123456789" 。
可以利用sub指令先分配兩個字符串的存儲空間,然后使用一組move指令對兩個字符串的內容按照前面分析的結果進行設置。然后用push指令將兩個字符串的地址作為參數壓入棧中。并進一步使用call指令調用目標函數。
然后利用as工具進行匯編,再利用objdump進行反匯編并查看:
第五步.
使用上步構造的調用輸出函數的指令代碼,替換do_ _phase()函數體中的nop指令,以實現期望輸出。
使用readelf工具及其“-S”命令行選項獲得節頭表,從中獲得.text在phase2.o中偏移量為 0x34
進一步得到函數中插入指令代碼的位置為:
0x34 + 0xcf = 0xc8 (0xcf是do_phase函數中第一個被替換的nop指令的偏移量)
使用hexedit將phase2.o文件中上述位置0xc8起始的字節內容(原為nop指令代碼0x90) 替換為調用指令代碼序列
然后使用調用輸出函數的指令代碼,替換do_phase()函數體中的nop指令,以獲得期望輸出。
最后重新鏈接、生成和運行程序,驗證修改有效:
可見,成功完成了目標。
總結
以上是生活随笔為你收集整理的计算机系统实验六:程序的链接的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win98 支持html5,90后第一次
- 下一篇: 漏洞C:/Windows/Fonts/c