我目前正在开发一个x86反汇编程序,我开始分解一个win32 PE文件。 大多数反汇编代码看起来不错,但是有一些非法的0xff / 7操作码(/ 7表示reg = 111,0xff是操作码inc / dec / call / callf / jmp / jmpf / push / r / m 16/32)。 第一个猜测是,/ 7是popup式指令,但它是用0x8f / 0编码的。 我已经根据英特尔架构软件开发人员指南手册第2卷:指令集参考进行了检查 – 所以我不只是被误导了。
实例拆解:( S00000000683a是一个被另一个指令跳转到的标签)
S0000O0040683a: inc edi ; 0000:0040683a ff c7 test dword ptr [eax+0xff],edi ; 0000:0040683c 85 78 ff 0xff/7 edi ; 0000:0040683f ff ff
顺便说一句:gdb反汇编这同样(除了错误0xff不屈服-1在我的反汇编):
(gdb) disassemble 0x0040683a 0x00406840 Dump of assembler code from 0x40683a to 0x406840: 0x0040683a: inc %edi 0x0040683c: test %edi,0xffffffff(%eax) 0x0040683f: (bad) End of assembler dump.
所以问题是:在Windows的非法操作码exception处理程序中是否有任何默认处理程序,它在这个非法操作码中实现了任何function,如果是:发生了什么?
问候,博多
经过许多额外的时间让我的反汇编程序产生与gdb完全相同的语法输出,我可以区分这两个版本。 这在我的反汇编中显示出一个相当尴尬的错误:我忘了考虑到,0x0f 0x8x跳转指令有两个字节的操作码(加上rel16 / 32操作数)。 所以每个0x0f 0x8x跳转目标都被一个导致实际上不可达的代码关闭。 修复这个bug之后,不再有0xff / 7的操作码被反汇编了。
感谢大家回答我的问题(并评论这个答案),因此至少试图帮助我。
Visual Studio将其分解为以下内容:
00417000 FF C7 inc edi 00417002 85 78 FF test dword ptr [eax-1],edi 00417005 ?? db ffh 00417006 FF 00 inc dword ptr [eax]
显然,在00417002发生了一般性的保护错误,因为eax没有指向任何有意义的东西,但是即使我把它抛出(90 90 90),它也会在00417005(它不会被内核处理)抛出一个非法的操作码异常。 我很确定这是一些数据,而不是可执行的代码。
若要回答您的问题,Windows将关闭与异常代码0xC000001D STATUS_ILLEGAL_INSTRUCTION
的应用程序。 该对话框将匹配用于任何其他应用程序崩溃的对话框,无论是提供调试器还是发送错误报告。
关于提供的代码,它似乎已经被不正确地组装(编码大于8位的位移)或者实际上是数据(已经被其他人建议)。
它看起来像0xFFFFFFFF已插入而不是0xFF的测试指令,可能是错误的?
85 =测试r / m32,78是参数[eax + disp8],edi的字节,其disp8跟随其中应该只是0xFF(-1),但是作为一个32位有符号整数这是0xFFFFFFFF。
所以我假设你有85 78 FF FF FF FF,对于32位的位移应该是85 B8 FF FF FF FF还是对于8位的位移应该是85 78 FF? 如果是这种情况,代码中的下一个字节应该是0xFF …
当然,正如已经提出的那样,这可能只是数据,不要忘记数据可以存储在PE文件中,并且没有任何特定结构的有力保证。 如果您正在进行优化以减小.exe大小,您实际上可以将代码或用户定义的数据插入到某些MZ或PE标头字段中。
编辑:根据下面的评论我还建议使用可执行文件,你已经知道到底什么是预期的反汇编代码应该是。