4

我想知道 hippomocks 做了什么来拦截exit调用函数,例如如下代码所示:

   MockRepository mocks;
   mocks.ExpectCallFunc(exit).With(2).Throw(std::exception());
4

2 回答 2

6

它将传入的函数(在本例中是一个简单的函数指针)转换为 char *,很好地请求操作系统允许对其进行写入(在 Unices 上使用 mprotect,在 Windows 上使用 VirtualProtect),然后将前 5 个字节修改为 14 个字节成为无条件跳转指令。它将具有相同签名的生成(使用模板)函数的地址放在适当的位置,从而有效地覆盖该函数。

如果您愿意,您可以直接重用 HippoMocks 的代码,方法是在堆栈上使用正确的参数构造类 Replace 的对象。您还可以复制代码(在 GitHub 上最新的 hippomocks.h 中,支持 32/64 位 x86、ARM 和 thumb)。它在 200 线附近,因此相对较高。您还需要复制出可怕的_cast 类和 Unprotect 类;第一个允许它将成员函数指针转换为任何其他类型(reinterpret_cast 不可能),第二个包装特定于操作系统的取消保护(和重新保护)调用。

在清理 C++11 的代码时,我还准确地提取了这个子集,因此您现在可以使用 detail/replace.h 文件来获取执行此操作的代码。如需直接链接,请查看https://github.com/dascandy/hippomocks/blob/cpp11/HippoMocks/detail/replace.h

于 2014-08-28T14:11:28.773 回答
5

进行拦截的代码在hippomocks.h. 它修改内存保护标志以允许写入提供的函数指针的地址,然后写入跳转指令来代替函数的初始字节。当不再需要挂钩时,将恢复原始字节。这与例如Microsoft Detours库使用的方法相同。

于 2014-08-01T12:12:03.760 回答