问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Detours框架实现原理探究

创作时间:
作者:
@小白创作中心

Detours框架实现原理探究

引用
CSDN
1.
https://blog.csdn.net/linlin003/article/details/126770323

Detours是微软研发并开源的一个API Hook框架,在自动化测试、性能分析以及安全攻防领域有着广泛的应用。本文将深入探讨Detours的实现原理,包括其核心概念、工作流程以及关键函数的源代码分析。

Hook API在自动化测试、性能分析以及安全攻防领域有着广泛的应用。Detours作为微软研发并开源的API HOOK框架,在微软内部以及业界有着广泛的使用,正如它的官方说明一样:

Detours is a software package for re-routing Win32 APIs underneath applications. For almost twenty years, has been licensed by hundreds of ISVs and used by nearly every product team at Microsoft.

首先要介绍该框架用到的几个概念:

  • Source Function:用户编写的源代码
  • Target Function:被调用的函数(比如Windows API)
  • Detour Function:自定义函数,用来替换Target Function的函数
  • Trampoline:从Detour Function跳转回Target Function所需的指令

下面我们看一下HOOK之前的正常调用流程:

再看一下HOOK之后的流程:

为了方便理解,我们看一下伪代码示意图:

上面就是 Detours Hook API的基本原理了,下面我们在看一下源代码,是具体如何实现以上部分的。

在代码里面,如果我们想hook 一个api一般编写如下代码:

其中Old_ReadProcessMemory 与 My_ReadProcessMemory 分别为 Target Function 以及 Detour Function

看到上面的代码我们可以思考一下,函数最后为什么调用Old_ReadProcessMemory 而不是直接调用 ReadProcessMemory呢?

接下来的源码分析可以解答这个问题。

我们先分析DetourTransactionBegin这个函数:

可以看到,这个函数的主要作用是修改之前已经分配的Trampoline内存的属性,确保它们是可以写入的,为之后的操作进行准备。

DetourUpdateThread函数的主要作用就是去让线程进入暂停状态,为后面的替换操作做准备。

接下来分析 DetourAttach函数

DetourAttach函数内部只有一句代码就是调用 DetourAttachEx函数。

由于DetourAttachEx函数特别长,下面的话就只指出几个关键片段

  • 复制Target Function开始处的机器码到Trampoline
  • 在复制到Trampoline的机器码结尾处填充跳转指令(跳转到Target Function没有被覆盖部分)
  • 另外一个要注意的点就是 函数用数据结构保存了第一个参数

DetourAttach函数的主要作用就是把必要的信息都计算好保存起来,并没有执行真正的Hook动作

真正的Hook动作是在DetourTransactionCommit(DetourTransactionCommitEx)函数中完成的

LONG WINAPI DetourTransactionCommit()
{
return DetourTransactionCommitEx(NULL);
}

以下是关键代码片段:

  • 将Target Function 开始处的机器码替换为跳转到Detour Function的跳转指令,同时将DetourAttach传入的第一个参数指向的地址改为Trampoline中备份的机器码
  • DetourAttach函数的第一个参数就传出了一个新的函数地址。

这样我们就可以回答前文的那个问题:为什么调用用Old_ReadProcessMemory 而不是直接调用 ReadProcessMemory呢?

因为Old_ReadProcessMemory 指向了Trampoline中备份的机器码,运行效果等同于被Hook前的Target Function

而ReadProcessMemory开始处的机器码已经被替换成了跳转到Detour Function的指令,如果Detour Function函数中再使用ReadProcessMemory的话就变成了死循环了~

参考文献:黑客防线2008.12《Detours源码探索》

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号