Capstone反汇编引擎数据类型及API分析与示例(一)
字数 2266 2025-08-04 08:17:33
Capstone反汇编引擎数据类型及API分析与示例
1. 开发准备
1.1 Capstone简介
Capstone是目前世界上最优秀的反汇编引擎之一,被IDA、Radare2、Qemu等著名项目使用。它支持多种架构的反汇编,包括:
- ARM (包括Thumb, Thumb-2)
- ARM-64 (AArch64)
- Mips
- X86 (包括x86 & x86-64)
- PowerPC
- Sparc
- SystemZ
- XCore
- 68K
- TMS320C64x
- 680X
- Ethereum
1.2 源码结构
Capstone源码目录结构如下:
. <- 主要引擎core engine + README + 编译文档COMPILE.TXT 等
├── arch <- 各语言反编译支持的代码实现
│ ├── AArch64 <- ARM64 (aka ARMv8) 引擎
│ ├── ARM <- ARM 引擎
│ ├── EVM <- Ethereum 引擎
│ ├── M680X <- M680X 引擎
│ ├── M68K <- M68K 引擎
│ ├── Mips <- Mips 引擎
│ ├── PowerPC <- PowerPC 引擎
│ ├── Sparc <- Sparc 引擎
│ ├── SystemZ <- SystemZ 引擎
│ ├── TMS320C64x <- TMS320C64x 引擎
│ ├── X86 <- X86 引擎
│ └└── XCore <- XCore 引擎
├── bindings <- 中间件
│ ├── java <- Java 中间件 + 测试代码
│ ├── ocaml <- Ocaml 中间件 + 测试代码
│ └└── python <- Python 中间件 + 测试代码
├── contrib <- 社区代码
├── cstool <- Cstool 检测工具源码
├── docs <- 文档
├── include <- C头文件
├── msvc <- Microsoft Visual Studio 支持(Windows)
├── packages <- Linux/OSX/BSD包
├── windows <- Windows 支持(Windows内核驱动编译)
├── suite <- Capstone开发测试工具
├── tests <- C语言测试用例
└└── xcode <- Xcode 支持 (MacOSX 编译)
1.3 编译方法
Windows下使用Visual Studio编译步骤:
- 复制msvc文件夹到合适位置
- 打开capstone.sln项目文件
- 在解决方案属性->配置属性中选择需要的架构支持
- 编译后会在Debug目录下生成capstone.lib和capstone.dll
预编译版本下载:
- Win32: https://github.com/aquynh/capstone/releases/download/4.0.1/capstone-4.0.1-win32.zip
- Win64: https://github.com/aquynh/capstone/releases/download/4.0.1/capstone-4.0.1-win64.zip
2. 引擎调用测试
2.1 基本调用示例
#include <iostream>
#include <stdio.h>
#include <cinttypes>
#include "capstone.h"
using namespace std;
#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00"
int main(void)
{
csh handle;
cs_insn* insn;
size_t count;
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) {
printf("ERROR: Failed to initialize engine!\n");
return -1;
}
count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn);
if (count) {
size_t j;
for (j = 0; j < count; j++) {
printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
}
cs_free(insn, count);
}
else {
printf("ERROR: Failed to disassemble given code!\n");
}
cs_close(&handle);
return 0;
}
注意事项:
- 编译选项需要与架构匹配(如x64模式对应CS_MODE_64)
- C++开发时,printf格式字符串需要调整为
"0x%""Ix"":\t%s\t\t%s\n"
3. 数据类型分析
3.1 基本数据类型
csh
size_t csh; // 用于生成调用capstone API的句柄
cs_arch (架构选择)
enum cs_arch {
CS_ARCH_ARM = 0, // ARM架构(包括Thumb, Thumb-2)
CS_ARCH_ARM64, // ARM-64, 也叫AArch64
CS_ARCH_MIPS, // Mips架构
CS_ARCH_X86, // X86架构(包括x86 & x86-64)
CS_ARCH_PPC, // PowerPC架构
CS_ARCH_SPARC, // Sparc架构
CS_ARCH_SYSZ, // SystemZ架构
CS_ARCH_XCORE, // XCore架构
CS_ARCH_M68K, // 68K架构
CS_ARCH_TMS320C64X, // TMS320C64x架构
CS_ARCH_M680X, // 680X架构
CS_ARCH_EVM, // Ethereum架构
CS_ARCH_MAX,
CS_ARCH_ALL = 0xFFFF, // 所有架构 - 用于cs_support()
};
cs_mode (模式选择)
enum cs_mode {
CS_MODE_LITTLE_ENDIAN = 0, // little-endian模式(default模式)
CS_MODE_ARM = 0, // 32-bit ARM
CS_MODE_16 = 1 << 1, // 16-bit模式(X86)
CS_MODE_32 = 1 << 2, // 32-bit模式(X86)
CS_MODE_64 = 1 << 3, // 64-bit模式(X86, PPC)
CS_MODE_THUMB = 1 << 4, // ARM's Thumb模式,包括Thumb-2
CS_MODE_MCLASS = 1 << 5, // ARM's Cortex-M系列
CS_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM
CS_MODE_MICRO = 1 << 4, // MicroMips模式(MIPS)
CS_MODE_MIPS3 = 1 << 5, // Mips III ISA
CS_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA
CS_MODE_MIPS2 = 1 << 7, // Mips II ISA
CS_MODE_V9 = 1 << 4, // SparcV9模式(Sparc)
CS_MODE_QPX = 1 << 4, // Quad Processing eXtensions模式(PPC)
CS_MODE_M68K_000 = 1 << 1, // M68K 68000模式
CS_MODE_M68K_010 = 1 << 2, // M68K 68010模式
CS_MODE_M68K_020 = 1 << 3, // M68K 68020模式
CS_MODE_M68K_030 = 1 << 4, // M68K 68030模式
CS_MODE_M68K_040 = 1 << 5, // M68K 68040模式
CS_MODE_M68K_060 = 1 << 6, // M68K 68060模式
CS_MODE_BIG_ENDIAN = 1 << 31, // big-endian模式
CS_MODE_MIPS32 = CS_MODE_32, // Mips32 ISA(Mips)
CS_MODE_MIPS64 = CS_MODE_64, // Mips64 ISA(Mips)
CS_MODE_M680X_6301 = 1 << 1, // M680X Hitachi 6301,6303模式
CS_MODE_M680X_6309 = 1 << 2, // M680X Hitachi 6309模式
CS_MODE_M680X_6800 = 1 << 3, // M680X Motorola 6800,6802模式
CS_MODE_M680X_6801 = 1 << 4, // M680X Motorola 6801,6803模式
CS_MODE_M680X_6805 = 1 << 5, // M680X Motorola/Freescale 6805模式
CS_MODE_M680X_6808 = 1 << 6, // M680X Motorola/Freescale/NXP 68HC08模式
CS_MODE_M680X_6809 = 1 << 7, // M680X Motorola 6809模式
CS_MODE_M680X_6811 = 1 << 8, // M680X Motorola/Freescale/NXP 68HC11模式
CS_MODE_M680X_CPU12 = 1 << 9, // M680X Motorola/Freescale/NXP CPU12
CS_MODE_M680X_HCS08 = 1 << 10, // M680X Freescale/NXP HCS08模式
};
3.2 配置相关数据类型
cs_opt_mem (内存操作)
struct cs_opt_mem {
cs_malloc_t malloc;
cs_calloc_t calloc;
cs_realloc_t realloc;
cs_free_t free;
cs_vsnprintf_t vsnprintf;
};
cs_opt_mnem (自定义助记符)
struct cs_opt_mnem {
unsigned int id; // 需要自定义的指令ID
const char *mnemonic; // 自定义的助记符
};
cs_opt_type (反编译运行时选项)
enum cs_opt_type {
CS_OPT_INVALID = 0, // 无特殊要求
CS_OPT_SYNTAX, // 汇编输出语法
CS_OPT_DETAIL, // 将指令结构分解为多个细节
CS_OPT_MODE, // 运行时改变引擎模式
CS_OPT_MEM, // 用户定义的动态内存相关函数
CS_OPT_SKIPDATA, // 在反汇编时跳过数据
CS_OPT_SKIPDATA_SETUP, // 为SKIPDATA选项设置用户定义函数
CS_OPT_MNEMONIC, //自定义指令助记符
CS_OPT_UNSIGNED, // 以无符号形式打印立即操作数
};
cs_opt_value (运行时选项值)
enum cs_opt_value {
CS_OPT_OFF = 0, // 关闭一个选项 - 默认为CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED
CS_OPT_ON = 3, // 打开一个选项 (CS_OPT_DETAIL, CS_OPT_SKIPDATA)
CS_OPT_SYNTAX_DEFAULT = 0, // 默认asm语法 (CS_OPT_SYNTAX)
CS_OPT_SYNTAX_INTEL, // X86 Intel asm语法
CS_OPT_SYNTAX_ATT, // X86 ATT 汇编语法
CS_OPT_SYNTAX_NOREGNAME, // 只打印寄存器名和编号
CS_OPT_SYNTAX_MASM, // X86 Intel Masm 语法
};
3.3 指令分析相关数据类型
cs_op_type (通用指令操作数类型)
enum cs_op_type {
CS_OP_INVALID = 0, // 未初始化/无效的操作数
CS_OP_REG, // 寄存器操作数
CS_OP_IMM, // 立即操作数
CS_OP_MEM, // 内存操作数
CS_OP_FP, // 浮点数
};
cs_ac_type (通用指令操作数访问类型)
enum cs_ac_type {
CS_AC_INVALID = 0, // 未初始化/无效的访问类型
CS_AC_READ = 1 << 0, // 操作数从内存或寄存器中读取
CS_AC_WRITE = 1 << 1, // 操作数从内存或寄存器中写入
};
cs_group_type (公共指令组)
enum cs_group_type {
CS_GRP_INVALID = 0, // 未初始化/无效指令组
CS_GRP_JUMP, // 所有跳转指令
CS_GRP_CALL, // 所有调用指令
CS_GRP_RET, // 所有返回指令
CS_GRP_INT, // 所有中断指令(int+syscall)
CS_GRP_IRET, // 所有中断返回指令
CS_GRP_PRIVILEGE, // 所有特权指令
CS_GRP_BRANCH_RELATIVE, // 所有相关分支指令
};
cs_opt_skipdata (SKIPDATA选项)
struct cs_opt_skipdata {
const char *mnemonic; // 跳过数据的"助记符"字符串(默认".byte")
cs_skipdata_cb_t callback; // 回调函数(默认为NULL)
void *user_data; // 用户自定义数据传递给回调函数
};
3.4 指令详细信息结构
cs_detail (指令细节)
struct cs_detail {
uint16_t regs_read[12]; // 隐式读取寄存器列表
uint8_t regs_read_count; // 隐式读取寄存器计数
uint16_t regs_write[20]; // 隐式修改寄存器列表
uint8_t regs_write_count; // 隐式修改寄存器计数
uint8_t groups[8]; // 指令所属的指令组列表
uint8_t groups_count; // 指令所属的组数
// 特定于体系结构的信息
union {
cs_x86 x86; // X86架构
cs_arm64 arm64; // ARM64架构
cs_arm arm; // ARM架构
cs_m68k m68k; // M68K架构
cs_mips mips; // MIPS架构
cs_ppc ppc; // PowerPC架构
cs_sparc sparc; // Sparc架构
cs_sysz sysz; // SystemZ架构
cs_xcore xcore; // XCore架构
cs_tms320c64x tms320c64x; // TMS320C64x架构
cs_m680x m680x; // M680X架构
cs_evm evm; // Ethereum架构
};
};
cs_insn (指令信息)
struct cs_insn {
unsigned int id; // 指令ID(数字ID)
uint64_t address; // 指令地址(EIP)
uint16_t size; // 指令长度
uint8_t bytes[16]; // 机器码
char mnemonic[CS_MNEMONIC_SIZE]; // 助记符文本
char op_str[160]; // 操作数文本
cs_detail *detail; // 指令细节指针(需CS_OP_DETAIL=CS_OPT_ON)
};
3.5 错误处理
cs_err (错误类型)
enum cs_err {
CS_ERR_OK = 0, // 无错误
CS_ERR_MEM, // 内存不足
CS_ERR_ARCH, // 不支持的架构
CS_ERR_HANDLE, // 句柄不可用
CS_ERR_CSH, // csh参数不可用
CS_ERR_MODE, // 无效的或不支持的模式
CS_ERR_OPTION, // 无效的或不支持的选项
CS_ERR_DETAIL, // 信息不可用(detail选项关闭)
CS_ERR_MEMSETUP, // 动态内存管理未初始化
CS_ERR_VERSION, // 不支持版本(bindings)
CS_ERR_DIET, // 在"diet"引擎中访问不相关的数据
CS_ERR_SKIPDATA, // 在SKIPDATA模式下访问与"数据"指令无关的数据
CS_ERR_X86_ATT, // X86 AT&T语法不支持
CS_ERR_X86_INTEL, // X86 Intel语法不支持
CS_ERR_X86_MASM, // X86 Intel语法不支持
};
4. API分析
4.1 基本API
cs_open
cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle);
- 功能:初始化Capstone引擎
- 参数:
- arch: 架构类型(cs_arch枚举)
- mode: 模式(cs_mode枚举)
- handle: 输出参数,返回引擎句柄
- 返回值:错误码(cs_err)
cs_close
cs_err cs_close(csh *handle);
- 功能:关闭Capstone引擎
- 参数:
- handle: 引擎句柄指针
- 返回值:错误码
cs_option
cs_err cs_option(csh handle, cs_opt_type type, size_t value);
- 功能:设置引擎选项
- 参数:
- handle: 引擎句柄
- type: 选项类型(cs_opt_type枚举)
- value: 选项值
- 返回值:错误码
cs_disasm
size_t cs_disasm(csh handle, const uint8_t *code, size_t code_size, uint64_t address, size_t count, cs_insn **insn);
- 功能:反汇编代码
- 参数:
- handle: 引擎句柄
- code: 要反汇编的代码缓冲区
- code_size: 代码大小
- address: 代码的基地址
- count: 要反汇编的指令数(0表示全部)
- insn: 输出参数,返回反汇编结果
- 返回值:成功反汇编的指令数
cs_free
void cs_free(cs_insn *insn, size_t count);
- 功能:释放cs_disasm分配的内存
- 参数:
- insn: cs_disasm返回的指针
- count: cs_disasm返回的指令数
cs_errno
cs_err cs_errno(csh handle);
- 功能:获取最后一次操作的错误码
- 参数:
- handle: 引擎句柄
- 返回值:错误码
4.2 其他API
cs_reg_name
const char *cs_reg_name(csh handle, unsigned int reg);
- 功能:获取寄存器名称
- 参数:
- handle: 引擎句柄
- reg: 寄存器ID
- 返回值:寄存器名称字符串
cs_insn_name
const char *cs_insn_name(csh handle, unsigned int id);
- 功能:获取指令名称
- 参数:
- handle: 引擎句柄
- id: 指令ID
- 返回值:指令名称字符串
cs_group_name
const char *cs_group_name(csh handle, unsigned int group);
- 功能:获取指令组名称
- 参数:
- handle: 引擎句柄
- group: 组ID
- 返回值:组名称字符串
cs_op_count
size_t cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type);
- 功能:获取指令中特定类型操作数的数量
- 参数:
- handle: 引擎句柄
- insn: 指令指针
- op_type: 操作数类型(cs_op_type枚举)
- 返回值:操作数数量
cs_op_index
int cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type, unsigned int position);
- 功能:获取指令中特定类型操作数的索引
- 参数:
- handle: 引擎句柄
- insn: 指令指针
- op_type: 操作数类型
- position: 位置
- 返回值:操作数索引
5. 使用建议
-
初始化流程:
- 调用
cs_open初始化引擎 - 使用
cs_option配置所需选项 - 调用
cs_disasm进行反汇编 - 使用完毕后调用
cs_free释放资源 - 最后调用
cs_close关闭引擎
- 调用
-
错误处理:
- 每次API调用后检查返回值
- 使用
cs_errno获取详细错误信息
-
性能考虑:
- 对于大量反汇编操作,重用引擎句柄
- 不需要详细分析时关闭
CS_OPT_DETAIL选项
-
多线程安全:
- Capstone引擎本身不是线程安全的
- 多线程环境下应为每个线程创建独立的引擎实例