4

私は32ビットのオペコードを持っています: FF 35 0E 20 40 00. これに対する答えを与える良い OpCode テーブルを知っている人はいますか? (逆アセンブラを使用できることは知っていますが、オペコードテーブルでこれを判断する方法を知りたいです)。このウェブページを見つけましたが、 には 7 つの異なるソリューションがありFFます。私はそれを取得していません。

4

2 に答える 2

18

あなたは間違った場所を見ています。これは、IntelまたはAMDの公式ドキュメントで確認する必要があります。

Appendix A Opcode MapのはそれがだVol 2BIntel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 3A and 3B言います。FFINC/DEC Grp51A

Table A-6 Opcode Extensions for One- and Two-byte Opcodes by Group NumberofVol 2Bは、バイトのビット5から3に応じて、、、、、、、、のいずれか、FF次のバイトを言います。(0x35 >> 3)&7=6またはバイナリで110。だから、これはです。Group 5INCDECCALLNCALLFJMPNJMPFPUSHModR/MPUSH Ev

Chapter 2 Instruction Formatofは、それらのバイトとそうでないVol 2Aものを含め、命令がどの部分で構成されているかを説明します。ModR/M

Appendix A Using Opcode TablesVol 2B教えてくれますE

ModR / Mバイトはオペコードの後に​​続き、オペランドを指定します。オペランドは、汎用レジスタまたはメモリアドレスのいずれかです。メモリアドレスの場合、アドレスはセグメントレジスタと次の値のいずれかから計算されます:ベースレジスタ、インデックスレジスタ、スケーリング係数、変位。

それはまたあなたに教えてくれますv

オペランドサイズ属性に応じて、ワード、ダブルワード、またはクアッドワード(64ビットモード)。

つまり、これEvはレジスタまたはメモリオペランドを意味し、これは32ビットコード用であり、命令プレフィックスがないため、オペランドサイズは32ビットです。したがって、Evメモリ内の32ビットレジスタまたは32ビット変数。

次に、ModR/Mから最後までの残りのバイトを把握する必要があります。

Figure 2-1. Intel 64 and IA-32 Architectures Instruction Formatを見てくださいVol 2AModR/M= 0x35の場合:

Mod= 00(バイナリ)
Reg= 110(バイナリ;前にこれらの3ビットを抽出しました)
R/M= 101(バイナリ)

Table 2-2. 32-Bit Addressing Forms with the ModR/M ByteofVol 2Aは、Mod=00およびR/M=101はdisp32、IOWを意味し、命令には32ビットの変位で構成されるメモリオペランドがあることを示しています。

バイトのRegフィールドはModR/M、7つの命令の1つを選択するためにすでに使用されているため、このフィールドはレジスタオペランドをエンコードしません。

だから、あなたの指示はPUSH DWORD [0x0040200E]です。

そして、それは私の逆アセンブラの出力と一致します。

于 2013-03-04T21:01:43.240 に答える
17

このバイト シーケンスを 1 バイトずつ調べてみましょう。

  1. 最初のバイトはFF. Intel Instruction Set Reference のオペコード マップを調べると、これが暗号化された "Grp 5 - 1A" と共に命令INCまたは命令であることがわかります。DEC1A は、「オペコード拡張として使用される ModR/M バイトのビット 5、4、および 3」を意味します。ModR/M バイトは、この命令に使用されるオペランドのソースとアドレスをエンコードするバイトです。この場合、オペコードを拡張するために 3 ビットが使用されます。
  2. 次のバイトは35. これは ModR/M バイトで、通常、それを使用する命令でオペコード自体の直後に表示されます。35(16 進数) は001101012 進数なので、ビット 5、4、および 3 は110. オペコード拡張テーブル (表 A-6) でこれを調べると、これがPUSH d64 Ev命令であることを意味することがわかります。脚注は、「64 ビット モードのd64場合、命令はデフォルトで 64 ビット オペランド サイズになり、32 ビット オペランド サイズをエンコードできない」ことを意味します。これはPUSH命令に期待されています。Evは、オペランドのエンコーディングを指定するシンボルです。最も重要なのは、ModR/M バイトがオペコード自体に続くことを示しています。のv一方、オペランドのサイズがオペランドサイズ属性に依存していることを示します。ModR/M バイトが既にあるので、それをデコードしましょう (表 2-2、このコードが 32 ビット モードで実行されていると仮定)。実効アドレスは adisp32で指定されます。これは、32 ビット ディスプレースメントが続く必要があることを意味します。 ModR/M バイト。レジスタを指定する部分はそれESIを使用する必要があると述べていますが、この場合、このフィールドはオペコード拡張に使用されるため、レジスタ ソース オペランドを示すためには使用されません。
  3. 次の 4 バイトは 32 ビットの変位です。0E 20 40 00は、リトル エンディアンとしてデコードされた場合、 を意味し0x40200eます。これは、この命令で使用されるオペランドのアドレスです。

つまり、アドレスから読み取った 32 ビット値をスタックにプッシュしFF 35 0E 20 40 00ます。PUSH DWORD [0x40200e]0x40200e

于 2013-03-04T20:53:10.867 に答える