逆アセンブラとは、機械語をアセンブリ言語に変換するコンピュータプログラムであり、アセンブラの逆の操作を行うものです。逆アセンブルの出力は通常、アセンブラへの入力ではなく、人間が読みやすい形式になっているため、逆アセンブラは主にリバースエンジニアリングツールとして使用されます。一般的な用途としては、高級プログラミング言語コンパイラの出力とその最適化の分析、ソースコードが失われた場合の復元、マルウェア分析、ソフトウェアの変更(バイナリパッチ適用など)、ソフトウェアクラッキングなどが挙げられます。
逆アセンブラは、アセンブリ言語ではなく高水準言語を対象とする逆コンパイラとは異なります。ソフトウェア分析の基本的な手法は逆アセンブルです。バイナリを使用して高水準の人間が読める構造を再現しようとする逆コンパイラとは異なり、逆アセンブラはシンボリックアセンブリを生成することを目的としており、実行に最も近いアセンブリを再構築しようとします。そのため、逆アセンブルされたコードは通常、逆コンパイルされたコードよりも正確ですが、低水準で抽象度も低いため、はるかに簡単に分析できます。[ 1 ]
アセンブリ言語のソースコードでは、一般的に定数とプログラマーコメントの使用が許可されています。これらは通常、アセンブラによってアセンブルされたマシンコードから削除されます。そのため、マシンコードに対して逆アセンブラを実行すると、これらの定数とコメントが欠落した逆アセンブル結果が生成されます。逆アセンブルされた出力は、元の注釈付きソースコードよりも人間が解釈しにくくなります。一部の逆アセンブラは、生成された出力に呼び出されたAPI関数または呼び出された関数のパラメータに関するコメントを追加する組み込みのコードコメント機能を提供します。一部の逆アセンブラは、ELFなどのオブジェクトファイルに存在するシンボルデバッグ情報を使用します。たとえば、IDAでは、対話型セッションでユーザーがコードの値または領域にニーモニックシンボルを作成できます。逆アセンブルプロセスに適用される人間の洞察は、コード作成プロセスにおける人間の創造性とよく似ています。
バイナリ内の実行可能コードとデータを常に区別できるとは限りません。ELFやPEなどの一般的な実行可能フォーマットでは、コードとデータが別々のセクションに分けられていますが、フラットバイナリではそうではないため、特定の場所に実行可能命令が含まれているのか、実行不可能なデータが含まれているのかが不明確になります。この曖昧さが、逆アセンブル処理を複雑にする可能性があります。
さらに、CPUは実行時に計算される動的なジャンプ命令を許容することが多く、そのため、命令として実行される可能性のあるバイナリ内のすべての場所を特定することは不可能です。
CISCアーキテクチャのような可変幅命令を持つコンピュータアーキテクチャでは、同じバイナリに対して複数の有効な逆アセンブルが存在する可能性がある。
逆アセンブラは、実行中に変更されるコードを処理することができません。静的解析では、実行時の変更を考慮できないためです。
暗号化、パッキング、難読化は、特にデジタル著作権管理の一環として、リバースエンジニアリングやクラッキングを防止するために、コンピュータプログラムによく適用されます。これらの技術は、コードを意味のある形で分析する前に、まずアンパックまたは復号化する必要があるため、逆アセンブルにおいて新たな課題をもたらします。
逆アセンブルは、静的または動的に実行できます。静的逆アセンブルはバイナリを実行せずに解析するため、オフラインでの検査が可能です。ただし、静的逆アセンブルでは、一部の操作や難読化を誤って解釈する可能性があります。
動的逆アセンブリは、実行時に実行される命令を、通常はCPUレジスタとCPUフラグを監視することによって観測します。動的解析は、実行された制御パスと実行時に解決されたアドレスを捕捉できます。これは逆コンパイラの大きな利点ですが、実行中にトリガーされないコードパスを見逃す可能性があります。
どちらもそれぞれ強力ですが、現代の逆アセンブラは、より複雑なバイナリの精度を向上させるために、両方のアプローチを組み合わせることがよくあります。[ 2 ]
逆アセンブラは、スタンドアロン型と対話型に分類できます。スタンドアロン型の逆アセンブラは、実行時にアセンブリ言語ファイルを生成し、ユーザーはそれを解析できます。一方、対話型の逆アセンブラは、ユーザーが行った変更を即座に反映します。例えば、逆アセンブラがプログラムのある部分をコードではなくデータとして扱う場合、ユーザーはそれをコードとして指定できます。すると、逆アセンブルされたコードが即座に更新されて表示されるため、ユーザーは同じセッション中にコードを解析し、さらに変更を加えることができます。
対話型デバッガには、デバッグ対象プログラムの逆アセンブリを表示する何らかの方法が含まれています。多くの場合、同じ逆アセンブリツールが、デバッガと一緒に配布されるスタンドアロンの逆アセンブラとしてパッケージ化されています。たとえば、GNU Binutilsの一部であるobjdump は、対話型デバッガgdbに関連しています。[ 3 ]
動的逆アセンブラは、エミュレータやハイパーバイザの出力に統合することで、マシン命令のリアルタイム実行をトレースし、行ごとに表示できます。この構成では、逆アセンブルされたマシンコードに加えて、各命令によって引き起こされるレジスタ、データ、またはその他の状態要素(条件コードなど)の変更も表示できます。これにより、問題解決のための強力なデバッグ情報が得られます。ただし、特にプログラムの実行全体を通してトレースがアクティブになっている場合、出力サイズが非常に大きくなる可能性があります。これらの機能は、1970年代初頭にOLIVER社がCICSデバッグ製品の一部として初めて導入し、現在はCompuware社のXPEDITER製品に組み込まれています。
長さ逆アセンブラ(長さ逆アセンブラエンジン(LDE )とも呼ばれる)は、バイト列(命令)が与えられると、解析された命令が占めるバイト数を出力するツールです。x86 アーキテクチャ向けの注目すべきオープンソースプロジェクトには、ldisasm [ 10 ] 、 Tiny x86 Length Disassembler [ 11 ]、Extended Length Disassembler Engine for x86-64 [ 12 ]などがあります。