反匯編測試


反匯編測試


任務詳情

1 通過輸入gcc -S -o main.s main.c 將下面c程序”week0303學號.c“編譯成匯編代碼
int g(int x){
    return x+3;
}
int f(int x){
     int i = 學號后兩位;
    return g(x)+i;
}
int main(void){
    return f(8)+1;
}

2. 參考http://www.cnblogs.com/lxm20145215----/p/5982554.html,使用gdb跟蹤匯編代碼,在紙上畫出f中每一條語句引起的eip(rip),ebp(rbp),esp(rsb),eax(rax)的值和棧的變化情況。提交照片,要有學號信息。

完成過程

1.編譯情況

image-20211101202835776

2.發現在樹莓派arm64架構下無法完成,便轉到kali上做了。

image-20211101205559577

使用gcc - g example.c -o example -m32指令在64位的機器上產生32位匯編,然后使用gdb example指令進入gdb調試器:

image-20211101205848876

進入之后先在main函數處設置一個斷點,再run一下,使用disassemble指令獲取匯編代碼,用i(info) r(registers)指令查看各寄存器的值:

image-20211101210029858

用x mian查看主函數的內存地址:

首先,結合display命令和寄存器或pc內部變量,做如下設置:display /i $pc,這樣在每次執行下一條匯編語句時,都會顯示出當前執行的語句。

image-20211102091745502

call指令將下一條指令的地址入棧,此時%esp,%ebp和堆棧的值為:

image-20211102093213399

將上一個函數的基址入棧,從當前%esp開始作為新基址:

image-20211102093527513

先為傳參做准備:

image-20211102093801321

f函數的匯編代碼:

image-20211102093949549

實參入棧:

image-20211102094125998

主函數匯編代碼:

image-20211102094502986


知識點

跟着博客做完整個人還是很暈,於是想梳理一下知識點。

1.寄存器

參考博客:https://www.cnblogs.com/lihaozy/archive/2011/08/01/2124315.html

(1)ESP:棧指針寄存器(extended stack pointer),其內存放着一個指針,該指針永遠指向系統棧最上面一個棧幀的棧頂。

(2)EBP:基址指針寄存器(extended base pointer),其內存放着一個指針,該指針永遠指向系統棧最上面一個棧幀的底部。

(3)Eax用來保存所有API函數的返回值。

(4)寄存器AX和AL通常稱為累加器(Accumulator),用累加器進行的操作可能需要更少時間。累加器可用於乘、除、輸入/輸出等操作,它們的使用頻率很高;

(5)寄存器BX稱為基地址寄存器(Base Register)。它可作為存儲器指針來使用;

(6)寄存器CX稱為計數寄存器(Count Register)。在循環和字符串操作時,要用它來控制循環次數;在位操作中,當移多位時,要用CL來指明移位的位數;

(7)寄存器DX稱為數據寄存器(Data Register)。在進行乘、除運算時,它可作為默認的操作數參與運算,也可用於存放I/O的端口地址。

(8)寄存器ESI、EDI、SI和DI稱為變址寄存器(Index Register),它們主要用於存放存儲單元在段內的偏移量,用它們可實現多種存儲器操作數的尋址方式,為以不同的地址形式訪問存儲單元提供方便。變址寄存器不可分割成8位寄存器。作為通用寄存器,也可存儲算術邏輯運算的操作數和運算結果。它們可作一般的存儲器指針使用。在字符串操作指令的執行過程中,對它們有特定的要求,而且還具有特殊的功能。

2.gdb指令

參考博客:https://blog.csdn.net/moonsheep_liu/article/details/39099969

3.學習匯編語言

參考博客:https://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html


重新嘗試反匯編

試圖理解反匯編

1.首先在main函數設置斷點 b main

2.使用display設置顯示內容。

display /x $esp
display /x $ebp
display /x $eax
display /i $pc

3.使用run指令跳到main函數開始處,使用x(examine) /nfu + 內存地址查看堆棧內容。

push 命令將$0x8放入stack,因為是int型占用4個字節,所以esp寄存器減去4

這時可以看到棧底地址是0xffffd168。

image-20211102140922607

4.使用si步入下一條指令,使用x(examine) /nfu + 內存地址查看堆棧內容(之后每一步都要用到,不重復說明)。

