本页介绍 Ghidra 如何实现对不同处理器架构的支持,从而能够在广泛的平台上对二进制文件进行逆向工程。处理器架构支持是 Ghidra 的核心功能之一,为反汇编、反编译和分析功能奠定了基础。
Ghidra 使用一套复杂的系统,通过规范文件(定义寄存器、指令、内存空间和语义行为)来建模处理器架构。这使得该工具能够准确地反汇编和反编译不同处理器的代码,而无需为每个处理器单独实现。
有关 x86 或 ARM 等特定架构支持的信息,请参阅 x86 架构支持 和 ARM 架构支持。有关用于定义处理器规范的语言的详细信息,请参阅 处理器规范语言。
Ghidra 的处理器架构支持围绕一个由规范文件和运行时组件组成的系统构建,该系统将机器代码转换为 Ghidra 的中间表示。该系统旨在实现准确性和可扩展性。
来源: Ghidra/Processors/x86/data/languages/x86.ldefs Ghidra/Processors/ARM/data/languages/ARM.ldefs Ghidra/Processors/x86/data/languages/x86.slaspec Ghidra/Processors/ARM/data/languages/ARM.sinc
处理器架构支持包含几个关键组件:
语言定义文件 (.ldefs):XML 文件,定义每个受支持处理器的元数据,包括字节序、地址大小和变体信息。
SLEIGH 规范文件 (.slaspec, .sinc):使用 SLEIGH 规范语言定义处理器指令集、寄存器和语义的文件。
处理器规范文件 (.pspec):XML 文件,定义处理器特定行为,如堆栈指针寄存器、默认调用约定等。
编译器规范文件 (.cspec):XML 文件,定义给定处理器的编译器特定约定,如调用约定、数据组织等。
SLEIGH 编译器:将规范文件转换为可由运行时组件使用的已编译规范文件 (.sla)。
这些组件协同工作,提供了处理器架构的完整描述,可供 Ghidra 的反汇编和反编译引擎使用。
来源: Ghidra/Processors/x86/data/languages/x86.ldefs1-121 Ghidra/Processors/ARM/data/languages/ARM.ldefs1-105
语言定义文件 (.ldefs) 通过指定处理器的元数据并指向其规范文件,为处理器支持提供了入口点。每个处理器可以定义多个变体,以支持不同的模式或功能。
例如,x86 处理器有 16 位实模式、32 位保护模式和 64 位长模式的变体,而 ARM 处理器则有不同指令集版本(v4、v5、v7、v8)和字节序配置的变体。
以下是 x86 语言定义文件的一个示例:
<language processor="x86"
endian="little"
size="32"
variant="default"
version="4.4"
slafile="x86.sla"
processorspec="x86.pspec"
manualindexfile="../manuals/x86.idx"
id="x86:LE:32:default">
<description>Intel/AMD 32-bit x86</description>
<compiler name="Visual Studio" spec="x86win.cspec" id="windows"/>
<compiler name="gcc" spec="x86gcc.cspec" id="gcc"/>
<!-- Additional compilers and external names -->
</language>
来源: Ghidra/Processors/x86/data/languages/x86.ldefs4-35 Ghidra/Processors/ARM/data/languages/ARM.ldefs4-25
每个处理器架构都需要定义其寄存器和内存空间。这些定义在 SLEIGH 规范文件中,为所有指令和语义定义提供了基础。
以下是 ARM 的寄存器和空间定义示例:
define space ram type=ram_space size=4 default;
define space register type=register_space size=4;
define register offset=0x0020 size=4 [ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc ];
define register offset=0x0060 size=1 [ NG ZR CY OV tmpNG tmpZR tmpCY tmpOV shift_carry TB Q GE1 GE2 GE3 GE4 ];
define register offset=0x0070 size=4 [ cpsr spsr ];
以及 x86 的示例:
define space ram type=ram_space size=$(SIZE) default;
define space register type=register_space size=4;
# General purpose registers
define register offset=0 size=4 [ EAX ECX EDX EBX ESP EBP ESI EDI ];
define register offset=0 size=2 [ AX _ CX _ DX _ BX _ SP _ BP _ SI _ DI ];
define register offset=0 size=1 [ AL AH _ _ CL CH _ _ DL DH _ _ BL BH ];
这些定义建立了处理器的寄存器集,包括通用寄存器、状态寄存器和专用寄存器。对于 AVX 或 NEON 等 SIMD 扩展,还会定义额外的寄存器集。
来源: Ghidra/Processors/ARM/data/languages/ARM.sinc4-28 Ghidra/Processors/x86/data/languages/ia.sinc10-32
处理器指令使用 SLEIGH 模式定义,将位模式映射到指令语义。这些定义是处理器架构支持的核心,因为它们决定了机器代码如何被解释并转换为 Ghidra 的中间表示(P-code)。
以下是指令定义结构的简化视图:
例如,这是 ARM ADC 指令的定义:
:adc^COND Rd,Rn,Rm is TMode=0 & ARMcond=1 & COND & c2027=0b0010101 & Rn & Rd & c0407=0b1001 & Rm
{
build COND;
local val = Rn + Rm + zext(CY);
tmpCY = carry(Rn, Rm) || carry(Rn + Rm, zext(CY));
tmpOV = scarry(Rn, Rm) ^^ scarry(Rn + Rm, zext(CY));
Rd = val;
resflags(val);
}
以及 x86 ADD 指令的定义:
:ADD^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=0 ... ; imm8
{
build lockx;
build m8;
addflags(m8, imm8:1);
resultflags(m8);
build unlock;
}
这些定义包括匹配二进制编码的模式、助记符和操作数格式,以及描述指令行为的 P-code 语义。
来源: Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc607-641 Ghidra/Processors/x86/data/languages/lockable.sinc7-23
Ghidra 支持广泛的处理器架构,其中 x86/x64 和 ARM/AARCH64 的支持最为广泛。以下是一些主要受支持架构及其变体的表格:
| 架构 | 变体 | 描述 |
|---|---|---|
| x86 | LE:32:default | 32 位 x86 |
| LE:16:Real Mode | 16位实模式 | |
| LE:16:Protected Mode | 16位保护模式 | |
| LE:32:System Management Mode | 系统管理模式 | |
| x86-64 | LE:64:default | 64位 x86-64 |
| LE:64:compat32 | 64位 32位兼容模式 | |
| ARM | LE:32:v8 | ARM/Thumb v8 小端序 |
| LE:32:v8T | ARM/Thumb v8 (Thumb 默认) | |
| BE:32:v8 | ARM/Thumb v8 大端序 | |
| LE:32:v7 | ARM/Thumb v7 小端序 | |
| BE:32:v7 | ARM/Thumb v7 大端序 | |
| LE:32:Cortex | ARM Cortex/Thumb 小端序 | |
| AARCH64 | LE:64:v8A | AARCH64 v8A 小端序 |
| BE:64:v8A | AARCH64 v8A 大端序 |
每个架构都支持多种变体,以处理不同的模式、指令集扩展和字节序配置。
来源: Ghidra/Processors/x86/data/languages/x86.ldefs4-120 Ghidra/Processors/ARM/data/languages/ARM.ldefs4-195
x86 架构支持包括:
指令集扩展作为单独的包含文件 (sinc 文件) 实现,根据处理器变体选择性地包含。
@include "ia.sinc"
@include "lockable.sinc"
with : lockprefx=0 {
@include "avx.sinc"
@include "avx_manual.sinc"
@include "avx2.sinc"
@include "avx2_manual.sinc"
@include "avx512.sinc"
@include "avx512_manual.sinc"
}
来源: Ghidra/Processors/x86/data/languages/x86.slaspec1-9 Ghidra/Processors/x86/certification.manifest1-105
ARM 架构支持包括:
ARM 指令集支持被组织成不同指令集版本和扩展的包含文件。
@if defined(SIMD) || defined(VFPv2) || defined(VFPv3)
@define INCLUDE_NEON "" # Neon instructions included with SIMD, VFPv2 or VFPv3
@endif
@if defined(T_VARIANT)
@define AMODE "TMode=0" # T_VARIANT must restrict ARM instruction decoding and require TMode=0
@else
@define AMODE "epsilon" # THUMB instructions not supported - ARM only
@endif
ARM 还支持 ARM 和 Thumb 指令集之间的上下文切换,这通过 TMode 上下文变量处理。
define context contextreg
@ifdef T_VARIANT
TMode = (0,0) # 1 if in Thumb instruction decode mode
T = (0,0) # exact copy (alias!) of TMode
LowBitCodeMode = (0,0) # 1 if low bit of instruction address is set on a branch
ISA_MODE = (0,0) # 1 for Thumb instruction decode mode
@endif
来源: Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc1-25 Ghidra/Processors/ARM/data/languages/ARM.sinc78-93
处理器架构规范对反编译器至关重要,因为它们提供了将机器代码转换为 Ghidra 的中间表示(P-code)的功能,而反编译器就是分析这种表示。
关键集成点包括
来源: Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/ARMAssemblyTest.java21-138 Ghidra/Processors/ARM/data/languages/ARM_win.cspec1-10 Ghidra/Processors/AARCH64/data/languages/AARCH64_win.cspec1-31
处理器架构支持通过广泛的测试进行验证:
例如,ARM 汇编测试套件测试了各种指令形式。
添加对新处理器架构的支持涉及创建必要的规范文件:
该过程通常涉及
对于复杂的架构,通常可以从类似的现有架构作为模板开始。
来源: Ghidra/Processors/ARM/data/languages/ARM.opinion1-4 Ghidra/Processors/AARCH64/certification.manifest1-9
Ghidra 的处理器架构支持为逆向工程各种二进制文件提供了灵活而强大的基础。SLEIGH 规范语言允许对处理器行为进行详细建模,而模块化设计则易于扩展以支持新架构。
架构支持与 Ghidra 的反编译器和分析功能集成,可在多个平台上实现高级逆向工程功能。每个受支持的架构都经过严格测试,以确保准确的反汇编、反编译和分析。