VC在Debug模式下的变量内存布局

来源:互联网 发布:如何成为淘宝粉丝 编辑:程序博客网 时间:2024/06/05 20:09

VCDebug模式下编译程序,编译器在内存处理中加入许多额外的代码以方便发现程序中可能出现的越界现象。先做个小测试,下面这个程序可以看到有个小越界。 

void FMemoryAllocTest()

{

     int x[4];

     int y1, y2, y3;

     x[0] = 0;

     x[1] = 1;

     x[2] = 2;

     x[3] = 3;

     x[4] = 4;

     y1 = 5;

     y2 = 6;

     y3 = 7;

}

 

先看看进入函数时编译器作了什么工作。其中绿色部分是正常的初始化部分,而红色部分就是在Debug中的额外处理,它把函数栈从栈顶开始的一段内存全部填上0XCC

void FMemoryAllocTest()

{

00411B10  push        ebp 

00411B11  mov         ebp,esp

00411B13  sub         esp,108h

00411B19  push        ebx 

00411B1A  push        esi 

00411B1B  push        edi 

00411B1C  lea         edi,[ebp-108h]

00411B22  mov         ecx,42h

00411B27  mov         eax,0CCCCCCCCh

00411B2C  rep stos    dword ptr es:[edi]

 

而当函数退出时,它会调用一个检查函数测试是否有内存越界。

}

00411B66  push        edx 

00411B67  mov         ecx,ebp

00411B69  push        eax 

00411B6A  lea         edx,[ (411B80h)]

00411B70  call        @ILT+145(@_RTC_CheckStackVars@8) (411096h)

00411B75  pop         eax 

00411B76  pop         edx 

00411B77  pop         edi 

00411B78  pop         esi 

00411B79  pop         ebx 

00411B7A  mov         esp,ebp

00411B7C  pop         ebp 

00411B7D  ret             

 

 

现在再看看具体的变量在内存中的布局。下面是在我系统中的一个例子。其中红色部分是越界内存,绿色为变量位置。

0x0012FE10  cc cc cc cc cc cc cc cc 07 00 00 00 cc cc cc cc 

0x0012FE20  cc cc cc cc 06 00 00 00 cc cc cc cc cc cc cc cc 

0x0012FE30  05 00 00 00 cc cc cc cc cc cc cc cc 00 00 00 00 

0x0012FE40  01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 

0x0012FE50  68 ff 12 00 03 36 41 00 00 00 00 00 9c f9 05 06

 

由上面内存可见,变量x,y1,y2,y3等的内存分布如下表。可见从变量的声明顺序,按照地址递减的顺序依次分配内存,而且每个变量都不是连续存在,而是被0xcc包围。这样如果我们在调试状态下察看内存内容,有经验的话可以幸运的发现是否有内存越界。或者,可以通过这一功能,开发特殊的工具来进行检测。

0x0012FE10 

cc cc cc cc

cc cc cc cc

Y3

cc cc cc cc

0x0012FE20 

cc cc cc cc

Y2

cc cc cc cc

cc cc cc cc

0x0012FE30 

Y1

cc cc cc cc

cc cc cc cc

X[0]

0x0012FE40 

X[1]

X[2]

X[3]

cc cc cc cc

0x0012FE50 

EBP

Return address

 

函数退出时,编译器捕捉到了这一越界,弹出一个对话框:

原创粉丝点击