Detours开发实战:CreateProcessWithDll实现进程注入完整案例

Detours开发实战:CreateProcessWithDll实现进程注入完整案例

【免费下载链接】Detours Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form. 【免费下载链接】Detours 项目地址: https://gitcode.com/gh_mirrors/de/Detours

一、进程注入技术痛点与解决方案

你是否在开发Windows应用时遇到以下困境:需要监控第三方进程行为却无法修改其源码?想要在目标进程启动时自动加载插件但缺乏有效手段?微软研究院开发的Detours库提供了优雅的解决方案,其中CreateProcessWithDll系列函数更是实现进程注入的利器。本文将通过完整案例,详解如何使用Detours实现进程注入,解决DLL加载时机、架构兼容性和注入稳定性三大核心痛点。

读完本文你将掌握:

  • CreateProcessWithDll的工作原理与调用流程
  • 32/64位进程混合注入的实现方案
  • 注入过程中的错误处理与调试技巧
  • 从DLL开发到注入验证的全流程实践

二、技术原理与核心函数解析

2.1 Detours进程注入原理

Detours通过修改目标进程的导入表(Import Table)实现DLL注入,其核心流程如下:

mermaid

这种技术相比传统的CreateRemoteThread具有三大优势:

  • 注入时机更早,可在进程初始化阶段加载
  • 支持多DLL链式加载
  • 对目标进程影响更小,稳定性更高

2.2 CreateProcessWithDll函数原型

Detours提供了三个核心函数实现进程注入:

BOOL WINAPI CreateProcessWithDllA(
    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,
    LPVOID lpResumeAddress
);

// 宽字符版本
BOOL WINAPI CreateProcessWithDllW(/* 参数同上 */);

// 支持多DLL注入的扩展版本
BOOL WINAPI CreateProcessWithMultipleDllsA(
    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,
    LPCSTR *rlpDlls
);

2.3 关键数据结构

进程注入过程中需要处理的核心数据结构包括:

DETOUR_EXE_RESTORE - 用于保存和恢复进程PE头信息:

typedef struct _DETOUR_EXE_RESTORE {
    DWORD cb;
    PBYTE pidh;
    DWORD cbidh;
    IMAGE_DOS_HEADER idh;
    PBYTE pinh;
    DWORD cbinh;
    IMAGE_NT_HEADERS inh;
    PBYTE pclr;
    DWORD cbclr;
    IMAGE_COR20_HEADER clr;
    BYTE raw[4096];
} DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE;

IMAGE_NT_HEADERS - PE文件头结构,用于解析目标进程架构信息:

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

三、开发环境准备与项目配置

3.1 环境要求

组件版本要求
Windows SDK10.0.19041.0+
Visual Studio2019+
Detours库4.0.1+
目标系统Windows 7 SP1+

3.2 项目配置步骤

  1. 获取Detours源码
git clone https://gitcode.com/gh_mirrors/de/Detours.git
cd Detours
  1. 编译Detours库
nmake -f Makefile
  1. 项目属性配置
    • 包含目录添加:Detours\include
    • 库目录添加:Detours\lib.X86Detours\lib.X64
    • 链接器输入添加:detours.lib

四、完整实现案例:进程监控DLL注入

4.1 注入DLL实现

创建monitor.dll,实现进程监控功能:

// monitor.cpp
#include <windows.h>
#include <detours.h>
#include <stdio.h>

// 全局日志文件句柄
HANDLE g_hLogFile = INVALID_HANDLE_VALUE;

// 日志函数
void Log(const char* format, ...) {
    if (g_hLogFile == INVALID_HANDLE_VALUE) {
        g_hLogFile = CreateFileA("C:\\detour_log.txt", GENERIC_WRITE, 
                               FILE_SHARE_READ, NULL, CREATE_ALWAYS, 
                               FILE_ATTRIBUTE_NORMAL, NULL);
        if (g_hLogFile == INVALID_HANDLE_VALUE) return;
    }
    
    char buffer[1024];
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    
    DWORD bytesWritten;
    WriteFile(g_hLogFile, buffer, strlen(buffer), &bytesWritten, NULL);
}

// 钩子函数定义
typedef BOOL (WINAPI *CreateFileAFunc)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
CreateFileAFunc g_origCreateFileA = NULL;

// 钩子实现
BOOL WINAPI HookedCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, 
                             DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                             DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) {
    Log("CreateFileA called: %s\n", lpFileName);
    return g_origCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, 
                            lpSecurityAttributes, dwCreationDisposition, 
                            dwFlagsAndAttributes, hTemplateFile);
}

