我不确定如何说出这个问题但是,我很想知道汇编程序和其他工具如何显示某些字节的操作码?
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
答案 0 :(得分:5)
通常,反汇编程序将具有表和“解码类型”(通常是函数指针或进入switch语句的东西)的组合 - 解码类型告诉指令是哪个类 - 例如,{ {1}}将具有相同的解码,但xor, or, and, add, sub
将是不同的解码。 call, jmp
还有另一种解码类型。
所以第一级表将是256条表。然后,您有一些“前缀”的条目,例如jnz, jz, jnc, jc, ja, jb, jbe, etc
,其中下一个字节表示指令“确实是”。再次,您将获得一个256 0xff
条目表的表。
有些条目可能无效,因为到目前为止并未采用所有组合[尽管几乎全部]。
一个棘手的问题是“修饰符前缀”条目。例如,0x66将指令从32位切换到16位操作数(如果处理器处于16位模式,则反之亦然)。
每个类别中的许多实际解码都涉及两个位,并将“位5-3”转换为寄存器号或“位1-2”转换为地址模式(是prefix0xff
,{{1}或者eax
,例如)。
这是相当多的工作。我为80186写了一个反汇编程序,这花了我两天几天的工作。但是,我已经知道我在做什么。将它转换为386需要另外2-3天,我不想考虑使用所有SSE,MMX,3DNow的现代x86处理器!等指令。
[我花了很长时间解释如何做到这一点来获得“正确答案” - 即使这是你如何做到这一点的正确答案 - 当然,使用现有的库显然更简单这样做的方式]。
答案 1 :(得分:2)
这是一项非常艰巨的任务。 x86指令集非常复杂。您最好的选择是使用现有的x86反汇编库中的一个来执行您想要的操作。
这些链接可以帮助您入门。
答案 2 :(得分: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
对位的其他部分执行相同操作以获取每个函数的参数。