Detours学习之三:使用Detours

使用Detours
为了达到拦截和截获绕过目标函数,有两件事是必要的:一个包含目标函数地址的目标指针和一个detour函数。为了正确拦截目标函数、detour函数和目标指针,必须具有完全相同的调用签名,包括参数数量和调用约定。使用相同的调用约定可以确保正确地保存寄存器,并确保在detour函数和目标函数之间正确地对齐堆栈

下面的代码片段说明了Detours库的用法。用户代码必须包含detours.h头文件并链接到detours.lib库。

#include <windows.h>
#include <detours.h>

static LONG dwSlept = 0;

// Target pointer for the uninstrumented Sleep API. 静态长dwSlept =0;
//未检测的Sleep API的目标指针。
//
static VOID (WINAPI * TrueSleep)(DWORD dwMilliseconds) = Sleep;
// Detour function that replaces the Sleep API.
//用来替换Sleep API的Detour函数。
//
VOID WINAPI TimedSleep(DWORD dwMilliseconds)
{
// Save the before and after times around calling the Sleep API.
//保存调用Sleep API前后的次数。

DWORD dwBeg = GetTickCount();
TrueSleep(dwMilliseconds);
DWORD dwEnd = GetTickCount();

InterlockedExchangeAdd(&dwSlept, dwEnd – dwBeg);
//DllMain函数将TimedSleep绕道附加和分离到

}

// 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.
//
//睡眠目标函数。Sleep目标函数被引用
//通过truessleep目标指针。
//
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;
}
简单的修改Windows Sleep API。

通过在一个DetourAttach事务中调用DetourAttach API来启用目标函数的拦截。通过调用DetourTransactionBegin API和DetourTransactionCommit API来标记一个detourtransaction。DetourAttach API接受两个参数:目标指针的地址和DetourAttach函数的指针。目标函数没有作为实参给出,因为它必须已经存储在目标指针中。

DetourUpdateThread API在事务中登记线程,以便在事务提交时适当地更新它们的指令指针。

DetourAttach API分配并准备一个蹦床来调用目标函数。当detour事务提交时,重写目标函数和trampoline,并更新目标指针以指向trampoline函数。

一旦绕过目标函数,对目标函数的任何调用都将通过detour函数重新路由。当通过蹦床调用目标函数时,由detour函数负责复制参数。这是很直观的,因为目标函数变成了一个简单的由detour函数调用的子例程。

通过在DetourDetach事务中调用DetourDetach API来删除对目标函数的拦截。与DetourAttach API一样,DetourDetach API也接受两个参数:目标指针的地址和指向detourfunction的指针。当detour事务提交时,目标函数被重写并恢复到原始代码,trampoline函数被删除,目标指针被恢复到指向原始目标函数。

如果需要在没有源代码访问的情况下将detour函数插入到现有的应用程序中,则应该将detour函数打包到DLL中。可以在创建时使用DetourCreateProcessWithDllEx或DetourCreateProcessWithDlls api将DLL加载到新进程中。如果使用DetourCreateProcessWithDllEx或DetourCreateProcessWithDlls插入DLL, DllMain函数必须调用DetourRestoreAfterWith API。如果DLL可以在32位和64位的混合环境中使用,那么DllMain函数必须调用DetourIsHelperProcess API。DLL必须将DetourFinishHelperProcess API导出为export Ordinal 1, rundll32.exe将调用该API来执行helper任务。

注意:微软绝不保证或支持任何通过迂回或任何其他机制更改的微软或第三方代码。

Detours包中包含的withdll.exe程序使用detourcreateprocesswithdll API来启动一个新的具有DLL的进程。
————————————————
版权声明:本文为CSDN博主「jyl_sh」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jyl_sh/article/details/121008515

本文为原创文章,转载请注明出处!

Detours学习之二:常见问题(FAQ)

 常见问题(FAQ)

本文介绍的内容包含了一个关于Detours的常见问题列表。这些问题是按主题类别和有趣 的领域分组的。

兼容性

Detours与Windows 10兼容吗?

是的。Detours完全兼容Windows 10桌面和服务器应用程序。虽然Detours可以用于Windows Store应用程序的开发和测试,但Windows 10的Windows Store新应用程序不能使用Detours。

为什么我的Windows 10商店应用程序不能包含Detours?

Windows Store应用程序只能使用Win32 API的一个子集。Detours需要几个Win32 api,这些api在Windows应用程序认证中是被禁止的。Detours禁用的api包括VirtualAlloc, VirtualProtect和FlushInstructionCache。

Detours兼容Windows 95, Windows 98或Windows ME吗?

不。Detours仅与Windows NT家族的操作系统兼容:Windows NT、Windows XP和Windows Server 2003等。Detours不能在Windows 9x系列操作系统上工作,因为它们有一个基本的虚拟内存系统。

用Detours代码编译

我该怎么做XDetours吗?Detours

查看Detours代码样本。Detours的样本相当广泛。很可能您想用Detours完成的任何事情都包含在其中一个示例中。

我在哪里可以找到detours.libdetours.h

