Detours 是微軟開發的一個強大的 Windows API 鉤子庫,用於監視和攔截函式呼叫。它廣泛應用於微軟產品團隊和眾多獨立軟體開發中,旨在無需修改原始程式碼的情況下實現函式攔截和修改。本篇文章旨在幫助開發者更好地理解和應用Detours庫進行DLL注入操作,從而實現對目標程序的高效控制和管理。無論您是剛接觸Detours的新手,還是希望深入瞭解其高階功能的老手,這篇文章都將提供有價值的參考。
通常情況下Detours
庫只會用於函式掛鉤,但實際上Detours
庫不僅可以攔截函式,還提供了對動態連結庫的注入功能。本章將詳細講解每個注入函式的使用方法、引數和實際應用。
DetourCreateProcessWithDllA
該函式用於建立一個新程序並在建立時注入一個DLL動態連結庫檔案。其重要引數僅有兩個,引數1用於指定被注入程式路徑,引數11用於指定DLL
檔案路徑。
函式原型
BOOL DetourCreateProcessWithDllA(
LPCSTR lpApplicationName, // 被注入程式路徑
LPSTR lpCommandLine, // 命令列引數
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 程序安全屬性
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 執行緒安全屬性
BOOL bInheritHandles, // 是否繼承控制代碼
DWORD dwCreationFlags, // 建立標誌
LPVOID lpEnvironment, // 環境變數
LPCSTR lpCurrentDirectory, // 當前目錄
LPSTARTUPINFOA lpStartupInfo, // 啟動資訊
LPPROCESS_INFORMATION lpProcessInformation, // 程序資訊
LPCSTR lpDllName, // DLL 檔案路徑
PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA // 自定義程序建立例程
);
使用示例
以下程式碼示例展示瞭如何使用 DetourCreateProcessWithDllA
函式,在啟動 Win32Project.exe
程序時將 hook.dll
注入到該程序中。
#include <windows.h>
#include <iostream>
#include "detours.h"
#pragma comment(lib, "detours.lib")
int main(int argc, char *argv[])
{
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
const char* exePath = "D://Win32Project.exe";
const char* dllPath = "D://hook.dll";
if (DetourCreateProcessWithDllA(
exePath,
NULL,
NULL,
NULL,
TRUE,
CREATE_DEFAULT_ERROR_MODE,
NULL,
NULL,
&si,
&pi,
dllPath,
NULL
)) {
printf("dwProcessId = %d \n", pi.dwProcessId);
printf("dwThreadId = %d \n", pi.dwThreadId);
printf("hProcess = %d \n", pi.hProcess);
printf("hThread = %d \n", pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
} else {
printf("DLL 注入失敗,錯誤碼: %d\n", GetLastError());
}
system("pause");
return 0;
}
DetourCreateProcessWithDllExA
DetourCreateProcessWithDllExA是DetourCreateProcessWithDllA的擴充套件版本,提供了更多的靈活性和控制。
函式原型
BOOL DetourCreateProcessWithDllExA(
LPCSTR lpApplicationName, // 被注入程式路徑
LPSTR lpCommandLine, // 命令列引數
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 程序安全屬性
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 執行緒安全屬性
BOOL bInheritHandles, // 是否繼承控制代碼
DWORD dwCreationFlags, // 建立標誌
LPVOID lpEnvironment, // 環境變數
LPCSTR lpCurrentDirectory, // 當前目錄
LPSTARTUPINFOA lpStartupInfo, // 啟動資訊
LPPROCESS_INFORMATION lpProcessInformation, // 程序資訊
LPCSTR lpDllName, // DLL 檔案路徑
PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA, // 自定義程序建立例程
PVOID pContext // 自定義上下文
);
使用示例
以下程式碼示例展示瞭如何使用 DetourCreateProcessWithDllExA
函式,在啟動 Win32Project.exe
程序時注入 hook.dll
,並透過自定義程序建立例程新增自定義邏輯。
#include <windows.h>
#include <iostream>
#include "detours.h"
#pragma comment(lib, "detours.lib")
// 自定義的程序建立例程
BOOL WINAPI MyCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
{
// 自定義邏輯
printf("自定義程序建立例程被呼叫\n");
// 呼叫原函式
return CreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
}
int main(int argc, char *argv[])
{
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
const char* exePath = "D://Win32Project.exe";
const char* dllPath = "D://hook.dll";
if (DetourCreateProcessWithDllExA(
exePath,
NULL,
NULL,
NULL,
TRUE,
CREATE_DEFAULT_ERROR_MODE,
NULL,
NULL,
&si,
&pi,
dllPath,
MyCreateProcessA
))
{
printf("dwProcessId = %d \n", pi.dwProcessId);
printf("dwThreadId = %d \n", pi.dwThreadId);
printf("hProcess = %d \n", pi.hProcess);
printf("hThread = %d \n", pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else {
printf("DLL 注入失敗,錯誤碼: %d\n", GetLastError());
}
system("pause");
return 0;
}
DetourCreateProcessWithDllsA
DetourCreateProcessWithDllsA函式與DetourCreateProcessWithDllA和DetourCreateProcessWithDllExA的使用方法類似,但它允許在程序建立時將多個 DLL 檔案注入到目標程序中。
函式原型
BOOL DetourCreateProcessWithDllsA(
LPCSTR lpApplicationName, // 被注入程式路徑
LPSTR lpCommandLine, // 命令列引數
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 程序安全屬性
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 執行緒安全屬性
BOOL bInheritHandles, // 是否繼承控制代碼
DWORD dwCreationFlags, // 建立標誌
LPVOID lpEnvironment, // 環境變數
LPCSTR lpCurrentDirectory, // 當前目錄
LPSTARTUPINFOA lpStartupInfo, // 啟動資訊
LPPROCESS_INFORMATION lpProcessInformation, // 程序資訊
DWORD nDlls, // DLL 的數量
LPCSTR *rlpDlls, // DLL 檔案路徑陣列
PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA // 自定義程序建立例程
);
使用示例
以下程式碼示例展示瞭如何使用 DetourCreateProcessWithDllsA
函式,在啟動 Win32Project.exe
程序時注入多個 DLL 檔案。
#include <windows.h>
#include <iostream>
#include "detours.h"
#pragma comment(lib, "detours.lib")
int main(int argc, char *argv[])
{
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
const char* exePath = "D://Win32Project.exe";
const char* dlls[] = {
"D://hook1.dll",
"D://hook2.dll"
};
DWORD nDlls = sizeof(dlls) / sizeof(dlls[0]);
// 開始注入
if (DetourCreateProcessWithDllsA(
exePath,
NULL,
NULL,
NULL,
TRUE,
CREATE_DEFAULT_ERROR_MODE,
NULL,
NULL,
&si,
&pi,
nDlls,
dlls,
NULL
)) {
printf("dwProcessId = %d \n", pi.dwProcessId);
printf("dwThreadId = %d \n", pi.dwThreadId);
printf("hProcess = %d \n", pi.hProcess);
printf("hThread = %d \n", pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
} else {
printf("DLL 注入失敗,錯誤碼: %d\n", GetLastError());
}
system("pause");
return 0;
}