我在这个问题上苦苦挣扎了大约三个月:

如何使用反汇编程序(IDA Pro等)来生成可重新组装的asm代码并将其重新组装

我的经验是:


没有工具可以在32位x86上生成可重新组装的asm代码。
您需要调整/启发式修改asm代码由IDA Pro创建以使其可重新组装。
可以自动调整/启发式修改良性程序(一个没有混淆的程序)。
非常繁琐,而VS编译的PE二进制文件非常繁琐。

所以我的问题是:


为什么没有反汇编程序可以针对良性生成可重新组装的asm代码程序(没有混淆的程序)?
如果我想实现这样的工具(没有IDA Pro的帮助,从一开始就画草图),有可能吗?
是否还有其他与此相关的问题,我可能错过了吗?


评论

亲密的投票是因为他们认为这是“基于观点”的。我认为情况并非如此。

您检查过VCOM Sourcer吗?它应该为DOS和Windows产生可重新组装的反汇编。也许您可以在某个地方找到它。 archive.is/UJrsa

#1 楼

因为这确实很难做到。

要详细说明:

您还需要提取非代码的内容。考虑导入表,导出表,字符串和其他数据。

编写代码时,这只是程序的一部分。另一部分是“编译器优化和数据”部分。这样几乎不可能创建可重新编译的程序集。如果要在汇编级别上编辑程序,建议使用windbg和LordPE。

#2 楼

这是来自IDA Pro的书,但即使是IDA,尽管它仍然是最好的,但最终仍在做出猜测。答案来自克里斯·伊格尔(Chris Eagle)的“ IDA Pro书”。


“为什么没有任何反汇编程序可以针对良性程序生成可重新组装的asm代码(一个没有混淆的代码) )?“


编译过程是有损失的。

在机器语言级别上,没有变量或函数名称,
和变量类型信息只能由数据的使用方式决定,而不由显式类型声明决定。当观察到正在传输的32
数据位时,您需要做一些调查性的工作,以确定这32位是代表整数,32位浮点值还是整数。一个32位指针。

编译是多对多操作。

这意味着源程序可以通过许多不同的方式转换为汇编语言,而机器语言可以通过许多不同的方式转换回源语言。因此,
编译文件并立即对其进行反编译很常见。
产生的源文件与输入的源文件截然不同。
反编译器非常依赖于语言和库。用反编译器处理Delphi编译器生成的二进制文件,该反编译器用于生成C代码,会产生非常奇怪的结果。同样,通过不了解Windows编程API的反编译器提供
已编译的Windows二进制文件可能不会产生任何有用的结果。
它仍然需要人类的判断。我听到的最好的类比是从源代码编译二进制文件就像在计算哈希。


“如果我想实现这样的工具(没有IDA Pro的帮助,从一开始就画草图),有可能吗?”

在我看来,这听起来像是一个有趣的理论研究问题:能否将编译真正视为生成哈希签名?我的肠子说“是”。数学将非常复杂,并且可能必须使用可证明的语言来完成。我们通常使用散列,因为它们不容易进行逆向工程。但是,您仍然可以使用彩虹表之类的方法来攻击哈希,因此需要考虑一个大型项目。我的直觉告诉我,所有可能的二进制文件上的彩虹表都是NP-Complete。

还要考虑确定数据类型还需要人工判断,而我们在自动化这类智能方面仍然不是很擅长。可能吗?也许。聪明的人仍然会使用IDA之类的工具是有原因的。


“还有其他与我可能遗漏的问题有关吗?”

我是反汇编的新手,所以我将其留给大个子,但希望至少我回答了一个问题,为什么它很难做到你所要求的。

鹰,克里斯(2011-06-16)。 IDA Pro书:全球最受欢迎的反汇编程序的非官方指南(Kindle位置151-152)。没有淀粉新闻。 Kindle版。

#3 楼

您的问题非常有趣,但并不是真正的新问题。

许多人已经将我们所谓的二进制重写用于分析目的。例如,DynInst和MAQAO这样做是为了分析应用程序,以便在基本块中找到瓶颈。现在您可能会问自己的问题是如何完成的?简单。大多数可用的反汇编程序(如objdump,objconv,IDA等)都在独立模式下工作,通常会在反汇编中打印一条指令,但是udis86和distorm等其他反汇编程序除了在独立模式下可用之外,还提供了访问反汇编代码的API。 >但是,DynInst,MAQAO和大多数二进制重写工具所做的工作是反汇编二进制文件,并在重组二进制文件之前在数据结构中的适当位置插入探针。因此,与地址,分支,上下文保存等相关的所有必要更改都将在重组之前得到正确处理。

您必须知道,编写此类工具非常困难。第一个挑战是编写可靠的反汇编程序。当然,这意味着选择一种反汇编算法(线性扫描与递归遍历),将指令与数据分离(它们可以混合使用-例如shellcode),等等。接下来是第二个挑战,修补反汇编的代码。这是非常棘手的问题,我将指出该文档将对您有很大帮助:http://www.maqao.org/publications/techreports/madras_techreport.pdf。
它是由MAQAO(MADRAS-多体系结构反汇编程序重写程序和汇编程序)中使用的反汇编程序的作者编写的。关于本文档的有趣部分是参考文献(超过50个,非常有用)和描述所使用算法的附录。

