首页 文章

x86汇编:反汇编程序如何知道如何分解指令?

提问于
浏览
4

x86反汇编程序如何知道在哪里分解指令?

我正在查看8088指令集 . 例如,移动指令有7种变化,范围从2到4个字节 . 说明本身似乎没有遵循特定的顺序 . Why is x86 ugly?的另一个原因 .

例如:

76543210  76543210  76543210  76543210
reg/mem to/from reg     100010dw  ||regr/m  
imm to reg/mem          1100011w  ||000r/m  dat       dat w=1
imm to reg              1011wreg  data      dat w=1
imm to accum            1010000w  addr-low  addrhigh
accum to mem            1010001w  addr-low  addrhigh
reg/mem to seg          10001100  ||0ssr/m
seg to reg/mem          10001100  ||0ssr/m

Legend:
||=mod {NO-DISP=0,DISP-LOW,DISP-HIGH,REG}
ss=seg enum{es=0,cs,ss,ds}
reg=enum{ax=0,bx,cd,dx,bx,sp,bp,si,di (if w=1)} enum{al,bl...} (if w=0)
r/m=reg or mem (mod=3 then REG, else mem)

许多指令可以在第一个字节中重叠:

76543210  76543210  76543210  76543210
push                    11111111  ||110r/m
inc                     1111111w  ||000r/m

位掩码似乎具有任意分配 . 拆卸器如何拆分指令?

这个问题是How to write a disassembler.的一个子集

1 回答

  • 8

    查看我的8086/8088用户手册程序员参考(ISBN 1-55512-010-5),可能已有数十年的绝版...附录A显示了以操作码顺序0b00000000到0b11111111的指令解码 . 看起来一点也不混乱 . 添加,子和,xor,cmp等都以这样的方式分组,即多路复用器可以直接使用操作码位来路由输入和输出,而其他位选择alu对这些位执行的操作 .

    对于编写反汇编程序,您希望使用此类表或操作码图表进行顶级的指令排序 .

    在您的特定示例中,请注意每当您将第一个操作码视为0xFF时,第二个字节中间有三个位,告诉您故事的其余部分是哪个指令 . 这些组合中的所有8个(一个未定义)被表示并且从这3个比特中容易地解码 .

    是的,x86指令集很疯狂 . 有趣和有趣的功能,但从那以后发明了相当好的指令集 . 例如,x86没有走向6502的唯一原因是动力,而不是质量 .

    你也应该看看这个:

    How are hex sequence translated to assembly without ambiguity?

    如何对此和任何其他可变字长指令集进行反汇编是按执行顺序进行的 . 如果您尝试按地址顺序线性执行,则会失败 . 从向量表开始获取入口地址,然后按地址顺序遵循这些指令,记下并跟踪所有分支,直到您点击无条件分支或返回或终止该指令串的其他指令 . 对每个分支目的地重复此操作 . 这不会涵盖所有可能的指令,因为代码可能会在执行时计算地址(你可以做很多关于拆解的地址) .

    如果这些代码中的任何一个是有意或无意地手写以驱逐反汇编程序,那么您可能会发生冲突,其中基于一个执行路径的一个操作码的第二个或第三个字节似乎是基于不同执行的指令的第一个操作码路径 . 例如,如果标志是清除的,则清除标志指令后跟条件分支,后跟一个数据字节,然后是作为分支目的地的实际指令 . 是的,我遇到过这个 . 它应该被你的反汇编程序困住,你需要把它们放入检查中以便在它们发生碰撞时停止拆解其中一条或两条执行路径 . 对于完整的反汇编,期望必须支持某种用户输入以将地址排除为操作码,以及用户手动添加有效的操作码以便您遵循执行路径 .

    对于固定长度的指令集,您可以轻松地在地址或执行顺序中进行反汇编,您的选择,地址顺序从0到内存结束当然是最简单的 . 不要在未定义的指令上输出错误,只需将它们标记为原样并继续运行,其中一些是数据 .

    x86绝对是我试图反汇编的最后一个可变长度指令集,我写了很多反汇编程序 . 不想尝试这个项目 . 从一些固定长度的开始,如pic和arm / thumb . 尝试msp430的可变字长,然后可能是6502(小行星,小行星豪华,月球着陆器等) . 可能需要一周或两周的时间来覆盖上面的内容并获得它的感觉,然后如果欲望仍然存在则攻击x86 . 如果你严格限制在8088/8086,那就不是那么糟糕,需要确保你的工具生成这些指令而不是进入386的指令 .

    如果push vs inc困扰你,那么首先要尝试像msp430这样的其他东西 .

相关问题