您当前的位置:首页 > 计算机 > 编程开发 > C语言

C语言空函数分析

时间:12-20来源:作者:点击数:

实验环境:WIN7虚拟机

软件:VC6

首先在VC6里面写一个空函数Fun();

F7编译运行一下,没有出错,接着在函数处使用F9下断点,使程序运行到Fun函数时停下。

接着F5开始运行这个程序

程序停在了Fun函数处,反汇编进去进行逆向分析

可以看到程序停在Fun函数的入口处,这里的call就是Fun函数的入口,F11跟进去进行分析。

原始堆栈图是这样的。

0040D408 call @ILT+5(_Fun) (0040100a)

F11,跟进这个call进行分析,进入函数之后编译器会将跳出函数之后下一个要执行的地址压入堆栈,即将0040D40D压入堆栈,同时esp-4,esp变成0012FEF8,这时的堆栈是这样的:

跟进来之后是一个jmp,F11直接跳转。

现在进到函数里面了

00401010 push ebp

首先将ebp压栈,就是将[ebp]压入堆栈,即将0012FF48压入堆栈,然后esp的位置向上提升一个变为0012FEF4。

查看检查寄存器进行验证:

00401011 mov ebp,esp

将esp的值赋给ebp,也就是将0012FEF4赋给ebp,这时的堆栈图是这样的

查看寄存器验证,这里可以看到esp和ebp的值相等,说明上面那个堆栈图没有问题

00401013 sub esp,40h

将esp减去40h,也就是将esp的位置提升到0012FEB4位置,这一步的作用是提升堆栈,这时的堆栈图是这样的

查看寄存器进行验证,看到esp的值为0012FEB4

00401016 push ebx

接着将ebx压栈,查看栈顶可以看到ebx被压入堆栈,同时esp的位置向上提升。

此时的堆栈是这样的:

00401017 push esi

将esi的值压入堆栈,此时的堆栈是这样的

查看寄存器进行验证:

00401018 push edi

接着将edi的值压入堆栈,此时的堆栈是这样的

查看寄存器验证:

00401019 lea edi,[ebp-40h]

将[ebp-40h]的地址存入edi中,也就是将0012FEB4存入edi。

查看寄存器验证,可以看到0012FEB4被存入edi中

0040101C mov ecx,10h

将10h存入ecx中,也就是将00000010存入ecx,查看寄存器验证:

00401021 mov eax,0CCCCCCCCh

将CCCCCCCC存入eax中,查看寄存器验证:

00401026 rep stos dword ptr [edi]

将eax的中的值存储到[edi]对应地址的内存中,并重复ecx次,也就是将CCCCCCCC存入地址0012FEB4对应的内存中,并重复10h次,rep每执行一次,[edi]会相应的加4(向下填充数值),ecx会相应的减4(减少执行次数)。

此时的堆栈是这样的:

查看寄存器验证一下,发现从0012FEF4到0012FEB4全部被填充为CCCCCCCC。

00401028 pop edi

将edi出栈,也就是将esp当前对应的值0012FF48赋给edi,同时esp加4变成0012FEAC,此时的堆栈

查看寄存器验证:

00401029 pop esi

将esi出栈,也就是将esp当前对应的值00000000赋给edi,同时esp加4变成0012FEB0,此时的堆栈

查看寄存器验证:

0040102A pop ebx

将ebx出栈,也就是将esp当前对应的值7FFDD000赋给ebx,同时esp加4变成0012FEB4,此时的堆栈

查看寄存器验证一下:

0040102B mov esp,ebp

将ebp的值赋给esp,这里的作用相当于降低堆栈,此时的堆栈是这样的

查看寄存器进行验证,esp的值和ebp的值相等

0040102D pop ebp

将ebp出栈,也就是将esp当前对应的值0012FF48赋给ebx,这时ebx又回到了一开始所在的位置,同时esp加4变成0012FEF8,此时的堆栈是这样的

查看寄存器验证一下

0040102E C3 ret

相当于pop eip,即将当前esp对应的值放入eip中,也就是将0040D40D放入eip中,同时ESP+4,esp变为0012FEFC,此时的堆栈是这样的

查看寄存器验证一下,至此堆栈恢复平衡,Fun函数执行完毕

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门