用于在运行时操作机器代码的库?

时间:2013-04-27 22:59:22

标签: c assembly x86 machine-code

是否有用于操作x86 / x64机器代码的C库?具体来说,我想在运行时修改程序地址空间中的函数。

例如,我有函数foobar,我有其内部工作的来源或知识,但无法重新编译它们所在的库,我有我自己写的函数baz。现在,我希望能够说出以下内容:“在函数foo中,找到对bar的调用,并在其前面注入baz的说明”。该工具必须相应地调整程序中的所有相关地址。

我知道所有的零碎都存在,例如,有工具可以进行热修补功能。我想由于优化等原因会对可能的内容有一些限制,但基本功能应该是可能的。我找不到这样的东西,有没有人有链接?

2 个答案:

答案 0 :(得分:3)

这被称为“自我修改代码”(参见wikipedia),它曾经在80年代和90年代初很流行。然而,特别是在机器代码和ASM中,它几乎作为现代语言的方法而消失,因为它非常脆弱。托管语言试图提供更安全的模型,因为它也是缓冲区溢出攻击的基础。

请记住,您的代码页可能被标记为只读或写时复制,并且您可能会在许多现代操作系统上获得访问冲突,但如果内存为我服务,则需要获取内存的基本原则变量或函数的地址,您需要对该位置生成的代码和/或堆栈布局有非常具体的了解。

这里有一些让你入门的链接;

  1. How to write self-modifying code in x86 assembly
  2. Self-modifying code for debug tracing in quasi-C
  3. 具体来说,在您的情况下,我不会通过插入操作来修改foo,然后尝试调整所有代码,您需要做的就是更改{{1} }地址jump通过中间人。这被称为bar。这样做的好处是,将跳转地址从一个地址修改为另一个地址要脆弱得多,因为它不会改变原始函数的结构,只是一个数字。事实上,相比之下它是微不足道的。

    Thunk中,您可以在调用真实函数之前和之后执行您喜欢的任何操作。如果您已经在相同的地址空间并且加载了thunk代码,那么您就回家了。

    如果您使用的是Windows,则可能还需要查看Detours.

答案 1 :(得分:1)

如果您正在使用gcc并且想要替换整个函数,则可以使用-Wl,wrap,functionName开关重定向,包装函数:https://stackoverflow.com/a/617606/111160

然后,只要代码想要访问,请调用functionName它运行您提供的__wrap_functionName。您仍然可以使用__real_functionName访问原始文件。

如果您想在每次致电baz之前执行某些操作,请让__wrap_baz执行此操作,然后再致电__real_baz