Microcode

  1. 介绍

记录Microcode

介绍

Microcode 是 hexrays 内部采用的介于机器代码与伪代码之间的一种中间表示语言(IR)。

Microcode 生成完成后,IDA 在 Microcode 的基础上生成 CTree。 CTree 是 IDA 内部用于表示 C语言伪代码的抽象语法树,IDA 也提供了大量 API 操作 CTree,可以实现一下伪代码展示方面的优化,例如删除某些节点等等。

Microcode 指令格式

opcode left, right, destination
一般来说有三个操作数,有一些指令可能缺少某个操作数,destination 也不一定会被修改(Store 指令)

Microcode 中常见的数据结构

函数是 IDA 中最大的汇编结果表示单位

函数 → 基本块 → 指令 → 操作数

Microcode 可视化插件

https://github.com/gaasedelen/lucid

Ctree 可视化插件
https://github.com/patois/HRDevHelper

Microcode生成过程:

  1. 生成 Microcode

  2. 变换 Microcode (例如优化)

  3. 局部变量分配

  4. 生成 CTree (CTree 是 IDA 用来表示伪代码的抽象语法树 AST)

  5. 优化 CTree

  6. 输出 CTree

Microcode 寄存器

microcode 的寄存器没有数量限制,物理寄存器往往会被直接映射到 microcode 寄存器,例如

  • AL is mapped into al.1 (mreg number 8)
  • AH is mapped into ah.1 (mreg number 9)
  • EAX is mapped into eax.4 (mreg numbers 8-11)
  • RSI is mapped into rsi.8

Microcode 分阶段生成, 最初阶段生成的代码非常冗余

image-20230119221600205

Microcode 快速上手,手动调用 microcode 生成

import ida_hexrays
import idaapi
def print_microcode(func_ea):
    maturity = ida_hexrays.MMAT_GLBOPT3
    #   maturity:
    #   MMAT_ZERO,          //< microcode 不存在
    #   MMAT_GENERATED      //< 已经生成的microcode
    #   MMAT_PREOPTIMIED    //< 预先优化的pass已完成
    #   MMAT_LOCOPT         //< local 本地每个基本块的优化已完成    control控制流图也就绪
    #   MMAT_CALLS          //< 检测调用参数
    #   MMAT_GLBOPT1        //< 执行第一个全局优化pass
    #   MMAT_GLBOPT2        //< 大多数全局优化pass已完成
    #   MMAT_GLBOPT3        //< 完成所有的优化,microcode被修改
    #   MMAT_LVAR3          //< 分配所有的局部变量
    hf = ida_hexrays.hexrays_failure_t()
    pfn = idaapi.get_func(func_ea)
    rng = ida_hexrays.mba_ranges_t(pfn)
    mba = ida_hexrays.gen_microcode(rng,hf,None,
                                    ida_hexrays.DECOMP_WARNINGS,maturity)
    vp = ida_hexrays.vd_printer_t()
    mba._print(vp)
print_microcode(0x1229)

Microcode 相关的数据结构,定义在 hexrays.hpp 文件

image-20230119221901715

image-20230119222011500

Microcode 相关的数据结构: mbl_array_t,这个结构用来存放函数的基本块信息

  • 基本块之间使用双向链表链接
  • 基本块数组存放在 natural 数组

image-20230119222056330

Microcode 相关的数据结构: mblock_t,这个结构用来描述基本块信息。±基本块内的指令与指令之间使用双向链表链接

image-20230119222156151

Microcode 相关的数据结构: minsn_t。用于描述指令信息的结构。(注意微码指令支持指令嵌套。)

image-20230119222222555

Microcode 相关的数据结构: mop_t

用于描述操作数信息的结构,指令 minsn_t 有 0 ~ 3 个操作数,分别时 l (left), r (right), d (destination) 操作数的类型用 mop_t 来表示

image-20230119222252600

Microcode 插件例子

  • 实现 svc 0x900001 与 svc 0x9000F8 指令反编译成一条 call 指令
  • install_microcode_filter 注册 microcode filter 实现拦截指令翻译
  • microcode filter 是一种可以拦截 microcode 指令生成的机制,开发者需要继承 microcode_filter_t 类并实现 match 与 apply 两个函数。
  • ida 在生成某一条指令的 microcode 之前会调用所有已经注册的 filter 的 match 函数,若 match 函数返回 True,则调用对应的 apply 函数实现指令替换。
  • 我们需要将 svc 指令替换成 call 指令,ida 已经为我们实现了替换类 udc_filter_t, 这个类继承于 microcode_filter_t 并实现了 apply 方法(即替换call指令),我们需要继承 udc_filter_t 并实现它的 match 方法用于判断拦截的指令。

Microcode 插件例子

image-20230119222437041


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com

×

喜欢就点赞,疼爱就打赏