Windows异常学习笔记(一)—— CPU异常记录模拟异常记录
Windows異常學習筆記(一)—— CPU異常記錄
- 基礎知識
- 異常的分類
- CPU異常
- 分析中斷處理函數 _KiTrap00
- 分析 CommonDispatchException
- 總結
- 軟件模擬異常
- 實驗:分析模擬異常
- 第一步:編譯并運行以下代碼
- 第二步:查看匯編代碼
- 第三步:分析 __CxxThrowException
- 第四步:分析 RaiseException
- 第五步:分析 KiRaiseException
- 總結
基礎知識
一個異常產生后,首先是要記錄異常信息(異常的類型、異常發生的位置等),然后要尋找異常的處理函數,稱為異常的分發,最后找到異常處理函數并調用,稱為異常處理。
異常的分類
例一:在C語言中使用除法時,若CPU檢測到除數為0,便會拋出異常(CPU產生的異常)
例二:使用代碼拋出異常(軟件模擬產生異常)
CPU異常
處理流程:
1.CPU指令檢測到異常(例:除0),異常一定是先由CPU發現的
2.查IDT表,執行中斷處理函數,不同的異常調用不同的中斷處理函數
3.CommonDispatchException
4.KiDispatchExceeption
Windows異常代碼(出自 張銀奎《軟件調試》):
分析中斷處理函數 _KiTrap00
執行流程:
查看IDT表反匯編(通過 ntoskrnl.exe 搜索字符串 _IDT 進行定位):
[ebp+68h]:指向 _Trap_Frame 中的 Eip 的位置,當程序產生異常時,保存進入異常處理前的地址
0xC0000094h:除0異常的異常代碼
loc_407399 調用了 CommonDispatchException
總結:
分析 CommonDispatchException
CommonDispatchException在堆棧上構建了一個結構體,然后把異常的一些相關信息存儲到一個結構體里
結構體:
總結
CPU異常執行的流程:
1、CPU指令檢測到異常
2、查IDT表,執行中斷處理函數
3、調用CommonDispatchException(構建EXCEPTION_RECORD)
4、KiDispatchException(分發異常:目的是找到異常的處理函數)
軟件模擬異常
模擬異常的產生:
CxxThrowException
↓
(KERNEL32.DLL)RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments)
↓
NTDLL.DLL!RtlRaiseException()
↓
NT!NtRaiseException
↓
NT!KiRaiseException
實驗:分析模擬異常
第一步:編譯并運行以下代碼
#include <stdio.h>int main() {throw 1;getchar();return 0; }第二步:查看匯編代碼
可以看到,當人為拋出一個異常時,實際上就是調用了 __CxxThrowException 這樣一個函數
注意:本實驗使用的編輯器為vc6.0,為C++環境,在不同的環境中,調用的函數可能是不同的,但是最終調用的系統函數都是相同的
第三步:分析 __CxxThrowException
__CxxThrowException 調用了 Kernel32.dll 中的函數 RaiseException
第四步:分析 RaiseException
2. 調用 Ntdll.dll!RtlRaiseException
注意一:當CPU產生異常時會記錄一個ErrorCode,通過查表可以查到ErrorCode具體的含義,不同的異常對應不同的錯誤代碼,但是軟件拋出的ErrorCode是根據編譯環境決定的,如下圖的EDX中存儲的值即為當前編譯環境的ErrorCode
注意二:CPU記錄異常的地址是真正發生異常的地址,但軟件拋出異常時記錄的地址是__RaiseException函數的地址
第五步:分析 KiRaiseException
(IDA代碼待補充)
EXCEPTION_RECORD.ExceptionCode最高位清零 用于區分CPU異常。
調用 KiDispatchException 開始分發異常
總結
異常只有在記錄的時候處理方式不同,最終在分發時走向同一個地方
總結
以上是生活随笔為你收集整理的Windows异常学习笔记(一)—— CPU异常记录模拟异常记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows句柄表学习笔记 —— 句柄
- 下一篇: Windows异常学习笔记(二)—— 内