Detours学习1 - 开始使用Detours
Using Detours
要绕过目标函数,必须具备两个条件:一个是包含目标函数地址的目标指针,另一个是绕过函数。为了正确拦截目标函数、detour函数和目标指针必须具有完全相同的调用签名,包括参数数和调用约定。使用相同的调用约定可以确保适当地保留寄存器,并确保堆栈在detour函数和目标函数之间正确对齐。
用户代码必须包含detours.h
头文件并与detours链接detorus.lib
库。
// dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "pch.h" #pragma comment(lib, "detours.lib") static VOID(WINAPI* TureSleep)(DWORD dwMilliseconds) = Sleep; VOID WINAPI hkSleep(DWORD dwMilliseconds) { ULONGLONG dwBeg = GetTickCount64(); TureSleep(dwMilliseconds); ULONGLONG dwEnd = GetTickCount64(); TCHAR buffer[512]; _stprintf_s(buffer, sizeof(buffer) / sizeof(TCHAR), _T("Sleeped %llu milli sec"), dwEnd - dwBeg); MessageBox(NULL, buffer, _T(""), MB_OK); } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { if (DetourIsHelperProcess()) { return TRUE; } switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)TureSleep, hkSleep); DetourTransactionCommit(); break; case DLL_PROCESS_DETACH: DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)TureSleep, hkSleep); DetourTransactionCommit(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; }
通过DetourAttach
在Hook事务中调用可以拦截目标函数。通过对DetourTransactionBegin
和DetourTransactionCommit
的调用来标记Hook事务。该DetourAttach
带有两个参数:目标函数指针的地址和指向DetourFunction
函数的指针。目标函数未作为参数提供,因为它必须已经存储在目标指针中。
该DetourUpdateThread
提供在目标线程中声明,以便在事务提交时更新指令指针。
该DetourAttach
分配和准备跳转调用目标函数。Hook事务提交时,将重写目标函数和跳转函数Trampoline
,并更新目标指针以指向跳转函数
一旦Hook目标函数,对目标函数的任何调用都将通过DetourFunction
函数重新路由。通过Trampoline
调用目标函数时,DetourFunction
函数负责复制参数。这很明确,因为目标函数是DetourFunction
函数的内部调用函数。
通过DetourDetach
在Hook事件中的调用,可以删除对目标函数的拦截。与DetourAttach
一样,DetourDetach
也有两个参数:目标指针的地址和指向DetourFunction
函数的指针。当Hook事务提交时,目标函数将被重写并恢复为其原始代码,Trampline
函数将被删除,目标指针将恢复为指向原始目标函数。
如果需要将Hook的API注入到目标程序中,则Hook需要编译成Dll。可以使用远程线程注入、Dll劫持等技术。也可以使用
DetourCreateProcessWithDllEx
或DetourCreateProcessWithDlls
将Dll注入到目标进程中。如果使用DetourCreateProcessWithDllEx
或DetourCreateProcessWithDlls
,则DllMain函数必须调用DetourRestoreAfterWith
。如果Dll可以在x86和x64混合环境中使用,则DllMain函数必须调用DetourIsHelperProcess
导出为序号1,rundll32.exe
以执行帮助任务来调用该API。
下面来注入一个刚刚到的Dll到一个进程中,测试一下效果
安装Detours库
VcPkg install detours:x86-windows VcPkg install detours:x64-windows
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