一、什麼是hook(鉤子)
windows系統,建立在事件驅動機制上,就是整個系統都是通過訊息傳遞實現的。hook(鉤子)是一種特殊的訊息處理機制,它可以監視系統或者程序中的各種事件訊息,截獲發往目標視窗的訊息並進行處理。
鉤子的種類很多,每種鉤子可以截獲相應的訊息,如鍵盤鉤子可以截獲鍵盤訊息,外殼鉤子可以擷取、啟動和關閉應用程式的訊息等。鉤子可以分為執行緒鉤子和系統鉤子,執行緒鉤子可以監視指定執行緒的事件訊息,系統鉤子監視系統中的所有執行緒的事件訊息。因為系統鉤子會影響系統中所有的應用程式,所以鉤子函式必須放在獨立的動態鏈結庫(dll) 中。
所以說,hook(鉤子)就是乙個windows訊息的攔截機制,可以攔截單個程序的訊息(執行緒鉤子),也可以攔截所有程序的訊息(系統鉤子),也可以對攔截的訊息進行自定義的處理。
二、hook分類:
1、 ring3 層的 hook 基本上可以分為兩種大的型別:
第一類即是 windows 訊息的 hook,第二類則是 windows api 的 hook。
訊息 hook 是通過 setwindowshookex 可以實現將自己的鉤子插入到鉤子鏈的最前端,
而對於傳送給被 hook 的視窗(也有可能是所有的視窗,即全域性 hook)的訊息都會被我們的鉤子處理函式所捕獲到,
也就是我們可以優先於窗體先捕獲到這些訊息
(1)程序內訊息 hook:可以簡單的將 hook 處理函式直接寫在這個程序內,即是自己 hook 自己。
(2)全域性訊息hook:
需要將 hook 處理函式寫在乙個 dll 中,這樣才可以讓你的處理函式被所有的程序所載入(程序自動載入包含 hook 訊息處理函式的 dll)。
2、ring0 層的 hook
(1)ssdt hook,一句話——windows把需要呼叫的核心api位址全都儲存在乙個表中(system service dispatch table),要想hook乙個核心api,比較簡單的辦法就是把該核心api在表(ssdt)中儲存的位址修改為自己撰寫的函式位址。
(2)hook int 2e 方法:idt hook
idt是中斷描述表,可以替換其中的中斷處理程式。
這種方法對於跟蹤、分析系統呼叫來說用的比較多。原理是通過替換 idt
表中的 int 2e 中斷,使之指向我們自己的中斷服務處理例程來實現的。掌握
此方法需要你對保護模式有一定的基礎。
(3) hook pe 方法:eat hook
這種方法對於攔截、分析其他核心驅動的函式呼叫來說用的比較多。原理
是根據替換 pe 格式匯出表中的相應函式來實現的。
eat是可執行檔案的匯出表,記錄dll中可供其他程式使用的函式,可執行檔案裝載時會使用相應dll的eat表來初始化iat表,通過替換eat表中的函式位址,就可以使依賴於本dll的程式得到乙個假的位址。
(4)iat hook (ring3 用)
iat是可執行檔案的匯入表,記錄可執行檔案使用的其它dll中的函式,通過替換iat表中的函式位址,可以hook相應dll中的函式呼叫。
(5)inline hook方法 (ring 0和ring3 都可以用)
inline hook的工作流程:
1)驗證核心api的版本(特徵碼匹配)。
2)撰寫自己的函式,要完成以上三項任務。
2)獲取自己函式的位址,覆蓋核心api記憶體,供跳轉。
inline hook的缺點:
1)不夠通用。各個windows版本中,核心api的開始一段不盡相同,要想通吃,就要多寫幾個版
本或者做乙個特徵碼搜尋(因為有的核心api在各個版本中非常相似,只是在「特徵碼」之前或之
後加一點東西)。
2)已被一些檢測工具列入檢測範圍,如果直接從核心api第乙個位元組開始覆蓋,那麼很容易被檢
測,如果把覆蓋範圍往後推,並加以變形,也許能抵擋一氣。具體情況,我才疏學淺,尚未試驗
(6)sysentry hook
為了效能的考慮,xp後的系統都改用sysentry命令來進入ring0,去呼叫ssdt中的服務,不再是通過idt中的 int 2e。這也使得我們hook也變得相對容易了。
首先獲得sysentry的位址,然後改之,不用再考慮idt了
(7)irp hook
irp是 i/o request packets,驅動程式中有一系列分發例程來處理請求,這些例程儲存在驅動裝置物件的資料結構中的乙個表中,也很容易替換。
三、hook(鉤子)的工作原理
當建立乙個鉤子時,windows會先在記憶體中建立乙個資料結構,該資料結構包含了鉤子的相關資訊,然後把該結構體加到已經存在的鉤子鍊錶中去。新的鉤子將加到老的前面。當乙個事件發生時,如果安裝的是乙個執行緒鉤子,程序中的鉤子函式將被呼叫。如果是乙個系統鉤子,系統就必須把鉤子函式插入到其它程序的位址空間,要做到這一點要求鉤子函式必須在乙個動態鏈結庫中。
當然有兩個例外:工作日誌鉤子和工作日誌回放鉤子。這兩個鉤子的鉤子函式必須在安裝鉤子的執行緒中。原因是:這兩個鉤子是用來監控比較底層的硬體事件的,既然是記錄和回放,所有的事件就當然都是有先後次序的。所以如果把**函式放在dll中,輸入的事件被放在幾個執行緒中記錄,所以我們無法保證得到正確的次序。故解決的辦法是:把鉤子函式放到單個的執行緒中,譬如安裝鉤子的執行緒。
幾點需要說明的地方:
(1) 如果對於同一事件(如滑鼠訊息)既安裝了執行緒鉤子又安裝了系統鉤子,那麼系統會自動先呼叫執行緒鉤子,然後呼叫系統鉤子。
(2) 對同一事件訊息可安裝多個鉤子處理過程,這些鉤子處理過程形成了鉤子鏈。當前鉤子處理結束後應把鉤子資訊傳遞給下乙個鉤子函式。而且最近安裝的鉤子放在鏈的開始,而最早安裝的鉤子放在最後,也就是後加入的先獲得控制權。
(3) 鉤子特別是系統鉤子會消耗訊息處理時間,降低系統效能。只有在必要的時候才安裝鉤子,在使用完畢後要及時解除安裝。
Oracle 基本知識
乙個表空間只能屬於乙個資料庫 每個資料庫最少有乙個控制檔案 建議3個,分別放在不同的磁碟上 每個資料庫最少有乙個表空間 system表空間 建立system表空間的目的是盡量將目的相同的表存放在一起,以提高使用效率,只應存放資料字典 每個資料庫最少有兩個聯機日誌組,每組最少乙個聯機日誌檔案 乙個資料...
Oracle 基本知識
乙個表空間只能屬於乙個資料庫 每個資料庫最少有乙個控制檔案 建議3個,分別放在不同的磁碟上 每個資料庫最少有乙個表空間 system表空間 建立system表空間的目的是盡量將目的相同的表存放在一起,以提高使用效率 每個資料庫最少有兩個聯機日誌檔案 乙個資料檔案只能屬於乙個表空間 乙個資料檔案一旦被...
Oracle 基本知識
oracle 文章摘要 oracle 基本知識。正文 oracle 基本知識 乙個表空間只能屬於乙個資料庫 每個資料庫最少有乙個控制檔案 建議3個,分別放在不同的磁碟上 每個資料庫最少有乙個表空間 system表空間 建立system表空間的目的是盡量將目的相同的表存放在一起,以提高使用效率 每個資...