Ghidra Processor创建教程——从二进制到汇编代码
字数 1951 2025-08-24 07:48:33

Ghidra Processor 创建教程——从二进制到汇编代码

1. 前言

Ghidra 提供了创建自定义 Processor 的功能,允许用户将特定的二进制代码翻译为汇编指令。本教程以强网杯 2020 年初赛的 QWBLogin 为例,详细介绍如何创建一个 Processor。

2. 准备工作

2.1 安装 Eclipse
  • 下载并安装 Eclipse IDE。
  • 确保 Eclipse 版本与 Ghidra 兼容。
2.2 安装 GhidraDev 插件
  • 插件路径:<ghidra_install_dir>/Extensions/Eclipse/GhidraDev/GhidraDev-2.1.1.zip
  • 安装步骤:
    1. 打开 Eclipse,点击 Help → Install New Software...
    2. 点击 Add...,然后选择 Archive...
    3. 浏览并选择 GhidraDev-2.1.1.zip
    4. 勾选 GhidraGhidraDev 条目,点击 Next
    5. 接受许可协议,完成安装并重启 Eclipse。
2.3 创建 Ghidra Module Project
  1. 在 Eclipse 中,选择 File → New → Project
  2. 选择 Ghidra Module Project
  3. 输入项目名称(如 qwbvm)。
  4. 在下一步中,仅勾选 Processor
  5. 指定 Ghidra 安装目录。
  6. 重命名模板文件(将 skel 改为 qwbvm)。

3. Processor 定义

3.1 指令结构

指令格式如下:

+-opcode | inst_switch | length | x1 | x2
1byte    | 4bit        | 4bit   |    |
  • opcode:操作码。
  • inst_switch:指令类型标识。
  • length:数据长度(1-4 字节)。
  • x1, x2:操作数(可选,长度不定)。
3.2 指令表

部分指令示例:

指令 opcode inst_switch length x1 x2
halt 0 0 - - -
mov x1, x2 1 0 [1-4] reg reg
mov x1, bss[x2] 1 1 [1-4] reg imm64
mov bss[x1], x2 1 2 [1-4] imm64 reg
call x1 16 6 - reg -
syscall 32 - - - -
3.3 寄存器
  • 通用寄存器:r0-r15
  • 特殊寄存器:
    • sp:栈指针。
    • pc:程序计数器。

4. 配置文件详解

4.1 qwbvm.pspec

定义寄存器和处理器特性:

<processor_spec>
  <programcounter register="pc"/>
  <register_data>
    <register name="r0" group="Alt"/>
    <!-- 其他寄存器 r1-r15 -->
  </register_data>
</processor_spec>
4.2 qwbvm.cspec

定义调用约定和编译器行为:

<compiler_spec>
  <stackpointer register="SP" space="ram"/>
  <default_proto>
    <prototype name="__asmA" extrapop="2" stackshift="2" strategy="register">
      <input>
        <pentry minsize="1" maxsize="8"><register name="r0"/></pentry>
        <!-- 其他输入寄存器 -->
      </input>
      <output><pentry minsize="1" maxsize="1"><register name="r0"/></pentry></output>
    </prototype>
  </default_proto>
</compiler_spec>
4.3 qwbvm.ldefs

定义语言和处理器属性:

<language_definitions>
  <language processor="qwbvm" endian="little" size="64" variant="default" 
            slafile="qwbvm.sla" processorspec="qwbvm.pspec" id="qwbvm:LE:64:default">
    <description>QWB VM Language Module</description>
    <compiler name="default" spec="qwbvm.cspec" id="default"/>
  </language>
</language_definitions>
4.4 qwbvm.slaspec

定义内存空间和寄存器:

define space ram type=ram_space size=8 default;
define space bss type=ram_space size=8;
define space register type=register_space size=8;

define register offset=0x00 size=8 [r0 r1 ... r15];
define register offset=0x100 size=8 [sp pc];
define register offset=0x200 size=8 contextreg;

@include "qwbvm.sinc"
4.5 qwbvm.sinc

定义指令解析逻辑:

define token opbyte(8) op = (0,5) rn = (0,3) rm = (0,3);
define token oplength(8) inst_switch = (0,3) data_length = (4,6);

define context contextreg addrmode = (0,2);

dl: "" is data_length=0 [addrmode=1;] {}
dl: "byte" is data_length=1 [addrmode=1;] {}
dl: "qword" is data_length=4 [addrmode=4;] {}

:mov dl rn, rm is op=1; dl & inst_switch=0; rn; rm {}
:mov dl rn, "bss"[imm64] is op=1; dl & inst_switch=1; rn; imm64 {}

5. 关键概念

5.1 Token
  • 组成指令的基本单元。
  • 示例:
    define token data8(8) imm8 = (0,7) simm8 = (0,7) signed;
    
