【问题标题】:How to modify a function in a compiled DLL如何修改已编译 DLL 中的函数
【发布时间】:2013-02-10 04:54:30
【问题描述】:

我想知道是否可以在已编译的 DLL 中“编辑”代码。

I.E.想象在Math.dll 中有一个名为sum(a,b) 的函数,它将ab 这两个数字相加

假设我丢失了 DLL 的源代码。所以我唯一拥有的是二进制 DLL 文件。 有没有办法我可以打开该二进制文件,找到我的函数所在的位置并将sum(a,b) 例程替换为例如另一个返回ab 相乘(而不是总和)的例程?

总结一下,是否可以编辑二进制代码文件?

也许使用像 ollydbg 这样的逆向工程工具?

【问题讨论】:

  • 在内存中比在磁盘上更容易。并且希望您没有任何类似于 AuthentiCode 或其他此类验证,以确保在相当智能的加载程序准备加载 PE 映像时磁盘上的映像不太可能被篡改。
  • 如果你的函数是在dll中导出的,为什么不直接包装dll呢?
  • 我说的不仅仅是 DLL 中的导出函数。如果 sum(a,b) 是 Dll 内部使用的私有函数怎么办?不是要公开使用的出口产品。是否可以找到这些例程并更改它们?
  • @RaymondChen 我认为这只是部分重复。

标签: c++ windows dll reverse-engineering disassembly


【解决方案1】:

是的,这绝对是可能的(只要 DLL 没有经过加密签名),但它具有挑战性。您可以使用简单的 Hex 编辑器来完成,但根据 DLL 的大小,您可能需要更新很多部分。不要试图读取原始二进制文件,而是通过反汇编程序运行它。

在编译后的二进制文件中,您会看到一堆深奥的字节。所有通常以汇编语言编写为指令(如“call”、“jmp”等)的操作码都将被转换为与机器架构相关的字节等价物。如果您使用反汇编程序,反汇编程序会将这些二进制值替换为汇编指令,以便更容易理解正在发生的事情。

在编译后的二进制文件中,您还会看到很多对硬编码位置的引用。例如,不是看到“call add()”,而是“call 0xFFFFF”。这里的值通常是对位于文件中特定偏移处的指令的引用。通常这是属于被调用函数的第一条指令。其他时候是堆栈设置/清理代码。这因编译器而异。

只要您替换的指令与原始指令的大小完全相同,您的偏移量仍然是正确的,您无需更新文件的其余部分。但是,如果您更改要替换的指令的大小,则需要手动更新对位置的所有引用(顺便说一句,这真的很乏味)。

提示:如果您添加的指令小于比您替换的指令,您可以用 NOP 填充其余指令以防止位置偏离。

希望能有所帮助,祝黑客愉快:-)

【讨论】:

  • 谢谢!您的回答非常有用且内容丰富!我没有考虑直接修补我的 dll 所涉及的偏移量和地址更改。
【解决方案2】:

Detours,一个用于在 x86 机器上检测任意 Win32 函数的库。 Detours 通过重写目标函数图像来截取 Win32 函数。 Detours 包还包含用于将任意 DLL 和数据段(称为有效负载)附加到任何 Win32 二进制文件的实用程序。 Download

【讨论】:

    【解决方案3】:

    当然,您可以根据自己的喜好对 DLL 进行十六进制编辑并做各种花哨的事情。但问题是,如果您的意图是替换开始的函数,为什么要这么麻烦?

    new函数创建一个新的DLL,并将旧DLL中调用函数的代码更改为调用新DLL中的函数。

    或者您是否也丢失了应用程序的源代码? ;)

    【讨论】:

      猜你喜欢
      • 2015-02-02
      • 2012-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多