高階語言反彙編程式的函式呼叫過程 (轉)

worldblog發表於2007-12-11
高階語言反彙編程式的函式呼叫過程 (轉)[@more@]

高階語言反匯序的過程
Jim Chan
10/25/2001
檢視:
字型:宋體 
字形:常規 
大小:小五 
字符集:CHINESE_GB2312
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

摘要:本文說明高階語言編譯成語言後,高階語言中函式呼叫的彙編過程。

正文:高階語言編譯成彙編程式以後,在高階語言中的函式呼叫的彙編程式過程如下:

1.將函式引數入棧,第一個引數在棧頂,最後一個引數在棧底。

2.CALL指令,呼叫該函式,進入該函式程式碼空間。
a.執行CALL指令,將CALL指令下一行程式碼的地址入棧。
b.進入函式程式碼空間後,將基址指標EBP入棧,然後讓基址指標EBP指向當前堆疊棧頂,並使用它訪問存在堆疊中的函式輸入引數及堆疊中的其他資料。
c.堆疊指標ESP減少一個值,如44H,向上移動一個距離,留出一個空間給該函式作為臨時區。
{
  // 以上準備工作做好後,函式正式被執行,如下所示。
  d.將其他指標或暫存器中的值入棧,以便在函式中使用這些暫存器。
  e.執行程式碼。
  f.執行return()返回執行結果,將要返回的值存入EAX中。
  g.步驟2.d中的指標出棧。
}
h.將EBP的值傳給堆疊指標ESP,使ESP復原為2.c之前的值。此時進入函式時EBP的值在棧頂。
i.基址指標EBP出棧,復原為2.b之前的EBP的值。
j.執行RET指令,“呼叫函式”的地址出棧,本函式返回到CALL指令的下一行。

3.函式返回到CALL指令下一行,將堆疊指標加一個數值,以使堆疊指標恢復到以上步驟1執行之前的值。該數值是上面第一步入棧引數的總長度。

注意:
1.堆疊指標ESP指向棧頂的新入棧資料的最低位。
2.MOV指令中偏移指標指向被“MOV”的資料的最低位。如下面指令是將ebp+8到ebp+11四個位元組的內容傳到eax暫存器中。
00402048  mov  eax,d ptr [ebp+8]

一個例子如下:

高階語言程式碼中的函式呼叫如下:

117:  bR = t1(p);

彙編程式碼如下:

00401FB8  mov  ecx,dword ptr [ebp-8]  ;將引數放入ecx暫存器
00401FBB  push  ecx  ;引數入棧
00401FBC  call  @ILT+10(t1) (0040100f)  ;函式呼叫,下一行地址00401FC1入棧
00401FC1  add  esp,4  ;函式返回,堆疊指標加4,復原為00401FB8時的值
00401FC4  mov  dword ptr [ebp-10h],eax ;從eax中取出高階語言中的函式返回值,放入bR變數中

其中t1函式如下:

125:  BOOL t1(void* p)
126:  {
00402030  push  ebp  ;ebp入棧
00402031  mov  ebp,esp  ;ebp指向此時堆疊的棧頂
00402033  sub  esp,44h  ;esp減少一個值,空出一段儲存區
00402036  push  ebx  ;將三個暫存器的值入棧,以便在函式中使用它
00402037  push  esi  ;
00402038  push  edi  ;
00402039  lea  edi,[ebp-44h]  ;
0040203C  mov  ecx,11h  ;
00402041  mov  eax,0CCCCCCCCh  ;
00402046  rep stos  dword ptr [edi]  ;
127:  int* q = (int*)p;  ;
00402048  mov  eax,dword ptr [ebp+8]  ;ebp+8指向函式輸入引數的最低位地址;
;如果是ebp+4則指向函式返回地址00401FC1的最低位,值為C1
0040204B  mov  dword ptr [ebp-4],eax  ;
128:  return 0;  ;
0040204E  xor  eax,eax  ;返回值放入eax暫存器中
129:  }
00402050  pop  edi  ;三個暫存器出棧
00402051  pop  esi  ;
00402052  pop  ebx  ;
00402053  mov  esp,ebp  ;esp復原
00402055  pop  ebp  ;ebp出棧,它的值也復原了
00402056  ret  ;返回到此時棧頂儲存的程式碼地址:00401FC1
;故而如果不幸被修改了返回地址,程式就會出現意外

以上彙編程式碼由VC++6.0編譯得到。

堆疊在EBP入棧後的情況:

  低位  高位
  ↓  ↓
地址  堆疊
  ┆  ┆
0012F600├──────┤← edi = 0012F600
  │  │
0012F604├─┄┄┄┄─┤
  │  │
  │  │
  ┆ 44h的空間  ┆
  ┆  ┆
  │  │
  │  │
0012F640├─┄┄┄┄─┤
  │  │
0012F644├──────┤← ebp被賦值後指向該單元,此時ebp=0012F644
  │AC F6 12 00 │ebp賦值為esp之前的值
0012F648├──────┤
  │C1 1F 40 00 │返回地址
0012F64C├──────┤← ebp + 8
  │A0 F6 12 00 │函式實參p的值
0012F650├──────┤
  │  │
  ├──────┤
  ┆  ┆

注:儲存器儲存空間堆疊按從高到低的排列,左邊標註的地址是其右下方儲存單元的最低位地址。如0012F644指向0012F6AC的AC位元組,AC在棧頂。圖中儲存器中的內容按從低到高位書寫,“AC F6 12 00”= 0x0012F6AC


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991377/,如需轉載,請註明出處,否則將追究法律責任。

相關文章