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!