非裸函数执行过程
002018D1 push 3 002018D3 push 2 002018D5 push 1 //将三个数压入栈中
002018D7 call std::basic_ostreamchar,std::char_traits<char >::sentry::sentry (0201497h)
002018DC add esp,0Ch //ebp表示栈底,esp表示栈顶,前面三个数将esp减去了0x0C,现在需要加上0x0C进行还原。
return 0;
002018DF xor eax,eax //将eax清零 }
进入到002018D7 call std::basic_ostreamchar,std::char_traits<char >::sentry::sentry (0201497h)
发现jmp fn1 (0202260h) 将eip的值改为fn1()函数的地址
继续f11,发现函数fn1()
void fn1(int x, int y, int z) { 00202260 push ebp //首先将ebp的原地址放入栈中 00202261 mov ebp,esp //ebp与esp相等,ebp的下方的三个值分别是要相加的三个值 00202263 sub esp,0C0h //将esp向上移动三个格子,ebp保持不变 00202269 push ebx //将ebx放入栈中 0020226A push esi //将esi放入栈中 0020226B push edi //将edi放入栈中 ,这三步都是方便后面对ebx,esi,edi进行还原,此时栈又向上移动三个格子。
0020226C mov edi,ebp //将ebp地址放入edi中 0020226E xor ecx,ecx //ecx进行清零 00202270 mov eax,0CCCCCCCCh //把eax的值复制为0xccccccccc,刚好为32位 00202275 rep stos dword ptr es:[edi] //把eax里面的双字赋值到es:[edi]的栈中,因为ecx为0,所以重复零次 00202277 mov ecx,offset A8F2BFD7源@cpp (020F029h) 0020227C call @__CheckForDebuggerJustMyCode@4 (020137Fh) //检查函数,不用看
} 00202281 pop edi 此时esp指向edi 00202282 pop esi 此时esp指向esi 00202283 pop ebx 此时esp指向ebx 00202284 add esp,0C0h 与上面相反进行相加 0020228A cmp ebp,esp 0020228C call __RTC_CheckEsp (020128Fh) //检查ebp 00202291 mov esp,ebp 00202293 pop ebp 然后将ebp取出 00202294 ret 返回原函数的下一句指令。
裸函数执行过程
fn(1,2,3);
009218D1 push 3 009218D3 push 2 009218D5 push 1 009218D7 call std::basic_ostreamchar,std::char_traits<char >::sentry::sentry (0921492h) 009218DC add esp,0Ch return 0; 009218DF xor eax,eax }
前面的过程和非裸函数执行的情况一模一样
00921492 jmp std::basic_ostreamchar,std::char_traits<char >::sentry::sentry (0921FB0h) 00921497 jmp fn1 (0922260h)
此时指针指向了第一条指令 00921492,进入这个,里面啥内容也没有,直接退出来了。。
可以发现不论是裸函数还是非裸函数 都出现了00921492 jmp std::basic_ostreamchar,std::char_traits<char >::sentry::sentry (0921FB0h) 这条指令,而裸函数在第一次调用call之后直接指向了这里,而非裸函数则指向了下一条指令。
假如在裸函数后面加上ret,此时可以正常返回
这是设置了int a=x+y+z的函数
void fn1(int x, int y, int z) { 00E42260 push ebp 00E42261 mov ebp,esp 00E42263 sub esp,0CCh //相对于不写内容的void多减了C个值,也就是三个格子 00E42269 push ebx 00E4226A push esi 00E4226B push edi
//上面是入堆栈存取数据
00E4226C lea edi,[ebp-0Ch] //与上方对应,将ebp先上移三个格子再放到edi中,esp与edi的对应位置相同 00E4226F mov ecx,3 00E42274 mov eax,0CCCCCCCCh
//缓冲数据区
00E42279 rep stos dword ptr es:[edi] //edi是向下放值的,这和标志寄存器有关。 00E4227B mov ecx,offset A8F2BFD7源@cpp (0E4F029h) 00E42280 call @CheckForDebuggerJustMyCode@4 (0E4137Fh) int a = x + y + z; 00E42285 mov eax,dword ptr [x] 00E42288 add eax,dword ptr [y] 00E4228B add eax,dword ptr [z] 00E4228E mov dword ptr [a],eax } 00E42291 pop edi 00E42292 pop esi 00E42293 pop ebx 00E42294 add esp,0CCh 00E4229A cmp ebp,esp 00E4229C call RTC_CheckEsp (0E4128Fh) 00E422A1 mov esp,ebp 00E422A3 pop ebp 00E422A4 ret
定义a,b,c值的函数
void fn1(int x, int y, int z) { 00972260 push ebp 00972261 mov ebp,esp 00972263 sub esp,0E4h //E4-C0=24 ,一共上移动6个格子,四个数为一个格子 00972269 push ebx 0097226A push esi 0097226B push edi 0097226C lea edi,[ebp-24h] 0097226F mov ecx,9 //?这里为什么要缓冲九个格子,而不是六个格子? 00972274 mov eax,0CCCCCCCCh 00972279 rep stos dword ptr es:[edi] 0097227B mov ecx,offset A8F2BFD7源@cpp (097F029h) 00972280 call @CheckForDebuggerJustMyCode@4 (097137Fh)
__
int a = 2;
00972285 mov dword ptr [a],2
int b = 3;
0097228C mov dword ptr [b],3
int c = 4;
00972293 mov dword ptr [c],4 } 0097229A pop edi 0097229B pop esi 0097229C pop ebx 0097229D add esp,0E4h 009722A3 cmp ebp,esp 009722A5 call __RTC_CheckEsp (097128Fh) 009722AA mov esp,ebp 009722AC pop ebp 009722AD ret
return x+y+z函数
int fn1(int x, int y, int z) { 00992260 push ebp 00992261 mov ebp,esp 00992263 sub esp,0C0h 00992269 push ebx 0099226A push esi 0099226B push edi 0099226C mov edi,ebp 0099226E xor ecx,ecx 00992270 mov eax,0CCCCCCCCh 00992275 rep stos dword ptr es:[edi] 00992277 mov ecx,offset A8F2BFD7源@cpp (099F029h) 0099227C call @CheckForDebuggerJustMyCode@4 (099137Fh) return x + y + z; 00992281 mov eax,dword ptr [x] 00992284 add eax,dword ptr [y] 00992287 add eax,dword ptr [z] } 0099228A pop edi 0099228B pop esi 0099228C pop ebx 0099228D add esp,0C0h 00992293 cmp ebp,esp 00992295 call RTC_CheckEsp (099128Fh) 0099229A mov esp,ebp 0099229C pop ebp 0099229D ret
自己编写的
int a=2;
int b=3;
int c=4;
return a+b+c+x+y+z;
push ebp
mov ebp,esp
sub esp,0E4h
push ebx
push esi
push edi
lea edi,[ebp-24h]
mov eax,CCCCCCCCh
mov ecx,6
rep stos dword ptr es:[edi]
mov ecx,offset A8F2BFD7源@cpp (097F029h)
call @CheckForDebuggerJustMyCode@4 (097137Fh)
mov dword ptr [a] ,2
mov dword ptr [b] ,3
mov dword ptr [c] ,4
mov eax,dword ptr [x]
add eax,dword ptr [y]
add eax,dword ptr [z]
add eax,dword ptr [a]
add eax,dword ptr [b]
add eax,dword ptr [c]
pop edi
pop esi
pop ebx
add esp,0E4h
cmp ebp,esp
call __RTC_CheckEsp (099128Fh)
mov esp,ebp
pop ebp
ret
标签:esp,edi,管旭,mov,eax,visual,studio,push,ebp From: https://www.cnblogs.com/zhz312/p/17857801.html