异常分发(用户异常)
文章目錄
- 內(nèi)容回顧:
- 用戶異常的處理流程:
- 總結(jié)
內(nèi)容回顧:
異常如果發(fā)送在內(nèi)核層,處理起來(lái)比較簡(jiǎn)單,因?yàn)楫惓L幚砗瘮?shù)也在0環(huán),不用切換堆棧,但是如果異常發(fā)生在3環(huán),就意味著必須要切換堆棧,回到3環(huán)執(zhí)行處理函數(shù)
切換堆棧的處理方式與用戶APC的執(zhí)行過程幾乎是一樣的,惟一的區(qū)別就是執(zhí)行用戶APC時(shí)返回3環(huán)后執(zhí)行的函數(shù)是KiUserApcDispatcher,而異常處理時(shí)返回3環(huán)后執(zhí)行的函數(shù)是KiUserExceprionDispatcher
所以,理解用戶APC的執(zhí)行過程是理解3環(huán)異常處理的關(guān)鍵
用戶異常的處理流程:
VOID KiDispatchException(ExceptionRecord,ExceptionFrame,TrapFrame,PreviousMode,FirstChance)
1._KeContextFromKframes 將Trap_frame備份到context為返回3環(huán)做準(zhǔn)備
第一步:不管用戶異常還是內(nèi)核異常,先把Trap_frame(當(dāng)前線程3環(huán)進(jìn)入0環(huán)時(shí),那些寄存區(qū)環(huán)境,也就是eip運(yùn)行地方那些值)備份到context里(為返回3環(huán)做準(zhǔn)備)
這個(gè)函數(shù)兩種異常(用戶異常和內(nèi)核異常)的分發(fā)都?xì)w它管,所以就存在異常處理是否需要回到三環(huán),內(nèi)核異常不用回去(內(nèi)核異常處理函數(shù)在0環(huán)),用戶異常需要回去(用戶層處理函數(shù)在3環(huán)0)。
2.第二步:判斷先前模式,0是內(nèi)核調(diào)用,1是用戶調(diào)用,用戶層異常呢,緊接著就是跳轉(zhuǎn):0x4258C3
第三步:第一次執(zhí)行時(shí),肯定是第一次調(diào)用(這個(gè)函數(shù)不止執(zhí)行一次),所以接著往下:
這里判斷是否啟用了內(nèi)核調(diào)試器,如果有內(nèi)核調(diào)試器的話,那么這個(gè)值是非零的,如果有內(nèi)核調(diào)試器的話,那它就調(diào)用,把異常信息先發(fā)送給異常調(diào)試器(那么我們此處假設(shè)沒有內(nèi)核異常調(diào)試器,或者內(nèi)核異常調(diào)試器沒有處理)
第四步:用來(lái)判斷3環(huán)調(diào)試器(3環(huán)調(diào)試器如果不存在或者3環(huán)調(diào)試器沒有處理的話,那么接著往下走)
第五步:為回到三環(huán)做準(zhǔn)備
一開始就把Trap_frame備份到context里,然后這里接下來(lái)就可以隨心所欲地改
最關(guān)鍵的修改,把KeUserExceptionDispatcher里面的值覆蓋到Eip,它并沒有在當(dāng)前位置直接返回三環(huán)。而是讓當(dāng)前程序結(jié)束執(zhí)行
總結(jié)
VOID KiDispatchException(ExceptionRecord,ExceptionFrame,TrapFrame,PreviousMode,FirstChance)
CPU異常:CPU檢測(cè)到異常—>查IDT執(zhí)行處理函數(shù)—>CommonDispatchException------>KiDispatchException 通過IRETD返回3環(huán)
模擬異常:CxxThrowException—>RaiseException—>RtlRaiseException---->Nt!NtRaiseException—>Nt!KiRaiseException---->KiDispatchException通過系統(tǒng)調(diào)用返回3環(huán)
總結(jié)
以上是生活随笔為你收集整理的异常分发(用户异常)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 异常分发(内核异常)
- 下一篇: SEH(结构化异常处理)