日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

堆内存破坏检测实战--附完整调试过程

發(fā)布時(shí)間:2023/12/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆内存破坏检测实战--附完整调试过程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

首先解釋一下,什么是堆內(nèi)存?

堆是一種常見的內(nèi)存管理器,應(yīng)用程序通過(guò)堆來(lái)動(dòng)態(tài)地分配和釋放內(nèi)存,通常使用堆的情況是無(wú)法預(yù)先知道所需要的內(nèi)存大小,或者申請(qǐng)內(nèi)存太大,無(wú)法通過(guò)棧內(nèi)存來(lái)自動(dòng)分配,下面讓我們?cè)賮?lái)看一段英文解釋。

A heap is a form of memory manager that an application can use when it needs to allocate?and free memory dynamically. Common situations that call for the use of a heap?are when the size of the memory needed is not known ahead of time and the size of?the memory is too large to neatly fit on the stack (automatic memory).

常見的情況是由于效率或特殊需求一個(gè)進(jìn)程中同時(shí)使用幾個(gè)堆,如下圖:

?

?

?

下面通過(guò)一個(gè)完整的demo來(lái)帶大家調(diào)試一個(gè)對(duì)破壞問(wèn)題,demo代碼如下:

?

#define SZ_MAX_LEN? 10 void?__cdecl?wmain?(int?argc,?WCHAR*?args[])
{
????if(argc==2)
????{
????????wprintf(L"Press?any?key?to?start\n");
????????_getch();
????????DupString(args[1]);
????}
????else
????{
????????wprintf(L"Please?enter?a?string");
????}
}
BOOL?DupString(WCHAR*?psz)
{
????BOOL?bRet=FALSE;
????
????if(psz!=NULL)
????{
????????pszCopy=(WCHAR*)?HeapAlloc(GetProcessHeap(),?0,?SZ_MAX_LEN*sizeof(WCHAR));
????????if(pszCopy)
????????{
????????????wcscpy(pszCopy,?psz);
????????????wprintf(L"Copy?of?string:?%s",?pszCopy);
????????????HeapFree(GetProcessHeap(),?0,?pszCopy);
????????????bRet=TRUE;
????????}
????}
????return?bRet;

?

在應(yīng)用程序驗(yàn)證器下啟用普通頁(yè)堆,配置gflags,?運(yùn)行build出來(lái)的代碼,

輸入?yún)?shù)為:SolidmangoSolidmangoSolidmango

得到如下輸出:

?

CommandLine:?C:\WinXP.x86.chk\06overrun.exe?SolidmangoSolidmangoSolidmango
Executable?search?path?is:?
ModLoad:?01000000?01005000???06overrun.exe
ModLoad:?7c900000?7c9b2000???ntdll.dll
AVRF:?06overrun.exe:?pid?0x120C:?flags?0x8044B026:?application?verifier?enabled
ModLoad:?5ad10000?5ad59000???C:\WINDOWS\System32\verifier.dll
ModLoad:?10000000?10029000???C:\WINDOWS\System32\vrfcore.dll
ModLoad:?003a0000?003dc000???C:\WINDOWS\System32\vfbasics.dll
ModLoad:?7c800000?7c8f6000???C:\WINDOWS\system32\kernel32.dll
AVRF:?verifier.dll?provider?initialized?for?06overrun.exe?with?flags?0x8044B026?
ModLoad:?77c10000?77c68000???C:\WINDOWS\system32\msvcrt.dll
(120c.1700):?Break?instruction?exception?-?code?80000003?(first?chance)
eax=00391ec4?ebx=7ffd8000?ecx=00000004?edx=00000010?esi=00391f98?edi=00391ec4
eip=7c90120e?esp=0006fb20?ebp=0006fc94?iopl=0?????????nv?up?ei?pl?nz?na?po?nc
cs=001b??ss=0023??ds=0023??es=0023??fs=003b??gs=0000?????????????efl=00000202
ntdll!DbgBreakPoint:
7c90120e?cc??????????????int?????3
0:000>?g0:000>?g

?

我們會(huì)看到一個(gè)訪問(wèn)違例,?繼續(xù)運(yùn)行得到如下輸出,說(shuō)明應(yīng)用程序驗(yàn)證器驗(yàn)證成功:

?

=======================================
VERIFIER?STOP?00000008:?pid?0x120C:?Corrupted?heap?block.?

