1

この質問の言い方がよくわかりませんが、アセンブラやその他のツールが特定のバイトのオペコードをどのように表示するか知りたいです。

std::string BytesToOpcode( __in ::BYTE Bytes );

int main( void )
{
    std::cout << BytesToOpcode( ( ::PBYTE )"\x33\xC0" );
    std::cin.get( );
    return( EXIT_SUCCESS );
};

// I don't know what type soo I'll just set as std::string for an example.
std::string BytesToOpcode( __in ::BYTE Bytes )
{
    // Convert Bytes to opcode??
    return( "" );
};


Output should be:
XOR EAX,EAX
4

3 に答える 3

5

一般に、逆アセンブラには、テーブルと「デコード タイプ」(通常は関数ポインタまたは switch ステートメントに入る何か)の組み合わせがあります。デコード タイプは、命令がどのクラスであるかを示します。たとえば、xor, or, and, add, sub同じデコードしcall, jmpますが、別のデコードになります。jnz, jz, jnc, jc, ja, jb, jbe, etcさらに別のデコードタイプがあります。

したがって、最初のレベルのテーブルは 256 エントリ テーブルになります。0xff次に、次のバイトが命令が「実際に」何であるかを示す「プレフィックス」などの特定のエントリがあります。ここでも、256prefix0xffエントリ テーブルのテーブルが得られます。

これまでのところ、すべての組み合わせが使用されているわけではないため (ほぼすべてではありますが)、一部のエントリは有効ではない可能性があります。

注意が必要なのは、「修飾子プレフィックス」エントリです。たとえば、0x66 は命令のオペランド サイズを 32 ビットから 16 ビットに切り替えます (プロセッサが 16 ビット モードの場合はその逆)。

各カテゴリ内の実際のデコードの多くには、ビットをいじり、「ビット 5 ~ 3」をレジスタ番号に、または「ビット 1 ~ 2」をアドレス モードに変換することが含まれます (たとえばeax、 、[eax]または)。[eax+esi]

かなり大変な作業です。私は 80186 用の逆アセンブラを書きましたが、ほぼ終日の作業で約 2 日かかりました。しかし、私は自分が何をしているのかをすでに知っていました。それを 386 に変換するには、さらに 2 ~ 3 日かかりました。SSE、MMX、3DNow をすべて備えた最新の x86 プロセッサでそれを行うことは考えたくありません。などの指示。

[そして、「正しい答え」を得るためにこれを行う方法を説明するのに非常に長い時間を費やしました-これはあなたがこれを行う方法の正しい答えですが-もちろん、既存のライブラリを使用することは明らかにより簡単な方法ですそれ]。

于 2013-01-20T22:16:53.130 に答える
2

これは非常に困難な作業です。x86 命令セットは非常に複雑です。最善の策は、既存の x86 逆アセンブリ ライブラリの 1 つを使用して、必要なことを行うことです。

これらのリンクから始めてください。

于 2013-01-20T22:05:22.907 に答える
1

ビット演算を使用できます。たとえば、命令が XOR で opcode=4 ビット長で、コードが 3 の場合、MASK と Shift を実行してその 3 を取得する必要があります。これを行うには、次のようにします。

your example in bin:   0011 0011 1100 0000
make a AND with:       1111 0000 0000 0000
Result:                0011 0000 0000 0000
Shift 12 places:       0000 0000 0000 0011 <-- This is 3, so you got the instruction 3

各機能のパラメーターを取得するために、ビットの他の部分にも同じことを行います。

于 2013-01-20T22:06:37.830 に答える