目录
- call 0x401000
-
- 相当于
-
- push 0x401000+5
- jmp 0x401000
调用函数前地址
执行后 进入函数执行代码段,call指令地址 00831f83+0x5 = 00831f88 压入堆栈
相当于
- mov eip,[esp]; ESP地址内存的地址(call 函数后下一条指令地址)给EIP
- add esp,0x4;
EIP存储的是一个地址,这个地址,这个地址的空间存储的是汇编指令
测试代码
- #include <stdio.h>
-
- int m = 999;
-
- int add(int a, int b)
- {
- int c = a + b;
- return c;
- }
-
- int main()
- {
- int x = 3;
- int y = 4;
- int z = add(x, y);
-
- printf("add()返回值是%d int m = %d", z, m );
-
- return 0;
- }
调用堆栈
invoke main函数调用了main函数,main函数有3个参数
- static int __cdecl invoke_main()
- {
- return main(__argc, __argv, _get_initial_narrow_environment());
- }
main()函数汇编代码分析
-
- int main()
- {
- 00542560 55 push ebp
- 00542561 8B EC mov ebp,esp
- 00542563 81 EC E4 00 00 00 sub esp,0E4h
- 00542569 53 push ebx
- 0054256A 56 push esi
- 0054256B 57 push edi
- 0054256C 8D 7D DC lea edi,[ebp-24h]
- 0054256F B9 09 00 00 00 mov ecx,9
- 00542574 B8 CC CC CC CC mov eax,0CCCCCCCCh
- 00542579 F3 AB rep stos dword ptr es:[edi]
- 0054257B B9 03 C0 54 00 mov ecx,offset _5899AD65_test@cpp (054C003h)
- 00542580 E8 87 ED FF FF call @__CheckForDebuggerJustMyCode@4 (054130Ch)
- int x = 3;
- 00542585 C7 45 F8 03 00 00 00 mov dword ptr [x],3
- int y = 4;
- 0054258C C7 45 EC 04 00 00 00 mov dword ptr [y],4
- int z = add(x, y);
- 00542593 8B 45 EC mov eax,dword ptr [y]
- 00542596 50 push eax
- 00542597 8B 4D F8 mov ecx,dword ptr [x]
- 0054259A 51 push ecx
- 0054259B E8 1B EE FF FF call add (05413BBh)
- 005425A0 83 C4 08 add esp,8
- 005425A3 89 45 E0 mov dword ptr [z],eax
-
- printf("add()返回值是%d int m = %d", z, m);
- 005425A6 A1 28 A0 54 00 mov eax,dword ptr [m (054A028h)]
- 005425AB 50 push eax
- 005425AC 8B 4D E0 mov ecx,dword ptr [z]
- 005425AF 51 push ecx
- 005425B0 68 CC 7B 54 00 push offset string "add()\xb7\xb5\xbb\xd8\xd6\xb5\xca\xc7%d" (0547BCCh)
- 005425B5 E8 E8 ED FF FF call _printf (05413A2h)
- 005425BA 83 C4 0C add esp,0Ch
-
- return 0;
- 005425BD 33 C0 xor eax,eax
- }
- 005425BF 5F pop edi
- 005425C0 5E pop esi
- 005425C1 5B pop ebx
- 005425C2 81 C4 E4 00 00 00 add esp,0E4h
- 005425C8 3B EC cmp ebp,esp
- 005425CA E8 61 EC FF FF call __RTC_CheckEsp (0541230h)
- 005425CF 8B E5 mov esp,ebp
- 005425D1 5D pop ebp
- 005425D2 C3 ret
开辟栈帧
- int main()
- {
- 00542560 55 push ebp
- 00542561 8B EC mov ebp,esp
给函数的局部变量开辟空间,0E4h个空间
00542563 81 EC E4 00 00 00 sub esp,0E4h
保存寄存器值
- 00542569 53 push ebx
- 0054256A 56 push esi
- 0054256B 57 push edi
给24h(36个字节)初始化,每个字节为0xCC,范围是EBP(0x009bfdb0) - 0x009bfd8C
具体细节:
REP STOS
指令的作用是将一个指定的值写入字符串中的每个字节或字。- 0054256C 8D 7D DC lea edi,[ebp-24h]
- 0054256F B9 09 00 00 00 mov ecx,9
- 00542574 B8 CC CC CC CC mov eax,0CCCCCCCCh
- 00542579 F3 AB rep stos dword ptr es:[edi]
初始化完成
VS2019系统函数
- 0054257B B9 03 C0 54 00 mov ecx,offset _5899AD65_test@cpp (054C003h)
- 00542580 E8 87 ED FF FF call @__CheckForDebuggerJustMyCode@4 (054130Ch)
局部变量赋值
- int x = 3;
- 00542585 C7 45 F8 03 00 00 00 mov dword ptr [x],3
- int y = 4;
- 0054258C C7 45 EC 04 00 00 00 mov dword ptr [y],4
取地址查看
转到对应内存空间
maiin函数执行到最后一条语句,EAX是返回值,要清0
- return 0;
- 005425BD 33 C0 xor eax,eax
恢复易失性寄存器
- 005425BF 5F pop edi
- 005425C0 5E pop esi
- 005425C1 5B pop ebx
恢复函数局部变量空间,函数外平栈
005425C2 81 C4 E4 00 00 00 add esp,0E4h
检查堆栈有无异常,VS2019函数,无需关注
- 005425C8 3B EC cmp ebp,esp
- 005425CA E8 61 EC FF FF call __RTC_CheckEsp (0541230h)
恢复栈帧,具体细节如下:
- 005425CF 8B E5 mov esp,ebp
- 005425D1 5D pop ebp
- 005425D2 C3 ret
main函数调用已经分析完毕,中间还调用了add函数
- int z = add(x, y);
- 00542593 8B 45 EC mov eax,dword ptr [y]
- 00542596 50 push eax
- 00542597 8B 4D F8 mov ecx,dword ptr [x]
- 0054259A 51 push ecx
- 0054259B E8 1B EE FF FF call add (05413BBh)
- 005425A0 83 C4 08 add esp,8
- 005425A3 89 45 E0 mov dword ptr [z],eax
具体细节:
函数参数压入堆栈
- 00542593 8B 45 EC mov eax,dword ptr [y]
- 00542596 50 push eax
- 00542597 8B 4D F8 mov ecx,dword ptr [x]
- 0054259A 51 push ecx
调用函数,并且下一条指令压入堆栈
0054259B E8 1B EE FF FF call add (05413BBh)
查看add函数汇编
- int add(int a, int b)
- {
-
- 开辟栈帧
-
- 00542EA0 55 push ebp
- 00542EA1 8B EC mov ebp,esp
-
- 开辟局部变量空间
-
- 00542EA3 81 EC CC 00 00 00 sub esp,0CCh
-
- 保存易失性寄存器
-
- 00542EA9 53 push ebx
- 00542EAA 56 push esi
- 00542EAB 57 push edi
-
- 初始化局部变量的堆栈
-
- 00542EAC 8D 7D F4 lea edi,[ebp-0Ch]
- 00542EAF B9 03 00 00 00 mov ecx,3
- 00542EB4 B8 CC CC CC CC mov eax,0CCCCCCCCh
- 00542EB9 F3 AB rep stos dword ptr es:[edi]
-
- VS2019的函数
-
- 00542EBB B9 03 C0 54 00 mov ecx,offset _5899AD65_test@cpp (054C003h)
- 00542EC0 E8 47 E4 FF FF call @__CheckForDebuggerJustMyCode@4 (054130Ch)
-
- 加法运算
-
- int c = a + b;
- 00542EC5 8B 45 08 mov eax,dword ptr [a]
- 00542EC8 03 45 0C add eax,dword ptr [b]
- 00542ECB 89 45 F8 mov dword ptr [c],eax
-
- c作为函数返回值,把值给eax寄存器
-
- return c;
- 00542ECE 8B 45 F8 mov eax,dword ptr [c]
- }
-
- 恢复寄存器
-
- 00542ED1 5F pop edi
- 00542ED2 5E pop esi
- 00542ED3 5B pop ebx
-
- 平栈局部变量
-
- 00542ED4 81 C4 CC 00 00 00 add esp,0CCh
-
- VS2019函数,检查堆栈是否有异常
-
- 00542EDA 3B EC cmp ebp,esp
- 00542EDC E8 4F E3 FF FF call __RTC_CheckEsp (0541230h)
-
- 恢复原栈帧的栈底
-
- 00542EE1 8B E5 mov esp,ebp
- 00542EE3 5D pop ebp
-
- 恢复原栈帧的栈顶,并且恢复程序执行流程
-
- 00542EE4 C3 ret
-
- 到此栈还未回复完全,还有函数参数
平栈函数参数
005425A0 83 C4 08 add esp,8
把函数返回值给z
005425A3 89 45 E0 mov dword ptr [z],eax
定位到main函数
add函数
main函数
IDA其实和x64dbg一样
- .text:00412560 ; int __cdecl main(int argc, const char **argv, const char **envp)
- .text:00412560 main proc near ; CODE XREF: j_main↑j
- .text:00412560
- .text:00412560 var_24 = byte ptr -24h
- .text:00412560 var_20 = dword ptr -20h
- .text:00412560 var_14 = dword ptr -14h
- .text:00412560 var_8 = dword ptr -8
- .text:00412560 argc = dword ptr 8
- .text:00412560 argv = dword ptr 0Ch
- .text:00412560 envp = dword ptr 10h
- .text:00412560
- .text:00412560 push ebp
- .text:00412561 mov ebp, esp
- .text:00412563 sub esp, 0E4h
- .text:00412569 push ebx
- .text:0041256A push esi
- .text:0041256B push edi
- .text:0041256C lea edi, [ebp+var_24]
- .text:0041256F mov ecx, 9
- .text:00412574 mov eax, 0CCCCCCCCh
- .text:00412579 rep stosd
- .text:0041257B mov ecx, offset unk_41C003
- .text:00412580 call sub_41130C
- .text:00412585 mov [ebp+var_8], 3
- .text:0041258C mov [ebp+var_14], 4
- .text:00412593 mov eax, [ebp+var_14]
- .text:00412596 push eax
- .text:00412597 mov ecx, [ebp+var_8]
- .text:0041259A push ecx
- .text:0041259B call sub_4113BB
- .text:004125A0 add esp, 8
- .text:004125A3 mov [ebp+var_20], eax
- .text:004125A6 mov eax, dword_41A028
- .text:004125AB push eax
- .text:004125AC mov ecx, [ebp+var_20]
- .text:004125AF push ecx
- .text:004125B0 push offset unk_417BCC
- .text:004125B5 call sub_4113A2
- .text:004125BA add esp, 0Ch
- .text:004125BD xor eax, eax
- .text:004125BF pop edi
- .text:004125C0 pop esi
- .text:004125C1 pop ebx
- .text:004125C2 add esp, 0E4h
- .text:004125C8 cmp ebp, esp
- .text:004125CA call sub_411230
- .text:004125CF mov esp, ebp
- .text:004125D1 pop ebp
- .text:004125D2 retn
- .text:004125D2 main endp