Linux実行可能ファイルで使用されるコード変換のタイプ


13

Linuxの実行可能ファイルを作成するために使用されるエンコードの種類、たとえば16進数、バイナリなどを尋ねたいと思います。どのように変換されますか?この実行可能ファイルから元のコードを取得する方法はありますか?

ここに私が持っている少しのコードがあります:

ELF���������>�����%|�����@�������������������@�8��@���������������������@�������@�����7<�����7<������� ������������������f�����f���������������������� ������[�UPX!L
h�h�8����������?�E�h=��ڊ̓�N�    4���9ISloB�q�w�]ȉ.��,ς��Q䝦����#e��-�N����/�b,���d<��'��-E��6E�s�/�U���ly�V�Y2]"a��S�.�hU�|�S�J�I�2���X}
�G0�;���5d�$���.)

どういう意味ですか?


多くの情報を取り戻すことはできませんが、stringsフィルタープログラムは、特定のバイナリプログラムが何であるかを識別するのに非常に役立ち、特定の長さよりも長いすべての埋め込みテキスト文字列を印刷するため、バイナリファイルとプログラム内のメッセージを見ると、それが何であり何をするかについて多くのことがわかります。
ジョー

回答:


29

バイナリです。ソースコードがコンパイルされました。エディターで表示できます(16進エディターblessは、より洗練された変更を行う場合があります)が、何をしているのかを本当に知る必要があります。文字列を変更する場合にのみ有効です。

よりハードコアなものについては、バイナリをリバースエンジニアリングしてアセンブリコードにすることができます。これは、多くの場合、人間が解析可能な最低レベルのコンピューター言語と見なされます。

objdump -d helloworld | less

しかし、それはコンパイラのナンセンスも多く含みます。たとえば、最も単純なものhelloworld.cppをG ++でコンパイルしてからコンパイルするobjdumpと、最終的に226行(208を削除)になります。あなたは可能性があり、アセンブリのわずか15行での「Hello World」を書き込み、それとコンパイルobjdump166本のライン(剥奪)にそれをしかしそれはまだの花。

アセンブリが十分であれば、何が起きているのかを理解するのに十分なアクセス権が与えられ、変更することさえできます...しかし、元の質問に答えるには:

コンパイルされたコードを元のソースコードに戻すことはできません。

ごめんなさい。情報(コメント、フォーマット、読み取り可能なアルゴリズムの概念など)を失う一方向の変換であり、他のものに静的にリンクされており、一般的に、最高の最も熟練したプログラマー以外には理解できないように最適化されています。

問題の規模を把握するために、リバースエンジニアリングソフトウェアのアイデア全体に独自のStack Exchangeサイトがあります。


リバースエンジニアリングし、ソースを失ったコードの最大量を取得する方法を教えてください
-redchief

7
最近の編集をご覧ください。元のソースに戻ることはありません。多くの学習と多くの時間で、逆アセンブルされたアセンブリコードに基づいてソースを書き換えることができるかもしれませんが、ほとんどの場合、安価で(時間の無駄がない限り)、ゼロから書き換える方が簡単です。
オリ

1
最大量のコードを取り戻す方法は、最新のバックアップを復元することです。偶然にも、元のソースコードに似たものを確実に戻す唯一の方法です。
CVn

1
最後のパラグラフにまったく異議はありません、ただの補足:一部の逆コンパイラーIMEは、正確なコード構造を復元するのに素晴らしい仕事をします(もちろん、コメント、フォーマット、シンボルの名前などは除く)。そもそもプログラムを作成しなかった場合、復元されたソースコードはまだわかりにくいかもしれませんが、失われたソースコード/不明なソースコード(少なくともその一部を含む)を(少なくとも部分的に)復元するのに最適なオプションだと思います特定のコードと幸運かどうかに応じて、実際にはわかりやすい)
コス

1
それは、プロプライエタリなソフトウェアの世界のすべてのEULAが、あなたがすることを許されないと言っていることです-リバースエンジニアリング/分解。実行できるため、このような句が含まれていますが、簡単ではありません!しかし、@MichaelKjörlingが言うように、物事を取り戻すための唯一の良い方法は、あなたが気にするもののための複数レベルのバックアップからです。
ジョー

7

コメントに対する評判ポイントが足りないので、答えです。

いいえ、「元に戻す」ことはできません。upx packerについて言及しましたが、upxのマニュアルを読んだことはありますか?

あなたがソースを失った場合、または他の誰かのコードにアクセスできない場合はここでは重要ではありませんが、それは単に不可能です。

バイナリ実行可能ファイルはコンパイラで作成されました。このサイトに記載されていることを信じないで、正確にそのコンパイラのマニュアルを読んでください。次に、ここで、元のコードが書かれた言語、使用されたコンパイラーを追加できます。そして、このステップ(前処理、コンパイル、リンク、多分パッキング)は全体として逆ではなく、原作者が意図したものを分析し、記述します。



3

オリが既に彼の答えで指摘したように、実行可能ファイルの非常に元のソースコードを取得することはできません。

ソースコードのコンパイル中(一般的に広く受け入れられているため、ソースコードを実行可能ファイルに "変換"するプロセス全体としてのコンパイル)、多くの情報が失われます。

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");

一番下の行は(他の回答で既に指摘したように)です実行可能ファイル *の非常に元のソースを取得することはできません

*ただし、実行可能ファイルと運によっては、逆コンパイラを使用して何かを取得できる場合があります。


2

コンパイル済みプログラムについて話している場合、実行可能ファイルは通常バイナリです。を使用して詳細情報を検索できますfile path/to/executable。例hexdump -C path/to/executable | less(使用するものは何でも)を使用して、バイナリ実行可能ファイルを16進数で表示できます。「元の形式に戻す」場合は、適切な逆コンパイラを使用する必要があります。たとえばこの投稿を参照してください。ただし、元のコードではなく、非常に読みにくいコードになります。コンパイルされたバイナリでない場合は、何らかの実行可能スクリプトになります。これは、任意のテキストエディターで簡単に読み取れるはずです。ここで示したのは、おそらくコンパイルされた実行可能ファイルです。ELFは「実行可能およびリンク形式」を意味し、Linux / Unixシステムで一般的なバイナリ形式です。そこ'strings path/to/executable、これが必要な場合。


upx packerでリバースエンジニアリングを試みましたが、動作しませんでしたし、あなたが提案した投稿でも機能しませんでした。別の方法があるかどうか教えてください。
redchief

大変申し訳ありませんが、@ Oliの優れた投稿に書かれていること以外は何も言えません。
ヒンズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.