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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows异常学习笔记(一)—— CPU异常记录模拟异常记录

發布時間:2025/3/21 windows 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows异常学习笔记(一)—— CPU异常记录模拟异常记录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Windows異常學習筆記(一)—— CPU異常記錄

    • 基礎知識
    • 異常的分類
    • CPU異常
      • 分析中斷處理函數 _KiTrap00
      • 分析 CommonDispatchException
      • 總結
    • 軟件模擬異常
      • 實驗:分析模擬異常
        • 第一步:編譯并運行以下代碼
        • 第二步:查看匯編代碼
        • 第三步:分析 __CxxThrowException
        • 第四步:分析 RaiseException
        • 第五步:分析 KiRaiseException
      • 總結

基礎知識

一個異常產生后,首先是要記錄異常信息(異常的類型、異常發生的位置等),然后要尋找異常的處理函數,稱為異常的分發,最后找到異常處理函數并調用,稱為異常處理

異常的分類

  • CPU產生的異常
  • 軟件模擬產生的異常
  • 例一:在C語言中使用除法時,若CPU檢測到除數為0,便會拋出異常(CPU產生的異常

    例二:使用代碼拋出異常(軟件模擬產生異常

    CPU異常

    處理流程

    1.CPU指令檢測到異常(例:除0),異常一定是先由CPU發現的
    2.查IDT表,執行中斷處理函數,不同的異常調用不同的中斷處理函數
    3.CommonDispatchException
    4.KiDispatchExceeption

    Windows異常代碼(出自 張銀奎《軟件調試》):

    分析中斷處理函數 _KiTrap00

    執行流程

  • 保存現場(將寄存器堆棧位置等信息保存到 _Trap_Frame 中)
  • 調用CommonDispatchException函數(分析參數EAX,EBX中的值)
  • 查看IDT表反匯編(通過 ntoskrnl.exe 搜索字符串 _IDT 進行定位):



    [ebp+68h]:指向 _Trap_Frame 中的 Eip 的位置,當程序產生異常時,保存進入異常處理前的地址
    0xC0000094h:除0異常的異常代碼
    loc_407399 調用了 CommonDispatchException

    總結

  • 異常處理函數中并沒有直接對異常進行處理,而是調用了CommonDispatchException
  • 這樣設計異常的目的是為了程序員有機會對異常進行處理
  • 分析 CommonDispatchException

    CommonDispatchException在堆棧上構建了一個結構體,然后把異常的一些相關信息存儲到一個結構體里

    結構體:

    type struct _EXCEPTION_RECORD { DWORD ExceptionCode; //異常代碼,除0時為0x0C0000094DWORD ExceptionFlags; //異常狀態,0位CPU異常,1位軟件模擬異常,堆棧異常為8等等struct _EXCEPTION_RECORD* ExceptionRecord; //下一個異常,通常為空PVOID ExceptionAddress; //異常發生地址DWORD NumberParameters; //附加參數個數ULONG_PTR ExceptionInformation [EXCEPTION_MAXIMUM_PARAMETERS]; //附加參數指針 }

    總結

    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

  • 填充ExceptionRecord結構體
  • type struct _EXCEPTION_RECORD { DWORD ExceptionCode; //異常代碼DWORD ExceptionFlags; //異常狀態struct _EXCEPTION_RECORD* ExceptionRecord; //下一個異常PVOID ExceptionAddress; //異常發生地址DWORD NumberParameters; //附加參數個數ULONG_PTR ExceptionInformation [EXCEPTION_MAXIMUM_PARAMETERS]; //附加參數指針 }


    2. 調用 Ntdll.dll!RtlRaiseException


    注意一:當CPU產生異常時會記錄一個ErrorCode,通過查表可以查到ErrorCode具體的含義,不同的異常對應不同的錯誤代碼,但是軟件拋出的ErrorCode是根據編譯環境決定的,如下圖的EDX中存儲的值即為當前編譯環境的ErrorCode

    注意二CPU記錄異常的地址是真正發生異常的地址,但軟件拋出異常時記錄的地址是__RaiseException函數的地址

    第五步:分析 KiRaiseException

    (IDA代碼待補充)

  • EXCEPTION_RECORD.ExceptionCode最高位清零 用于區分CPU異常。

  • 調用 KiDispatchException 開始分發異常

  • 總結

    異常只有在記錄的時候處理方式不同,最終在分發時走向同一個地方

    總結

    以上是生活随笔為你收集整理的Windows异常学习笔记(一)—— CPU异常记录模拟异常记录的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。