【问题标题】:C++ Translate bytes to opcodes?C ++将字节转换为操作码?
【发布时间】:2013-01-20 21:59:19
【问题描述】:

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

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

【问题讨论】:

  • 你是在问反汇编是如何拆开一大堆操作码并从中生成汇编列表的吗?了解每条指令是什么(即操作码表)有助于ton,并且通常是多层表驱动的。

标签: c++ byte opcodes


【解决方案1】:

通常,反汇编程序将包含表和“解码类型”(通常是函数指针或进入 switch 语句的东西)的组合 - 解码类型告诉指令是哪个类 - 例如,@ 987654321@ 将具有相同的解码,但 call, jmp 将是不同的解码。 jnz, jz, jnc, jc, ja, jb, jbe, etc 会有另一种解码类型。

所以第一级表将是 256 个条目表。然后,您有某些“前缀”条目,例如0xff,其中下一个字节告诉指令“真正是什么”。同样,您会得到一个包含 256 个 prefix0xff 条目表的表。

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

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

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

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

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

【讨论】:

  • +1 不过答案很好。我之前已经启动了一个反汇编程序,并很快说“去他妈的”并去了一个现有的图书馆:-)
  • 当然,这假设有一个库可以实际执行您想要的操作... ;)
【解决方案2】:

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

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

【讨论】:

  • 这太棒了!图书馆也不错。但是,很高兴了解他们做到了等等。但是,谢谢。
【解决方案3】:

您可以使用按位运算,例如,如果您的指令是 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

对位的其他部分进行相同的操作,以获得每个函数的参数。

【讨论】:

    猜你喜欢
    • 2022-06-11
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    相关资源
    最近更新 更多