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,下一个字节告诉指令“真正是什么”。同样,您会得到一个包含 256 个prefix0xff条目的表。

某些条目可能无效,因为到目前为止并非所有组合都被采用 [尽管几乎全部]。

一个棘手的问题是“修饰符前缀”条目。例如,0x66 会将指令从 32 位操作数大小切换到 16 位操作数大小(如果处理器处于 16 位模式,反之亦然)。

每个类别中的许多实际解码将涉及旋转位并将“位 5-3”转换为寄存器编号或将“位 1-2”转换为地址模式(例如eax,是[eax]还是[eax+esi])。

这是相当多的工作。我为 80186 编写了一个反汇编程序,我花了大约两天的时间几乎整天工作。然而,我已经知道我在做什么。将其转换为 386 又需要 2-3 天,而且我不想考虑为具有所有 SSE、MMX、3DNow 的现代 x86 处理器执行此操作!等说明。

[而且我花了太长时间解释如何做到这一点以获得“正确答案”——即使这是你如何做到这一点的正确答案——当然,使用现有的库显然是更简单的方法它]。

于 2013-01-20T22:16:53.130 回答
2

这是一项非常艰巨的任务。x86 指令集非常复杂。你最好的选择是使用现有的 x86 反汇编库之一来做你想做的事。

这些链接应该可以帮助您入门。

于 2013-01-20T22:05:22.907 回答
1

您可以使用按位运算,例如,如果您的指令是 XOR 并且您的操作码 = 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 回答