Posted on 2009-04-06 00:13
S.l.e!ep.¢% 閱讀(2063)
評論(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"
相差這么多? 中間一大截是干嘛的?