HOOK汇总
HOOK技術(shù)主要分為兩大類,一是內(nèi)核層HOOK,一是用戶層HOOK. 用戶層HOOK也就是在ring3環(huán)境下hook kenerl32.dll、User3.dll、Gui32.dll、Advapi.dll等導(dǎo)出的函數(shù)。而內(nèi)核層HOOK就是HOOK只有ring0級別環(huán)境下才能操作寫入改變的內(nèi)核對象,例如SSDT系統(tǒng)服務(wù)描述符表等。綜合而言,主要有以下9種HOOK技術(shù)。
(1)消息鉤子
消息鉤子是最常見的鉤子之一,例如常見的鍵盤鼠標(biāo)鉤子,很多木馬就是通過消息鉤子獲取密碼的。消息鉤子是由Win32子系統(tǒng)提供,用戶通過它注冊全局鉤子。當(dāng)系統(tǒng)獲取某些事件,比如用戶按鍵,鍵盤driver將掃描碼等傳入win32k的KeyEvent處理函數(shù),處理函數(shù)判斷有無相應(yīng)hook,有則通過回調(diào)函數(shù)處理。此時,系統(tǒng)取得Hook對象信息,若目標(biāo)進(jìn)程沒有裝載對應(yīng)的Dll,則裝載之。
(2)IAT HOOK
IAT HOOK[4]是最常見和普遍的HOOK之一。IAT表示導(dǎo)入地址表(Import Address Table),導(dǎo)入函數(shù)就是被程序調(diào)用但其執(zhí)行代碼又不在程序中的函數(shù),當(dāng)PE 文件被裝入內(nèi)存的時候,Windows 裝載器才將DLL 裝入,并將調(diào)用導(dǎo)入函數(shù)的指令和函數(shù)實際所處的地址聯(lián)系起來(動態(tài)連接),這種操作就需要導(dǎo)入表完成。其中導(dǎo)入地址表就指示函數(shù)實際地址。程序每個調(diào)用的 API 函數(shù)地址都保存在 IAT 表中,而每個調(diào)用 API 函數(shù)的 CALL 指令所使用的地址都是相應(yīng)函數(shù)登記在 IAT 表的地址。IATHOOK原理是在將 IAT 表中的地址換成用戶自己的 函數(shù)地址,這樣每個 API 調(diào)用都是先調(diào)用用戶自己的 函數(shù)。在這個函數(shù)中我們可以完成函數(shù)名稱的記錄、參數(shù)的記錄、調(diào)用原來的過程,并在返回時記錄結(jié)果。
(3)EAT HOOK
EAT HOOK的原理是根據(jù)替換 PE 格式導(dǎo)出表中的相應(yīng)函數(shù)來實現(xiàn)的。EAT表示導(dǎo)出地址表(Export Address Table),EAT存在于PE文件中的edata節(jié),保存了可執(zhí)行文件(如DLL 文件)的導(dǎo)出的可供其他模塊來調(diào)用的函數(shù)和公共變量,包括函數(shù)名稱和地址等。通過替換Windows 系統(tǒng)某些重要DLL中的輸出函數(shù)地址,即可實現(xiàn)目標(biāo)函數(shù)的掛接。EAT記錄DLL中可供其他程序使用的函數(shù),可執(zhí)行文件裝載時會使用相應(yīng)DLL的EAT表來初始化IAT表。EAT HOOK原理是通過替換EAT表中的函數(shù)地址,使依賴于本DLL的程序得到一個假的地址。
(4)SSDT HOOK
SSDT是最常見的內(nèi)核層 HOOK。SSDT的全稱是系統(tǒng)服務(wù)描述符表(System Services Descriptor Table)。SSDT是關(guān)聯(lián)ring3的Win32 API和ring0的內(nèi)核API的重要數(shù)據(jù)結(jié)構(gòu),它存儲著Windows把需要調(diào)用的所有內(nèi)核API地址。SSDT HOOK原理是將內(nèi)核層 API地址修改為指向其位于Ring0層的驅(qū)動入口,這樣每次系統(tǒng)執(zhí)行到這個函數(shù)時,都會通過SSDT表將原始調(diào)用引向修改后的模塊中。
(5)IDT HOOK
IDT HOOK是Win2000操作系統(tǒng)上常用的一種HOOK。IDT是中斷描述表,可以替換其中的中斷處理程序。這種方法對于跟蹤、分析系統(tǒng)調(diào)用來說用的比較多。IDT HOOK的原理是通過替換 IDT表中的 INT 2E 中斷,使之指向新的中斷服務(wù)處理例程來實現(xiàn)的。它首先保存出特定的中斷向量中斷服務(wù)程序(ISR), 然后直接修改該中斷向量的ISR為自定義的函數(shù),每當(dāng)這個中斷向量對應(yīng)的中斷產(chǎn)生時,就會調(diào)用自定義的函數(shù)。由于我們自定義的函數(shù)里面執(zhí)行完我們的功能后再跳轉(zhuǎn)到原ISR處執(zhí)行。
(6)SYSENTRY HOOK
SYSENTRY是Windows XP之后的操作系統(tǒng)進(jìn)入ring0的函數(shù)。Win2000中通過 int2e系統(tǒng)調(diào)用機制,涉及到的Interrupt/Exception Handler的調(diào)用都是通過 call/trap/task這一類的gate來實現(xiàn)的,這種方式會進(jìn)行棧切換,并且系統(tǒng)棧的地址等信息由TSS提供,可能會引起多次內(nèi)存訪問 (來獲取這些切換信息),系統(tǒng)開銷較大。SYSENTER通過匯編指令實現(xiàn)快速系統(tǒng)調(diào)用機制。SYSENTER HOOK的原理是首先Ntdll 加載相應(yīng)的請求服務(wù)號到EAX 寄存器中,同時EDX 寄存器存貯當(dāng)前的棧指針ESP,然后Ntdll發(fā)出SYSENTER 指令,該指令轉(zhuǎn)移控制權(quán)到寄存器IA32_SYSENTER_EIP 存貯的地址中[21],通過修改這個地址,可實現(xiàn)相應(yīng)的掛接。
(7)Inline HOOK
inline hook是直接在以前的函數(shù)體內(nèi)修改指令,用一個跳轉(zhuǎn)或者其他指令來實現(xiàn)掛鉤的目的。 而普通的hook只是修改函數(shù)的調(diào)用地址,而不是在原來的函數(shù)體里面做修改。
Inline hook原理是解析函數(shù)開頭的幾條指令,把他們Copy到數(shù)組保存起來,然后用一個調(diào)用我們的函數(shù)的幾條指令來替換,如果要執(zhí)行原函數(shù),則在我們函數(shù)處理完畢,再執(zhí)行我們保存起來的開頭幾條指令,然后調(diào)回我們?nèi)≈噶钪蟮牡刂穲?zhí)行。它需要在程序中嵌入?yún)R編代碼(Inline Assembly)以操作堆棧和執(zhí)行內(nèi)核API對應(yīng)的部分匯編指令。
(7)OBJECT HOOK
OBJECT HOOK是相對于IAT HOOK之類的 API HOOK而言,API HOOK是掛鉤應(yīng)用層函數(shù),而OBJECT HOOK是掛鉤內(nèi)核層函數(shù)。其原理與API HOOK類似。
(9)IRP HOOK
IRP是 I/O request packets,在Windows中幾乎所有的I/O都是通過包(packet)驅(qū)動的,每個單獨的I/O由一個工作命令描述,此命令將會告訴驅(qū)動程序需要一些什么操作,并通過I/O子系統(tǒng)跟蹤處理過程。這些工作命令就表現(xiàn)為一個個被稱為IRP的數(shù)據(jù)結(jié)構(gòu)。IRP HOOK原理是攔截管理器發(fā)向文件或網(wǎng)絡(luò)系統(tǒng)等驅(qū)動程序的IRP。一般通過創(chuàng)建一個上層過濾器設(shè)備對象并將之加入系統(tǒng)設(shè)備所在的設(shè)備堆棧中。也有部分IRP HOOK通過攔截傳遞IRP請求包的函數(shù)IofCallDriver或MajorFunction函數(shù)表來實現(xiàn)的。
(1)消息鉤子
消息鉤子是最常見的鉤子之一,例如常見的鍵盤鼠標(biāo)鉤子,很多木馬就是通過消息鉤子獲取密碼的。消息鉤子是由Win32子系統(tǒng)提供,用戶通過它注冊全局鉤子。當(dāng)系統(tǒng)獲取某些事件,比如用戶按鍵,鍵盤driver將掃描碼等傳入win32k的KeyEvent處理函數(shù),處理函數(shù)判斷有無相應(yīng)hook,有則通過回調(diào)函數(shù)處理。此時,系統(tǒng)取得Hook對象信息,若目標(biāo)進(jìn)程沒有裝載對應(yīng)的Dll,則裝載之。
(2)IAT HOOK
IAT HOOK[4]是最常見和普遍的HOOK之一。IAT表示導(dǎo)入地址表(Import Address Table),導(dǎo)入函數(shù)就是被程序調(diào)用但其執(zhí)行代碼又不在程序中的函數(shù),當(dāng)PE 文件被裝入內(nèi)存的時候,Windows 裝載器才將DLL 裝入,并將調(diào)用導(dǎo)入函數(shù)的指令和函數(shù)實際所處的地址聯(lián)系起來(動態(tài)連接),這種操作就需要導(dǎo)入表完成。其中導(dǎo)入地址表就指示函數(shù)實際地址。程序每個調(diào)用的 API 函數(shù)地址都保存在 IAT 表中,而每個調(diào)用 API 函數(shù)的 CALL 指令所使用的地址都是相應(yīng)函數(shù)登記在 IAT 表的地址。IATHOOK原理是在將 IAT 表中的地址換成用戶自己的 函數(shù)地址,這樣每個 API 調(diào)用都是先調(diào)用用戶自己的 函數(shù)。在這個函數(shù)中我們可以完成函數(shù)名稱的記錄、參數(shù)的記錄、調(diào)用原來的過程,并在返回時記錄結(jié)果。
(3)EAT HOOK
EAT HOOK的原理是根據(jù)替換 PE 格式導(dǎo)出表中的相應(yīng)函數(shù)來實現(xiàn)的。EAT表示導(dǎo)出地址表(Export Address Table),EAT存在于PE文件中的edata節(jié),保存了可執(zhí)行文件(如DLL 文件)的導(dǎo)出的可供其他模塊來調(diào)用的函數(shù)和公共變量,包括函數(shù)名稱和地址等。通過替換Windows 系統(tǒng)某些重要DLL中的輸出函數(shù)地址,即可實現(xiàn)目標(biāo)函數(shù)的掛接。EAT記錄DLL中可供其他程序使用的函數(shù),可執(zhí)行文件裝載時會使用相應(yīng)DLL的EAT表來初始化IAT表。EAT HOOK原理是通過替換EAT表中的函數(shù)地址,使依賴于本DLL的程序得到一個假的地址。
(4)SSDT HOOK
SSDT是最常見的內(nèi)核層 HOOK。SSDT的全稱是系統(tǒng)服務(wù)描述符表(System Services Descriptor Table)。SSDT是關(guān)聯(lián)ring3的Win32 API和ring0的內(nèi)核API的重要數(shù)據(jù)結(jié)構(gòu),它存儲著Windows把需要調(diào)用的所有內(nèi)核API地址。SSDT HOOK原理是將內(nèi)核層 API地址修改為指向其位于Ring0層的驅(qū)動入口,這樣每次系統(tǒng)執(zhí)行到這個函數(shù)時,都會通過SSDT表將原始調(diào)用引向修改后的模塊中。
(5)IDT HOOK
IDT HOOK是Win2000操作系統(tǒng)上常用的一種HOOK。IDT是中斷描述表,可以替換其中的中斷處理程序。這種方法對于跟蹤、分析系統(tǒng)調(diào)用來說用的比較多。IDT HOOK的原理是通過替換 IDT表中的 INT 2E 中斷,使之指向新的中斷服務(wù)處理例程來實現(xiàn)的。它首先保存出特定的中斷向量中斷服務(wù)程序(ISR), 然后直接修改該中斷向量的ISR為自定義的函數(shù),每當(dāng)這個中斷向量對應(yīng)的中斷產(chǎn)生時,就會調(diào)用自定義的函數(shù)。由于我們自定義的函數(shù)里面執(zhí)行完我們的功能后再跳轉(zhuǎn)到原ISR處執(zhí)行。
(6)SYSENTRY HOOK
SYSENTRY是Windows XP之后的操作系統(tǒng)進(jìn)入ring0的函數(shù)。Win2000中通過 int2e系統(tǒng)調(diào)用機制,涉及到的Interrupt/Exception Handler的調(diào)用都是通過 call/trap/task這一類的gate來實現(xiàn)的,這種方式會進(jìn)行棧切換,并且系統(tǒng)棧的地址等信息由TSS提供,可能會引起多次內(nèi)存訪問 (來獲取這些切換信息),系統(tǒng)開銷較大。SYSENTER通過匯編指令實現(xiàn)快速系統(tǒng)調(diào)用機制。SYSENTER HOOK的原理是首先Ntdll 加載相應(yīng)的請求服務(wù)號到EAX 寄存器中,同時EDX 寄存器存貯當(dāng)前的棧指針ESP,然后Ntdll發(fā)出SYSENTER 指令,該指令轉(zhuǎn)移控制權(quán)到寄存器IA32_SYSENTER_EIP 存貯的地址中[21],通過修改這個地址,可實現(xiàn)相應(yīng)的掛接。
(7)Inline HOOK
inline hook是直接在以前的函數(shù)體內(nèi)修改指令,用一個跳轉(zhuǎn)或者其他指令來實現(xiàn)掛鉤的目的。 而普通的hook只是修改函數(shù)的調(diào)用地址,而不是在原來的函數(shù)體里面做修改。
Inline hook原理是解析函數(shù)開頭的幾條指令,把他們Copy到數(shù)組保存起來,然后用一個調(diào)用我們的函數(shù)的幾條指令來替換,如果要執(zhí)行原函數(shù),則在我們函數(shù)處理完畢,再執(zhí)行我們保存起來的開頭幾條指令,然后調(diào)回我們?nèi)≈噶钪蟮牡刂穲?zhí)行。它需要在程序中嵌入?yún)R編代碼(Inline Assembly)以操作堆棧和執(zhí)行內(nèi)核API對應(yīng)的部分匯編指令。
(7)OBJECT HOOK
OBJECT HOOK是相對于IAT HOOK之類的 API HOOK而言,API HOOK是掛鉤應(yīng)用層函數(shù),而OBJECT HOOK是掛鉤內(nèi)核層函數(shù)。其原理與API HOOK類似。
(9)IRP HOOK
IRP是 I/O request packets,在Windows中幾乎所有的I/O都是通過包(packet)驅(qū)動的,每個單獨的I/O由一個工作命令描述,此命令將會告訴驅(qū)動程序需要一些什么操作,并通過I/O子系統(tǒng)跟蹤處理過程。這些工作命令就表現(xiàn)為一個個被稱為IRP的數(shù)據(jù)結(jié)構(gòu)。IRP HOOK原理是攔截管理器發(fā)向文件或網(wǎng)絡(luò)系統(tǒng)等驅(qū)動程序的IRP。一般通過創(chuàng)建一個上層過濾器設(shè)備對象并將之加入系統(tǒng)設(shè)備所在的設(shè)備堆棧中。也有部分IRP HOOK通過攔截傳遞IRP請求包的函數(shù)IofCallDriver或MajorFunction函數(shù)表來實現(xiàn)的。
總結(jié)
- 上一篇: IDT系列:(二)中断处理过程,使用bo
- 下一篇: STL中的find_if函数