導(dǎo)讀:
版權(quán)聲明:轉(zhuǎn)載時(shí)請(qǐng)以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明
http://chenshine.blogbus.com/logs/4414354.html
剛 進(jìn)入計(jì)算機(jī)相關(guān)專(zhuān)業(yè)領(lǐng)域時(shí),大家最先用過(guò)的調(diào)試器大多會(huì)是Turbo C。它雖然古老但用過(guò)的人卻很多,然而嚴(yán)格的講,Turbo C是一個(gè)集成開(kāi)發(fā)環(huán)境,雖然擁有獨(dú)立的編譯器,鏈接器,卻沒(méi)有獨(dú)立的調(diào)試器,這和Visual Studio一樣。如果你做過(guò)DOS,早期Windows下的匯編,也許你會(huì)對(duì)Debug,CodeView等調(diào)試工具熟悉,但這些工具太老 了,Debug甚至不能調(diào)試32位程序,介紹它們與這篇文章的主旨不符,如果你對(duì)它們感興趣,可以去查閱相關(guān)資料。本文主要是介紹與調(diào)試技術(shù)相關(guān)的理論知 識(shí)以及常用調(diào)試器的使用,Windows設(shè)備驅(qū)動(dòng)程序與內(nèi)核的調(diào)試等。具體的講解方法是理論結(jié)合實(shí)踐,并且是站在給新手看的角度,循序漸進(jìn)的,用一個(gè)一個(gè) 調(diào)試會(huì)話向你展示每個(gè)重要命令的使用。
目錄
1。調(diào)試器
2。調(diào)試信息
3。用戶(hù)模式程序的調(diào)試
4。驅(qū)動(dòng)程序與內(nèi)核的調(diào)試
1 調(diào)試器1。1 概覽調(diào) 試器,與編譯器,鏈接器一樣,都屬于基礎(chǔ)軟件,它們?cè)谥谱魃隙加泻艽蟮碾y度,但盡管如此,現(xiàn)實(shí)中還是有不少專(zhuān)業(yè)級(jí)的調(diào)試器,微軟官方的就有 cdb,ntsd,WinDbg,kd等,還有SoftIce,OllyDbg等來(lái)自于其它公司的優(yōu)秀調(diào)試器。本文不可能對(duì)這幾個(gè)調(diào)試器一一介紹,一個(gè)是 限于篇幅,另一個(gè)是上面列舉的這幾個(gè)調(diào)試器無(wú)論是哪一個(gè)都需要你花很長(zhǎng)的時(shí)間去完全掌握(在市面上有很多書(shū)籍甚至專(zhuān)門(mén)講解某一個(gè)調(diào)試器的使用,比如 SoftIce)。雖然本文不會(huì)講解SoftIce的詳細(xì)使用,但我還是要對(duì)它進(jìn)行簡(jiǎn)短的介紹,因?yàn)樗忻耍踔帘萕indows出生的早。
1。2 SoftIceSoftIce 是NuMega公司生產(chǎn)的調(diào)試器,產(chǎn)于80年代后期,直到今天為止,這個(gè)軟件已經(jīng)變革過(guò)好幾次了,因?yàn)樘幚砥鞯捏w系結(jié)構(gòu)在更新,操作系統(tǒng)也在更新,所以調(diào) 試器也必須相應(yīng)的更新。它之所以有名,那是與歷史有關(guān)的,在Intel推出386 Cpu的時(shí)候,NuMega立即讓SoftIce支持了386 Cpu的新特性,同時(shí)吸引了大量黑客的使用,使它在黑客界產(chǎn)生了一定的地位(功能強(qiáng)大的調(diào)試器可以對(duì)軟件的保護(hù)機(jī)制進(jìn)行破解,如突破序列號(hào)之類(lèi)的)。在 Windows推出時(shí),所有的調(diào)試器都不適用這種新的系統(tǒng)軟件體系結(jié)構(gòu)了,唯一能用的就是微軟自己生產(chǎn)的調(diào)試器,卻很拙劣,這時(shí)NuMega又對(duì) SoftIce進(jìn)行了變革,不僅讓它可以在新的系統(tǒng)上很好的工作,甚至還可以調(diào)試Windows的內(nèi)核,這是當(dāng)時(shí)是不敢想象的。也正是因?yàn)樗芎玫男阅埽?卓越的功能,它成為了黑客們的寵兒,并且培養(yǎng)了幾代的黑客。讀完本文后,你自己應(yīng)該有能力去探索它,或許你也可以在這幾款調(diào)試器里找到適合自己的。
1。3 微軟的調(diào)試工具本 文主要介紹的是微軟官方的調(diào)試器,并且MS微軟也最積極,調(diào)試工具包一直在更新中。在微軟的調(diào)試器里,大家可能最為熟悉Visual Studio Debugger,就是你在Visual C++里使用的那個(gè),它并不是一個(gè)單獨(dú)可運(yùn)行的程序,而是內(nèi)嵌在Visual Studio中的,它的功能相對(duì)于上面幾個(gè)調(diào)試器來(lái)說(shuō)要弱很多,這里并不會(huì)對(duì)它進(jìn)行介紹,如果你想全方面的了解它的話,你可以去參考MSDN,那里專(zhuān)門(mén)有 幾章講解它,是一份很好的文檔化的資源(而且還是中文的)。其它的微軟調(diào)試工具cdb,ntsd,WinDbg,kd都在微軟的一個(gè)安裝包里,被稱(chēng)作
Debugging Tools for Windows(10 多M的大小,請(qǐng)通過(guò)這個(gè)鏈接下載并安裝,一會(huì)兒就要用到)。這些調(diào)試器在下文中會(huì)分別介紹,這里先做一個(gè)簡(jiǎn)單的區(qū)別,cdb與ntsd幾乎是一樣的程序, 唯一的不同是cdb是一個(gè)CUI程序,即Console程序,而ntsd是GUI程序,但ntsd并沒(méi)有產(chǎn)生窗口,而是又分配了一個(gè)Console窗口, 這個(gè)Console窗口就相當(dāng)于是cdb。它與真正的cdb執(zhí)行完全一樣的功能(官方如是說(shuō),然而實(shí)際上還有一些個(gè)不同)。在命令行中啟動(dòng)它們時(shí)下面兩句 命令有一樣的效果(C:/Progs/Debug是調(diào)試工具包的安裝位置):
C:/Progs/Debug/>start cdb
C:/Progs/Debug/>ntsd
cdb 與ntsd是用來(lái)調(diào)試用戶(hù)模式應(yīng)用程序的。kd調(diào)試器也是一個(gè)命令行程序,不過(guò)正如其名kernel debugger所描述的一樣,它是內(nèi)核調(diào)試器的,是驅(qū)動(dòng)程序開(kāi)發(fā)者,系統(tǒng)Hacker的最?lèi)?ài)。WinDbg是一個(gè)稱(chēng)職的GUI程序,它有菜單,有工具 欄,還有多個(gè)子窗口,可以分別顯示源代碼,調(diào)用棧,命令等,它既可以調(diào)試ring 0程序,也可以調(diào)試ring 3程序,其實(shí)它只是一個(gè)殼而已,當(dāng)調(diào)試ring 3級(jí)程序時(shí)它實(shí)際上是用cdb/ntsd,而當(dāng)調(diào)試ring 0級(jí)程序時(shí)是用kd。WinDbg的到來(lái)吸引了很多的人使用,你也將會(huì)發(fā)現(xiàn),它確實(shí)是一款優(yōu)秀的調(diào)試器。
2 調(diào)試信息
調(diào)試器之所以能夠工作,完全是依賴(lài)于編譯和鏈接程序時(shí)所生成的調(diào)試信息,當(dāng)然調(diào)試信息是具有一定的格式的。
2。1 格式微 軟的調(diào)試信息格式經(jīng)過(guò)了幾代變化,最終形成了Program DataBase這種格式,并且這種格式還在進(jìn)行版本上的更新,VS.Net所用的新的Program DataBase版本與Visual C++ 6.0所用的老的版本是不兼容的,并且你也可以用編譯器和鏈接器明確指定你想要生成的調(diào)試信息格式,這一點(diǎn)下文中有闡述。
2。2 內(nèi)容關(guān) 于調(diào)試信息我們還必須知道兩件事,一是調(diào)試信息包括哪些內(nèi)容,二是調(diào)試信息儲(chǔ)存在什么地方。其實(shí)調(diào)試信息所應(yīng)該包括的內(nèi)容正是調(diào)試信息格式變化的原因,從 COFF格式,到CodeView格式,到Program DataBase格式,調(diào)試信息變得越來(lái)越豐富了,并且是只多不少。Program DataBase格式的調(diào)試信息中主要包括了所有全局函數(shù),static 函數(shù),全局變量,static變量,局部變量,函數(shù)形參的名字及其位置,源代碼與可執(zhí)行文件中指令的映射信息,每個(gè)函數(shù)與變量的類(lèi)型,以及FPO信息,編 輯和繼續(xù)信息。編輯與繼續(xù)信息主要用于在Visual Studio中調(diào)試時(shí),可以在調(diào)試的同時(shí)編輯源代碼,并在接下來(lái)的調(diào)試中得到體現(xiàn)。Program DataBase格式的調(diào)試信息包含了這么多的內(nèi)容,所以用這種調(diào)試信息來(lái)調(diào)試程序時(shí),你將能夠得到更多,更準(zhǔn)確,更深入的反饋。
2。3 存儲(chǔ)位置調(diào) 試信息的存儲(chǔ)位置是與其格式相關(guān)的,Program DataBase格式的調(diào)試信息存儲(chǔ)在一個(gè)單獨(dú)的文件里,擴(kuò)展名為pdb。像以前的CodeView格式的調(diào)試信息即可存儲(chǔ)在單獨(dú)的文件里,又可存儲(chǔ)在編 譯時(shí)所生成的obj文件中。知道了這些知識(shí)后,我們就可以正確地生成調(diào)試信息了。在后面的內(nèi)核調(diào)試中我們還要繼續(xù)談到它。
3 用戶(hù)模式程序的調(diào)試根 據(jù)上面的講述,我們可以用cdb或WinDbg來(lái)進(jìn)行ring 3程序的調(diào)試,這里先講解cdb。cdb允許你啟動(dòng)某個(gè)被調(diào)試程序(以下稱(chēng)debugee)的一個(gè)新的實(shí)例來(lái)進(jìn)行調(diào)試,即先創(chuàng)建cdb,然后cdb再把你 所指定的程序創(chuàng)建為一個(gè)新進(jìn)程進(jìn)而對(duì)其調(diào)試,也允許debugee在已經(jīng)運(yùn)行的情況下被cdb attach上。cdb還可以對(duì)Crash Dump(程序崩潰時(shí)的內(nèi)存Copy,下文將會(huì)說(shuō)明)進(jìn)行調(diào)試,只需要加上-z選項(xiàng),后面再加上Crash Dump的文件名即可。這幾種調(diào)試方式下面將會(huì)一一講述。
3。1 調(diào)試前的準(zhǔn)備
第 2節(jié)中對(duì)調(diào)試信息進(jìn)行了理論上的說(shuō)明,接下來(lái)我們來(lái)看看在實(shí)際中應(yīng)該如何操作。首先我們的程序必須要經(jīng)過(guò)編譯,鏈接,并且在編譯和鏈接時(shí)還要指定一些選項(xiàng) 以正確地生成調(diào)試信息。這里所使用的編譯器是cl.exe,鏈接器是link.exe,都是微軟官方的,Visual Studio就是用的這兩個(gè)(CTRL+F5就是順序調(diào)用cl和link的快捷鍵),如果你安裝了Visual C++或Visual Studio,就會(huì)有它們,另外一種選擇是安裝SDK,也能夠得到它們。本文所用的cl.exe和link.exe是Visual C++ 6.0的版本。若要生成調(diào)試信息,編譯時(shí)我們需要加上的選項(xiàng)應(yīng)是/Zi,而鏈接時(shí)則要加上/debug。在下面的調(diào)試中,我們將用C語(yǔ)言來(lái)寫(xiě)程序,所以你 有必要知道用C語(yǔ)言寫(xiě)出來(lái)的程序與用匯編寫(xiě)出來(lái)的有什么不同。首先,每個(gè)程序都有一個(gè)入口函數(shù),它的地址需要在鏈接時(shí)指定,并被鏈接器放到最終可執(zhí)行文件 的頭部,通常用匯編語(yǔ)言寫(xiě)的程序,有選擇的,你可以在源代碼中指定入口函數(shù),而用C語(yǔ)言寫(xiě)的程序則需要在鏈接的時(shí)候來(lái)指定入口函數(shù),說(shuō)到這你可能不以為 然,“C語(yǔ)言寫(xiě)的程序的入口函數(shù)不就是main嗎?“。實(shí)際上,控制臺(tái)C程序的入口函數(shù)默認(rèn)情況下是C運(yùn)行時(shí)的啟動(dòng)函數(shù):mainCRTStartup。 然后由這個(gè)函數(shù)調(diào)用你寫(xiě)的main函數(shù),所以可執(zhí)行文件的頭部存放的入口地址是mainCRTStartup的地址,而不是你寫(xiě)的main函數(shù)地址。 mainCRTStartup主要做了一些為了正確執(zhí)行C/C++程序的初始化工作。它已經(jīng)由微軟寫(xiě)好了,由鏈接器自動(dòng)鏈接到可執(zhí)行文件中。如果你在程序 中不使用C語(yǔ)言的庫(kù)以及一些ANSI規(guī)定的全局變量,只是單純地使用C語(yǔ)言這種語(yǔ)法,那么你也可以不鏈接mainCRTStartup,直接指定你自己寫(xiě) 的某個(gè)函數(shù)為入口函數(shù),這也是我們?cè)谙挛闹兴褂玫姆椒ǎ唧w的做法是在鏈接時(shí)加入如下選項(xiàng):/subsystem:console /entry:你的入口函數(shù)名稱(chēng)。這個(gè)入口函數(shù)應(yīng)該是不帶參數(shù)的。現(xiàn)在我們來(lái)總結(jié)一下上面所講的內(nèi)容,假定你的源程序名為exam.c,你想指定的入口函 數(shù)為main,那么應(yīng)該如下生成可執(zhí)行程序:
C:/Pro/>cl /Zi exam.c /link /debug /subsystem:console /entry:main
另 外,就算你不鏈接mainCRTStartup(它會(huì)調(diào)用很多的Win32 API),也不在源程序中調(diào)用任何的系統(tǒng)函數(shù)。那么系統(tǒng)還是會(huì)把一些動(dòng)態(tài)鏈接庫(kù),如kernel32.dll,Ntdll.dll等動(dòng)態(tài)鏈接到你的程序所 對(duì)應(yīng)的進(jìn)程里,即把它們映射到你的程序?qū)?yīng)的進(jìn)程地址空間里。這是因?yàn)樵谀闼付ǖ娜肟诤瘮?shù)運(yùn)行之前,還會(huì)有一系列的 Kernel32.dll,Ntdll.dll中的函數(shù)要運(yùn)行。即在用戶(hù)空間中你指定的入口函數(shù),例如上面的main,根本不是第一個(gè)運(yùn)行的函數(shù)。那么那 些函數(shù)是做什么的呢,通過(guò)大量的反匯編和調(diào)試能夠推斷出它們是做一些進(jìn)程,線程在用戶(hù)空間的初始化,設(shè)置一些異常楨等。在下面的調(diào)試中我們將會(huì)用一些手段 來(lái)研究它們。這些函數(shù)是操作系統(tǒng)的一部分,因些我們必須從官方網(wǎng)站下載它的符號(hào)文件,當(dāng)然不下載也行,那么你將面臨的會(huì)是一大堆的警告。說(shuō)到下載,沒(méi)有比 這更簡(jiǎn)單的了,你不需要預(yù)先的下載,只需要添加一個(gè)環(huán)境變量_NT_SYMBOL_PATH即可,而真正的下載工作由調(diào)試器來(lái)做,這個(gè)環(huán)境變量的值與已存 在的PATH環(huán)境變量類(lèi)似,是由分號(hào)分隔的一系列的路徑組成。這些路徑應(yīng)該包括你的調(diào)試信息文件(pdb文件)所在地,如前面的C:/Pro/。如果要下 載系統(tǒng)文件如Kernel32.dll,Ntdll.dll的pdb文件,你僅僅需要再加一個(gè)這樣的路徑:SRV*D:/Symbols*http: //msdl.microsoft.com/download/symbols,其中D:/Symbols是可更換的,你可以換成任何一個(gè)其它的路徑,這 個(gè)D:/Symbls是用來(lái)存放從后面的URL路徑所下載下來(lái)的系統(tǒng)調(diào)試信息文件的。其實(shí)你也可以預(yù)先下載系統(tǒng)調(diào)試信息文件到一個(gè)路徑里,然后在 _NT_SYMBOL_PATH里指定那個(gè)目錄,但這樣一來(lái)有兩個(gè)缺點(diǎn),一是你必須得進(jìn)行版本的匹配,做這件事簡(jiǎn)直太乏味了,二是你一次需要把整個(gè)操作系 統(tǒng)的調(diào)試信息文件都下載下來(lái),可能會(huì)需要1G的空間。而通過(guò)前面設(shè)置環(huán)境變量的方式,調(diào)試器會(huì)根據(jù)需要只下載這次調(diào)試會(huì)話所需要的調(diào)試信息文件,并且它會(huì) 自動(dòng)給你匹配版本。由于我們將要編寫(xiě)的源代碼都在C:/Pro/文件夾中,生成的pdb文件也在C:/Pro/中,所以我們的 _NT_SYMBOL_PATH環(huán)境變量應(yīng)該如下設(shè)置,假設(shè)你希望系統(tǒng)pdb文件下載到D:/Symbols:
C:/Pro/>set _NT_SYMBOL_PATH=SRV*D:/Symbols*http://msdl.microsoft.com/download/symbols;C:/Pro/
最后,我們需要在命令行中啟動(dòng)cdb調(diào)試器,但當(dāng)前目錄通常是源代碼文件夾C:/Pro/,為了避免如下冗余的鍵入:
C:/Pro/>C:/Progs/Debug/cdb example1.exe
應(yīng)該為cdb,ntsd,WinDbg設(shè)置PATH環(huán)境變量:
C:/Pro/>set PATH=%PATH%;C:/Progs/Debug/
這里的C:/Progs/Debug是Debugging Tools for Windows的安裝目錄。以后就可以這樣來(lái)調(diào)試了:
C:/Pro/>cdb example1.exe
3。2 cdb啟動(dòng)新實(shí)例的調(diào)試3。2。1 編寫(xiě)一源程序,啟動(dòng)cdb首先我編寫(xiě)了下面的C程序,先用這個(gè)程序來(lái)介紹一些基本的命令,并且來(lái)驗(yàn)證一下調(diào)試信息中是否確切包含了上面所說(shuō)的那些內(nèi)容:
[example1.c]int gVar;
static int sgVar;
int Inc(int Param);
static int sDec(int sParam);
void main(void)
{
int lVar;
static int slVar;
lVar = 3;
slVar = 4;
gVar = Inc(lVar);
sgVar = sDec(slVar);
}
int Inc(int Param)
{
return (Param+1);
}
int sDec(int sParam)
{
return (sParam-1);
}
對(duì)這個(gè)程序用上面所講的方法編譯鏈接:
C:/Pro/>cl /Zi example1.c /link /debug /subsystem:console /entry:main
接下來(lái)啟動(dòng)cdb調(diào)試器:
C:/Pro/>cdb example1.exe
Microsoft (R) Windows Debugger
Copyright (c) Microsoft Corporation. All rights reserved.
CommandLine: example1.exe
Symbol search path is: SRV*D:/Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
ModLoad: 00400000 00406000 example1.exe
ModLoad: 7c920000 7c9b4000 ntdll.dll
ModLoad: 7c800000 7c91c000 C:/WINDOWS/system32/kernel32.dll
(c94.c24): Break instruction exception - code 80000003 (first chance)
eax=00251eb4 ebx=7ffd4000 ecx=00000001 edx=00000002 esi=00251f48 edi=00251eb4
eip=7c921230 esp=0012fb20 ebp=0012fc94 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:
7c921230 cc int 3
0:000>
cdb 輸出了此時(shí)主線程的上下文信息(這個(gè)例子中也只有這一個(gè)線程)以及程序斷點(diǎn)信息后便會(huì)進(jìn)入一個(gè)新的提示符:0:000>。以后我們會(huì)一直工作在這種 類(lèi)型的提示符上,下面在這個(gè)提示符上輸入一個(gè)命令來(lái)加載所有的調(diào)試信息文件,此時(shí)可能會(huì)慢一些,因?yàn)橐螺d系統(tǒng)DLL的pdb文件,所以要確保你能上網(wǎng)。
0:000>.reload /f
看到這個(gè)以"."號(hào)做為前綴的命令,可能你會(huì)覺(jué)得怪怪的,但實(shí)際上還有用"!"號(hào)做前綴的呢,用"."號(hào)做前綴的命令表示元命令,而用"!“號(hào)做前綴的命令表示擴(kuò)展命令,這里只做一個(gè)簡(jiǎn)單的區(qū)分即可。
其 實(shí)這時(shí)我們所要調(diào)試的程序已經(jīng)運(yùn)行起來(lái)了,不過(guò)停在了某處,主線程處于凍結(jié)狀態(tài)。這一點(diǎn)和Linux的Gnu調(diào)試器GDB不一樣,對(duì)于GDB調(diào)試器,你先 要設(shè)置一個(gè)斷點(diǎn),然后再鍵入運(yùn)行命令(如果自己不手動(dòng)設(shè)置一個(gè)斷點(diǎn),那么程序?qū)?huì)一直運(yùn)行直到結(jié)束,你根本沒(méi)有調(diào)試的機(jī)會(huì)。),這時(shí)程序才處于運(yùn)行狀態(tài)。 沒(méi)有運(yùn)行和運(yùn)行之后處于凍結(jié)狀態(tài)是兩個(gè)完全不同的概念。那么我們這個(gè)example1.exe停在了什么地方呢。下面我將介紹一個(gè)很重要的命令,用它我們 可以來(lái)研究這方面的問(wèn)題。
3。2。2 查看堆棧及用戶(hù)空間的初始化用kb命令可以來(lái)查看堆棧,它顯示棧上一些重要的信息。
0:000>kb
ChildEBP RetAddr Args to Child
0012fb1c 7c95edc0 7ffdf000 7ffd4000 00000000 ntdll!DbgBreakPoint
0012fc94 7c941639 0012fd30 7c920000 0012fce0 ntdll!LdrpInitializeProcess+0xffa
0012fd1c 7c92eac7 0012fd30 7c920000 00000000 ntdll!_LdrpInitialize+0x183
00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7
這個(gè)命令所列出來(lái)的信息后面還要詳細(xì)介紹,這里先關(guān)注一下函數(shù)的調(diào)用關(guān)系。從上面的列表可以看到有四個(gè)函數(shù),這四個(gè)函數(shù)都是ntdll模塊里的,從下至上函數(shù)依次被調(diào)用。要注意這是當(dāng)前線程的用戶(hù)棧里所有的東西,就四個(gè)函數(shù),
KiUserApcDispatcher是第一個(gè),上面已經(jīng)提到過(guò),在你指定的入口函數(shù)執(zhí)行之前還有很多的函數(shù)被調(diào)用,
KiUserApcDispatcher是第一個(gè)被調(diào)用的,接下來(lái)它再調(diào)用
_LdrpInitialize,
_LdrpInitialize調(diào)用
LdrpInitializeProcess,再調(diào)用
DbgBreakPoint。至于是誰(shuí)調(diào)用的
KiUserApcDispatcher,我現(xiàn)在只能簡(jiǎn)單的告訴你是操作系統(tǒng)調(diào)度例程調(diào)度的結(jié)果。深入地探討它就離開(kāi)本文的主題了。現(xiàn)在我們可以肯定的是程序停在了
DbgBreakPoint里,因?yàn)樗菞I献詈笠粋€(gè)函數(shù)。從cdb調(diào)試器的輸出可以看到example1.exe停在了
DbgBreakPoint函數(shù)里的
int 3語(yǔ)句上,
int 3是一個(gè)異常,它將會(huì)通知操作系統(tǒng)掛起這個(gè)線程,并且通知調(diào)試器,這是操作系統(tǒng)對(duì)調(diào)試的一個(gè)支持。其實(shí)
DbgBreakPoint函數(shù)只有一條語(yǔ)句,那就是
int 3。敏感點(diǎn)的人可能會(huì)想到,這樣一來(lái),所有的程序,無(wú)論是否被調(diào)試,在運(yùn)行的時(shí)候最初都會(huì)執(zhí)行
DbgBreakPoint函數(shù)了,這也太傻了吧?情況并非如此,當(dāng)我們鍵入cdb example1.exe時(shí),cdb在啟動(dòng)example1.exe的時(shí)候會(huì)加一個(gè)特殊的標(biāo)記,在這種情況下
LdrpInitializeProcess才會(huì)調(diào)用
DbgBreakPoint,這又是操作系統(tǒng)對(duì)調(diào)試的一個(gè)支持。
本文轉(zhuǎn)自
http://chenshine.blogbus.com/logs/4414354.html