问题标签 [detours]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
929 浏览

c++ - 绕道并使用 _thiscall 作为钩子(GCC 调用约定)

我最近一直在研究迂回函数(仅在 Linux 中),到目前为止我已经取得了巨大的成功。在我发现这个之前,我一直在开发自己的绕道课程。我对代码进行了一些现代化改造,并将其转换为 C++(当然是一类)。该代码就像任何其他迂回实现一样,它将原始函数地址替换为我自己指定的“挂钩”函数的 JMP。它还为原始功能创建了一个“蹦床”。

一切都完美无缺,但我想做一个简单的调整。我用纯 C++ 编程,我不使用全局函数,所有内容都包含在类中(就像 Java/C# 一样)。问题是这种迂回方法打破了我的模式。“钩子”函数必须是静态/非类函数。

我想做的是实现对 _thiscall 钩子的支持(这对于 GCC _thiscall约定应该很简单)。我没有成功修改此代码以使用 _thiscall 挂钩。我想要的最终结果就是这样简单;PatchAddress(void * target, void * hook, void * class);. 我没有要求任何人为我做这件事,但我想知道如何解决/解决我的问题?

据我所知,我只需要增加“补丁”的大小(即现在是 5 个字节,我应该需要额外的 5 个字节吗?),然后在我使用 JMP 调用(到我的钩子函数)之前,我将我的“this”指针推送到堆栈(应该就像我将它作为成员函数调用一样)。为了显示:

而不是直接/仅进行“jmp”调用。这是正确的方法还是需要考虑下面的其他内容(注意:我不关心对 VC++ _thiscall 的支持)?

注意:这是我对上述代码的实现:header : source,使用libudis86

0 投票
1 回答
1020 浏览

c++ - C++ 和全动态函数

我有绕路的问题。众所周知,Detours 只能在 5 个字节的空间中移动(即一个 'jmp' 调用和一个 4 个字节的地址)。因此,在类(方法)中不可能有“钩子”函数,您无法提供“this”指针,因为根本没有足够的空间(这里的问题更彻底地解释了)。因此,我整天都在集思广益以寻求解决方案,现在我想请您对这个主题提出想法,这样我就不会在不知道是否可行的情况下开始一个 3-5 天的项目。

我最初有 3 个目标,我希望“挂钩”函数是类方法,我希望整个方法是面向对象的(没有静态函数或全局对象),最糟糕/最难的部分是完全动态的。这是我的(理论上)解决方案;使用汇编可以在运行时修改函数(一个完美的例子是任何绕行方法)。所以既然我可以动态修改函数,我不应该也可以动态创建它们吗?例如; 我分配内存,比如说~30字节(通过malloc/new)。难道不能只用对应于不同汇编运算符的二进制数替换所有字节(如 0xE9 是'jmp'),然后直接调用地址(因为它会包含一个函数)?

注意:我事先知道返回值,以及我想要绕行的所有函数的所有参数,并且由于我使用的是 GCC,thiscall 约定实际上与 _cdecl 相同。

所以这是我的想法/即将实现;我创建了一个“功能”类。此构造函数采用可变数量的参数(第一个参数除外,它描述了目标函数的返回值)。

每个参数都是对钩子将接收的参数的描述(大小,以及它是否是指针)。因此,假设我想为 a 创建一个 Function 类int * RandomClass::IntCheckNum(short arg1);。然后我只需要这样做:Function func(Type(4, true), Type(4, true), Type(2, false));. 其中“类型”定义为Type(uint size, bool pointer). 然后通过汇编我可以动态地创建函数(注意:这都将使用 _cdecl 调用约定),因为我可以计算参数的数量和总大小。

编辑:在这个例子中,Type(4, true)是返回值(int*),scondType(4, true)是 RandomClass 'this' 指针并Type(2, false)描述了第一个参数(短 arg1)。

通过这种实现,我可以轻松地将类方法作为回调,但它需要大量的汇编代码(我什至没有特别的经验)。最后,唯一非动态的东西是我的回调类中的方法(这也需要 pre 和 post 回调)。

所以我想知道;这可能吗?它需要做多少工作,我在这里过头了吗?

编辑:如果我把所有的东西都说得有点模糊,我很抱歉,但是如果你想更彻底地解释一些事情,请询问!

EDIT2:我也想知道,我是否可以在某处找到所有汇编运算符的十六进制值?一份清单会有很多帮助!和/或是否有可能以某种方式“保存” asm(""); 内存地址的代码(我非常怀疑)。

0 投票
1 回答
1265 浏览

c++ - 我的蹦床不会弹跳(绕行、C++、GCC)

感觉就像我在用我所有的问题滥用 Stackoverflow,但它毕竟是一个问答论坛:) 无论如何,我已经使用 detours 有一段时间了,但我还没有实现我自己的一个(我使用过包装器较早)。因为我想完全控制我的代码(谁不想呢?)我决定自己实现一个功能齐全的 detour'er,这样我就可以理解我的代码的每一个字节。

代码(如下)尽可能简单,但问题不是。我已经成功实现了 detour (即我自己的函数的挂钩),但我无法实现trampoline

