计算机系统基础实验-LinkLab实验
這是大三時的實驗課,很久以前的東西,應要求放出來,做的不是很好。linux永遠都是很重要的,希望我和大家都記得這個。實際上做到第五階段我就不會了。
實驗課程名稱:計算機系統基礎
實驗項目名稱:LinkLab實驗
|
在實驗中的每一階段n(n=1,2,3,4,5…),按照階段的目標要求修改相應可重定位二進制目標模塊phase[n].o后,使用如下命令生成可執行程序linkbomb: $ gcc -o linkbomb main.o phase[n].o [其他附加模塊——見具體階段說明] 正確性驗證:如下運行可執行程序linkbomb,應輸出符合各階段期望的字符串:? $ ./linkbomb $ 123456789 ?????????[僅供示例,具體目標字符串見每階段說明] 實驗結果:將修改后正確完成相應功能的各階段模塊(phase1.o, phase2.o, …)提交供評分。? |
| 實驗原理與內容 實驗內容 每個實驗階段(共6個)考察ELF文件組成與程序鏈接過程的不同方面知識 階段1:全局變量ó數據節 階段2:指令ó代碼節 階段3:符號解析 階段4:switch語句與重定位? 階段5:重定位? ???階段6:重定位(?PIC) ? 實驗步驟 1. 實驗數據 學生實驗數據包:?linklab-學號.tar 數據包中包含下面文件: main.o:主程序的二進制可重定位目標模塊(實驗中無需修改) phase1.o, phase2.o, phase3.o, phase4.o, phase5.o, phase6.o:各階段實驗所針對的二進制可重定位目標模塊,需在相應實驗階段中予以修改。 解壓命令:tar xvf linklab-學號.tar 2. 實驗工具 readelf:讀取ELF格式的各.o二進制模塊文件中的各類信息,如節(節名、偏移量及其中數據等)、符號表、字符串表、重定位記錄等? objdump:反匯編代碼節中指令并提供上述部分類似功能? (可選)hexedit:編輯二進制文件內容? ? 實驗階段1 要求:修改二進制可重定位目標文件“phase1.o”的數據節內容(不允許修改其它節的內容),使其與main.o鏈接后能夠運行輸出(且僅輸出)自己的學號:? ? ? ? ? ? ? ? ? 實驗提示:? 檢查反匯編代碼,獲得printf輸出函數的調用參數的(數據節中)地址? 使用hexedit工具(或自己編寫實現二進制ELF文件編輯程序),對phase1.o數據節中相應字節進行修改? ? 實驗階段2 要求:修改二進制可重定位目標文件“phase2.o”的代碼節內容(不允許修改其它節的內容),使其與main.o鏈接后能夠運行輸出(且僅輸出)自己的學號: ? ? ? ? ? ? 實驗提示:? 檢查反匯編代碼,定位模塊中的各組成函數并推斷其功能作用? 修改入口函數do_phase()中的機器指令(用自己指令替換函數體中的nop指令)以實現期望的輸出? ? 實驗階段3 要求:創建生成一個名為“phase3_patch.o”的二進制可重定位目標文件(不允許修改其它.o模塊),使其與main.o、phase3.o鏈接后能夠運行和輸出(且僅輸出)自己的學號:? ? ? 實驗提示:? phase3.o模塊入口函數do_phase()依次遍歷一個COOKIE字符串(由一組互不相同的英文字母組成,且總長度與學號字符串相同)中的每一字符,并將其不同可能ASCII編碼取值映射為特定輸出字符? 了解并利用符號解析規則? ? 實驗階段4 要求:修改二進制可重定位目標文件“phase4.o”中相應節中的數據內容(不允許修改.text節的內容),使其與main.o鏈接后能夠運行輸出(且僅輸出)自己的學號:? ? 實驗提示:? 模塊入口函數do_phase()依次遍歷一個COOKIE字符串(由一組互不相同的大寫英文字母組成,且總長度與學號字符串相同)中的每一字符,并將其不同可能ASCII編碼取值映射為特定輸出字符? 了解掌握switch語句的機器表示的各組成部分及其重定位信息 實驗階段5 要求:修改二進制可重定位目標文件“phase5.o”的相關重定位節中的數據內容(不允許修改其它節的內容),補充完成其中被清零的一些重定位記錄(分別對應于本模塊中需要重定位的符號引用),使其與main.o鏈接后能夠正確輸出(且僅輸出)自己學號的編碼結果: ? ? ? ??? 實驗提示:如果實驗中對缺失重定位信息的恢復不完整或不正確的話,鏈接生成linkbomb程序時可能不報錯,但運行程序可能得到以下結果之一:? 出現“Segmentation fault”出錯信息——原因?“如果未對相關引用進行必要的重定位會發生什么?” 輸出“Welcome to this small lab of linking. To begin lab, please link the relevant object module(s) with the main module. ”——提示模塊未鏈接。可能原因:雖然按上述步驟在生成linkbomb程序時實際已鏈接進phase4.o模塊,但某個重要的重定位記錄未正確設置。 輸出不正確的編碼結果? 實驗第六階段不做強制性要求 ? ? ? 實驗階段6 要求:修改二進制可重定位目標文件“phase6.o”的相關重定位節中的數據內容(不允許修改其它節的內容),補充完成其中被清零的一些重定位記錄(分別對應于本模塊中需要重定位的符號引用),使其與main.o鏈接后能夠正確輸出(且僅輸出)自己學號的編碼結果:? ? ? ? 實驗提示:? 本階段的程序框架與階段5相同,唯一區別是phase6.o采用了Position Independent Code (PIC)的編譯方式(即編譯生成可重定位目標模塊時使用了GCC的“-fPIC”選項),因此模塊中對數據和函數的引用方式及其重定位信息發生變化? 了解、熟悉PIC的基本實現技術? 可編寫樣例程序并分別加上或省略“-fPIC”選項進行編譯,再通過比較各自反匯編的結果,了解相同C源代碼的PIC與Non-PIC機器級實現之間的差異。 ? 學生實驗結果提交 將修改完成的各階段模塊(phase1.o, phase2.o, phase3_patch.o, phase4.o, phase5.o, phase6.o)和未改動的main.o、phase3.o模塊一起用tar工具打包并命名為“學號.tar”:? linux> tar cvf 學號尾數(與拿到的tar包相同).tar main.o phase1.o phase2.o phase3.o phase3_patch.o phase4.o phase5.o phase6.o |
| 實驗設備與軟件環境 Linux 32-bit,C/匯編語言 ? ? |
| 實驗過程與結果(可貼圖) 實驗階段1要求:修改二進制可重定位目標文件“phase1.o”的數據節內容(不允許修改其它節的內容),使其與main.o鏈接后能夠運行輸出(且僅輸出)自己的學號:? ? ? 實驗提示:? 檢查反匯編代碼,獲得printf輸出函數的調用參數的(數據節中)地址? 使用hexedit工具(或自己編寫實現二進制ELF文件編輯程序),對phase1.o數據節中相應字節進行修改? 輸入mydebian@Mydebian:~/23$ readelf -a phase1.o 查看elf文件內容 找到輸出的.data 節中偏移量為32的位置。 如下圖: ? ? ? ? 然后輸入 mydebian@Mydebian:~/23$?gcc -m32 -o linkbomb1 main.o phase1.o mydebian@Mydebian:~/23$?./linkbomb1 Y? ? ? ? ? ? ? ? ?On5TXwyRqWFIARrElCC3uFZ1XpL8WYFNgr2hRgaTvpwppI6UmbGZEizWx6JSTu5jfamz0LqFXDoHti9J9T1 Sn1FXeRxBm143PaIosUOhgNDjjClFjbQwoIUGG1BsTVVlFINsjooMWwgkHu7 青色的字體為輸處的文字,然后輸入hexedit phase1.o 再運行linkbomb程序,得到如下圖所示: ? 找到了剛剛青色背景標記的字符串。 從y開始哪個字符串開始修改,對比ASCII碼,我的學號為是多少,就對應的ASCII碼。 ? 直接修改對應的字符串: ? 刪除前一個linkbomb,生成新的linkbomb,最后重新輸出得到我們要的結果: 階段一完成 ? ? ? 實驗階段2要求:修改二進制可重定位目標文件“phase2.o”的代碼節內容(不允許修改其它節的內容),使其與main.o鏈接后能夠運行輸出(且僅輸出)自己的學號: ? 實驗提示:? 檢查反匯編代碼,定位模塊中的各組成函數并推斷其功能作用? 修改入口函數do_phase()中的機器指令(用自己指令替換函數體中的nop指令)以實現期望的輸出? 創建文件phase2_linkbomb2.s 輸入如下文本: movl %eax,%ebx subl $0x8,%ebx movl -0xc(%eax),%eax addl %ebx, %eax pushl $0x00003332???//我的學號為23號,ASCII碼為32 33小端存放 pushl %esp call *%eax addl $0x8,%esp 輸入gcc -m32 -c phase2_linkbomb2.s生成phase2_linkbomb2.o文件 再輸入objdump -d phase2_linkbomb2.o讀取文件 mydebian@Mydebian:~/23$ objdump -d phase2_linkbomb2.o phase2_linkbomb2.o: ????file format elf32-i386 Disassembly of section .text: 00000000 <.text>: ???0: ??89 c3 ??????????????????mov ???%eax,%ebx ???2: ??83 eb 08 ???????????????sub ???$0x8,%ebx ???5: ??8b 40 f4 ???????????????mov ???-0xc(%eax),%eax ???8: ??01 d8 ??????????????????add ???%ebx,%eax ???a: ??68 32 33 00 00 ?????????push ??$0x3332 ???f: ??54 ?????????????????????push ??%esp ??10: ??ff d0 ??????????????????call ??*%eax ??12: ??83 c4 08 ???????????????add ???$0x8,%esp 輸入hexedit phase2.o將上面的內容填補進nop中。 ? 相當于修改上面的反匯編代碼。 ? ? CTRL+W保存 再輸入: mydebian@Mydebian:~/23$ gcc -m32 -c phase2_linkbomb2.s ./linkbomb2 可以得到需要的結果。 階段二完成。 ? ? 實驗階段3要求:創建生成一個名為“phase3_patch.o”的二進制可重定位目標文件(不允許修改其它.o模塊),使其與main.o、phase3.o鏈接后能夠運行和輸出(且僅輸出)自己的學號:? ? 實驗提示:? phase3.o模塊入口函數do_phase()依次遍歷一個COOKIE字符串(由一組互不相同的英文字母組成,且總長度與學號字符串相同)中的每一字符,并將其不同可能ASCII編碼取值映射為特定輸出字符? 了解并利用符號解 ? 首先輸入命令objdump -d -r phase3.o查詢: ? 然后用命令readelf -s phase3.o讀取字符串長度: ? 創建文本phase03_take.c 可以知道這個函數中存放著256個可查詢的字符,編寫代碼如下: #include<stdio.h> int main(){ ????for(int i=0, p=0; i<=256; ++i ){ ????????char ch='A'+p; ????????printf("'%c',", ch); ????????if(!(i%16)) printf("\n"); ????????if('A'+(++p)>'Z') p=0;//注意帶小寫 ????} ????return 0; } 輸入 gcc phase03_take.c -std=gnu99&& ./a.out查看。 (-std=gnu99->C99標準) ? ? ? 這些字符用于填充zcbGMMwCmU()函數中可存放的區域。 復制建立新文本phase03_patch.c,將截圖中的字符放入文本中 ? 連續輸入指令 mydebian@Mydebian:~/23$ gcc -c phase03_patch.c -m32 mydebian@Mydebian:~/23$ ?gcc main.o phase3.o phase03_patch.o -m32 mydebian@Mydebian:~/23$ ./a.out IU//這個字符為phase03輸出的字符, 也就是說將I,U字符改為2,3(這里的I,U不是說所有的字符,而是所有字符中被輸出的某個字符’I’和字符’U’,為了不需要逐個尋找被輸出的那兩位字符)即可,如下圖(可以改用其他字符,例如數字字符由’1’-’9’,但這樣需要修改的位置更多)。 ? ? 修改后重新輸出: mydebian@Mydebian:~/23$ gcc -c phase03_patch.c -m32 mydebian@Mydebian:~/23$ gcc main.o phase3.o phase03_patch.o -m32 mydebian@Mydebian:~/23$ ?./a.out 23 階段3完成。 ? ? 實驗階段4要求:修改二進制可重定位目標文件“phase4.o”中相應節中的數據內容(不允許修改.text節的內容),使其與main.o鏈接后能夠運行輸出(且僅輸出)自己的學號:? ? 實驗提示:? 模塊入口函數do_phase()依次遍歷一個COOKIE字符串(由一組互不相同的大寫英文字母組成,且總長度與學號字符串相同)中的每一字符,并將其不同可能ASCII編碼取值映射為特定輸出字符? 了解掌握switch語句的機器表示的各組成部分及其重定位信息 連續輸入指令 ? 查看可得輸出放入字符為這兩個。那么直接用階段一的方法, 輸入hexedit phase4.o進入程序內查看 S|對應ASCII碼分別為53 7C,修改為學號23對應ASCII碼為32,33 ? 輸入命令查看結果正確: ? ? 實驗階段5 要求:修改二進制可重定位目標文件“phase5.o”的相關重定位節中的數據內容(不允許修改其它節的內容),補充完成其中被清零的一些重定位記錄(分別對應于本模塊中需要重定位的符號引用),使其與main.o鏈接后能夠正確輸出(且僅輸出)自己學號的編碼結果: 實驗提示:如果實驗中對缺失重定位信息的恢復不完整或不正確的話,鏈接生成linkbomb程序時可能不報錯,但運行程序可能得到以下結果之一:? 出現“Segmentation fault”出錯信息——原因?“如果未對相關引用進行必要的重定位會發生什么?” 輸出“Welcome to this small lab of linking. To begin lab, please link the relevant object module(s) with the main module. ”——提示模塊未鏈接。可能原因:雖然按上述步驟在生成linkbomb程序時實際已鏈接進phase4.o模塊,但某個重要的重定位記錄未正確設置。 輸出不正確的編碼結果? 首先輸入命令objdump phase5.o -d >phase5.txt轉化成文本: 打開文本phase5.txt尋找偏移量:??????? ? ? ? ? ? ? ? |
總結
以上是生活随笔為你收集整理的计算机系统基础实验-LinkLab实验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在canvas上进行绘图,实现要素配准
- 下一篇: [ubuntu]用SSH实现ubuntu