天天看點

16、函數調用間,系統棧,彙編檢視

#include <iostream><?xml:namespace prefix = o />

using namespace std;

void f1(int a,int b)

{

}

int main()

    f1(3,4);

    system("pause");

将上述代碼反彙編如下(vs05debug):

004113D0  push        ebp  ;/儲存棧基址

004113D1  mov         ebp,esp ;将棧頂指針賦給ebp,此時都指向函數調用的棧頂

004113D3  sub         esp,0C0h ;棧頂指針下移0xc0h,為main函數内局部變量配置設定空間

004113D9  push        ebx     ;在棧中儲存ebx

004113DA  push        esi 

004113DB  push        edi 

004113DC  lea         edi,[ebp-0C0h] ;将ebp-0c0h值賦給edi

004113E2  mov         ecx,30h

004113E7  mov         eax,0CCCCCCCCh

004113EC  rep stos    dword ptr es:[edi];從lea指令到這條指令作用就是把為局部變量配置設定的記憶體空間填充CC資料。Stos将eax中資料放入es:[edi]中,同時edi增加4個位元組。Rep使指令重複執行ecx次數。

f1(3,4);

004113EE  push        4   

004113F0  push        3    ;參數入棧

004113F2  call        f1 (4111D6h) ;call指令實際動作是push eip;mov eip,4111D6h連續兩條指令。

004113F7  add         esp,8 ;c的調用約定,調整棧

system("pause");

004113FA  mov         esi,esp

004113FC  push        offset string "pause" (415810h)

00411401  call        dword ptr [__imp__system (4182B4h)]

00411407  add         esp,4

0041140A  cmp         esi,esp

0041140C  call        @ILT+315(__RTC_CheckEsp) (411140h)

void f1(int a,int b) //f1函數反彙編代碼。

004113A0  push        ebp 

004113A1  mov         ebp,esp

004113A3  sub         esp,0C0h

004113A9  push        ebx 

004113AA  push        esi 

004113AB  push        edi 

004113AC  lea         edi,[ebp-0C0h]

004113B2  mov         ecx,30h

004113B7  mov         eax,0CCCCCCCCh

004113BC  rep stos    dword ptr es:[edi] ;上述彙編指令每個函數都有主要用來初始化棧和儲存一些寄存器的值。

004113BE  pop         edi 

004113BF  pop         esi 

004113C0  pop         ebx  ;函數調用完畢,回複edi等寄存器的值

004113C1  mov         esp,ebp

004113C3  pop         ebp  ;回收為f1函數配置設定的棧幀。

004113C4  ret                   ;此指令實際動作是pop eip;call f1時push eip,那時eip的值是call函數下條指令的值,程式跳轉main函數執行。

是以通過上述分析,我們得到一下的棧内資料的布局:

16、函數調用間,系統棧,彙編檢視

由于eip要存入棧中,是以就有可能被修改,導緻程式異常的運作,很多病毒就是利用了這一點。

參考:

[2] 天書夜讀

繼續閱讀