概述:Detours 的说明和简单使用
Detours
Detours 是微软提供的一套工具,主要用于win32 API的拦截
Github:microsoft/Detours: Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form.
仓库中有挺多示例程序可供参考。
使用 Detours 的大致流程:
在 Detours 的工作过程中,DetourTransactionBegin
函数首先用于启动一个截获(Hook)或解除截获(Unhook)的过程,这个过程中可能包含对多个函数的修改。然后,开发者可以使用 DetourAttach
或 DetourAttachEx
函数将 Detour 钩子附加到目标函数上,或使用 DetourDetach
函数将钩子从目标函数中分离出来。
相关函数说明
DetourUpdateThread 函数说明
DetourUpdateThread
函数是 Detours 库中的一个重要函数,用于在 Detour 事务处理过程中将特定的线程列入更新范围。Detours 是一个用于在运行时修改二进制代码(如函数钩子)的库,它允许开发者在不修改原始代码的情况下,拦截和修改函数的执行流程。
DetourUpdateThread
函数的作用是在这个事务过程中,将一个或多个线程列入需要更新的范围。这是因为在多线程环境中,直接修改函数的代码可能会导致竞态条件,即一个线程正在执行原始代码时,另一个线程可能已经修改了该代码。通过 DetourUpdateThread
将线程列入更新范围,Detours 库可以确保在事务提交时,所有相关线程的代码都被正确地更新,从而避免竞态条件。
具体来说,DetourUpdateThread
函数的作用是:
- 将指定的线程加入到 Detour 事务的更新列表中。
- 在事务提交时,Detours 库会遍历这个更新列表,并对列表中的每个线程执行必要的代码更新操作。
需要注意的是,在调用 DetourTransactionCommit
或 DetourTransactionCommitEx
函数提交事务之前,所有的附加、分离和线程更新操作都不会生效。一旦事务被提交,所有的修改就会立即生效,所有相关线程的代码都会被更新以反映这些修改。
因此,DetourUpdateThread
函数是 Detours 库中用于确保多线程环境下代码修改一致性和安全性的重要工具之一。
可以看下 DetourUpdateThread
的源码,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread) { LONG error;
if (s_nPendingError != NO_ERROR) { return s_nPendingError; }
if (hThread == GetCurrentThread()) { return NO_ERROR; }
DetourThread *t = new NOTHROW DetourThread; if (t == NULL) { error = ERROR_NOT_ENOUGH_MEMORY; fail: if (t != NULL) { delete t; t = NULL; } s_nPendingError = error; s_ppPendingError = NULL; DETOUR_BREAK(); return error; }
if (SuspendThread(hThread) == (DWORD)-1) { error = GetLastError(); DETOUR_BREAK(); goto fail; }
t->hThread = hThread; t->pNext = s_pPendingThreads; s_pPendingThreads = t;
return NO_ERROR; }
|
hookDemo
修改 GetLocalTime
,使其返回的分钟数为 52
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include <iostream> #include <Windows.h>
#include "detours.h" #pragma comment (lib,"detours.lib") using namespace std;
void (*OldGetLocalTime)(LPSYSTEMTIME) = GetLocalTime;
void NewGetLocalTime(LPSYSTEMTIME lpSystemTime) { OldGetLocalTime(lpSystemTime); lpSystemTime->wMinute = 52; }
void StartHook() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)OldGetLocalTime, NewGetLocalTime); DetourTransactionCommit(); }
void EndHook() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)OldGetLocalTime, NewGetLocalTime); DetourTransactionCommit(); }
int main() { SYSTEMTIME time, time2; GetLocalTime(&time); cout << time.wHour << ":" << time.wMinute << endl; StartHook();
GetLocalTime(&time2); cout << time2.wHour << ":" << time2.wMinute << endl;
EndHook(); return 0; }
|