彙編看函式呼叫過程
阿新 • • 發佈:2019-02-06
分析下列原始碼:
#include <windows.h>
DWORD _stdcall Function(DWORD dwP1, PVOID p2)
{
DWORD v1;
DWORD v2 = 3;
v1 = dwP1 + v2;
return v1;
}
int main()
{
Function(100,nullptr);
return 0;
}
轉匯編 vs2012
#include <windows.h> DWORD _stdcall Function(DWORD dwP1, PVOID p2) { 00FE13D0 push ebp //ebp = 003EFDCC 00FE13D1 mov ebp,esp //ebp = esp = 003EFCF0 00FE13D3 sub esp,0D8h //esp = esp -512=003EFC18 擴充512位元組 00FE13D9 push ebx //ebx = 7EFDE000 00FE13DA push esi //esi = 00000000 00FE13DB push edi //edi = 003EFDCC 00FE13DC lea edi,[ebp-0D8h]//edi = 003EFC18 00FE13E2 mov ecx,36h //ecx = 36h 00FE13E7 mov eax,0CCCCCCCCh//eax = 0CCCCCCCCh //rep重複其上面的指令,ECX的值是重複的次數. //stos將eax中的值拷貝到ES:EDI指向的地址(4位元組dword). ecx值隨著拷貝次數減少 //如果設定了direction flag, 那麼edi會在該指令執行後減小, 如果沒有設定direction flag, 那麼edi的值會增加, 這是為了下一次的儲存做準備. 00FE13EC rep stos dword ptr es:[edi]//即從記憶體003EFC18-003EFCEC值都為0CCCCCCCCh DWORD v1; DWORD v2 = 3; //00FE13EE mov dword ptr [ebp-14h],3 00FE13EE mov dword ptr [v2],3 v1 = dwP1 + v2; //00FE13F5 mov eax,dword ptr [ebp+8] 00FE13F5 mov eax,dword ptr [dwP1] //00FE13F8 add eax,dword ptr [ebp-14h] 00FE13F8 add eax,dword ptr [v2] //00FE13FB mov dword ptr [ebp-8],eax 00FE13FB mov dword ptr [v1],eax return v1; //00FE13FE mov eax,dword ptr [ebp-8] 00FE13FE mov eax,dword ptr [v1] } 00FE1401 pop edi //edi = 003EFDCC 00FE1402 pop esi //esi = 00000000 00FE1403 pop ebx //ebx = 7EFDE000 00FE1404 mov esp,ebp //esp = ebp = 003EFCF0 00FE1406 pop ebp //ebp = 003EFDCC 00FE1407 ret 8//因為_stdcall 所以由被呼叫者平衡棧 +8 ----------------------------------------- int main() { 00FE1420 push ebp 00FE1421 mov ebp,esp 00FE1423 sub esp,0C0h 00FE1429 push ebx 00FE142A push esi 00FE142B push edi 00FE142C lea edi,[ebp+FFFFFF40h] 00FE1432 mov ecx,30h 00FE1437 mov eax,0CCCCCCCCh 00FE143C rep stos dword ptr es:[edi] Function(100,nullptr); 00FE143E push 0 00FE1440 push 64h 00FE1442 call 00FE11EA return 0; 00FE1447 xor eax,eax } 00FE1449 pop edi } 00FE144A pop esi 00FE144B pop ebx 00FE144C add esp,0C0h 00FE1452 cmp ebp,esp 00FE1454 call 00FE113B 00FE1459 mov esp,ebp 00FE145B pop ebp 00FE145C ret//因為_cdecl,所以由呼叫者平衡棧 直接ret即可
記憶體棧顯示:
地址 | 值 | 說明 |
003EFC0C | 003EFDCC | push edi(edi = 003EFDCC) |
003EFC10 | 00000000 | push esi(esi = 00000000) |
003EFC14 | 7EFDE000 | push ebx(ebx = 7EFDE000) |
003EFC18 | cccccccc | ESP = ESP - 0X0D8H(216) |
003EFC1C | cccccccc | |
003EFC20 | cccccccc | |
................ | ||
................ | ||
003EFCD4 | cccccccc | |
003EFCD8 | cccccccc | |
003EFCDC | 00000003 | mov [ebp-14h],3 |
003EFCE0 | cccccccc |
|
003EFCE4 | cccccccc | |
003EFCE8 | 00000067 | mov [ebp-8],eax//103 |
003EFCEC | cccccccc | |
003EFCF0 | 003EFDCC | EBP = ESP = 003EFCF0 |
003EFCF4 | 00FE1447 | CALL Function下一條指令地址 EIP儲存 |
003EFCF8 | 00000064 | push 64h |
003EFCFC | 00000000 | push 0 |
................ | ||
................ | ||
................ | ||
003EFDCC | 003EFE1C | EBP--main() |
003EFDD0 | 00FE1989 | 呼叫main函式返回後的下一條指令地址0x00fe1989 |
圖形顯示: