教程 逆向反彙編第三課

2021-05-23 17:06:43 字數 4438 閱讀 7510

說完利用堆疊傳遞引數了,下面該說說使用暫存器傳遞引數的話題了.暫存器傳遞傳輸的方式並沒有乙個標準,所有與平台相關的方法都是由ide(也就是編譯器)開發人員制定的.儘管沒有統一的標準,但絕大多數編譯器提供商都在不對相容性宣告的情況下,遵循相應的規範,吉fastcall規範._fastcall顧名思義,特點就是快,因為他是靠暫存器來傳遞引數的.

不同編譯器實現的fastcall稍有不同,如microsoft visual c++編譯器採用fastcall規範傳遞引數時,最左邊的兩個不大於4個位元組(dword)的引數分別放在ecx和edx暫存器.當暫存器用完後,就要使用堆疊,其餘引數仍然按照從右到左的順序壓入堆疊,被呼叫的函式在返回前清理傳送引數的堆疊.浮點值員指標和int64型別總是通過對戰來傳遞的.而borland delphi/c++編譯器總是通過將暫存器來傳遞引數的,其最左邊的三個不大於4個位元組(dword)的引數分別放在eax  edx  和 ecx暫存器,暫存器用完後,引數按照從左到右的pascal方式來壓棧.另外一款編譯器watcom c總是通過暫存器來傳遞引數的,嚴格為每乙個引數分配乙個暫存器,預設時第乙個引數用eax,第二個引數用edx,第三個引數用ebx,第四個引數用 ecx,如果暫存器用完了,就會用堆疊來傳遞引數.watcom c可以由程式設計師指定任意乙個暫存器傳遞引數,因此,其引數實際上可能通過任何暫存器進行傳遞.

來看乙個手動指定fastcall呼叫引數的例項:

c原始碼如下:

view plain

copy to clipboard

print

?

int_fastcall add(char,long,int,int);   

main(void)   

int_fastcall add(chara,longb,intc,intd);     

這個反彙編後的**

view plain

copy to clipboard

print

?

00401000     /$  55            push    ebp   

00401001     |.  8bec          mov     ebp, esp   

00401003     |.  6a 04         push    4                                ;  後面兩個引數從右到左入棧,先壓入a   

00401005     |.  6a 03         push    3                                ;  再將第三個引數數值3入棧   

00401007     |.  ba 02000000   mov     edx, 2                           ;  再將第二個引數數值2放入edx   

0040100c     |.  b1 01         mov     cl, 1                            ;  傳遞第乙個引數(字元型別的變數是8位大小)   

0040100e     |.  e8 04000000   call    fastcall.00401017                ;  呼叫add()函式   

00401013     |.  33c0          xor     eax, eax   

00401015     |.  5d            pop     ebp   

00401016     /.  c3            retn   

00401017     /$  55            push    ebp   

00401018     |.  8bec          mov     ebp, esp   

0040101a     |.  83ec 08       sub     esp, 8                           ;  為區域性變數分配8個位元組   

0040101d         8955 f8       mov     dword ptr ss:[ebp-8], edx        ;  第二個引數放到區域性變數[ebp-08]中   

00401020         884d fc       movbyteptr ss:[ebp-4], cl          ;  第乙個引數放到區域性變數[ebp-4]中   

00401023     |.  0fbe45 fc     movsx   eax,byteptr ss:[ebp-4]         ;  將字元型資料擴充套件成乙個雙字   

00401027     |.  0345 f8       add     eax, dword ptr ss:[ebp-8]        ;  將左邊2個引數相加   

0040102a     |.  0345 08       add     eax, dword ptr ss:[ebp+8]        ;  相加之後的和(放到eax中)再加第三個引數   

0040102d     |.  0345 0c       add     eax, dword ptr ss:[ebp+c]        ;  最後再將eax的結果加上第四個引數   

00401030     |.  8be5          mov     esp, ebp   

00401032     |.  5d            pop     ebp   

00401033     /.  c2 0800       retn    8  

另乙個呼叫規範thiscall也用到了暫存器傳遞引數.thiscall是c++中的非靜態類成員函式的預設呼叫約定,物件的每個函式隱含接受this 引數.採用thiscall約定時,函式引數按照從右到左的順序入棧,被呼叫的函式在返回前清理傳送引數的棧,只是另外通過暫存器ecx傳送乙個額外的引數:this指標.

定義乙個類,並在類中定義乙個成員函式:

view plain

copy to clipboard

print

?

classcsun   

};   

voidmain()   

看看他反彙編後的**:   

[code]   

00401004  |.  6a 02         push    2                                ;  傳遞第三個引數   

00401006  |.  6a 01         push    1                                ;  傳遞第二個引數   

00401008  |.  8d4d fc       lea     ecx, dword ptr ss:[ebp-4]        ;this指標通過ecx暫存器傳遞   

0040100b  |.  e8 10000000   call    vf.00401020                      ;  呼叫函式sum.add(1,2)   

00401010  |.  8be5          mov     esp, ebp   

00401012  |.  5d            pop     ebp   

00401013  /.  c3            retn   

sum.add()函式實現部分反彙編**:   

00401020  /$  55            push    ebp   

00401021  |.  8bec          mov     ebp, esp   

00401023  |.  51            push    ecx   

00401024  |.  894d fc       mov     dword ptr ss:[ebp-4], ecx   

00401027  |.  8b45 08       mov     eax, dword ptr ss:[ebp+8]   

0040102a  |.  0345 0c       add     eax, dword ptr ss:[ebp+c]   

0040102d  |.  8be5          mov     esp, ebp   

0040102f  |.  5d            pop     ebp   

00401030  /.  c2 0800       retn    8  

我就不過多分析了,和前面差不多.

教程 逆向反彙編第三課

說完利用堆疊傳遞引數了,下面該說說使用暫存器傳遞引數的話題了.暫存器傳遞傳輸的方式並沒有乙個標準,所有與平台相關的方法都是由ide 也就是編譯器 開發人員制定的.儘管沒有統一的標準,但絕大多數編譯器提供商都在不對相容性宣告的情況下,遵循相應的規範,吉fastcall規範.fastcall顧名思義,特...

python第三課答案 python第三課

字串操作 s alexwusir s1 s.capitalize 首字母大寫 print s1 全大寫,全小寫 s2 s.upper s21 s.lower print s2,s21 大小寫翻轉 s3 s.swapcase print s3 每個隔開 特殊字元或數字 的單詞首字母大寫 s alex ...

python第三課答案 python第三課筆記

以下哪個變數的命名不正確?為什麼?a mm 520 b mm520 c 520 mm d 520 mm 答 c不正確,不能數字開頭 在不上機的情況下,以下 你能猜到螢幕會列印什麼內容嗎?myteacher 小甲魚 yourteacher myteacher yourteacher 黑夜 print ...