2010-02-20 219 views
0

假设有一个包含sprintf()的错误程序,我想将其更改为snprintf,所以它没有缓冲区溢出。我如何在IDA中执行此操作?使用IDA修补EXE

+0

这是一个相当大的改变,因为你需要改变整个调用堆栈...你试图与开发者交谈吗? – kennytm 2010-02-20 06:39:22

+0

我的项目并未停止,我想修复这个错误以保护我自己 – 2010-02-22 04:12:30

回答

3

你真的不想使用来自IDA pro的信息进行这种改变。

尽管IDA的反汇编质量相对较高,但其质量不足以支持可执行重写。将调用转换为sprintf以调用snprintf需要将新参数推入堆栈。这需要引入一条新的指令,这会影响可执行映像中所有跟随它的EA的EA。更新这些有效地址需要非常高质量的拆卸。特别是,你需要能够:

  1. 确定可执行哪些地址数据,以及哪些代码
  2. 确定哪些指令操作数的符号(地址引用)和指令操作数是数字。

Ida不能(可靠地)给你这些信息。另外,如果可执行文件与crt静态链接,它可能不包含snpritnf,这将使手动执行重写变得非常困难。

有几种潜在的解决方法。如果在进行调用的函数中(或之后)有足够的填充,则可能只能重写单个函数。或者,如果您有权访问对象文件,并且这些对象文件是使用/ GY开关编译的(假设您使用的是Visual Studio),那么您可能能够编辑该对象文件。但是,编辑目标文件可能仍然需要大量修复。

但是,如果您有权访问目标文件,那么您可能也有权访问源代码。改变来源可能是你最好的选择。

+0

不需要在任何接近该功能的地方提供可用空间,只要您可以在某处找到(或制作)一些空间在适当的章节中,您可以用JMP将原始函数中的某些内容替换为您的新指令序列。但是,说实话,OllyDbg如何做到这一点更容易。 – SamB 2010-07-15 19:30:04

+0

你是对的..你不一定需要在功能附近有空间。但我不会主张频繁做,因为这可能会对业绩产生不利影响(地区差)。对于一个打电话给sprintf的人来说,这没关系。但是,如果你有很多打电话给sprintf的话,那么你不想在整个地方引入一堆疯狂的跳跃。 – 2010-07-16 02:23:51