尽管我对MAQAO和DynInst都不十分了解,但我还是建议您检查有关它们的出版物(文档,科学论文等)。我还建议您检查PEBIL(PMaC高效二进制仪器工具包),英特尔的PIN,Valgrind,PLTO,Elfsh / ERESI和Etch。

这些工具大多数都广泛执行二进制重写和修补程序,我相信这是可以进行二进制重写的很好的例子。

希望我的回答能帮助您找到想要的东西。

评论


您好yaspr,非常感谢您的出色回答!恕我直言,您所说的这些工具基本上是二进制重写工具,需要“反汇编并修补到原始二进制文件”过程。但是,我要问的是,该工具可以支持“在已反汇编的asm代码上反汇编+重新组装”。

– lllllllllllll
2014年5月18日下午5:30

恕我直言,当您仅修补原始二进制文件时,事情就会变得容易得多,在这种情况下,您无需(启发式)处理在反汇编的asm代码中生成的繁琐的具体内存地址。

– lllllllllllll
2014年5月18日下午5:33

那么,MADRAS是您所需要的。它的目的不仅在于修补,以在有或没有补丁的情况下反汇编和重新汇编反汇编的代码!

– Yaspr
2014年5月18日在17:55

您好,yaspr,我已经阅读了随附的MADRAS的技术报告,并注意到以下这些内容:1. MADRAS仅可在x86-64上运行2.需要(可选)调试信息!

– lllllllllllll
2014年5月18日在18:15

嗨@yaspr,您读过这篇文章吗?您可能想看看他们发布的代码。 github.com/s3team/uroboros

– lllllllllllll
2015年10月23日在16:51

#4 楼

某些系统使用简单的可执行格式,该格式通过将指令和处理后的汇编文件中包含的已定义数据按指定顺序组合在一起进行链接。链接器将应用地址修复程序,但否则输出可执行文件的内容将与程序员指定的内容完全相同,仅此而已;不外乎。原来的MS-DOS .COM文件格式是这样的,因此反汇编程序可以获取一个COM文件并生成一个文件,该文件在组装和链接时会产生位相同的文件(反汇编可能必须使用数据伪指令,用于任何它不了解的指令,或者可能编译为除文件中显示的位模式以外的任何指令的指令,但是如果没有其他任何条件,则可以使用define-byte指令创建任何可执行文件字节。 />
但是,其他系统则使用更复杂的链接器,并且必须生成存储在文件中的其他信息,使用不同版本的工具构建相同的源文件可能会产生不同的二进制文件。通常,在执行反汇编-补丁-重新汇编序列时,应努力减少地址更改的代码量:如果代码将某个函数的地址存储在某个地方,但反汇编程序没有意识到这是一个函数添加ress(而不是常量),代码起作用的唯一方法是如果函数停留在相同的地址。不幸的是,没有一种与MS-DOS或Windows构建工具兼容的目标文件来指定应该放置的位置。当代码最初被编译或汇编时,链接器可以自由地将函数放置在任何地方,并将适当地更新“常量”函数地址。在处理反汇编代码时,无法确保该函数停留在旧地址,也无法确保所有依赖它的地址都可以在移动时得到更新。

#5 楼

到目前为止,已建立的二进制重写方法是动态重写,其中在真实输入上运行二进制文件时对其进行重写。想想诸如PIN,DynamoRIO和Dyninst之类的工具工具,以及诸如qemu之类的二进制转换器。

与动态重写相比,静态重写工具具有根本的挑战,后者是精确的控制流图恢复。也就是说,对于二进制文件中的每个基本块,我们需要知道其跳转指令的可能目标集。困难在于二进制文件有许多间接跳转指令。例如,如果我们面对一个以bx r3结尾的基本块,那么我们需要一个精确而可靠的值集分析(VSA),它可以告诉我们r3在运行时可以取的可能值。不幸的是,这种分析通常是不确定的。但是,行为良好的编译器会生成以某种方式结构化的二进制文件,这一事实在很大程度上是有用的。

请注意,解决CFG恢复问题将使我们能够作为副产品解决代码/数据分离问题。也就是说,递归下降反汇编可以使我们在这种情况下将代码与代码字节流中的数据完全分开。 >

王帅,王培,吴鼎好:
可拆卸组装。 USENIX Security 2015:627-642


其工具Uroboros不是开源的。它基于使用objdump的迭代线性扫描反汇编。拆卸技术本身已在较早的文章中进行了讨论。尽管如此,它为实际有效的静态二进制重写提供了有趣的技术(或者至少是他们的主张)。他们甚至多次重写同一二进制文件而不破坏它。最后,请注意,静态二进制重写很大程度上不适用于运行时代码生成的二进制文件。

更新:

看来Uroboros的许多缺点已在Ramblr中得到了解决,请在此处进行讨论:


Wang等。等网络和分布式系统安全研讨会(NDSS'17),“ Ramblr:使重组变得更加出色”。 2017


特别地,他们提到重新组装的二进制文件没有执行开销或大小扩展。