call指令調用f函數,f函數的地址在0x5655619e

image-20211102140103395

5.push命令將ebp里的值寫入f函數這個幀,內容為0x565561bd,這是因為后面要用到這個寄存器,就先把里面的值取出來,用完后再寫回去。這時,push指令會再將 ESP 寄存器里面的地址減去4個字節(累計減去8)。

image-20211102135701329

6.mov指令用於將一個值寫入某個寄存器。這一行代碼表示,從ebp寄存器存的地址在 Stack 取出數據。根據前面的步驟,可以推算出這里取出的是8,再將8寫入ESP寄存器。

image-20211102141232311

這里沒有使用push指令,但是esp減去了4(累計減去12),堆棧中也存入了ebp的地址0xffffd168,參照阮一峰的理解是

image-20211102142015117

7.sub指令代表第一個寄存器中的值減去第二個寄存器中的值,將結果存入第一個寄存器中。這里就是用10(我的學號)減去esp中的值(此處應該是8),得到了2,存入?

(此處不理解)將我的學號傳入f函數中,堆棧中存入了0xf7de2fd6。

image-20211102142513989

此處因為進入了f函數中,所以ebp指向了f函數的棧底0xffffd15c。

8.call指令調用(此處應該是一個奇奇怪怪的函數,估計是某個庫函數,用來初始化函數調用的?),建立該函數的幀。

esp減去了16,說明存入了4個東西(為什么呢)

image-20211102144144974

9.mov指令將esp的地址存入了eax寄存器中,地址為0x565561a9,存入了堆棧中,esp中的值減去4。

image-20211102144312122

10.ret指令用於終止當前函數的執行,將運行權交還給上層函數。也就是,當前函數的幀將被回收。

隨着函數的終止,系統就回到剛才f函數中斷的地方,繼續往下執行。

image-20211102144615115

11.add指令是將0x2e57與eax寄存器中的值相加,存到?

此處應該發生了pop指令,esp寄存器的值加上4。

image-20211102145139156

12.movl指令將0xa(10,我的學號)傳入地址(ebp的地址減去4,這里應該是i的地址)中,此處movl中的l為長字節的意思(雖然感覺用mov也可以)。

image-20211102145312214

13.push將地址(ebp的值0+8,就是8)中的值取出來寫入f函數這個幀,esp減去4。

image-20211102150055177

14.call指令調用g函數,建立g函數的幀。

image-20211102150843846

15.push命令將ebp中的值(地址0xffffd15c的值,此處應是0xa)寫入g函數幀里,esp的地址減去4。

image-20211102151703325

16.mov將esp中的值寫入ebp中(為傳回上層函數做准備)。

image-20211102152132580

17.call指令調用不知名函數。

image-20211102152327988

18.mov指令將寄存器eax中的值存入地址(寄存器esp的值)中。

image-20211102152432179

19.ret指令終止函數,返回上層函數的幀。

image-20211102152623460

20.add指令將0x2e6f與寄存器eax中的值(0x56556191)相加,存入eax中。

image-20211102152811118

21.mov指令將寄存器ebp中的值(此處為0)加8,存入eax寄存器中。

image-20211102153038631

22.add指令將3加上eax中的值存入eax中(3+8=11)。

image-20211102153332093

23.pop指令

image-20211102153504867

24.ret指令終止當前函數。

image-20211102153626430

25.add指令將4與esp寄存器中的值(此處為8)相加,存入esp寄存器中。

image-20211102153806067

25.mov指令將地址(寄存器ebp的值減去4)中的值存入寄存器edx中。

image-20211102154141197

26.add指令將edx中的值與eax中的值相加(11+8=21),存入eax中。

image-20211102154222592

27.leave指令用於釋放當前堆棧中的內容。

image-20211102181539933

28.ret指令用於終止函數。

image-20211102181824981

29.add指令將4與寄存器esp中的值相加,存到esp中(4+8 = 12)

image-20211102181911321

30.add指令將1與寄存器eax中的值相加,存到eax中(21+1 = 22)。

image-20211102181948090

31.leave指令釋放當前堆棧的內容。

image-20211102182052262

32.ret指令結束當前函數調用,之后就是系統調用,很多看不完。

image-20211102182324016

總結

​ 看了一整天,看麻了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM