2016-03-18 4 views
1

私たちはバッファに入っており、x86オペコードを見ています。 |現在のポインタをマークします。アドレスから前の命令の開始を取得する

68 0F 00 6A 90 | 00 

電流のサイズが決定可能であるため、次の命令の開始を見つけることは簡単です。しかし、あなたは以前のものの始まりをいくらか正確に推測するでしょうか?

68 0F 00 6A 90 - 合計5バイトは、

0F 00 6A 90 - 合計4バイトは、

00 6A 90 - 合計3バイトは、

6A 90 - 合計2バイトが|

90 - 1バイトの合計で終了します。

明らかに、これは実際的な例ではありませんが、問題を示しています。これは問題よりも好奇心ですが、現代の逆アセンブラーはどのようにして正確に推測できますか?コール/ジャンプ参照のあるポイントを保存していますか?現在の命令で終わる最も近いラベルに最も近いアドレスを見つけますか?

答えて

3

このように可変長命令が設定されていると、正確に直線的に分解できません。あなたはエントリーポイントから始めることができますし、すべてのコードパスに従ってください。もちろん、逆アセンブラーを上回るのはかなり簡単です(条件を強制し、条件分岐を使用すると、1つのパス次の命令デコードをトリップする未使用パスにデータを残す)。しかし、エントリーポイントから線形に行い、データを調べない(例えば、コンパイラーが無条件ブランチの後にポーリングデータを置いたり、逆アセンブラーが命令データと見なすなど)場合は、悪化します。

コードパスに従うか、実行するブランチの前のどこかにコードパスをたどらない限り、本当に正確に後ろに移動することはできません。

+0

ありがとうございました。私はこのようなことを考えていました。あなたはollyのようなプログラムがメモリ上のランダムな場所にどのように行くことができ、それはかなりうまくいくのか知っていますか?それとも、それは最終的にうまくいくのですか? – Lupe

+0

いいえ、私は疑っていますが、いくつかのファイルフォーマットが情報を残していることを確認していないのですが、gnu objdumpはどのようにうまくいくのでしょうか?コンパイラで生成されたコードは、きれいで簡単に分解できるようになり、ツールが本当にうまくいくかを調べるためにツールを上ろうとする必要があります。ジャンプテーブルや関数ポインタは、生のバイナリが使用されていて、デバッグ情報の多い形式ではない場合には、それらをトリップする可能性があります。デバッグのためにコンパイルすることは、この種のものを手助けするための情報を追加する必要があります、それでいくつかの実験をすることができます... –

+0

それは本当に他の方法はありません、プロセッサは明らかに道を見つけることができますすべての命令を完全に実行します。ディスアセンブラはこれを試すことができますが、ユーザ入力に依存するパスがあるため、動作しない可能性があります。したがって、ファイル形式の助けを借りずに、コードパスごとにコードを実行することができない場合、どうすればそれが可能ですか?あなたができることは、各命令の長さを知るために十分にデコードし、条件の各パスが取られていると仮定してすべての可能な分岐に従うことです。 –

関連する問題