// DLL入口函数
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
            Log("Monitor DLL loaded\n");
            // 开始挂钩
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            
            // 挂钩CreateFileA函数
            g_origCreateFileA = (CreateFileAFunc)GetProcAddress(
                GetModuleHandleA("kernel32.dll"), "CreateFileA");
            
            DetourAttach(&(PVOID&)g_origCreateFileA, HookedCreateFileA);
            DetourTransactionCommit();
            break;
            
        case DLL_PROCESS_DETACH:
            // 解除挂钩
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            DetourDetach(&(PVOID&)g_origCreateFileA, HookedCreateFileA);
            DetourTransactionCommit();
            
            if (g_hLogFile != INVALID_HANDLE_VALUE) {
                CloseHandle(g_hLogFile);
            }
            break;
    }
    return TRUE;
}

4.2 注入器实现

创建注入工具injector.cpp

#include <windows.h>
#include <detours.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    if (argc < 3) {
        printf("用法: injector <目标进程路径> <DLL路径>\n");
        return 1;
    }

    const char* targetPath = argv[1];
    const char* dllPath = argv[2];

    STARTUPINFOA si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    
    // 使用CreateProcessWithDll注入DLL
    BOOL success = CreateProcessWithDllA(
        targetPath,        // 目标进程路径
        NULL,              // 命令行参数
        NULL,              // 进程安全属性
        NULL,              // 线程安全属性
        FALSE,             // 不继承句柄
        CREATE_SUSPENDED,  // 创建挂起进程
        NULL,              // 使用当前环境变量
        NULL,              // 使用当前工作目录
        &si,               // 启动信息
        &pi,               // 进程信息输出
        dllPath,           // 要注入的DLL路径
        NULL               // 恢复地址(NULL表示使用原始入口点)
    );

    if (success) {
        printf("注入成功! 进程ID: %d\n", pi.dwProcessId);
        
        // 可以在这里添加额外操作...
        
        // 关闭句柄
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return 0;
    } else {
        printf("注入失败! 错误代码: %lu\n", GetLastError());
        return 1;
    }
}

4.3 多DLL注入实现

使用CreateProcessWithMultipleDllsA实现多DLL注入:

// 多DLL注入示例
const char* dlls[] = {
    "C:\\path\\to\\monitor.dll",
    "C:\\path\\to\\logger.dll"
};

BOOL success = CreateProcessWithMultipleDllsA(
    targetPath,
    NULL,
    NULL,
    NULL,
    FALSE,
    CREATE_SUSPENDED,
    NULL,
    NULL,
    &si,
    &pi,
    2,                  // DLL数量
    dlls                // DLL路径数组
);

五、32/64位架构兼容性处理

5.1 架构检测实现

Detours提供了DetourIsWow64Process函数检测进程架构:

BOOL Is64BitProcess(HANDLE hProcess) {
    BOOL isWow64 = FALSE;
    if (DetourIsWow64Process(hProcess, &isWow64)) {
        // 在64位系统上:
        // - 64位进程: isWow64 = FALSE
        // - 32位进程: isWow64 = TRUE
        // 在32位系统上: 始终返回FALSE
        
        SYSTEM_INFO si;
        GetNativeSystemInfo(&si);
        
        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
            return !isWow64; // 64位系统上非Wow64进程是64位
        }
    }
    return FALSE; // 32位系统或检测失败
}

5.2 跨架构注入解决方案

当注入器与目标进程架构不同时,需要使用架构适配的DLL:

// 架构适配注入示例
int InjectTarget(const char* targetPath, const char* dll32Path, const char* dll64Path) {
    // 1. 创建挂起的目标进程
    STARTUPINFOA si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    
    BOOL success = CreateProcessA(
        targetPath, NULL, NULL, NULL, FALSE, 
        CREATE_SUSPENDED | DEBUG_PROCESS, NULL, NULL, &si, &pi
    );
    
    if (!success) {
        printf("创建进程失败! 错误代码: %lu\n", GetLastError());
        return 1;
    }
    
    // 2. 检测目标进程架构
    BOOL is64Bit = Is64BitProcess(pi.hProcess);
    const char* dllPath = is64Bit ? dll64Path : dll32Path;
    
    // 3. 使用DetourUpdateProcessWithDll注入DLL
    const char* dlls[] = { dllPath };
    success = DetourUpdateProcessWithDll(pi.hProcess, dlls, 1);
    
    if (success) {
        // 4. 恢复进程执行
        ResumeThread(pi.hThread);
        printf("注入成功! 进程ID: %d (架构: %s)\n", 
               pi.dwProcessId, is64Bit ? "64位" : "32位");
    } else {
        printf("注入失败! 错误代码: %lu\n", GetLastError());
        TerminateProcess(pi.hProcess, 0);
    }
    
    // 关闭句柄
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return success ? 0 : 1;
}

六、错误处理与调试技巧

6.1 常见错误码及解决方案

错误码含义解决方案
0x2 (ERROR_FILE_NOT_FOUND)文件未找到检查目标进程和DLL路径是否正确
0x5 (ERROR_ACCESS_DENIED)访问被拒绝以管理员权限运行注入器
0xC1 (ERROR_BAD_EXE_FORMAT)无效的PE格式确保DLL与目标进程架构匹配
0x7E (ERROR_PROC_NOT_FOUND)函数未找到更新Detours库到最新版本
0x126 (ERROR_MOD_NOT_FOUND)模块未找到检查DLL依赖是否完整

