我有一个需要加载的 DLL(我已经编写并编译了它),我想在将 DLL 加载到内存之前在汇编代码的现有指令之间插入指令。当然,您不能只读取每个字节并将它们插入其中,因为指令有时是多个字节。
我正在考虑使用 Udis86 之类的东西并一一阅读指令,然后将它们写入内存,并在它们之间编写我的其他指令。这是一个好方法还是有更好的方法?
我有一个需要加载的 DLL(我已经编写并编译了它),我想在将 DLL 加载到内存之前在汇编代码的现有指令之间插入指令。当然,您不能只读取每个字节并将它们插入其中,因为指令有时是多个字节。
我正在考虑使用 Udis86 之类的东西并一一阅读指令,然后将它们写入内存,并在它们之间编写我的其他指令。这是一个好方法还是有更好的方法?
我不确定您要在哪里插入代码。但是,如果它位于函数体的中间,而不一定是函数序言或结语,那么为什么不使用带有一堆 nop 的 __asm 块来填充您将编写代码的区域。然后只需在运行时填写 nop 所在的代码。
你有(至少)两个选择:
两者都是可能的,但对于后者,有必要规避或禁用安全保护:代码(相对于数据)被加载到在大多数(如果不是全部——不确定 CE)Windows 环境中不可写的内存中。
加载代码后,有直接的 o/s 支持来查找符号地址。修改文件将需要有关解码符号信息和解释文件偏移量的高级知识,或者搜索专门为此目的放置在文件中的模式。这可以是调用以初始化 DLL 的 DllMain 入口点中的逻辑,或 DLL 中已知足够早执行的任何其他函数。
还有一些DLL注入技术可以达到同样的目的。
但是,除了所有这些,如何安排 DLL 使用一些回调函数传递给它,一旦您编写了要执行的代码?如果不了解您要完成的工作,就很难说出什么是有用的。
至于怎么做,一个简单的方法是在汇编模块中编写指令,汇编它,然后检查生成的字节。自然,您应该彻底了解目标汇编语言,以便正确计算或修复分支和相对跳转偏移以及数据引用。虽然在运行时反汇编指令是可能的并且有时是可行的,但通常更容易通过其他方式(如调试器)识别指令并让程序查找字节序列,然后执行所需的任何转换。