逆アセンブラがバイナリをアセンブリ命令として識別するために使用するさまざまなアルゴリズムについて読んでいました。さまざまな逆アセンブラでプログラムを開き、プログラムの特定の部分をコードとして表示するものと、データと同じ部分を表示するものがありました。だから私の質問は、逆アセンブラが命令またはデータのいずれかであるオペコードの間で混乱した場合、プロセッサはどのようにしてそのオペコードをどう処理するかを正確に知るのですか?
私の質問が明確であることを願っています..よろしくお願いします..
逆アセンブラがバイナリをアセンブリ命令として識別するために使用するさまざまなアルゴリズムについて読んでいました。さまざまな逆アセンブラでプログラムを開き、プログラムの特定の部分をコードとして表示するものと、データと同じ部分を表示するものがありました。だから私の質問は、逆アセンブラが命令またはデータのいずれかであるオペコードの間で混乱した場合、プロセッサはどのようにしてそのオペコードをどう処理するかを正確に知るのですか?
私の質問が明確であることを願っています..よろしくお願いします..
逆アセンブラがバイナリをアセンブリ命令として識別するために使用するさまざまなアルゴリズムについて読んでいました。
それによって、線形スイープと再帰的トラバーサルを意味していると思います-ここに興味深いページがあります。
だから私の質問は、逆アセンブラが命令またはデータのいずれかであるオペコードの間で混乱した場合、プロセッサはどのようにしてそのオペコードをどう処理するかを正確に知るのですか?
だから、問題の本質-彼らは気にしませんし、気にしません。CPUは、データと命令について何も知りません。これが、オペコードを含む文字列に置き換えることで、バッファオーバーフローからスタックへの入力を実行できる理由です。これは、ページを実行しないとマークすることで無効になります。この場合、命令ポインタ(EIP / RIP)がそこに到達すると、プロセッサは障害を発生させます(基本的にOSでうめき声を上げます)。
逆アセンブルの課題は、実際に実行しているすべてのバーを実行するコードの構造を理解しようとしていることです。これを解決する唯一の方法は、x86エミュレーターを作成して使用することです。
これは停止性問題と呼ばれます。
プロセッサは、実行を要求されたものがコードなのかデータなのかを知りません。同時にどちらかまたは両方にすることができます。CPUは、与えられたものは何でも実行しようとします。
実行に失敗すると、「無効な命令が検出されました」、「命令によって参照されているメモリにアクセスできません」、「ゼロ除算」、「不十分な特権」などのイベントが生成され、OSが(うまくいけば)処理します。 。方法がわかっている場合は問題を修正するか(仮想メモリは通常このメカニズムに基づいています)、アプリケーションにこのイベントを処理させるか、アプリケーションを終了します。
さまざまな逆アセンブラがあります。一部の逆アセンブラは、実行可能ファイル形式をあまり理解しようとせず、与えられたものをすべて逆アセンブルしようとするという点で「ダム」逆アセンブラです。他の人は、コードとしてマークされたファイルの部分を分解し、エントリポイントの場所から分解を開始し(すべての実行可能ファイルには、OS / CPUによって実行を開始する場所があります)、さまざまなヒューリスティックを使用して適切な分解を行います。
ただし、分解を完全に行うことはほとんどできません。正しい逆アセンブルの主な問題は、逆アセンブラがコードの一部が何を実行し、何を実行しないかを知らないことです。
たとえば、ジャンプまたは呼び出すアドレスを計算するようにコードを記述できます。逆アセンブラは、コードを実行、エミュレート、または解釈しないため、このようなアドレスを計算できません。そのため、逆アセンブラは、逆アセンブルする次の場所を特定できない場合があります。
可変長命令を持つCPUもあります。これにより、コードが命令の途中にジャンプする可能性があります。逆アセンブラはそのようなコードをどのように逆アセンブルする必要がありますか?
もう1つの悪化する慣行は、コードによる操作です。コードは、実行時にその場で変更できます。コードは、より多くのコードを生成することもできます。コードはデータとして保存することもできます。どのようにそれらすべてを分解しますか?
したがって、多くの逆アセンブラがかなり馬鹿げていることは驚くべきことではありません。彼らは、あらゆる種類のひねりを加えたプログラムを作成するプログラマーの頭脳と競争することはできません。
編集:
また、同じ可変長命令の問題があるため、わずかに異なる場所から始まる同じコードを逆アセンブルすると、異なる命令が生成される可能性があります。
例:
32ビットモードのx86プロセッサの次のバイトシーケンスを検討してください:66h、0B8h、90h、90h、90h、90h。
最初のバイトで分解を開始すると、次のようになります。
mov ax,9090h
nop
nop
次のバイトで分解を開始すると、次のようになります。
mov eax,90909090h
さらに別のバイトをスキップすると、次のようになります。
nop
nop
nop
nop