Detours 是微软开发的一个强大的 Windows API 钩子库,用于监视和拦截函数调用。它广泛应用于微软产品团队和众多独立软件开发中,旨在无需修改原始代码的情况下实现函数拦截和修改。本篇文章旨在帮助开发者更好地理解和应用Detours库进行DLL注入操作,从而实现对目标进程的高效控制和管理。无论您是刚接触Detours的新手,还是希望深入了解其高级功能的老手,这篇文章都将提供有价值的参考。
通常情况下Detours
库只会用于函数挂钩,但实际上Detours
库不仅可以拦截函数,还提供了对动态链接库的注入功能。本章将详细讲解每个注入函数的使用方法、参数和实际应用。
DetourCreateProcessWithDllA
该函数用于创建一个新进程并在创建时注入一个DLL动态链接库文件。其重要参数仅有两个,参数1用于指定被注入程序路径,参数11用于指定DLL
文件路径。
函数原型
c
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
注入到该进程中。
c
#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的扩展版本,提供了更多的灵活性和控制。
函数原型
c
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
,并通过自定义进程创建例程添加自定义逻辑。
c
#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 文件注入到目标进程中。
函数原型
c
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 文件。
c
#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;
}