windows核心基礎與異常處理

2022-09-20 03:33:08 字數 3532 閱讀 4722

前兩日碰到了用異常處理來做加密的re題目 所以系統學習一下windows核心相關

核心層:r0 零環 核心態工作區域 大多數驅動程式

應用層:r3 使用者態工作區域 只能使用win32 api與系統互動

當使用者呼叫乙個有關i/o的api時

該api封裝在乙個使用者層的dll檔案中(如kernel32.dll或user32.dll)

此dll函式的更底層函式被包含在ntdll.dll中

即使用者呼叫的系統api在ntdll.dll均有對應

(ntdll.dll中的函式均為成對出現 且為nt與zw開頭 他們本質一樣)

當呼叫到ntdll.dll中的函式時,檢查完引數後,會通過int 2eh或sysenter進入r0核心層

呼叫核心ntoskrnl.exe中的ssdt(系統服務處理函式)他們與ntdll.dll的函式一一對應

從使用者態呼叫 nt 與zw 函式時**

完全一致 均為設定系統服務表與棧中引數後由sysenter跳入核心態

再由kisystemservice跳入對應系統例程

**會嚴格檢驗傳入引數

從核心態呼叫 nt 與zw 函式時**

nt* api:直接呼叫對應函式**

zw* api:由kisystemservice跳入對應函式**

使用者模式nt*api會將previous mode改為使用者態

核心模式nt*api會將previous mode改為核心態

zw*api只有使用者態 但一呼叫就會將previous mode改為核心態

而zw*不會嚴格檢查傳入引數 進而提高效率

zw和nt在表面功能一模一樣!

也可使用raiseexception()函式來主動丟擲乙個異常

window正常啟動後執行在保護模式下,當中斷或異常發生時,cpu會通過idt(中斷描述符表 interrupt descriptor table)來尋找相對應的處理函式

idt存在於物理記憶體中 共有256項 32位每項8位元組 64位中每項64位元組

每個cpu中都有乙份idt拷貝 下面主要考慮32位

會根據異常號來尋找異常處理函式 如中斷號03(即int 3)對應斷點異常 由nt!kitrap03 函式處理

該函式封裝異常資訊(包括異常產生原因與異常時執行緒狀態(如暫存器值與其他特殊變數))

然後下發給核心的nt!kidispatchexception來處理

該函式會根據是否存在核心偵錯程式使用者態偵錯程式,以及偵錯程式對異常的干預結果來進行不同的處理

1.交由核心態偵錯程式

當在被核心態偵錯程式除錯時,將異常處理控制權移交,表明firstchance,

​ 核心偵錯程式根據設定來判斷處理,若無法決定則發生中斷將控制權移交給使用者

​ 若正確處理則繼續執行程式

若無核心態偵錯程式則跳過該步

2.交由nt!rtldispatchexception函式處理(由seh處理

若無核心偵錯程式或核心偵錯程式選擇不處理該異常,將會呼叫核心的nt!rtldispatchexception函式,根據seh來處理

3.交由核心態偵錯程式

若nt!rtldispatchexception函式未能處理該異常,系統將異常處理控制權移交核心偵錯程式(secondchance)

4.藍屏!

若不存在核心態偵錯程式或在第二次機會時仍不處理,則系統呼叫kebugcheckex的bsod 引發藍屏

在以上任何一步異常被處理 整個異常處理流程就會被終結

完全可以交由核心偵錯程式來處理 但一般核心偵錯程式對使用者異常不關心

所以將會分發給使用者偵錯程式

1.交由使用者態偵錯程式

當在被使用者態偵錯程式除錯時,將異常處理控制權移交,表明firstchance,

若無使用者態偵錯程式則跳過該步

2.由seh與veh來處理

若無使用者態偵錯程式或使用者態偵錯程式未處理該異常,

將在棧上放置exception_record和context兩個結構

然後呼叫ntdll.dll的nt!rtldispatchexception函式

若無偵錯程式附加或偵錯程式無法處理異常則exitprocess函式來終結程式

3.再次分發給使用者態偵錯程式

若nt!rtldispatchexception函式未能處理該異常,系統將異常處理控制權移交使用者偵錯程式(secondchance)

若無偵錯程式則直接結束程序

4.錯誤彈窗

若第二次機會偵錯程式仍不處理則

tib(執行緒資訊塊)位於teb(執行緒環境塊)頭部

而tib的首項指向異常處理鍊錶

32位下fs暫存器指向teb 即指向tib 即指向異常處理鍊錶

64位下是gs暫存器指向teb

而tib[0]對應的

因為teb是執行緒環境塊,所屬於當前執行緒,所以seh機制僅限於當前執行緒

若想新增或刪除 則直接在鍊錶頭部編寫乙個新的_exception_registration_record

可以說seh是基於棧幀的異常處理機制

因此seh是從0開始往後面找的異常處理

veh與seh大抵類似 同樣是鍊錶 但呼叫順序為偵錯程式》veh>seh

veh對整個程序都有效 而seh對單個執行緒有效

對我目前碰到的re題來說 與異常相關的只有主動丟擲異常(如idiv rax)在迴圈加密過程中rax可能為0 從而進入另外的加密函式

若想動態跟蹤該類函式 可以除錯od x64dbg 或ida 的debug除錯 將異常交由被除錯者處理

(別沒事瞎f5 偽**還真不顯示seh 彙編

只總結了一點點 實際上加密與解密中關於核心和異常處理還有很多更深的內容 (但我還是選擇先看17章(

Windows上python開發 5 異常處理

python的異常處理能力是很強大的,可向使用者準確反饋出錯資訊。在python中,異常也是物件,可對它進行操作。所有異常都是基類exception的成員。所有異常都從基類exception繼承,而且都在exceptions模組中定義。python自動將所有異常名稱放在內建命名空間中,所以程式不必匯...

windows 環境下 mysql 啟動異常處理

我出問題的mysql版本是5.7.17 net start mysql 以下為原文 不知道為什麼最近幾個版本的mysql zip 都沒有data檔案,弄得我吃了不少骨頭,還不曉得是 出了問題。解決方案 第一步 mysql 5.7.10x預設的配置檔案是在c program files mysql m...

Linux核心與Windows核心

windows 和 linux 可以說是我們比較常見的兩款作業系統。windows 基本占領了電腦時代的市場,商業上取得了很大成功,但是它並不開源,所以要想接觸原始碼得加入 windows 的開發團隊中。這兩個作業系統各有千秋,不分伯仲。作業系統核心的東西就是核心,這次我們就來看看,linux 核心...