4

我有一个需要加载的 DLL(我已经编写并编译了它),我想在将 DLL 加载到内存之前在汇编代码的现有指令之间插入指令。当然,您不能只读取每个字节并将它们插入其中,因为指令有时是多个字节。

我正在考虑使用 Udis86 之类的东西并一一阅读指令,然后将它们写入内存,并在它们之间编写我的其他指令。这是一个好方法还是有更好的方法?

4

3 回答 3

3

转移指令不是一个好主意。许多 x86 指令取决于它们的位置,所以如果你改变它们,你可能会破坏很多东西。
您可以做的是将指令复制到您需要修补的位置;将 jmp 修补到某个空闲区域,然后在该空闲区域中放置复制的指令,您的额外代码,然后最后将 jmp 放回原始代码。不是微不足道的,而是可行的。检查thisthis以了解可能的实现。
也就是说,当您可以修改源代码时,为什么需要修改二进制文件?你应该问实际的问题,而不是“如何做 X [因为我决定我需要 X 来解决我的问题]”。

于 2010-11-30T16:58:50.717 回答
1

我不确定您要在哪里插入代码。但是,如果它位于函数体的中间,而不一定是函数序言或结语,那么为什么不使用带有一堆 nop 的 __asm 块来填充您将编写代码的区域。然后只需在运行时填写 nop 所在的代码。

于 2010-11-30T16:52:30.643 回答
0

你有(至少)两个选择:

  • 打开 DLL 文件并使用文件读/写操作对其进行修改
  • 在执行之前加载 DLL 并修改指令

两者都是可能的,但对于后者,有必要规避或禁用安全保护:代码(相对于数据)被加载到在大多数(如果不是全部——不确定 CE)Windows 环境中不可写的内存中。

加载代码后,有直接的 o/s 支持来查找符号地址。修改文件将需要有关解码符号信息和解释文件偏移量的高级知识,或者搜索专门为此目的放置在文件中的模式。这可以是调用以初始化 DLL 的 DllMain 入口点中的逻辑,或 DLL 中已知足够早执行的任何其他函数。

还有一些DLL注入技术可以达到同样的目的。


但是,除了所有这些,如何安排 DLL 使用一些回调函数传递给它,一旦您编写了要执行的代码?如果不了解您要完成的工作,就很难说出什么是有用的。


至于怎么做,一个简单的方法是在汇编模块中编写指令,汇编它,然后检查生成的字节。自然,您应该彻底了解目标汇编语言,以便正确计算或修复分支和相对跳转偏移以及数据引用。虽然在运行时反汇编指令是可能的并且有时是可行的,但通常更容易通过其他方式(如调试器)识别指令并让程序查找字节序列,然后执行所需的任何转换。

于 2010-11-30T16:57:18.350 回答