正如Oli在其答案中已经指出的那样,您无法获得可执行文件的原始源代码。
在源代码的编译过程中(编译的意图是接受更广泛的接受,因此将源代码“转换”为可执行文件的整个过程)会丢失很多信息。
例如,C预处理器将执行以下操作(除其他外):
- 解释,执行和删除预处理器指令(
#
语句)
- 删除评论
- 删除不必要的空格
另一方面,在源代码的编译过程中没有丢失的东西在技术上可以恢复为功能上等效的源代码。
这是因为:
- 二进制指令与汇编指令的对应关系为1:1。汇编源代码的汇编仅仅是基于对应表的汇编指令到二进制指令的转换。单个二进制指令总是可识别并可恢复为单个汇编指令 ;
- 汇编指令与C指令之间没有 1:1的对应关系;C源代码的编译通常不仅仅是将C指令转换为基于对应表的汇编指令,事实上,情况往往恰恰相反。通常,一条C指令被转换为多个(根据编译器通常是不同的)汇编指令;但是,多个汇编指令的模式通常是可识别的,并且可以恢复为单个C指令;
有一些称为反编译器的工具,其目的是试图将可执行文件还原为功能上等效的源代码。但是结果通常与原始源代码相去甚远(并且通常也无法编译);
考虑以下程序:
#include <stdio.h>
#define MESSAGE "Literal strings will be recovered" // This preprocessor directive won't be recovered
/*
This comment and the comment above won't be recovered
*/
int main(int argc, char* argv[]) {
printf(MESSAGE);
return 0;
}
通过将其编译为可执行文件并再次将其反编译为源代码,这或多或少是您通常会得到的(在这种情况下,我使用gcc
/ Boomerang):
// address: 0x80483fb
int main(int argc, char **argv, char **envp) {
printf("Literal strings will be recovered");
return 0;
}
如预测的那样:
- 缺少预处理器指令
- 缺少注释(除了
// address: 0x80483fb
,反编译器已添加)
- 缺少不必要的空格(除反汇编程序已添加的换行符和制表符之外)
这也是一个很好的结果。将内联汇编指令添加到代码中并不少见:
asm("assembly_instruction");
__asm__("assembly_instruction");
底线是(正如其他答案中已经指出的那样):您无法获得可执行文件 *的原始来源。
*但是,取决于可执行文件和您的运气,您也许可以使用反编译器获得某些东西。
strings
筛选器程序在识别特定的二进制程序是什么或做什么方面非常有用,因为它会打印所有嵌入的文本字符串,而这些字符串的长度超过了指定长度。二进制文件和查看程序中的消息有时会告诉您很多有关其含义和作用的信息。