5.2 Symbol
  • 用于简化指令定义。
  • 示例(dl 符号):
    dl: "byte" is data_length=1 [addrmode=1;] {}
    
5.3 Context
  • 根据处理器状态动态解析指令。
  • 示例:
    define context contextreg addrmode = (0,2);
    
5.4 相对地址计算
  • 用于 call 和跳转指令:
    rel: reloc is simm8 [reloc = inst_next + simm8;] {}
    

6. 完整指令定义示例

:halt is op=0; inst_switch & data_length {}
:mov dl rn, rm is op=1; dl & inst_switch=0; rn; rm {}
:call rel is op=0x10; inst_switch=7; rel {}
:syscall is op=0x20; inst_switch {}

7. 测试与验证

  1. 在 Eclipse 中运行 Processor 模块。
  2. 将二进制文件(如 test.bin)拖入 Ghidra。
  3. 选择 qwbvm 作为 Processor。
  4. 检查反汇编结果是否符合预期。

8. 总结

通过本教程,你可以:

  1. 创建自定义 Processor。
  2. 定义指令集和寄存器。
  3. 使用 Token 和 Symbol 简化指令解析。
  4. 实现动态上下文和相对地址计算。

最终生成的 Processor 可将二进制代码准确翻译为汇编指令,适用于逆向工程和二进制分析。

Ghidra Processor 创建教程——从二进制到汇编代码 1. 前言 Ghidra 提供了创建自定义 Processor 的功能,允许用户将特定的二进制代码翻译为汇编指令。本教程以强网杯 2020 年初赛的 QWBLogin 为例,详细介绍如何创建一个 Processor。 2. 准备工作 2.1 安装 Eclipse 下载并安装 Eclipse IDE。 确保 Eclipse 版本与 Ghidra 兼容。 2.2 安装 GhidraDev 插件 插件路径: <ghidra_install_dir>/Extensions/Eclipse/GhidraDev/GhidraDev-2.1.1.zip 。 安装步骤: 打开 Eclipse,点击 Help → Install New Software... 。 点击 Add... ,然后选择 Archive... 。 浏览并选择 GhidraDev-2.1.1.zip 。 勾选 Ghidra 或 GhidraDev 条目,点击 Next 。 接受许可协议,完成安装并重启 Eclipse。 2.3 创建 Ghidra Module Project 在 Eclipse 中,选择 File → New → Project 。 选择 Ghidra Module Project 。 输入项目名称(如 qwbvm )。 在下一步中,仅勾选 Processor 。 指定 Ghidra 安装目录。 重命名模板文件(将 skel 改为 qwbvm )。 3. Processor 定义 3.1 指令结构 指令格式如下: opcode :操作码。 inst_switch :指令类型标识。 length :数据长度(1-4 字节)。 x1 , x2 :操作数(可选,长度不定)。 3.2 指令表 部分指令示例: | 指令 | opcode | inst_ switch | length | x1 | x2 | |--------------------|--------|-------------|--------|------|------| | halt | 0 | 0 | - | - | - | | mov x1, x2 | 1 | 0 | [ 1-4 ] | reg | reg | | mov x1, bss[ x2] | 1 | 1 | [ 1-4 ] | reg | imm64| | mov bss[ x1], x2 | 1 | 2 | [ 1-4 ] | imm64| reg | | call x1 | 16 | 6 | - | reg | - | | syscall | 32 | - | - | - | - | 3.3 寄存器 通用寄存器: r0 - r15 。 特殊寄存器: sp :栈指针。 pc :程序计数器。 4. 配置文件详解 4.1 qwbvm.pspec 定义寄存器和处理器特性: 4.2 qwbvm.cspec 定义调用约定和编译器行为: 4.3 qwbvm.ldefs 定义语言和处理器属性: 4.4 qwbvm.slaspec 定义内存空间和寄存器: 4.5 qwbvm.sinc 定义指令解析逻辑: 5. 关键概念 5.1 Token 组成指令的基本单元。 示例: 5.2 Symbol 用于简化指令定义。 示例( dl 符号): 5.3 Context 根据处理器状态动态解析指令。 示例: 5.4 相对地址计算 用于 call 和跳转指令: 6. 完整指令定义示例 7. 测试与验证 在 Eclipse 中运行 Processor 模块。 将二进制文件(如 test.bin )拖入 Ghidra。 选择 qwbvm 作为 Processor。 检查反汇编结果是否符合预期。 8. 总结 通过本教程,你可以: 创建自定义 Processor。 定义指令集和寄存器。 使用 Token 和 Symbol 简化指令解析。 实现动态上下文和相对地址计算。 最终生成的 Processor 可将二进制代码准确翻译为汇编指令,适用于逆向工程和二进制分析。