我有兴趣将x86解析器编写为教育项目。
我找到的唯一真实资源是Spiral Space,“How to write a disassembler”。虽然这给出了反汇编程序各种组件的高级描述,但我对一些更详细的资源感兴趣。我还快速浏览了NASM's源代码,但这对于学习有点重要。
我意识到这个项目的一个主要挑战是我将要处理的相当大的x86指令集。我也对基本结构,基本反汇编链接等感兴趣。
有人能指出我编写x86反汇编程序的任何详细资源吗?
答案 0 :(得分:62)
查看section 17.2的80386 Programmer's Reference Manual。反汇编真的只是一个美化finite-state machine。反汇编的步骤是:
F3
,F2
或F0
);如果是这样,那么您就有REP
/ REPE
/ REPNE
/ LOCK
前缀。前进到下一个字节。67
)。如果是,则如果当前处于32位模式,则以16位模式解码其余指令中的地址;如果当前处于16位模式,则解码32位模式下的地址66
)。如果是,则如果当前处于32位模式,则以16位模式解码立即操作数,或者如果当前处于16位模式,则以32位模式解码立即操作数2E
,36
,3E
,26
,64
或{{1 }})。如果是这样,请使用相应的段寄存器来解码地址而不是默认的段寄存器。65
,则它是扩展操作码,并将下一个字节作为扩展操作码读取。操作码会告诉您正在执行的操作。操作码的参数可以从Mod R / M,SIB,位移和立即值的值解码。由于x86的复杂性,有很多可能性和许多特殊情况。请参阅上面的链接以获得更详尽的解释。
答案 1 :(得分:22)
我建议查看一些开源的反汇编程序,最好是distorm,特别是“disOps(Instructions Sets DataBase)”(ctrl +在页面上找到它)。
文档本身充满了关于操作码和说明的丰富信息。
引自 https://code.google.com/p/distorm/wiki/x86_x64_Machine_Code
80x86说明:
80x86指令分为a 元素数量:
- 指令前缀,影响指令的行为 操作
- 强制前缀用作SSE指令的操作码字节。
- 操作码字节,可以是一个或多个字节(最多3个整字节)。
- ModR / M字节是可选的,有时可能包含部分内容 操作码本身。
- SIB字节是可选的,表示复杂的内存间接 形式。
- 位移是可选的,它是不同大小的值 字节(字节,字,长)并用作 偏移量。
- 立即是可选的,它用作构建的一般数字值 从不同大小的字节(字节, 字,长)。
醇>格式如下:
/-------------------------------------------------------------------------------------------------------------------------------------------\ |*Prefixes | *Mandatory Prefix | *REX Prefix | Opcode Bytes | *ModR/M | *SIB | *Displacement (1,2 or 4 bytes) | *Immediate (1,2 or 4 bytes) | \-------------------------------------------------------------------------------------------------------------------------------------------/ * means the element is optional.
数据结构和解码阶段在https://code.google.com/p/distorm/wiki/diStorm_Internals
中进行了解释引用:
解码阶段
- [前缀]
- [获取操作码]
- [过滤操作码]
- [提取操作数]
- [文字格式]
- [Hex Dump]
- [解码指令]
醇>
每个步骤也都有解释。
原始链接由于历史原因而保留:
http://code.google.com/p/distorm/wiki/x86_x64_Machine_Code和http://code.google.com/p/distorm/wiki/diStorm_Internals
答案 2 :(得分:6)
从一个已组装的小程序开始,它既为您提供生成的代码,也为您提供指令。使用instruction architecture获取参考资料,并手动完成一些生成的代码和体系结构参考。您会发现这些指令具有非常典型的 inst op op op 结构,具有不同数量的操作数。您需要做的就是翻译代码的十六进制或八进制表示以匹配指令;一点点玩耍都会揭示它。
这个过程是自动化的,是反汇编程序的核心。理想情况下,您可能希望在内部(或外部,如果程序非常大)构建n个指令结构数组。然后,您可以将该数组转换为汇编程序格式的指令。
答案 3 :(得分:4)
您需要一个可从中加载的操作码表。
基本的查找数据结构是一个特里结构,但是如果你不关心速度,表格会做得很好。
要获得基本操作码类型,请从表格开始匹配。
有一些解决寄存器参数的库存方法;但是,有足够的特殊情况需要单独实施其中的大多数。
由于这是教育性的,请看一下ndisasm。
答案 4 :(得分:2)
Checkout objdump 来源 - 它是一个很棒的工具,它包含许多操作码表,它的源代码可以为你自己的反汇编程序提供一个很好的基础。