????00081000?:?Heap?handle?used?in?the?call.
????001E2B60?:?Heap?block?involved?in?the?operation.
????00000014?:?Size?of?the?heap?block.
????00000000?:?Reserved
=======================================
This?verifier?stop?is?not?continuable.?Process?will?be?terminated?
when?you?use?the?`go'?debugger?command.
=======================================
(120c.1700):?Break?instruction?exception?-?code?80000003?(first?chance)
eax=1000e848?ebx=1000cd44?ecx=00000001?edx=0006f939?esi=00000000?edi=1000e848
eip=7c90120e?esp=0006f9cc?ebp=0006fbd0?iopl=0?????????nv?up?ei?pl?nz?na?po?nc
cs=001b??ss=0023??ds=0023??es=0023??fs=003b??gs=0000?????????????efl=00000202
ntdll!DbgBreakPoint:
7c90120e?cc??????????????int?????3

?

繼續(xù)調(diào)試,此時(shí)我們已經(jīng)找到了出問(wèn)題的堆快,注意觀察上面的輸出中有這樣一條語(yǔ)句:

001E2B60?:?Heap?block?involved?in?the?operation,好的,讓我們看看這個(gè)堆塊里面是什么東西,

0:000>?dt?_DPH_BLOCK_INFORMATION?001E2B60-0x20
ntdll!_DPH_BLOCK_INFORMATION
???+0x000?StartStamp???????:?0xabcdaaaa
???+0x004?Heap?????????????:?0x80081000?Void
???+0x008?RequestedSize????:?0x14
???+0x00c?ActualSize???????:?0x3c
???+0x010?FreeQueue????????:?_LIST_ENTRY?[?0x1e?-?0x0?]
???+0x010?TraceIndex???????:?0x1e
???+0x018?StackTrace???????:?0x00286c3c?Void
???+0x01c?EndStamp?????????:?0xdcbaaaaa
0:000>?dds?0x00286c3c?//callstack
00286c3c??abcdaaaa
00286c40??00000001
00286c44??00000007
00286c48??00000001
00286c4c??00000014
00286c50??00081000
00286c54??00000000
00286c58??00286c5c
00286c5c??7c94b244?ntdll!RtlAllocateHeapSlowly+0x44
00286c60??7c919c0c?ntdll!RtlAllocateHeap+0xe64
00286c64??003afd2c?vfbasics!AVrfpRtlAllocateHeap+0xb1
00286c68??010012f4?06overrun!DupString+0x24?[c:\awd\chapter6\overrun\overrun.cpp?@?41]
00286c6c??010012ab?06overrun!wmain+0x2b?[c:\awd\chapter6\overrun\overrun.cpp?@?28]
00286c70??010014b8?06overrun!__wmainCRTStartup+0x102?[d:\vistartm\base\crts\crtw32\dllstuff\crtexe.c?@?711]
00286c74??7c817077?kernel32!BaseProcessStart+0x23
00286c78??00000000
我們找到了出問(wèn)題的callstack:
0:000>?kb
ChildEBP?RetAddr??Args?to?Child??????????????
0006f9c8?10003b68?10062cb0?00000008?001e2b60?ntdll!DbgBreakPoint
0006fbd0?100078c9?1000c540?00000008?00081000?vrfcore!VerifierStopMessageEx+0x4d1
0006fbf4?7c96c06e?00000008?7c96c314?00081000?vrfcore!VfCoreRedirectedStopMessage+0x81
0006fc70?7c96d147?00081000?00000004?001e2b60?ntdll!RtlpDphReportCorruptedBlock+0x17c
0006fc94?7c96d34a?00081000?01000002?00000010?ntdll!RtlpDphNormalHeapFree+0x2e
0006fce4?7c9703eb?00080000?01000002?001e2b60?ntdll!RtlpDebugPageHeapFree+0x79
0006fd58?7c94bafc?00080000?01000002?001e2b60?ntdll!RtlDebugFreeHeap+0x2c
0006fe40?7c91a1ba?00080000?01000002?001e2b60?ntdll!RtlFreeHeapSlowly+0x37
0006ff10?003afe9c?00080000?00000000?001e2b60?ntdll!RtlFreeHeap+0xf9
0006ff58?01001340?00080000?00000000?00000014?vfbasics!AVrfpRtlFreeHeap+0xf8
0006ff70?010012ab?00a64692?0006ffc0?010014b8?06overrun!DupString+0x70?[c:\awd\chapter6\overrun\overrun.cpp?@?47]
0006ff7c?010014b8?00000002?00a64648?00a66e98?06overrun!wmain+0x2b?[c:\awd\chapter6\overrun\overrun.cpp?@?28]
0006ffc0?7c817077?00daf6ee?00daf784?7ffd8000?06overrun!__wmainCRTStartup+0x102?[d:\vistartm\base\crts\crtw32\dllstuff\crtexe.c?@?711]
0006fff0?00000000?010015f6?00000000?78746341?kernel32!BaseProcessStart+0x23
0:000>?du?00a64692?
00a64692??"SolidmangoSolidmangoSolidmango"

?

總結(jié):

原來(lái)是我們的參數(shù)破壞了了堆內(nèi)存,終于找到了根源,我們代碼中定義的堆的大小為10,而我們使用的時(shí)候,由于堆塊越界,破壞了堆塊的完整性,從而導(dǎo)致了crash的發(fā)生..

?

注:本文的附圖和代碼靈感源自網(wǎng)絡(luò),具體出處不詳,其他內(nèi)容為原創(chuàng)..

總結(jié)

以上是生活随笔為你收集整理的堆内存破坏检测实战--附完整调试过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。