将字节转换为操作码

C++ Translate bytes to opcodes?

本文关键字:操作码 转换 字节      更新时间:2023-10-16

我不确定如何表达这个问题,但是,我很好奇地想知道汇编器和其他工具如何显示某些字节的操作码?

std::string BytesToOpcode( __in ::BYTE Bytes );
int main( void )
{
    std::cout << BytesToOpcode( ( ::PBYTE )"x33xC0" );
    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

一般来说,反汇编程序将有一个表和一个"解码类型"的组合(通常是一个函数指针或进入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处理器做这件事!等指令。

[我已经花了很长时间来解释如何做到这一点以得到一个"正确答案"-即使这是你如何做到这一点的正确答案-当然,使用一个已经存在的库显然是更简单的方法]。

这是一项非常艰巨的任务。x86指令集非常复杂。您最好的选择是使用现有的x86反汇编库之一来完成您想要的操作。

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

  • libdisasm
  • nasm
  • diStorm
  • X86反汇编程序库

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

对比特的其他部分做同样的操作,以获得每个函数的参数