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