int print_out(int begin, int end) { printf("%d ", begin++); int *p; p = (int*)(int(&begin) - 4); if(begin <= end) *p -= 5; return 1; } int add(int a, int b) { return a+b; } int pass(int a, int b, int c) { char buffer[4] = {0}; int sum = 0; int *ret; ret = (int*)(buffer+28); //(*ret) += 0xA; sum = a + b + c; return sum; } int main() { print_out(0, 2); printf("\n"); int a = 1; int b = 2; int c; c = add(a, b); pass(a, b, c); int __sum; __asm { mov __sum, eax } printf("%d\n", __sum); system("pause"); }
28: int main() 29: { 011C1540 push ebp //壓棧,保存ebp,注意push操做隱含esp-4 011C1541 mov ebp,esp //把esp的值傳遞給ebp,設置當前ebp 011C1543 sub esp,0F0h //給函數開闢空間,範圍是(ebp, ebp-0xF0) 011C1549 push ebx 011C154A push esi 011C154B push edi 011C154C lea edi,[ebp-0F0h] //把edi賦值爲ebp-0xF0 011C1552 mov ecx,3Ch //函數空間的dword數目,0xF0>>2 = 0x3C 011C1557 mov eax,0CCCCCCCCh 011C155C rep stos dword ptr es:[edi] //rep指令的目的是重複其上面的指令.ECX的值是重複的次數. //STOS指令的做用是將eax中的值拷貝到ES:EDI指向的地址,而後EDI+4
30: print_out(0, 2); 013D155E push 2 //第二個實參壓棧 013D1560 push 0 //第一個實參壓棧 013D1562 call print_out (13D10FAh)//返回地址壓棧,本例中是013D1567,而後調用print_out函數 013D1567 add esp,8 //兩個實參出棧 //注意在call命令中,隱含操做是把下一條指令的地址壓棧,也就是所謂的返回地址
013D141C mov eax,1 //返回值傳入eax中 013D1421 pop edi 013D1422 pop esi 013D1423 pop ebx //寄存器出棧 013D1424 add esp,0D0h //如下3條命令是調用VS的__RTC_CheckEsp,檢查棧溢出 013D142A cmp ebp,esp 013D142C call @ILT+315(__RTC_CheckEsp) (13D1140h) 013D1431 mov esp,ebp //ebp的值傳給esp,也就是恢復調用前esp的值 013D1433 pop ebp //彈出ebp,恢復ebp的值 013D1434 ret //把返回地址寫入EIP中,至關於pop EIP
int *p; p = (int*)(int(&begin) - 4); if(begin <= end) *p -= 5;
013D1560 push 0 //第一個實參壓棧 013D1562 call print_out (13D10FAh)//返回地址壓棧,本例中是013D1567,而後調用print_out函數 013D1567 add esp,8 //兩個實參出棧