您需要构建一个版本的Detours。为您的c/c++编译器。构建detours的步骤是:

  1. 为目标架构初始化Microsoft c++工具集命令行环境。
  2. 克隆Detours库:git Clone https://github.com/microsoft/Detours.git
  3. 构建与nmake

    a.要仅仅构建detours库,请切换到detours/src目录并运行nmake命令。

    b.要构建detours和示例,请切换到detours目录并运行nmake命令。

  4. 一个自由。 目录现在应该存在,包含Detours静态库,其中 是您要编译的目标架构。include目录也将在构建过程中生成,它包含库的头文件。

    C:\detours> dir /b *。x64垃圾箱。X64自由。X64 C:\detours> dir /b lib. txt文件。X64弯路。自由弯路。pdb syelog。lib C:\detours> dir /b include detours.h detver.h syelog.h

使用Detours

为什么没人打电话来找我malloc

可能是因为目标程序没有使用您绕过的malloc函数。

像malloc这样的标准库函数可以从libc*中静态地链接到程序。Lib库,或动态地从msvcrt*.dll库之一。当静态链接时,程序接收标准库函数的私有版本。动态链接时,程序共享DLL中标准库函数的版本。如果您绕过函数的私有版本,或者如果目标程序使用它自己的函数的私有版本,目标程序将不会调用您的绕道。

为什么Detours被打包为静态库(detours.lib),而不是动态链接库(例如detours.dll)?

将Detours打包为静态库,可以最大限度地降低意外地使Detours包本身所需的函数的风险,并减少版本问题。注意,当与代码静态链接时,Detours只增加了大约16KB。

我还需要使用吗detoured.dll

不,Detours .dll标记文件在Detours 3.0中被删除了。在Detours 3.0之前,该文件被用作标记,用于指导微软技术支持人员和工具,如Windows错误报告,帮助他们快速确定进程已被Detours包更改。Windows 7中Windows OCA的进步消除了这个标记的需要,因为Windows 7维护了一个已从进程中卸载的DLL列表。微软不能以任何方式保证或支持第三方对微软二进制文件的修改。微软也不能以任何方式支持包含由第三方修改的微软二进制文件的应用程序。这包括使用Detours包在内存中进行修改。

如何调试我的detour DLL的启动?

Windbg可以单步执行,也可以在进程启动时出现异常而中断。Windbg可以从msdn.microsoft.com的“Windows调试工具”下载。例如,你可以使用命令行:

Windbg -o withdll.exe

在Visual Studio中,也可以使用Microsoft子进程调试强大工具扩展来调试子进程启动。安装完成后,您将需要使用扩展启用子进程调试,关于如何实现这一点的详细说明可以在宣布扩展的博客文章中找到。

为什么我的代码在调试器下表现不同?

调试器通过用break指令替换函数代码来插入断点。例如,在X86和X64处理器上,调试器将为断点编写0xCC (int 3)。如果在应用一个detour之前编写了断点,那么detour库将看到0xCC而不是真正的指令。

解决这个问题的最佳方法是确保在目标函数上没有设置调试器断点。

许可

Detours可以用于商业应用吗?

Dettours是根据麻省理工学院许可许可的,允许商业使用。

错误报告

如何报告错误或问题?

请在GitHub问题跟踪系统上打开一个问题。在您的问题中,请确保包含您正在使用的Detours版本。在打开一个问题之前,请尽一切努力确保问题不是您自己的代码或使用Detours的错误。本FAQ中涵盖了最常见的用户错误来源。

您还可以将详细的错误报告发送到detours@microsoft.com。请在主题行中包含“DETOURS BUG报告”文本。在您的消息体中,请包含README.TXT文件中的第一行,该文件包含您正在使用的Detours版本的完整描述,包括Build号。

detours@microsoft.com电子邮件地址只用于bug报告,而不是产品支持线。

页面87

概述

API参考

Detours学习之一:概述

Microsoft Research Detours Package概述

Detours是一个用于在ARM, ARM64, X86, X64和IA64机器上拦截二进制函数的库。Detours最常用来拦截应用程序中的Win32 api调用,比如添加调试工具。拦截代码在运行时动态应用。Detours将目标函数的前几个指令替换为无条件跳转到用户提供的detour函数。来自目标函数的指令被放置在Trampoline函数中。Trampoline函数的地址放在目标指针中。detour函数可以替换目标函数,也可以通过目标指针作为子例程调用目标函数来扩展其语义。

在执行时插入Trampoline,绕开目标函数,或者先做一次拦截。目标函数的代码是在内存中修改的,而不是在磁盘上,因此可以在非常细的粒度上拦截二进制函数。例如,DLL中的过程可以在应用程序的一次执行中拦截绕开执行目标函数,而原始过程不能在同时运行的另一次执行中拦截绕开执行目标函数。与DLL重链接或静态重定向不同,无论应用程序或系统代码使用何种方法定位目标函数,Detours库中使用的拦截技术都保证能够正常工作。

除了基本的detour功能外,Detours还包括编辑任何二进制文件的DLL导入表、将任意数据段附加到现有二进制文件以及将DLL加载到新进程的功能。一旦加载到进程中,检测DLL可以拦截绕开执行目标函数进程中的任何函数,无论是在应用程序中还是系统库中,比如Windows api。

Detours的技术概述分为四个部分:

拦截二进制函数

使用detours

Payloads有效负载和DLL导入编辑

32位和64位进程

刚接触Detours的开发人员会发现,阅读所有四个技术概述部分和Simple示例程序非常有用。

本文档还包含以下信息:

detours API参考

使用Detours api的示例程序。

常见问题(FAQ)

本文为原创文章,转载请注明出处!