首页 文章

如何写一个反汇编程序? [关闭]

提问于
浏览
64

我有兴趣将x86解析器编写为教育项目 .

我发现的唯一真实资源是Spiral Space,“How to write a disassembler” . 虽然这给出了反汇编程序的各种组件的高级描述,但我也快速查看了NASM's源代码,但这有点重要 .

我意识到这个项目的一个主要挑战是我将要处理的相当大的x86指令集 . 我也对基本结构,基本反汇编链接等感兴趣 .

有人能指出我有关编写x86反汇编程序的任何详细资源吗?

5 回答

  • 4

    看看80386 Programmer's Reference Manualsection 17.2 . 一个反汇编真的只是一个美化的finite-state machine . 反汇编的步骤是:

    • 检查当前字节是否为指令前缀字节( F3F2F0 );如果是这样,那么你有一个 REP / REPE / REPNE / LOCK 前缀 . 前进到下一个字节 .

    • 检查当前字节是否为地址大小字节( 67 ) . 如果是,如果当前处于32位模式,则以16位模式解码其余指令中的地址;如果当前处于16位模式,则解码32位模式下的地址

    • 检查当前字节是否为操作数大小字节( 66 ) . 如果是,如果当前处于32位模式,则以16位模式解码立即操作数,如果当前处于16位模式,则解码32位模式下的立即操作数

    • 检查当前字节是否为段覆盖字节( 2E363E266465 ) . 如果是,请使用相应的段寄存器来解码地址而不是默认的段寄存器 .

    • 下一个字节是操作码 . 如果操作码是 0F ,则它是扩展操作码,并将下一个字节读作扩展操作码 .

    • 根据特定操作码,读入并解码Mod R / M字节,Scale Index Base(SIB)字节,位移(0,1,2或4字节)和/或立即值(0, 1,2或4个字节) . 这些字段的大小取决于操作码,地址大小覆盖和先前解码的操作数大小覆盖 .

    操作码告诉您正在执行的操作 . 操作码的参数可以从Mod R / M,SIB,位移和立即值的值解码 . 由于x86的复杂性,有很多可能性和许多特殊情况 . 有关更详细的说明,请参阅上面的链接 .

  • 21

    我建议检查一些开源的反汇编程序,最好是distorm,特别是"disOps (Instructions Sets DataBase)"(ctrl在页面上找到它) .

    文档本身充满了关于操作码和指令的丰富信息 .

    引自https://code.google.com/p/distorm/wiki/x86_x64_Machine_Code

    80x86指令:80x86指令被分成许多元素:指令前缀,影响指令操作的行为 . 强制前缀用作SSE指令的操作码字节 . 操作码字节可以是一个或多个字节(最多3个整字节) . ModR / M字节是可选的,有时可能包含操作码本身的一部分 . SIB字节是可选的,表示复杂的内存间接形式 . 位移是可选的,它是不同大小的字节(字节,字,长)的值,并用作偏移量 . Immediate是可选的,它用作通过不同大小的字节(字节,字,长)构建的通用数值 . 格式如下:/ ------------------------------------------- -------------------------------------------------- ----------------------------------------------
    | *前缀| *强制性前缀| * REX前缀|操作码字节| * ModR / M | * SIB | *位移(1,2或4字节)| *立即(1,2或4字节)|
    \ ------------------------------------------------- -------------------------------------------------- ---------------------------------------- /
    *表示元素是可选的 .

    数据结构和解码阶段在https://code.google.com/p/distorm/wiki/diStorm_Internals中解释

    引用:

    解码阶段[前缀] [获取操作码] [过滤操作码] [提取操作数] [文本格式] [十六进制转储] [解码指令]

    每个步骤也都有解释 .


    原始链接由于历史原因而保留:

    http://code.google.com/p/distorm/wiki/x86_x64_Machine_Codehttp://code.google.com/p/distorm/wiki/diStorm_Internals

  • 6

    从一些已组装的小程序开始,它既为您提供生成的代码,也为您提供指令 . 使用instruction architecture获取参考,并完成一些生成的工作手工编写带有体系结构参考的代码 . 你会发现这些指令有一个非常定型的inst op op op结构,它有不同数量的操作数 . 您需要做的就是翻译代码的十六进制或八进制表示以匹配指令;一点点玩都会揭示它 .

    这个过程是自动化的,是反汇编程序的核心 . 理想情况下,您可能希望在内部(或外部,如果程序非常大)构建n个指令结构数组 . 然后,您可以将该数组转换为汇编程序格式的指令 .

  • 2

    您需要一个可加载的操作码表 .

    基本的查找数据结构是一个特里,但如果你不太关心速度,那么表格就可以做得很好 .

    要获得基本操作码类型,请从表格开始匹配 .

    有一些解决寄存器参数的库存方法;但是,有足够的特殊情况需要单独实施其中的大多数 .

    由于这是教育,看看ndisasm .

  • 61

    结帐 objdump 来源 - 它's a great tool, it contains many opcode tables and it' s源可以为您自己的反汇编程序提供一个很好的基础 .

相关问题