組み立てと分解は逆ではないと言われました。どうやら、プログラムを逆アセンブルし、その出力をアセンブラーに直接入れて、正しく実行されることを期待することはできません。情報が失われるからです。
私の質問は、なぜ情報が失われるのですか? また、どのような情報が失われますか?
組み立てと分解は逆ではないと言われました。どうやら、プログラムを逆アセンブルし、その出力をアセンブラーに直接入れて、正しく実行されることを期待することはできません。情報が失われるからです。
私の質問は、なぜ情報が失われるのですか? また、どのような情報が失われますか?
逆アセンブラー (またはそのユーザー) が日常的に保存しない重要なことの 1 つは、命令のエンコードです。一部の命令は、複数の異なる方法でエンコードできます。次に例を示します。
mov rdx, -1
48,BA,FF,FF,FF,FF,FF,FF,FF,FF (10 バイト) または 48,C7,C2,FF,FF,FF,FF (7 バイト) のいずれかです。
プログラムの残りの部分が、上記の命令の長さが正確に 10 (または 7) バイトであること、またはこれらの特定のバイト値に機能的に依存し、アセンブラーがmov rdx, -1
元のプログラムとは異なる方法でアセンブルすることを選択した場合、逆アセンブル後 +アセンブリを作成すると、動作が異なる別のプログラムが得られます。あいまいなエンコーディングを持つ命令の場合、アセンブラは命令ニーモニック ( mov rdx, -1
) ではなく、元のプログラムの逆アセンブルで正確なエンコーディング (48,BA,FF,FF,FF,FF,FF,FF,FF,FF など) を使用する必要があります。
アセンブラまたはリンカが別の方法で実行する可能性があるその他のことがあります (たとえば、出力ファイルでコード/データ、名前および順序 (セクション/セグメント) を別の方法で追加調整するなど) は、通常は問題にはなりませんが、繰り返しになりますが、 、元のプログラムでこれらのものに異常な依存関係がある場合、再アセンブルされたプログラムは異なる動作をします。
それは損失ではなく、実際には利益です。まだ試していないようですが、試してみませんか?
.global reset
reset:
mov #0x0280,r1
call #notmain
jmp hang
.global hang
hang:
jmp hang
objdump を使用すると、次のように組み立てることができます。
0000f800 <reset>:
f800: 31 40 80 02 mov #640, r1 ;#0x0280
f804: b0 12 b2 f8 call #0xf8b2
f808: 00 3c jmp $+2 ;abs 0xf80a
0000f80a <hang>:
f80a: ff 3f jmp $+0 ;abs 0xf80a
コア コードがまだそこにあることがわかります。列またはその他の長方形のカット アンド ペーストを備えたテキスト エディタがある場合は、そのコードを途中から切り取って、直接または少しマッサージして再構築できます。
再アセンブル可能な出力を生成する逆アセンブラを使用できない理由はありません。私は何度も実行し、何度も見てきました。問題は逆アセンブラです。使用例は、その追加情報を確認することです。再アセンブルできる逆アセンブラの使用例は、誰かのコードをハッキングするなどです。
とにかく逆アセンブラを書くことを強くお勧めします。これは、可変長命令セット (x86) がたくさんある場合、命令セットを学習する技術とそれがどのようにエンコードされるかの両方を教育する良い理由になります。もっと学ぶ必要があります(最初にこれらのいずれかを学習しないことをお勧めします。腕や親指などを最初に学習するか、少なくとも x86 ほど苦痛ではない msp430 のようなものを学習してください)。逆アセンブラーをテストする良い方法は、再アセンブル可能なコードを出力することです。アセンブル、逆アセンブル、アセンブルし、2 つのアセンブリ出力が一致する場合、逆アセンブラは適切に機能しました。