API Hook的幾種實現

2022-07-27 18:24:20 字數 1982 閱讀 8025

intfunc()

//return

ret;

}此處,函式get_hardware_code()是與特定平台相關的,在普通pc上執行肯定無法獲得正確的結果。如果拿不到正確的結果,也就不能對函式func()進行測試了。於是,我們就可以利用api hook技術,在測試**裡面,把所有對get_hardware_code()的呼叫換成我們自定義的函式mock_get_hardware_code()的呼叫,這樣,在我們自己定義的函式裡面,可以返回乙個有效的**以保證原**能夠正確的往下執行。

經過研究,api hook有這麼幾種方法。

1. 改寫函式的首位址。

這個是在《windows核心程式設計》裡面大師提到的api hook的方法之一。原理就是,首先獲得要被hook的函式的位址(比如get_hardware_code()),然後將其首位址之後的若干位元組(通常是5個位元組)改成一條jmp指令,而jmp的目標位址就是自定義函式的位址(此處為mock_get_hardware_code())。這樣,當函式每次執行目標函式的時候,就會跳轉到我們自定義的函式裡面去。這種方法很簡潔,據說在win16的年代經常被使用。但是大師並不推薦,好像是因為這種方法在多執行緒的環境下會有什麼問題(具體的我忘記了,大家可以翻書看看)。

2. 改寫匯入表

這個也是《windows核心程式設計》裡面提到的,也是大師所推薦的。具體來說,就是遍歷當前程序裡面的所有模組,對其中每乙個模組查詢它的匯入表。如果找到被測函式所在的dll,並且發現這個函式,那麼就把這個位址修改成自定義函式的位址。關於如何從匯入表中發現被測函式,我也總結了兩種方式。1)對於一般的c匯出函式,可以直接通過比較位址的方式去找,這個也在核心程式設計上面有乙個小例子。2)對於c++中的匯出的類成員函式而言,由於c++的指向成員函式的指標和普通的指標有所差別(我沒仔細研究過,從網上查的),在將乙個成員函式指標轉化成普通的函式指標的時候編譯通不過,因此我採取了第二種查詢方式,也就是查詢函式名。這還有乙個問題,由於c++的匯出成員函式名都進行了修飾,類似於?methodname@classname@...@z這種怪異的名字,不過,只要知道類名和方法名,然後查詢methodname@classname字串就行。如果找到了這樣的函式,然後在修改它的位址就行了。

另,關於匯入表,大家可以去看雪論壇上有關windows pe檔案格式的介紹。此處就不多說了。

3. 改寫虛函式表。

本來以為通過方法2就能hook住所有的匯出類成員函式和普通函式,但還是出現了乙個問題,因為我在嘗試hook乙個成員函式的時候,發現這個函式根本沒有在匯入表裡面。後通過反彙編發現,由於那個匯出類成員函式是乙個虛函式,因為在通過指標呼叫的時候,它實際上是從虛函式表裡面獲得的函式位址進行呼叫的。因此對於hook這類函式,就需要改寫它的虛函式表了。關於這個需要對c++的記憶體布局有所了解。我在這裡就說一種比較簡單的方式吧。

一般來說,對於某個含有虛函式表的c++類,this指標指向的位址,取值就是虛函式表指標。虛函式表指標指向了虛函式表,裡面的每乙個元素都指向了實際要呼叫的函式的位址。因此,可以按照這樣的方式訪問虛函式表指標:

int** pvtable = (int**)this;

也就是將指向物件的指標強制轉化成指標的指標,這樣就可以通過取值就可以訪問虛函式表:

(*pvtable)[0] = address of virtual function 1;

(*pvtable)[1] = address of virtual function 2;

因此,我們就可以改寫虛函式的位址了,從而達到hook的目的。這種技術**於網上。當然,我對c++的記憶體布局也不是十分的清楚,如果乙個類進行了多重繼承,它的虛函式表是什麼樣子我也不太明白,這裡只是說明了這樣一種技術。

以上就是目前為止我應用到的三種api hook的技術,其實實際應用到的也就是後兩種,這兩種技術能夠滿足我目前專案的需要了。如果還有其他關於api hook技術的話大家也可以交流。

另外需要說明的一點是,上述三種方法中不管哪一種在改寫位址的時候,由於windows一般將那個位址所在的頁面設定了保護屬性,因為你需要用virtualprotect函式將頁面改為可讀可寫的屬性才能改寫,否則會有異常的。

乙個API HOOK的例子

乙個api hook的例子 2010年07月20日 include include 執行緒操作api hinstance hinst 任務例項id hwnd mainfrmhwnd 主視窗控制代碼 hfont globalfont 字型 typedef struct remoteparam 視窗類名...

關於DELPHI中的API HOOK 1

angliu aixihuan at 21cn.com 關於api hook,我相信大家比我知道的多,大家應該記得在dos中程式設計,經常都要用擷取中斷向量的技術,這樣我們可以設定新的中斷服務程式,因此當乙個新的程式呼叫這個中斷向量的時候,它就會先呼叫我們自己設定的中斷程式,然後呼叫原來的中斷程式,...

Java Pi的幾種實現

無窮級數計算 p 1 1 3 1 5 1 7 4p使用 nilakantha 級數 3 4 2 3 4 4 4 5 6 4 6 7 8 4 8 9 10 4 10 11 12 4 12 13 14 假設有乙個圓半徑為1,所以四分之一圓面積就為pi,而包括此四分之一圓的正方形面積就為1,如果隨意的在正...