反彙編測試

20191310李燁龍發表於2021-11-02

反彙編測試


任務詳情

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

總結

​ 看了一整天,看麻了!

相關文章