Detour

什麼是Detours

簡單地說,Detours是微軟提供的一個開發庫,使用它可以簡單、高校、穩定地實現API HOOK的功能。

Detours是一個可以在x86、x64和IA64平臺上測試任意Win32函數的程序開發庫。它可以通過爲目標函數重寫在內存中的代碼而達到攔截Win32函數的目的。Detours還可以將任意的DLL或數據片段(稱之爲有效載荷)注入到任意Win32二進制文件中。Detours 被廣泛應用在微軟內部和其他行業中。

你可以從微軟官方網站下載到Detours的express版本,目前最新版本是2.1,它包含有下列的嶄新特性:

l 完整的Detours API文檔

l 附加和拆卸處理模塊

l 支持附加和拆卸Detours的時候更新對等線程

l 靜態和動態注入單個API

l 支持監視注入後的進程

l 改進後更加健壯的API可以將一個掛鉤函數,通過一個進程附着到dll上

l 新的API通過複製將有效載荷注入到目標進程中

l 支持x64和IA64平臺上的64-位源代碼(僅專業版可用)

l 支持Visual Studio 2005,Visual Studio .NET 2003, Visual Studio .NET (VC8)以及Visual Studio (VC7)開發工具

 

 

Detours的使用

Detours開發包被下載回來會不能直接使用,安裝完畢後需要自己使用nmake生成相應的DLL以及lib文件。這裏我已經編譯好了,隨文附上,一共有四個文件,分別是detoured.dll、detoured.lib、detours.lib、detours.h。

我們需要編寫一個DLL,然後將該DLL注入到目標進程的空間中,(注意這裏我們需要將生成的hook.dll和detoured.dll都複製到目標進程目錄,或者將他們複製到system32目錄等地方)下面我給一個例子,如下所示:

// HOOK.CPP

#include "Detours.h"


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

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


// 共享數據段

#pragma data_seg("MyData")

DWORD nPid = 0; // 受保護的進程PID

#pragma data_seg()


BOOL APIENTRY DllMain( HANDLE hModule,

                       DWORD  ul_reason_for_call,

                       LPVOID lpReserved )

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:

{

// 安裝 HOOK

SetHook(TRUE);

break;

}

case DLL_PROCESS_DETACH:

{

// 卸載 HOOK

SetHook(FALSE);

}

case DLL_THREAD_DETACH:

default:

break;

}

    return TRUE;

}


/*

 * 函數:SetHook

 *

 * 作用:安裝/卸載 API HOOK

 *

 * 參數:TRUE - 安裝,FALSE - 卸載

 *

 * 返回:無

 */

void SetHook(BOOL flag)

{

if (flag)

{

DetourRestoreAfterWith();

DetourTransactionBegin();

DetourUpdateThread(GetCurrentThread());


// HOOK 函數列表

DetourAttach(&(PVOID&)Old_OpenProcess, New_OpenProcess);


DetourTransactionCommit();

}

else

{

DetourTransactionBegin();

DetourUpdateThread(GetCurrentThread());


// 取消 HOOK 函數列表

DetourDetach(&(PVOID&)Old_OpenProcess, New_OpenProcess);


DetourTransactionCommit();

}

}


/*

 * 函數:New_OpenProcess

 *

 * 作用:攔截系統 OpenProcess 函數調用

 */

HANDLE WINAPI New_OpenProcess(DWORD dwDesiredAccess,

  BOOL bInheritHandle,

  DWORD dwProcessId)

{

// 是否爲可信任程序

if (strcmp(szCurrentApp, szTrustFile) != 0)

{

// 是否爲受保護進程

if (dwProcessId == nPid)

{

return NULL;

}

}


return Old_OpenProcess( dwDesiredAccess,

bInheritHandle,

dwProcessId);

}


// HOOK.H

static HANDLE (WINAPI* Old_OpenProcess)(DWORD dwDesiredAccess,

BOOL bInheritHandle,

DWORD dwProcessId) = OpenProcess;


HANDLE WINAPI New_OpenProcess(DWORD dwDesiredAccess,

  BOOL bInheritHandle,

  DWORD dwProcessId);


然後要在def文件中將New_OpenProcess函數導出,最後將生成的HOOK.DLL注入到其他進程空間就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章