异常记录(CPU产生的异常和软件模拟产生的异常)
文章目錄
- 前奏
- 異常的分類
- CPU產(chǎn)生的異常
- 軟件模擬產(chǎn)生的異常
- 異常產(chǎn)生
- CPU異常的產(chǎn)生
- CommonDispatchException函數(shù)分析
- 總結(jié):
- 軟件模擬異常
- 填充ExceptionRecord結(jié)構(gòu)體
- KiRaiseException函數(shù)分析
- 總結(jié):
前奏
當(dāng)API函數(shù)3環(huán)進(jìn)0環(huán)時(shí),第一件事就是保存現(xiàn)場(chǎng),保存到_Trap_Frame
異常的分類
CPU產(chǎn)生的異常
錯(cuò)誤首先肯定被CPU先發(fā)現(xiàn),然后CPU就會(huì)執(zhí)行相應(yīng)的錯(cuò)誤處理程序
軟件模擬產(chǎn)生的異常
throw 1異常產(chǎn)生
CPU異常的產(chǎn)生
CPU指令檢測(cè)到異常(例:除0)------>查IDT表,執(zhí)行中斷處理函數(shù)--------->CommonDispatchException------>KiDispatchException
在跳轉(zhuǎn)CommonDispatchException之前,還傳了兩個(gè)參數(shù)
ebp+68h也就是上圖Trap結(jié)構(gòu)體的Eip
0x0c0000094h也就是ExceptionCode
傳了兩個(gè)參數(shù)后調(diào)用CommonDispatchException,
CommonDispatchException函數(shù)分析
該函數(shù)構(gòu)造一個(gè)_EXCEPTION_RECORD結(jié)構(gòu)體,并賦值
CommonDispatchException函數(shù)的作用也就是把一些值賦值給一個(gè)_EXCEPTION_RECORD結(jié)構(gòu)體
結(jié)構(gòu)體作用就是用來記錄異常信息
ExceptionFlags(給后面的處理程序所用,辨別異常狀態(tài))
Struct _EXCEPTION_RECORD* ExceptionRecord(通常為空,當(dāng)發(fā)生嵌套異常(當(dāng)異常處理程序里面又發(fā)生異常時(shí))這個(gè)指針會(huì)指向下一個(gè)異常)
總結(jié):
CPU異常執(zhí)行的流程:
軟件模擬異常
模擬異常的產(chǎn)生:
CxxThrowException------->(KERNEL32.DLL)RaiseException(DWORD dwException,DWORD dwExceptionFlags,DWORD nNumberOfArguments,const of ULONG_PTR *IPArguments)--------->NTDLL.DLL!RtIRaiseException()------->NT!NtRaiseException---->NT!KiRaiseException
填充ExceptionRecord結(jié)構(gòu)體
type struct _EXCEPTION_RECORD { DWORD ExceptionCode;//異常代碼(異常類型) DWORD ExceptionFlags;//異常狀態(tài) Struct _EXCEPTION_RECORD* ExceptionRecord;//下一個(gè)異常PVOID ExceptionAddress; //附加發(fā)生地址(異常發(fā)生地址)DWORD NumberParameters; //附加參數(shù)個(gè)數(shù)ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];//附加參數(shù)指針}
軟件模擬異常這個(gè)ExceptionCode是固定的,值取決于編譯環(huán)境,編譯環(huán)境不同,ExceptionCode也不同
這個(gè)ExceptionAddress并不是拋出異常的位置,而是存了一個(gè)固定的值,這個(gè)值就是函數(shù)RaiseException地址
(以上兩點(diǎn)就是CPU產(chǎn)生的異常和軟件模擬產(chǎn)生的異常之間的區(qū)別)
KiRaiseException函數(shù)分析
總結(jié):
CPU異常:
CPU指令檢測(cè)到異常------>查IDT表,執(zhí)行中斷處理函數(shù)--------->CommonDispatchException(填充ExceptionRecord結(jié)構(gòu)體)------>KiDispatchException
模擬異常:throw關(guān)鍵詞(依賴編譯器)---->CxxThrowException------->(KERNEL32.DLL)RaiseException(DWORD dwException,DWORD dwExceptionFlags,DWORD nNumberOfArguments,const of ULONG_PTR *IPArguments)(作用:填充ExceptionRecord結(jié)構(gòu)體)--------->NTDLL.DLL!RtIRaiseException()------->NT!NtRaiseException(ExceptionCode最高位清零)---->NT!KiRaiseException
CPU異常和模擬異常類型不同,僅僅異常記錄時(shí)不同,但是等到異常分發(fā)時(shí),就沒法區(qū)分了
總結(jié)
以上是生活随笔為你收集整理的异常记录(CPU产生的异常和软件模拟产生的异常)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: My First Window构造过程,
- 下一篇: 异常分发(内核异常)