コンパイル後のバイナリファイルの内容を理解できないのはなぜですか?


11

私の知る限り、すべてのプログラムは、プロセッサレジスタで動作する特定のデータ変数(float、int、char ...)を備えたプロセッサ命令のパックで構成されています

それで、私が最初に考えたのは(かなり前のことですが)、ASCII値%¨#$¨#(単なるランダムな例)がx86のスタックポインタレジスタ(単なる例)のアドレスとして解釈されることがわかっている場合です。プロセッサ。これが当てはまる場合、バイナリファイルの内容を読み取るときにこの「読み取り不可能な」値が見つかるたびに、スタックポインタレジスタがデータ変数の管理に使用されていると解釈できます。

残念ながらこれは起こりません。以下に、ping.exeWindowsで開いたプログラムの内容の例を示しますnotepad.exe

MS Notepadで表示されるPing.exe

バイナリファイルであり、そのデータは私たち人間には理解できません(マシンでは理解できます)。アセンブリコード(機械語の最低レベル)を知っていても、誰にとっても意味がありません。

だから、私がすべてを正しく理解していれば、誰かが説明できますか

  1. なぜ、バイナリコードがアセンブリコードに戻ることができないのですか?
  2. アセンブリコードを理解できるとしたら、なぜこのコードから生成されたコンパイル済みバイナリが「読み取り可能」にならないのですか

12
できます。逆アセンブラが必要です。
David Schwartz

だから私は.exeファイルを分解することができますか??? 私はそれがマネージコードで動作することを知っていました...
Diogo

13
実行可能ファイルを逆アセンブルできます。逆アセンブルされた出力を理解できるかどうかは、別の話です。
David Schwartz、

5
コンパイルまたはアセンブリは、変数名、ブランチラベルなど、人間に重要な多くの情報を削除します。命令ストリームを逆アセンブルして取得しますが、まだ理解することがたくさんあります。
mpez0 2012年

1
また、コードの難読化は逆アセンブリを妨げる可能性があります。
数学

回答:


13

まず、レジスタにはアドレスがありません。アセンブリ言語の各命令は、オペコードに変換されます。x86のオペコードは、1、2、3、またはそれ以上のバイト数になる可能性があります(他の一部のプロセッサでは「固定幅」です)。通常、オペコードは、関連する命令、アドレッシングモード、およびレジスタを識別します。「アドレッシングモード」は、CPUでオペコード以上が必要かどうかを決定します。つまり、「即時」アドレッシングモードは、その命令の命令の直後(または「直後」)に追加のデータがあることを意味します。「絶対」アドレッシングモードは、メモリアドレスは命令の後に続き、その命令によって使用されます。

MOV AL,SP似たようなまたは類似のオペコードを見つけて検索できます。x86には、スタックポインタを操作する多くの命令があります。

ただし、メモ帳の使用終了し、代わりに16進エディタを使用してください。他にもたくさんありますが、HxDをお勧めします。

そして、@ David Schwartzは正しいです。逆アセンブラは、ファイルを反復処理し、オペコードを読み取り可能なテキストに変換します。あなたがしたいことは完全に可能です。

ただし、ファイルのどこで命令が始まるかを知っておく必要があります。間違ったアドレスから開始すると、オペコードの「オペランド」となるデータ(オペランドまたは「引数」のアドレスを取る命令など)がオペコードとして誤解されます。これを知るには、実行可能ファイルの形式に関する知識が必要です。これは、Windowsでは「Portable Executable」またはPE形式です(Linuxシステムでは多くの場合ELFです)。PEなどを理解している逆アセンブラはきっといると思いますが、手抜きはわかりません。


1
IDAは、最も一般的なPE逆アセンブラーの1つです。LinuxおよびMacファイルでも動作します。バージョン5.0は引き続きフリーウェアとして利用可能です
Scott Chamberlain

1
>間違ったアドレスから始めると、…誤解される可能性があります。 これがのすべての出現が%¨#$¨#必ずしもスタックポインタへの参照であるとは限らない理由です。これは、2つの異なるコマンドの真ん中である可能性があります_3p%¨#および$¨#b5F_3p   %¨#$¨#   b5F)。
Synetech 2012

12

だから、私がすべてを正しく理解したなら

結構です。

