不同 C 编译器生成的可执行文件的差异

Posted

技术标签:

【中文标题】不同 C 编译器生成的可执行文件的差异【英文标题】:Differences in executables produced by different C compilers 【发布时间】:2020-05-06 16:47:28 【问题描述】:

如果尝试利用二进制文件,如果可执行文件是由特定的编译器和链接器生成的,会有什么不同吗?

我会详细说明这个问题。我试图了解 Windows 漏洞利用的工作原理。我有一个用 C 编写的源代码文件。我可以使用 Microsoft 的“cl”编译器或 GNU gcc 编译器。这两者会产生相同的可执行文件,因此两者都可以以相同的方式被利用,或者可执行文件会不同,因此利用会不同?如果它们不同,我应该考虑哪些差异?

【问题讨论】:

这只是假设,对吧?对?好吧,如果您说的是应用程序级漏洞利用,那么是的,这通常需要特定于用于构建应用程序的编译器,但是,应用程序供应商通常只为每个平台发布一个版本。 可执行文件在编译器之间、同一编译器的版本之间、有时甚至在连续构建之间是不同的。 一些漏洞可能与编译器无关,例如,如果您在源代码中看到system(argv[2]);,但这种情况很少见。 只需将/Ox 添加到您的cl 构建或-O3 到您的gcc 构建将导致不同的可执行文件。影响最终可执行文件的所有编译器都有许多选项。 好的,谢谢大家,你们的回答很有帮助 【参考方案1】:

如果尝试利用二进制文件,如果可执行文件是由特定的编译器和链接器生成的,会有什么不同吗?

一般来说,是的。二进制程序的利用通常取决于程序中确切的内存布局和机器指令序列。当使用不同的编译器构建程序时,情况会有所不同 - 甚至,正如 David C. Rankin 指出的那样,使用不同选项的相同编译器。

这两者是否会产生相同的可执行文件,因此可以以相同的方式利用它们,或者可执行文件会不同,随后利用会不同?

它们通常会有所不同。如果幸运的话,某些类型的漏洞利用可能对两者都起作用,但这取决于漏洞利用的具体内容。例如,可能会发生以下情况:

相同的漏洞可在新版本中使用,无需更改

基本攻击相同,但由于内存布局不同,地址必须更改

漏洞利用仍然可能,但需要完全不同的技术

由于巧合或此编译器实施的有意对策(堆栈保护、地址随机化等),利用不再可能。

如果它们不同,我应该考虑哪些差异?

太宽泛,无法回答。一般来说,您可能必须从头开始分析由第二个编译器构建的程序的行为,以确定它是否仍然可以利用,如果可以,如何实现。

【讨论】:

好的,谢谢 Nate,我明白了一些新的东西。谢谢回复!!

以上是关于不同 C 编译器生成的可执行文件的差异的主要内容,如果未能解决你的问题,请参考以下文章

程序编译链接后形成的可执行文件是啥文件

一个编译生成的可执行程序是用啥命令执行

写了一个程序可以编译c语言,怎么自动再链接然后执行生成的可执行文件?

linux下的gcc编译器

C连载3-不同环境下的C

C连载3-不同环境下的C