Re: 请问VC6调试版本在每个函数末尾都会插入_chkesp函数吗?

《软件调试》答疑

请问VC6调试版本在每个函数末尾都会插入_chkesp函数吗?


小兵 2010-04-30, 18:03 下午
P607 (从清单22-15往上数3行)
"当编译调试版本时,VC6会自动在每个函数的末尾插入指令来调用一个名为_chkesp的函数。"

然而,我发现VC6的调试版本:并不是在每个函数末尾都会插入_chkesp函数。

例如下例:
#include "stdafx.h"

int main(int argc, char* argv[])
{
    int i=0;
    return 0;
}

对应反汇编代码(使用VC6默认compile与link选项的调试版本,编译选项中有/GZ):
CheckThisPuzzle!main:
00401010 55              push    ebp
00401011 8bec           mov     ebp,esp
00401013 83ec44       sub     esp,44h
00401016 53               push    ebx
00401017 56               push    esi
00401018 57               push    edi
00401019 8d7dbc            lea     edi,[ebp-44h]
0040101c b911000000    mov     ecx,11h
00401021 b8cccccccc        mov     eax,0CCCCCCCCh
00401026 f3ab                     rep stos dword ptr es:[edi]
00401028 c745fc00000000  mov     dword ptr [ebp-4],0
0040102f 33c0           xor     eax,eax
00401031 5f               pop     edi
00401032 5e              pop     esi
00401033 5b              pop     ebx
00401034 8be5          mov     esp,ebp
00401036 5d              pop     ebp
00401037 c3               ret

我在原程序加上一个for循环后,在反汇编代码中也没有看到_chkesp的函数。
但是,在有些情况下确实会看到_chkesp的函数。

请问这是什么原因呀?
谢谢!

Re: 请问VC6调试版本在每个函数末尾都会插入_chkesp函数吗?


格蠹老雷 2010-05-01, 18:06 下午

这里的“每个”不够准确,的确如你所说,不是所有函数都会加_chkesp,对与ESP绝对不会被破坏的情况,编译器就没有必要再加这个检查,这有点像基于Cookie的溢出检查,是根据需要来加的,编译器内部有一个简单的判断规则。

多谢你的反馈。

Re: 请问VC6调试版本在每个函数末尾都会插入_chkesp函数吗?


小兵 2010-05-01, 19:19 下午
呵呵,Raymond老师,其实我不是对"每个"这两字较真。
而是因为不知道“编译器内部有一个简单的判断规则”,本想写个几个语句编译后看一看_chkesp,不料却没看到,呵呵,所以觉得有点奇怪。 :)

你所说的简单的判断规则可否理解为: 要看程序本身是否改变了ESP  (不考虑编译器自动加入的那些PUSH、POP指令,例如:PUSH esi等)

昨晚论坛一直不能访问,心中特焦急...
刚才看到老师的回复后,虽然还不是很明白,但大致有了一点了解。
说着说着貌似跑题了,呵呵

Re: 请问VC6调试版本在每个函数末尾都会插入_chkesp函数吗?


Oak 2010-05-05, 12:14 下午

_chkesp 是为了防止栈溢出攻击的防护代码,有些函数是要有的,但不是每个都有,像张老师说的一样。

像main函数,程序都退出了,也没有加_chkesp的必要了。即使能实现,感觉也不是很好能控制的住。

Powered by Community Server Powered by CnForums.Net