从二进制文件中获取源代码

时间:2015-03-23 19:16:50

标签: compilation binary

不应该从二进制文件中获取源代码吗? 由于编译是将高级语言(源代码)转换为低级语言(机器代码)的过程,我们不能只是为了获取源代码而反转过程吗?如果没有,为什么?

1 个答案:

答案 0 :(得分:2)

假设我给你编号3,并告诉你我是通过将两个数字相加得到的。你能告诉我3是一个总和的两个数字吗?这是不可能的,因为总和是单向函数 - 从输出中恢复其参数是不可能的。我可以从-5558获得它,即使为你 12仍然可以得到同样的答案。

编译类似。有无数个C ++程序可以生成任何特定的机器代码输出(或多或少)。

您当然可以反转编译过程并生成C或C ++代码,这些代码至少会在具有相同语义(含义)的机器代码中产生,但可能不是逐字节相同的。这些工具存在不同程度。

所以是的,这是可能的,但是因为源代码中的很多信息必然会丢失,所以您将获得的代码将会没有深入了解原始源代码的设计。对于任何规模很大的项目,你得到的东西都是做同样事情的代码,但对人类来说几乎是不可读的。它是一些非常非常混淆的C / C ++。

为什么信息会丢失?因为高级语言的重要性在于它们应该对人类有效处理。源代码越高级和人类可理解,它与编译器完成时产生的机器代码的差别越大。作为软件设计人员,您的主要目标是利用编译器和其他代码生成工具将高级创意和概念转换为机器代码。两者之间的差距越大,关于高级设计的信息就越多。

请记住,编译器必须保留的唯一内容是代码的语义(含义)。只要它出现代码正在做你想要做的事情,一切都很好。例如,现代编译器可以预先执行代码的一部分,只存储操作的结果,当它产生" sense"根据一些指标这样做。假设您的整个程序如下所示:

#include <iostream>
#include <cmath>
int main() {
  std::cout << sin(1)+cos(2) << std::endl;
  return 0;
}

假设有一个Unix系统,编译器完全可以生成执行两个系统调用的机器代码:写入stdout,使用常量缓冲区和退出。在反编译此类代码后,您可以获得:

#include <unistd.h>
#include <cstdlib>
int main() {
  write(0, "0.425324\n", 9);
  exit(0);
}
相关问题