每当我调用蹦床时,根据我使用的偏移量,我会得到“分段错误”或“非法指令”。两种情况的结局都是一样的;'核心倾销'。我认为这是因为我混淆了“相对地址”(注意:我对 Linux 还很陌生,所以我还远远没有掌握 GDB)。

正如代码中所评论的那样,取决于sizeof(jmpOp)(在第 66 行),我要么得到非法指令,要么得到分段错误。对不起,如果这是显而易见的事情,我熬夜太晚了......

如果感兴趣,这是正常运行期间的输出(使用上面的确切代码):

果我在第 66 行使用 +/- sizeof(jmpOp),这就是结果:

注意:我正在运行 Ubuntu 32 位并编译g++ global.cpp main.cpp -o main -Iinclude

0 投票
3 回答
1677 浏览

c++ - 虚函数和绕行

我最近一直在绕弯路编程,以及随之而来的一切。我绕了很多不同的功能;thiscall、stdcall、cdecl、虚函数等。但是有一件事我没有管理(这甚至可能是不可能的),那就是挂钩一个基类虚函数。例如; 有一个 Car 类,它声明了一个虚函数(空)Drive。然后还有其他 3 个 car 类继承了 car 和 implements Drive

如果我挂钩 Car 的(基类)Drive函数(使用简单的 'jmp' 挂钩),如果他们调用基函数,它会在触发时由 的后代Car触发吗?Drive

更彻底地解释:

所以我想知道是否调用了基本方法 get 或者是否可以以某种方式挂钩?函数执行是直接跳转到Lamborghini::Drive还是以某种方式通过Car类,以便在后代调用时可以检测到Drive

编辑:如果基类函数为空,是否甚至可以挂钩它,因为它需要 5 个字节的空间?

0 投票
1 回答
1861 浏览

c++ - Detours - 挂钩类成员函数 - 设置目标函数偏移的语法?

对于非类函数 - 我可以简单地声明要绕行的函数的偏移量,例如:

现在,绕行类的成员函数变得很困难 - detours 有一个示例:

https://github.com/microsoft/Detours/blob/master/samples/member/member.cpp

该示例已经定义了目标成员函数 - 但我不只知道将我的 DLL 注入的二进制文件中的偏移量 - 那么我该如何转换它

像这样:

我在这里遇到编译错误

有什么提示吗?

0 投票
4 回答
4075 浏览

c++ - 通过注入的 DLL 绕过成员函数

原帖:

我试图从我注入的 DLL 中绕过一个成员函数。我已经获得了要挂接的函数的地址,但无法找出正确的语法或通过 detours 库挂接它的方法。我已经用错误消息评论了给我错误的行。

我已经阅读了成员函数挂钩的 detours 示例的源代码,这就是此代码的基础,但由于某种原因它不起作用。

任何帮助将不胜感激,谢谢!

解决方案:

0 投票
2 回答
2233 浏览

c++ - WriteFile 钩子不会捕获写入文件操作

我有一个应用程序,它将一些文本数据写入文件。我正在尝试做的是挂钩写作过程。我迷上了 MS Detours、CreateFile、WriteFile 和 WriteFileEx 函数。CreateFile 正确捕获这些文本文件的创建/打开,但 WriteFile 的钩子没有。它捕获了许多其他的东西,但不是这些。挂钩工作正常。我已经检查过了。

进程监视器还将这些写入操作显示为 WriteFile 操作(广告名称 IRP_MJ_WRITE 和 FASTIO_WRITE),就像我自己写东西时一样(我的操作挂钩正常工作)

这里发生了什么?除了WriteFile之外,还有其他方法可以将内容写入文件吗?

0 投票
0 回答
197 浏览

c++ - 指向 Direct3D 函数的指针

我有代码:

TrueSetWindowText 一个指向winapi 函数SetWindowText 的指针。接下来我使用它一切正常。

我决定尝试 Direct3D 功能。添加:

指向D3DX11CreateShaderResourceViewFromFile的指针。当我编译项目时,我得到一个错误。

在项目属性VC++目录中,我添加了:

包括目录 C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include

库目录 C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86

有谁知道为什么会出现这个错误?

0 投票
2 回答
524 浏览

c++ - 绕行 LoadLibraryA 时应用程序崩溃

我绕过了 LoadLibraryA,以阻止该函数被调用到我的应用程序中。它旨在阻止'dll注入'。如果您从未见过这些,请参考著名的 CDetour 库。

它钩住了加载库函数,甚至成功返回,也阻止了未知的dll被加载到内存中。有小费吗?

0 投票
2 回答
256 浏览

c++ - 关于修改虚拟表绕行的问题

我一直在使用与 Microsoft Detours 相同的方法练习 detours(将前五个字节替换为 jmp 和地址)。最近,我一直在阅读有关通过修改虚拟表来绕行的信息。如果有人能通过提及与前面提到的方法相比的一些优点和缺点来阐明这个主题,我将不胜感激!

我还想询问有关堆栈上已修补的 vtable 和对象的信息。考虑以下情况:

在这种情况下foo->Call(),最终会在调用原始函数(即方法)MyCall(Foo * object)时调用。这是因为如果可能,编译器将尝试在编译期间决定任何虚拟调用(如果我错了,请纠正我)。这是否意味着您是否修补虚拟表并不重要,只要您使用堆栈上的对象(不是堆分配的)?foo2.Call()Foo::Call(void)