Detour開發包介紹 2 使用

2021-09-30 16:21:46 字數 4482 閱讀 1060

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

detourtransactionbegin():開始一次

截獲或者

解除截獲

過程。

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

detourattach()

:新增乙個要截獲的

目標函式。

detourdetach():

用來解除截獲

的函式。

detourtransactioncommit():執行當前的transaction過程。在這個函式中才會真正進行

截獲或者

解除截獲

操作。前面三個函式都只是做一些記錄工作。

在使用的時候,這幾個函式的呼叫步驟基本上也是按照上面列出來的順序。舉例來說,

我們要截獲

api函式messageboxa,將訊息框彈出的訊息修改掉,可以按下面的方法做

(這裡是

dll注入的方式)。

先寫乙個呼叫了

messageboxa的程式。

建立乙個mfc對話方塊工程

(在建立嚮導中選

"dialog based",其餘預設),開啟

ok按鈕的單擊

處理事件onbnclickedok

(),在其

中加入對messageboxa函式的呼叫,

如下:

[cpp]view plain

copy

void  

編譯後的程式名稱

為.exe,執行它並單擊ok按鈕時會彈出相應訊息框。現在我們要截獲這個exe檔案中對messageboxa函式的呼叫,以跳轉到我們自己定義的d函式處。我們需要先編寫乙個dll以攔截目標函式,然後將該dll注入到目標程式

.exe的空間中。

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

建立乙個

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

[cpp]view plain

copy

#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;  

//截獲函式

intwinapi 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的原型是:

[cpp]view plain

copy

intmessageboxa( 

hwnd

hwnd, 

lpcstr

lptext, 

lpcstr

lpcaption, 

uint

utype);  

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

[cpp]view plain

copy

typedef

int(winapi *pfnmessageboxa)( 

hwnd

hwnd, 

lpcstr

lptext, 

lpcstr

lpcaption, 

uint

utype);  

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

[cpp]view plain

copy

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 開始一次 截獲 或者 解除截獲 過程。detourupdat...

Detour開發包介紹 2 使用

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

Libnids開發包介紹

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