Detours学习

Detours用于插桩任意Win32函数,通过重写目标函数的内存插桩。

通过保留没有插桩的目标函数作为插桩的一部分。基于Detours的应用有DCOM协议栈,为基于COM的OS API创建thunk层,广泛用于微软工业。

安装

git clone https://github.com/Microsoft/vcpkg.git
    cd vcpkg
    ./bootstrap-vcpkg.sh
    ./vcpkg integrate install
    vcpkg install detours

进入Detours使用Developer Command Prompt 的nmake构建samples即可

代码

需要添加.h文件以及lib库(解决方案视图-->选中要添加lib的工程-->点击右键-->"添加"-->"现有项"-->选择lib文件)

新建32位dll项目,引入官方代码

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "detours.h"
#include <stdio.h>

static LONG dwSlept = 0;

// Target pointer for the uninstrumented Sleep API.
//
static VOID(WINAPI* TrueSleep)(DWORD dwMilliseconds) = Sleep;

// Detour function that replaces the Sleep API.
//
VOID WINAPI TimedSleep(DWORD dwMilliseconds)
{
    // Save the before and after times around calling the Sleep API.
    DWORD dwBeg = GetTickCount();
    TrueSleep(dwMilliseconds);
    DWORD dwEnd = GetTickCount();
    InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
    printf("[Sleeped]: %d\n, all sleep time:%d\n", dwMilliseconds,dwSlept);
}

// DllMain function attaches and detaches the TimedSleep detour to the
// Sleep target function.  The Sleep target function is referred to
// through the TrueSleep target pointer.
//
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
    if (DetourIsHelperProcess()) {
        return TRUE;
    }

    if (dwReason == DLL_PROCESS_ATTACH) {
        DetourRestoreAfterWith();

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)TrueSleep, TimedSleep);
        DetourTransactionCommit();
    }
    else if (dwReason == DLL_PROCESS_DETACH) {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)TrueSleep, TimedSleep);
        DetourTransactionCommit();
    }
    return TRUE;
}

使用HelloSleep引入代码

#include <Windows.h>
#include <stdio.h>

int main() {
    HMODULE h = LoadLibraryA("HelloDetours.dll");
    if (h == NULL) {
    	printf("Error loading library: %d\n", GetLastError());
    }
    Sleep(10);
    Sleep(20);
    printf("HelloWorld!\n");
}

结果

[Sleep]: 10, all sleep time:31
[Sleep]: 20, all sleep time:62
HelloWorld!

参考

https://www.microsoft.com/en-us/research/project/detours/

https://github.com/microsoft/detours