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事务中调用可以拦截目标函数。通过对DetourTransactionBeginDetourTransactionCommit的调用来标记Hook事务。该DetourAttach带有两个参数:目标函数指针的地址和指向DetourFunction函数的指针。目标函数未作为参数提供,因为它必须已经存储在目标指针中。

DetourUpdateThread提供在目标线程中声明,以便在事务提交时更新指令指针。

DetourAttach分配和准备跳转调用目标函数。Hook事务提交时,将重写目标函数和跳转函数Trampoline,并更新目标指针以指向跳转函数

一旦Hook目标函数,对目标函数的任何调用都将通过DetourFunction函数重新路由。通过Trampoline调用目标函数时,DetourFunction函数负责复制参数。这很明确,因为目标函数是DetourFunction函数的内部调用函数。

通过DetourDetach在Hook事件中的调用,可以删除对目标函数的拦截。与DetourAttach一样,DetourDetach也有两个参数:目标指针的地址和指向DetourFunction函数的指针。当Hook事务提交时,目标函数将被重写并恢复为其原始代码,Trampline函数将被删除,目标指针将恢复为指向原始目标函数。

如果需要将Hook的API注入到目标程序中,则Hook需要编译成Dll。可以使用远程线程注入、Dll劫持等技术。也可以使用DetourCreateProcessWithDllExDetourCreateProcessWithDlls将Dll注入到目标进程中。如果使用DetourCreateProcessWithDllExDetourCreateProcessWithDlls,则DllMain函数必须调用DetourRestoreAfterWith。如果Dll可以在x86和x64混合环境中使用,则DllMain函数必须调用DetourIsHelperProcess导出为序号1,rundll32.exe以执行帮助任务来调用该API。


下面来注入一个刚刚到的Dll到一个进程中,测试一下效果

安装Detours库

VcPkg install detours:x86-windows
VcPkg install detours:x64-windows

posted @   非法关键字  阅读(2179)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示