我知道从二进制到源代码(例如 C++)的逆向工程通常被认为是困难的或不可能的,但是有没有计算机科学家实际上“从数学上”证明将(任何)二进制逆向工程到源代码是不可能或可能的?逆向工程是一个非常困难的谜题,还是存在无法手动或通过反编译器逆向的二进制文件?
注意:我知道答案可能是“它取决于平台和编程语言”,所以我假设所使用的语言是 C++,因为它通常被认为是不可能逆转的。
我知道从二进制到源代码(例如 C++)的逆向工程通常被认为是困难的或不可能的,但是有没有计算机科学家实际上“从数学上”证明将(任何)二进制逆向工程到源代码是不可能或可能的?逆向工程是一个非常困难的谜题,还是存在无法手动或通过反编译器逆向的二进制文件?
注意:我知道答案可能是“它取决于平台和编程语言”,所以我假设所使用的语言是 C++,因为它通常被认为是不可能逆转的。
似乎不同的答案对应于对问题的不同解释。C++ 编译器从源代码创建二进制文件。C++ 反编译器将从二进制文件中创建源代码。
通常,重新创建源代码是不可能的(例如,注释、宏定义和局部变量名称,例如在最终二进制文件中通常不以任何形式存在),所以我们剩下的就是尝试创建一些源代码在功能上是等效的。
一种简单的方法是逐条指令反汇编可执行二进制文件,为每条机器指令创建 C++ 等效代码。这实际上可以完成这项工作,但结果对人类来说完全无法使用。
随着源语言变得越来越复杂,自动将其转换为有用的、可读的、惯用的形式变得越来越困难。请参阅Chen 等人最近发表的题为“A Refined Decompiler to Generate C Code with High Readability”的论文。它描述了反编译的目标和挑战。
正如其他人所说,您始终可以编写模拟机器代码的 C 代码。不过,这并不总是有用的。通常,您想了解的不仅仅是如何运行程序——比如如何以有用的方式修改它。
研究人员仍在试图找出哪些混淆定义是有用的。 这篇著名的论文说你不能一直隐藏所有的秘密。他们将“秘密”定义为您无法通过反复运行程序并分析输出而获得的任何信息。 最近的这篇论文展示了一种方法,可以让人们无法分辨哪个等效的源代码是原始的。他们的技术是“最好的”混淆技术,因为它隐藏了任何可以隐藏的秘密。
其中的第一个成功的迷惑是为点功能,即输出“是”当你在一个秘密的密码输入。您可以通过对密码的 MD5 散列进行编码来混淆该程序(就像 Unix 登录功能那样)。您可以运行该程序,但无法破解密码。这算不算“无法逆转”?
一段时间以来,人们都知道软件静态分析的某些方面在形式上是困难的。例如,请参阅本文及其参考资料。
我不知道有什么研究专门关于使以某种可预测的方式修改程序的行为变得困难。那会很有趣。
如果任何二进制表示任意二进制数据文件,那么答案是肯定的,这是不可能的。为了证明这一点,只需考虑具有单个字节的文件的情况。
如果您将其限制为 C/C++,那么当然可以将其反转。但是,不可能将其逆向为原始源代码,因为机器代码和源代码之间没有1:1的关系。根据优化的不同,源看起来可能与原始源非常不同,即使它在语义上是相同的。