Detour開發包介紹 2 使用

2021-05-24 00:14:43 字數 3770 閱讀 5782

一般來說,使用detours 的**都具有固定的模式。 detours 1.5 和 detours 2.1 的介面函式變了很多,這裡按照 2.1 版本對基本的使用方法進行說明。常用的函式有下面幾個:

detourtransactionbegin():開始一次 截獲 或者 解除截獲 過程。

detourupdatethread():列入乙個在 detourtransaction 過程中要進行 update 的執行緒。這個函式的作用稍微有一些複雜,會在後面專門說明。

detourattach() : 新增乙個要 截獲 的 目標 函式。

detourdetach(): 用來解除截獲 的函式。

detourtransactioncommit():執行當前的 transaction 過程。在這個函式中才會真正進行 截獲 或者 解除截獲 操作。前面三個函式都只是做一些記錄工作。

在使用的時候,這幾個函式的呼叫步驟基本上也是按照上面列出來的順序。舉例來說, 我們要截獲 api函式 messageboxa ,將訊息框彈出的訊息修改掉,可以按下面的方法做 (這裡是 dll注入的方式) 。

view plain

copy to clipboard

print?

1、編寫目標函式的攔截 dll

建立乙個 win32的 dll 工程(在 win32 應用程式嚮導中選 dll ),名為 apihook ,也可以不用 ide 而是用原始的記事本來編寫 dll 。把 detours.h 和 detours.lib 、 detoured.lib 拷貝到工程目錄下。原始檔 apihook.cpp 的**如下:

view plain

copy to clipboard

print?

#include "stdafx.h"

#include 

#include "detours.h"

#pragma comment(lib,"detours.lib")

#pragma comment(lib,"detoured.lib")

#ifdef _managed

#pragma managed(push, off)

#endif

//目標函式原型宣告

typedef

int (winapi* pfnmessageboxa)(hwnd hwnd,lpcstr lptext,lpcstr lpcaption,uint utype);  

//宣告乙個指向目標函式的指標

pfnmessageboxa g_pmessageboxa=::messageboxa;  

//截獲函式

int winapi hookmessageboxa(hwnd hwnd,lpcstr lptext,lpcstr lpcaption,uint utype)  

//截獲操作

__declspec(dllexport) bool starthook()  

//完成事務

if(detourtransactioncommit()!=no_error)else  

return false;  

}  //解除截獲操作

__declspec(dllexport) bool stophook()  

//完成事務

if(detourtransactioncommit()!=no_error)else  

return false;  

}  bool apientry dllmain( hmodule hmodule,dword  ul_reason_for_call,lpvoid lpreserved)  

return true;  

}  #ifdef _managed

#pragma managed(pop)

#endif

攔截操作一般按如下步驟進行:

1) 首先需要定義目標函式的原型。如果目標函式是 windows api ,可以到 msdn 中查閱,但是需要注意 ansi 版本和 unicode 版本的區別。如果沒有確切的原型宣告,或者目標函式是通過逆向工程找出來的,那麼需要定義乙個和目標函式原型相容的宣告,即引數個數和呼叫約定要相同。如 messageboxa 的原型是:

view plain

copy to clipboard

print?

int messageboxa( hwnd hwnd, lpcstr lptext, lpcstr lpcaption, uint utype);  

則使用typedef 定義目標函式原型如下:

view plain

copy to clipboard

print?

typedef

int (winapi *pfnmessageboxa)( hwnd hwnd, lpcstr lptext, lpcstr lpcaption, uint utype);  

2) 定義指向目標函式的函式指標:

view plain

copy to clipboard

print?

pfnmessageboxa g_pmessageboxa = ::messageboxa;  

3) 定義截獲函式並編寫**,用於替換目標函式。

4) 呼叫 detourtransactionbegin 開始一次 detours 事務。

5) 對程序中每個可能呼叫到目標函式的執行緒,都需要使用 detourupdatethread 加入到 update 佇列中。這是因為攔截時修改目標函式的前幾個位元組,如果某個執行緒剛好執行到這幾個位元組的位置時,粗暴的修改掉會造成該執行緒出現異常。 detours 事務處理時,會先列舉並暫停 update 佇列中所有執行緒,獲取它們的指令指標,如果發現這種情況,則將指令指標修改到跳板**的對應位元組上。這樣就避免出現崩潰的問題。

6) 對每個需要攔截的函式,呼叫 detourattach 加入到事務列表中。

7) 呼叫 detourtransactioncommit 進行實際的攔截操作。

解除攔截的操作和上面的流程基本一樣,只是第6 步改為呼叫 detourdetach 函式。另外, detours 還包含一系列其他函式,如果需要使用的話,可以參考 detours 安裝目錄下的示例。

最後,在dll 的載入事件加入攔截操作函式,在解除安裝事件中加入解除攔截的操作函式,把它編譯成 apihook.dll 。

總體來說,detours 庫的**是非常穩定的,但是如果使用方法不對,會造成一些問題。有下面一些地方需要特別注意:

1) 一定要列舉執行緒並呼叫 detourupdatethread 函式。否則可能出現很低機率的崩潰問題,這種問題很難被檢查出來。

2) 如果攔截函式在 dll 中,那麼絕大多數情況下不能在 unhook 之後解除安裝這個 dll ,或者解除安裝存在造成崩潰的危險。因為某些執行緒的呼叫堆疊中可能還包含 hook 函式,這時解除安裝掉 dll ,呼叫堆疊返回到 hook 函式時記憶體位置已經不是合法的**了。

3) detours庫設計時並沒有考慮到解除安裝的問題,這是因為鉤子的解除安裝本身是不安全的。當 detours 庫**存在於 dll 中的時候,即使 unhook 了所有函式,清理了所有自己使用到的函式,還是會占用一些記憶體。解除安裝這個 dll 會造成記憶體洩露,特別是反覆的進行載入 dll->hook->unhook-> 解除安裝 dll 的過程,會讓這個問題變得非常嚴重。

4) 有一些非常短的目標函式是無法 hook 的。因為 jmp 指令需要占用一定空間,有些函式太過短小,甚至不夠 jmp 指令的長度,自然是沒有辦法 hook 掉的。

5) detours不支援 9x 核心的 windows 系統。因為 9x 核心下的記憶體模型和 nt 核心下有非常大的差別。

2、將攔截 dll 注入到目標應用程式中

Detour開發包介紹 2 使用

一般來說,使用detours的 都具有固定的模式。detours 1.5和detours 2.1的介面函式變了很多,這裡按照2.1版本對基本的使用方法進行說明。常用的函式有下面幾個 detourtransactionbegin 開始一次 截獲或者 解除截獲 過程。detourupdatethread...

Detour開發包介紹 2 使用

一般來說,使用detours的 都具有固定的模式。detours 1.5和detours 2.1的介面函式變了很多,這裡按照2.1版本對基本的使用方法進行說明。常用的函式有下面幾個 detourtransactionbegin 開始一次 截獲或者 解除截獲 過程。detourupdatethread...

Libnids開發包介紹

libnids開發包介紹 libnids是乙個用於網路入侵檢測開發的專業程式設計介面,它使用了libpcap所以它具有捕獲資料報的功能。同時,libnids提供了tcp資料流重組功能,所以對於分析基於tcp協議的各種協議libnids都能勝任.libnids還提供了對ip分片進行重組的功能,以及埠掃...