Posted on 2009-04-06 00:13
S.l.e!ep.¢% 阅读(2054)
评论(4) 编辑 收藏 引用 所属分类:
WinDbg
#include <iostream>
using namespace std;
int main()
{
const char* p = "test";
char szBuf[53221] = {0};
memcpy(szBuf, p, sizeof(szBuf)); // Debug "0x004082f0" 指令引用的 "0x0043e000" 内存。该内存不能为 "read"
// Relase 无报错
/*
0:000> g
(410.c88): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0043e001 ebx=7ffd9000 ecx=00000000 edx=00000001 esi=0043e000 edi=0012ff78
eip=004082f0 esp=00122f2c ebp=00122f34 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
*** WARNING: Unable to verify checksum for test.exe
test!TrailUpVec+0x18:
004082f0 8a06 mov al,byte ptr [esi] ds:0023:0043e000=??
0:000> !address esi
0043e000 : 0043e000 - 7c3c2000
Type 00000000
Protect 00000001 PAGE_NOACCESS
State 00010000 MEM_FREE
Usage RegionUsageFree
很明显访问到不应该访问的内存了
0:000> knL
# ChildEBP RetAddr
00 00122f34 00401084 test!TrailUpVec+0x18
01 0012ff80 00408749 test!main+0x54
02 0012ffc0 7c816fd7 test!mainCRTStartup+0xe9
03 0012fff0 00000000 kernel32!BaseProcessStart+0x23
首先 bp main
再 p
test!main+0x22:
00401052 c745fc1c104300 mov dword ptr [ebp-4],offset test!`string' (0043101c)
0:000> dc 0043101c
0043101c 74736574 00000000 00432880 00402dd0 test.....(C..-@.
0043102c 00000000 00000004 004328e8 00402e10 .........(C...@.
0043103c 00432938 00402e40 00000000 00000008 8)C.@.@.........
0043104c 004329a0 00402eb0 00402550 004027b0 .)C...@.P%@..'@.
0043105c 004020d0 00402980 004029e0 00402180 . @..)@..)@..!@.
0043106c 004022b0 00402bb0 00402c40 00402d40 ."@..+@.@,@.@-@.
0043107c 00402d90 00402430 004329d0 00402e80 .-@.0$@..)C...@.
0043108c 00402080 004020b0 004020d0 004020e0 . @.. @.. @.. @.
0:000> !address 0043DFFF
00400000 : 0043c000 - 00002000
Type 01000000 MEM_IMAGE
Protect 00000002 PAGE_READONLY
State 00001000 MEM_COMMIT
Usage RegionUsageImage
FullPath test.exe
0:000> !address 0x0043e000
0043e000 : 0043e000 - 7c3c2000
Type 00000000
Protect 00000001 PAGE_NOACCESS
State 00010000 MEM_FREE
Usage RegionUsageFree
计算机内存运行分配的区域分为3个
程序段区域:不允许写的
数据段区域:静态全局变量是位于数据段并且在程序开始运行的时候被加载
堆栈区域:放置程序的动态的用于计算的局部和临时变量则分配在堆栈里面和在过程调用中压入的返回地址数据。堆栈是一个先入后出的队列。一般计算机系统堆栈的方向与内存的方向相反。压栈的操作push=ESP-4,出栈的操作是pop=ESP+4.
*/
return 0;
}
BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。
数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
事实上,当 release 取消优化时,也会报错
char szBuf[20320] = {0}; 改成这样,有可能不会报错
release 版的
"0x004044f0"指令引用的"0x00413000"内存。该内存不能为"read"。
跟
debug 版的
"0x004082f0" 指令引用的 "0x0043e000" 内存。该内存不能为 "read"
相差这么多? 中间一大截是干嘛的?