それはバイナリファイルであり、そのデータは私たち人間にとって理解不可能です

通常、バイナリファイルは、特にファイルの目的が不明な場合、人間やマシンには理解できません。すべてのバイナリファイルが実行可能ファイルであるとは限らないことに注意してください。バイナリファイルの多くは、機械命令を含まないデータファイルです。ファイルに名前を付けるときにファイル拡張子が使用されるのはそのためです(一部のOS)。。拡張子comは、実行可能ファイルを示すためにCP / Mによって使用されました。。exe拡張子は、別の実行可能ファイル形式を示すためにMS-DOSによって追加されました。* nixesは、execute属性を使用して、実行できるファイルを示しますが、スクリプトだけでなくコードでもかまいません。

他の人がすでに述べたように、数値を含むバイナリファイルは、テキストビューアではなく、16進ダンププログラムまたは16進エディタで表示する必要があります。

ping.exeプログラムの内容の例があります

そのファイルは実際には再配置可能なプログラムであり、そのファイル内のすべてのデータがマシンコードを表すわけではありません。プログラムに関する情報には、必要なダイナミックライブラリ、リンクする必要のあるルーチン、スタックとプログラムとデータメモリの要件、プログラムのエントリポイントなどがあります。ファイル内のアドレスオペランドは、絶対値に計算する必要がある相対値、または解決する必要がある参照です。

おそらくあなたが考えている「プログラムファイル」は、バイナリイメージファイルまたはプログラムメモリのダンプと呼ばれます。このようなファイルには、マシンコードとデータのみが含まれ、すべてのアドレス参照が実行用に適切に設定されます。

アセンブリコードを知っていても(機械語の最低レベル)

アセンブリ言語は機械語と同じではありません。典型的な(高級言語のコンピューターを除外する)CPUは、一度に1つの命令で機械コードを入力として受け入れます。オペランドは、レジスタまたは数値メモリアドレスです。アセンブリ言語は、命令の場所や変数にシンボリックラベルを使用したり、数値演算コードをニーモニックに置き換えたりできる、より高水準の言語です。アセンブリ言語プログラムは、実際に実行する前に、機械語/コードに変換する必要があります(通常、アセンブラー、リンカー、ローダーと呼ばれるユーティリティによって)。

逆の操作である逆アセンブルは、プログラムファイルに対して実行でき、シンボリック情報がある程度失われます。コードとデータの場所を手動で識別する必要があるため、メモリダンプまたはプログラムイメージファイルの逆アセンブルは、試行錯誤です。

ところで、(数値の)マシンコードを読んでコード化できる人がいます。もちろん、これは12ビットのメモリアドレスモードを備えた32ビットCISCプロセッサよりも、8ビットCPUまたはマイクロコントローラの方がはるかに簡単です。


3

メモ帳では、バイナリファイルの適切な意図されたエンコードを確認できません。今後の参考のためにこれ確認してください。ほとんどのテキスト編集プログラムはバイナリエンコード形式を解析せず、ASCII文字コード形式の解析が期待されています。

したがって、バイナリファイルをテキストエディタで開くと、テキストエディタで解析されたバイナリデータの元の形式をまったく理解できない同等のASCII文字が生成されます。前述のように、16進エディターと一部のエディターにはバイナリー機能があり、コンテンツを純粋なバイナリー形式で表示します。

バイナリファイルの内容が理解できないのは間違いです。それらは難しくなり、最近のコンピューターアーキテクチャでは、バイナリのみから実行用のCPU(またはエミュレートされた/仮想CPU)によって認識される適切な命令などに手動で逆アセンブルすることが非常に困難ですが、それを行うことができます。

エミュレータはどのようにプログラムされていると思いますか?開発者は、実際のハードウェアが何らかの方法で認識して動作するように仮想システムをプログラムできるように、オペコードを知る必要があります。ドキュメンテーションはCPUの多くのアーキテクチャを説明しており、GPUでさえそれを持っています(より秘密ですが)。

注意すべきもう1つの点は、相関関係はありますが、「バイナリデータ」は実際にはゼロと1の束ではなく、電気回路を通じて電流として増幅/切り替えられた高低電圧です。

これは通常、バイナリが1:1であるため、数値システムを使用することは理にかなっています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.