6.2 调试技巧

  1. 启用Detours调试输出
#define DETOUR_DEBUG 1
#include <detours.h>
  1. 使用DebugView监控调试输出

    • 下载并运行DebugView
    • 在注入器中添加调试输出:
    DETOUR_TRACE(("注入进度: 正在修改进程导入表...\n"));
    
  2. 进程注入流程验证

mermaid

七、高级应用与最佳实践

7.1 DLL加载顺序控制

当注入多个DLL时,可以通过以下方式控制加载顺序:

// 按顺序加载多个DLL
const char* dlls[] = {
    "C:\\deps\\first.dll",   // 第一个加载
    "C:\\deps\\second.dll",  // 第二个加载
    "C:\\main\\monitor.dll"  // 最后加载
};

BOOL success = CreateProcessWithMultipleDllsA(
    targetPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED,
    NULL, NULL, &si, &pi, 3, dlls
);

7.2 注入后的进程通信

注入DLL后,可以通过多种方式与主进程通信:

  1. 共享内存
// 创建共享内存
HANDLE hMapFile = CreateFileMappingA(
    INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "Global\\MySharedMem"
);

// 映射到进程地址空间
LPVOID pBuf = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 4096);
  1. 命名管道
// 创建命名管道
HANDLE hPipe = CreateNamedPipeA(
    "\\\\.\\pipe\\MyPipe", PIPE_ACCESS_DUPLEX,
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
    1, 4096, 4096, 0, NULL
);

7.3 注入防御与绕过

在实际应用中,可能需要应对目标进程的注入防御机制:

  1. 反调试检测
// 检查是否处于调试状态
BOOL IsDebuggerPresent() {
    __asm {
        mov eax, fs:[0x30]  // 获取PEB地址
        mov bl, [eax+0x2]   // PEB->BeingDebugged
        movzx eax, bl
    }
}
  1. 注入点隐藏
// 使用自定义恢复地址隐藏注入痕迹
VOID CustomResumeAddress() {
    // 这里可以添加反调试或反检测代码
    __asm {
        jmp original_entry_point  // 跳转到原始入口点
    }
}

// 在注入时指定自定义恢复地址
BOOL success = CreateProcessWithDllA(
    targetPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED,
    NULL, NULL, &si, &pi, dllPath, CustomResumeAddress
);

八、总结与扩展学习

本文详细介绍了使用Detours库的CreateProcessWithDll函数实现进程注入的完整流程,包括:

  • 核心原理:通过修改导入表实现早期DLL加载
  • 代码实现:从DLL开发到注入器的完整代码
  • 架构适配:32/64位进程的兼容处理方案
  • 错误调试:常见问题的诊断与解决方法
  • 高级应用:多DLL注入与进程通信

扩展学习资源

  1. Detours官方文档

    • 深入理解导入表修改技术
    • 事务处理与线程同步机制
  2. PE文件格式解析

    • 导入表结构详解
    • 重定位表处理
  3. 进程注入防御技术

    • API监控与钩子检测
    • 内存完整性校验

通过本文的案例实践,你可以构建稳定、高效的进程注入工具,实现对目标进程的监控、扩展或修复。在实际应用中,请确保遵守相关法律法规,仅在授权环境下使用这些技术。

九、附录:核心函数参考

CreateProcessWithDll参数说明

参数含义备注
lpApplicationName目标进程路径可以为NULL,此时从lpCommandLine解析
lpCommandLine命令行参数需以可写内存传入
dwCreationFlags创建标志必须包含CREATE_SUSPENDED
lpDllName注入DLL路径支持绝对路径或相对路径
lpResumeAddress恢复地址NULL表示使用原始入口点

DetourUpdateProcessWithDll工作流程

// 简化的DetourUpdateProcessWithDll实现逻辑
BOOL DetourUpdateProcessWithDll(HANDLE hProcess, LPCSTR* dlls, DWORD nDlls) {
    // 1. 枚举进程模块找到主EXE
    HMODULE hModule = FindMainModule(hProcess);
    
    // 2. 检测进程架构
    BOOL is32BitProcess = CheckProcessArchitecture(hProcess);
    
    // 3. 保存原始PE头信息
    DETOUR_EXE_RESTORE der;
    RecordExeRestore(hProcess, hModule, &der);
    
    // 4. 更新导入表添加DLL
    UpdateImports(hProcess, hModule, is32BitProcess, dlls, nDlls);
    
    // 5. 恢复进程保护属性
    RestoreProtection(hProcess, &der);
    
    return TRUE;
}

【免费下载链接】Detours Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form. 【免费下载链接】Detours 项目地址: https://gitcode.com/gh_mirrors/de/Detours

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值