オリが既に彼の答えで指摘したように、実行可能ファイルの非常に元のソースコードを取得することはできません。
ソースコードのコンパイル中(一般的に広く受け入れられているため、ソースコードを実行可能ファイルに "変換"するプロセス全体としてのコンパイル)、多くの情報が失われます。
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
フィルタープログラムは、特定のバイナリプログラムが何であるかを識別するのに非常に役立ち、特定の長さよりも長いすべての埋め込みテキスト文字列を印刷するため、バイナリファイルとプログラム内のメッセージを見ると、それが何であり何をするかについて多くのことがわかります。