1*9a0e4156SSadaf Ebrahimi# Capstone-Engine API Documentation 2*9a0e4156SSadaf Ebrahimi 3*9a0e4156SSadaf Ebrahimi| Version | 4.0.2 | 4*9a0e4156SSadaf Ebrahimi| ------- | ----- | 5*9a0e4156SSadaf Ebrahimi 6*9a0e4156SSadaf Ebrahimi**Official API document by [kabeor](https://github.com/kabeor)** 7*9a0e4156SSadaf Ebrahimi 8*9a0e4156SSadaf Ebrahimi[Capstone Engine](https://github.com/capstone-engine/capstone)是一个支持多种硬件架构的二进制反汇编引擎。 9*9a0e4156SSadaf Ebrahimi 10*9a0e4156SSadaf Ebrahimi 11*9a0e4156SSadaf Ebrahimi## 0x0 开发准备 12*9a0e4156SSadaf Ebrahimi 13*9a0e4156SSadaf Ebrahimi Capstone官网: http://www.capstone-engine.org 14*9a0e4156SSadaf Ebrahimi 15*9a0e4156SSadaf Ebrahimi### 自行编译lib和dll方法 16*9a0e4156SSadaf Ebrahimi 17*9a0e4156SSadaf Ebrahimi 源码: https://github.com/capstone-engine/capstone.git 18*9a0e4156SSadaf Ebrahimi 19*9a0e4156SSadaf Ebrahimi git clone下来 20*9a0e4156SSadaf Ebrahimi 文件结构如下: 21*9a0e4156SSadaf Ebrahimi 22*9a0e4156SSadaf Ebrahimi``` 23*9a0e4156SSadaf Ebrahimi . <- 主要引擎core engine + README + 编译文档COMPILE.TXT 等 24*9a0e4156SSadaf Ebrahimi├── arch <- 各语言反编译支持的代码实现 25*9a0e4156SSadaf Ebrahimi│ ├── AArch64 <- ARM64 (aka ARMv8) 引擎 26*9a0e4156SSadaf Ebrahimi│ ├── ARM <- ARM 引擎 27*9a0e4156SSadaf Ebrahimi│ ├── EVM <- Ethereum 引擎 28*9a0e4156SSadaf Ebrahimi│ ├── M680X <- M680X 引擎 29*9a0e4156SSadaf Ebrahimi│ ├── M68K <- M68K 引擎 30*9a0e4156SSadaf Ebrahimi| ├── MOS65XX <- MOS65XX 引擎 31*9a0e4156SSadaf Ebrahimi│ ├── Mips <- Mips 引擎 32*9a0e4156SSadaf Ebrahimi│ ├── PowerPC <- PowerPC 引擎 33*9a0e4156SSadaf Ebrahimi│ ├── Sparc <- Sparc 引擎 34*9a0e4156SSadaf Ebrahimi│ ├── SystemZ <- SystemZ 引擎 35*9a0e4156SSadaf Ebrahimi│ ├── TMS320C64x <- TMS320C64x 引擎 36*9a0e4156SSadaf Ebrahimi│ ├── X86 <- X86 引擎 37*9a0e4156SSadaf Ebrahimi│ └── XCore <- XCore 引擎 38*9a0e4156SSadaf Ebrahimi├── bindings <- 绑定 39*9a0e4156SSadaf Ebrahimi│ ├── java <- Java 绑定 + 测试代码 40*9a0e4156SSadaf Ebrahimi│ ├── ocaml <- Ocaml 绑定 + 测试代码 41*9a0e4156SSadaf Ebrahimi│ ├── powershell <- powershell 绑定 + 测试代码 42*9a0e4156SSadaf Ebrahimi│ ├── python <- python 绑定 + 测试代码 43*9a0e4156SSadaf Ebrahimi│ └── vb6 <- vb6 绑定 + 测试代码 44*9a0e4156SSadaf Ebrahimi├── contrib <- 社区代码 45*9a0e4156SSadaf Ebrahimi├── cstool <- Cstool 检测工具源码 46*9a0e4156SSadaf Ebrahimi├── docs <- 文档,主要是capstone的实现思路 47*9a0e4156SSadaf Ebrahimi├── include <- C头文件 48*9a0e4156SSadaf Ebrahimi├── msvc <- Microsoft Visual Studio 支持(Windows) 49*9a0e4156SSadaf Ebrahimi├── packages <- Linux/OSX/BSD包 50*9a0e4156SSadaf Ebrahimi├── suite <- 项目开发所需工具 51*9a0e4156SSadaf Ebrahimi├── tests <- C语言测试用例 52*9a0e4156SSadaf Ebrahimi├── windows <- Windows 支持(Windows内核驱动编译) 53*9a0e4156SSadaf Ebrahimi├── windowsce <- Windows CE 支持 54*9a0e4156SSadaf Ebrahimi└── xcode <- Xcode 支持 (MacOSX 编译) 55*9a0e4156SSadaf Ebrahimi``` 56*9a0e4156SSadaf Ebrahimi 57*9a0e4156SSadaf Ebrahimi下面演示Windows10使用Visual Studio2019编译 58*9a0e4156SSadaf Ebrahimi 59*9a0e4156SSadaf Ebrahimi复制msvc文件夹到一个比较清爽的位置,内部结构如下: 60*9a0e4156SSadaf Ebrahimi 61*9a0e4156SSadaf Ebrahimi 62*9a0e4156SSadaf Ebrahimi 63*9a0e4156SSadaf EbrahimiVS打开capstone.sln项目文件,解决方案自动载入这些 64*9a0e4156SSadaf Ebrahimi 65*9a0e4156SSadaf Ebrahimi 66*9a0e4156SSadaf Ebrahimi 67*9a0e4156SSadaf Ebrahimi可以看到支持的所有语言都在这里了,如果都需要的话,直接编译就好了,只需要其中几种,则右键解决方案->属性->配置属性 如下 68*9a0e4156SSadaf Ebrahimi 69*9a0e4156SSadaf Ebrahimi 70*9a0e4156SSadaf Ebrahimi 71*9a0e4156SSadaf Ebrahimi生成选项中勾选你需要的支持项即可 72*9a0e4156SSadaf Ebrahimi编译后会在当前文件夹Debug目录下生成capstone.lib静态编译库和capstone.dll动态库这样就可以开始使用Capstone进行开发了 73*9a0e4156SSadaf Ebrahimi 74*9a0e4156SSadaf Ebrahimi如果不想自己编译,官方也提供了官方编译版本 75*9a0e4156SSadaf Ebrahimi 76*9a0e4156SSadaf EbrahimiWin32: https://github.com/capstone-engine/capstone/releases/download/4.0.2/capstone-4.0.2-win32.zip 77*9a0e4156SSadaf Ebrahimi 78*9a0e4156SSadaf EbrahimiWin64: https://github.com/capstone-engine/capstone/releases/download/4.0.2/capstone-4.0.2-win64.zip 79*9a0e4156SSadaf Ebrahimi 80*9a0e4156SSadaf Ebrahimi选x32或x64将影响后面开发的位数 81*9a0e4156SSadaf Ebrahimi 82*9a0e4156SSadaf Ebrahimi 83*9a0e4156SSadaf Ebrahimi 84*9a0e4156SSadaf Ebrahimi### 引擎调用测试 85*9a0e4156SSadaf Ebrahimi 86*9a0e4156SSadaf Ebrahimi新建一个VS项目,将capstone\include\capstone中的头文件以及编译好的lib和dll文件全部拷贝到新建项目的主目录下 87*9a0e4156SSadaf Ebrahimi 88*9a0e4156SSadaf Ebrahimi 89*9a0e4156SSadaf Ebrahimi 90*9a0e4156SSadaf Ebrahimi在VS解决方案中,头文件添加现有项capstone.h,资源文件中添加capstone.lib,重新生成解决方案 91*9a0e4156SSadaf Ebrahimi 92*9a0e4156SSadaf Ebrahimi 93*9a0e4156SSadaf Ebrahimi 94*9a0e4156SSadaf Ebrahimi那么现在来测试一下我们自己的capstone引擎吧 95*9a0e4156SSadaf Ebrahimi 96*9a0e4156SSadaf Ebrahimi主文件写入如下代码 97*9a0e4156SSadaf Ebrahimi 98*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 99*9a0e4156SSadaf Ebrahimi 100*9a0e4156SSadaf Ebrahimi```c++ 101*9a0e4156SSadaf Ebrahimi#include <iostream> 102*9a0e4156SSadaf Ebrahimi#include <stdio.h> 103*9a0e4156SSadaf Ebrahimi#include <cinttypes> 104*9a0e4156SSadaf Ebrahimi#include "capstone.h" 105*9a0e4156SSadaf Ebrahimiusing namespace std; 106*9a0e4156SSadaf Ebrahimi 107*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00" 108*9a0e4156SSadaf Ebrahimi 109*9a0e4156SSadaf Ebrahimiint main(void) 110*9a0e4156SSadaf Ebrahimi{ 111*9a0e4156SSadaf Ebrahimi csh handle; 112*9a0e4156SSadaf Ebrahimi cs_insn* insn; 113*9a0e4156SSadaf Ebrahimi size_t count; 114*9a0e4156SSadaf Ebrahimi 115*9a0e4156SSadaf Ebrahimi if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) { 116*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to initialize engine!\n"); 117*9a0e4156SSadaf Ebrahimi return -1; 118*9a0e4156SSadaf Ebrahimi } 119*9a0e4156SSadaf Ebrahimi 120*9a0e4156SSadaf Ebrahimi count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn); 121*9a0e4156SSadaf Ebrahimi if (count) { 122*9a0e4156SSadaf Ebrahimi size_t j; 123*9a0e4156SSadaf Ebrahimi 124*9a0e4156SSadaf Ebrahimi for (j = 0; j < count; j++) { 125*9a0e4156SSadaf Ebrahimi printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); 126*9a0e4156SSadaf Ebrahimi } 127*9a0e4156SSadaf Ebrahimi 128*9a0e4156SSadaf Ebrahimi cs_free(insn, count); 129*9a0e4156SSadaf Ebrahimi } 130*9a0e4156SSadaf Ebrahimi else 131*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to disassemble given code!\n"); 132*9a0e4156SSadaf Ebrahimi 133*9a0e4156SSadaf Ebrahimi cs_close(&handle); 134*9a0e4156SSadaf Ebrahimi 135*9a0e4156SSadaf Ebrahimi return 0; 136*9a0e4156SSadaf Ebrahimi} 137*9a0e4156SSadaf Ebrahimi``` 138*9a0e4156SSadaf Ebrahimi 139*9a0e4156SSadaf Ebrahimi</details> 140*9a0e4156SSadaf Ebrahimi 141*9a0e4156SSadaf Ebrahimi运行结果 142*9a0e4156SSadaf Ebrahimi 143*9a0e4156SSadaf Ebrahimi 144*9a0e4156SSadaf Ebrahimi 145*9a0e4156SSadaf Ebrahimi 146*9a0e4156SSadaf Ebrahimi## 0x1 数据类型 147*9a0e4156SSadaf Ebrahimi 148*9a0e4156SSadaf Ebrahimi### csh 149*9a0e4156SSadaf Ebrahimi 150*9a0e4156SSadaf Ebrahimi用于生成调用capstone API的句柄 151*9a0e4156SSadaf Ebrahimi 152*9a0e4156SSadaf Ebrahimi```cpp 153*9a0e4156SSadaf Ebrahimisize_t csh 154*9a0e4156SSadaf Ebrahimi``` 155*9a0e4156SSadaf Ebrahimi 156*9a0e4156SSadaf Ebrahimi> 用法: `csh handle;` 157*9a0e4156SSadaf Ebrahimi 158*9a0e4156SSadaf Ebrahimi 159*9a0e4156SSadaf Ebrahimi### cs_arch 160*9a0e4156SSadaf Ebrahimi 161*9a0e4156SSadaf Ebrahimi架构选择 162*9a0e4156SSadaf Ebrahimi 163*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 164*9a0e4156SSadaf Ebrahimi 165*9a0e4156SSadaf Ebrahimi```cpp 166*9a0e4156SSadaf Ebrahimi enum cs_arch { 167*9a0e4156SSadaf Ebrahimi CS_ARCH_ARM = 0, ///< ARM 架构 (包括 Thumb, Thumb-2) 168*9a0e4156SSadaf Ebrahimi CS_ARCH_ARM64, ///< ARM-64, 也叫 AArch64 169*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS, ///< Mips 架构 170*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, ///< X86 架构 (包括 x86 & x86-64) 171*9a0e4156SSadaf Ebrahimi CS_ARCH_PPC, ///< PowerPC 架构 172*9a0e4156SSadaf Ebrahimi CS_ARCH_SPARC, ///< Sparc 架构 173*9a0e4156SSadaf Ebrahimi CS_ARCH_SYSZ, ///< SystemZ 架构 174*9a0e4156SSadaf Ebrahimi CS_ARCH_XCORE, ///< XCore 架构 175*9a0e4156SSadaf Ebrahimi CS_ARCH_M68K, ///< 68K 架构 176*9a0e4156SSadaf Ebrahimi CS_ARCH_TMS320C64X, ///< TMS320C64x 架构 177*9a0e4156SSadaf Ebrahimi CS_ARCH_M680X, ///< 680X 架构 178*9a0e4156SSadaf Ebrahimi CS_ARCH_EVM, ///< Ethereum 架构 179*9a0e4156SSadaf Ebrahimi CS_ARCH_MAX, 180*9a0e4156SSadaf Ebrahimi CS_ARCH_ALL = 0xFFFF, // All 架构 - for cs_support() 181*9a0e4156SSadaf Ebrahimi} cs_arch; 182*9a0e4156SSadaf Ebrahimi``` 183*9a0e4156SSadaf Ebrahimi 184*9a0e4156SSadaf Ebrahimi</details> 185*9a0e4156SSadaf Ebrahimi 186*9a0e4156SSadaf Ebrahimi> 用法:API中cs_arch参数填入枚举内容,如API中cs_open(cs_arch arch, cs_mode mode, csh *handle);第一个参数填CS_ARCH_X86则支持X86 架构 187*9a0e4156SSadaf Ebrahimi 188*9a0e4156SSadaf Ebrahimi 189*9a0e4156SSadaf Ebrahimi### cs_mode 190*9a0e4156SSadaf Ebrahimi 191*9a0e4156SSadaf Ebrahimi模式选择 192*9a0e4156SSadaf Ebrahimi 193*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 194*9a0e4156SSadaf Ebrahimi 195*9a0e4156SSadaf Ebrahimi```cpp 196*9a0e4156SSadaf Ebrahimienum cs_mode { 197*9a0e4156SSadaf Ebrahimi CS_MODE_LITTLE_ENDIAN = 0, ///< little-endian 模式 (default 模式) 198*9a0e4156SSadaf Ebrahimi CS_MODE_ARM = 0, ///< 32-bit ARM 199*9a0e4156SSadaf Ebrahimi CS_MODE_16 = 1 << 1, ///< 16-bit 模式 (X86) 200*9a0e4156SSadaf Ebrahimi CS_MODE_32 = 1 << 2, ///< 32-bit 模式 (X86) 201*9a0e4156SSadaf Ebrahimi CS_MODE_64 = 1 << 3, ///< 64-bit 模式 (X86, PPC) 202*9a0e4156SSadaf Ebrahimi CS_MODE_THUMB = 1 << 4, ///< ARM's Thumb 模式, 包括 Thumb-2 203*9a0e4156SSadaf Ebrahimi CS_MODE_MCLASS = 1 << 5, ///< ARM's Cortex-M 系列 204*9a0e4156SSadaf Ebrahimi CS_MODE_V8 = 1 << 6, ///< ARMv8 A32解码方式 205*9a0e4156SSadaf Ebrahimi CS_MODE_MICRO = 1 << 4, ///< MicroMips 模式 (MIPS) 206*9a0e4156SSadaf Ebrahimi CS_MODE_MIPS3 = 1 << 5, ///< Mips III ISA 207*9a0e4156SSadaf Ebrahimi CS_MODE_MIPS32R6 = 1 << 6, ///< Mips32r6 ISA 208*9a0e4156SSadaf Ebrahimi CS_MODE_MIPS2 = 1 << 7, ///< Mips II ISA 209*9a0e4156SSadaf Ebrahimi CS_MODE_V9 = 1 << 4, ///< SparcV9 模式 (Sparc) 210*9a0e4156SSadaf Ebrahimi CS_MODE_QPX = 1 << 4, ///< Quad Processing eXtensions 模式 (PPC) 211*9a0e4156SSadaf Ebrahimi CS_MODE_SPE = 1 << 5, ///< Signal Processing Engine 模式 (PPC) 212*9a0e4156SSadaf Ebrahimi CS_MODE_BOOKE = 1 << 6, ///< Book-E 模式 (PPC) 213*9a0e4156SSadaf Ebrahimi CS_MODE_M68K_000 = 1 << 1, ///< M68K 68000 模式 214*9a0e4156SSadaf Ebrahimi CS_MODE_M68K_010 = 1 << 2, ///< M68K 68010 模式 215*9a0e4156SSadaf Ebrahimi CS_MODE_M68K_020 = 1 << 3, ///< M68K 68020 模式 216*9a0e4156SSadaf Ebrahimi CS_MODE_M68K_030 = 1 << 4, ///< M68K 68030 模式 217*9a0e4156SSadaf Ebrahimi CS_MODE_M68K_040 = 1 << 5, ///< M68K 68040 模式 218*9a0e4156SSadaf Ebrahimi CS_MODE_M68K_060 = 1 << 6, ///< M68K 68060 模式 219*9a0e4156SSadaf Ebrahimi CS_MODE_BIG_ENDIAN = 1 << 31, ///< big-endian 模式 220*9a0e4156SSadaf Ebrahimi CS_MODE_MIPS32 = CS_MODE_32, ///< Mips32 ISA (Mips) 221*9a0e4156SSadaf Ebrahimi CS_MODE_MIPS64 = CS_MODE_64, ///< Mips64 ISA (Mips) 222*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_6301 = 1 << 1, ///< M680X Hitachi 6301,6303 模式 223*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_6309 = 1 << 2, ///< M680X Hitachi 6309 模式 224*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_6800 = 1 << 3, ///< M680X Motorola 6800,6802 模式 225*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_6801 = 1 << 4, ///< M680X Motorola 6801,6803 模式 226*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_6805 = 1 << 5, ///< M680X Motorola/Freescale 6805 模式 227*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_6808 = 1 << 6, ///< M680X Motorola/Freescale/NXP 68HC08 模式 228*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_6809 = 1 << 7, ///< M680X Motorola 6809 模式 229*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_6811 = 1 << 8, ///< M680X Motorola/Freescale/NXP 68HC11 模式 230*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_CPU12 = 1 << 9, ///< M680X Motorola/Freescale/NXP CPU12 231*9a0e4156SSadaf Ebrahimi ///< 用于 M68HC12/HCS12 232*9a0e4156SSadaf Ebrahimi CS_MODE_M680X_HCS08 = 1 << 10, ///< M680X Freescale/NXP HCS08 模式 233*9a0e4156SSadaf Ebrahimi CS_MODE_BPF_CLASSIC = 0, ///< Classic BPF 模式 (默认) 234*9a0e4156SSadaf Ebrahimi CS_MODE_BPF_EXTENDED = 1 << 0, ///< Extended BPF 模式 235*9a0e4156SSadaf Ebrahimi CS_MODE_RISCV32 = 1 << 0, ///< RISCV RV32G 236*9a0e4156SSadaf Ebrahimi CS_MODE_RISCV64 = 1 << 1, ///< RISCV RV64G 237*9a0e4156SSadaf Ebrahimi CS_MODE_RISCVC = 1 << 2, ///< RISCV 压缩指令模式 238*9a0e4156SSadaf Ebrahimi CS_MODE_MOS65XX_6502 = 1 << 1, ///< MOS65XXX MOS 6502 239*9a0e4156SSadaf Ebrahimi CS_MODE_MOS65XX_65C02 = 1 << 2, ///< MOS65XXX WDC 65c02 240*9a0e4156SSadaf Ebrahimi CS_MODE_MOS65XX_W65C02 = 1 << 3, ///< MOS65XXX WDC W65c02 241*9a0e4156SSadaf Ebrahimi CS_MODE_MOS65XX_65816 = 1 << 4, ///< MOS65XXX WDC 65816, 8-bit m/x 242*9a0e4156SSadaf Ebrahimi CS_MODE_MOS65XX_65816_LONG_M = (1 << 5), ///< MOS65XXX WDC 65816, 16-bit m, 8-bit x 243*9a0e4156SSadaf Ebrahimi CS_MODE_MOS65XX_65816_LONG_X = (1 << 6), ///< MOS65XXX WDC 65816, 8-bit m, 16-bit x 244*9a0e4156SSadaf Ebrahimi CS_MODE_MOS65XX_65816_LONG_MX = CS_MODE_MOS65XX_65816_LONG_M | CS_MODE_MOS65XX_65816_LONG_X, 245*9a0e4156SSadaf Ebrahimi} cs_mode; 246*9a0e4156SSadaf Ebrahimi``` 247*9a0e4156SSadaf Ebrahimi 248*9a0e4156SSadaf Ebrahimi</details> 249*9a0e4156SSadaf Ebrahimi 250*9a0e4156SSadaf Ebrahimi> 用法:API中cs_mode参数填入枚举内容,如API中cs_open(cs_arch arch, cs_mode mode, csh *handle);第二个参数填CS_MODE_64则支持X64模式 251*9a0e4156SSadaf Ebrahimi 252*9a0e4156SSadaf Ebrahimi 253*9a0e4156SSadaf Ebrahimi### cs_opt_mem 254*9a0e4156SSadaf Ebrahimi 255*9a0e4156SSadaf Ebrahimi内存操作 256*9a0e4156SSadaf Ebrahimi 257*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 258*9a0e4156SSadaf Ebrahimi 259*9a0e4156SSadaf Ebrahimi```cpp 260*9a0e4156SSadaf Ebrahimistruct cs_opt_mem { 261*9a0e4156SSadaf Ebrahimi cs_malloc_t malloc; 262*9a0e4156SSadaf Ebrahimi cs_calloc_t calloc; 263*9a0e4156SSadaf Ebrahimi cs_realloc_t realloc; 264*9a0e4156SSadaf Ebrahimi cs_free_t free; 265*9a0e4156SSadaf Ebrahimi cs_vsnprintf_t vsnprintf; 266*9a0e4156SSadaf Ebrahimi} cs_opt_mem; 267*9a0e4156SSadaf Ebrahimi``` 268*9a0e4156SSadaf Ebrahimi 269*9a0e4156SSadaf Ebrahimi</details> 270*9a0e4156SSadaf Ebrahimi 271*9a0e4156SSadaf Ebrahimi> 用法:可使用用户自定义的malloc/calloc/realloc/free/vsnprintf()函数,默认使用系统自带malloc(), calloc(), realloc(), free() & vsnprintf() 272*9a0e4156SSadaf Ebrahimi 273*9a0e4156SSadaf Ebrahimi 274*9a0e4156SSadaf Ebrahimi### cs_opt_mnem 275*9a0e4156SSadaf Ebrahimi 276*9a0e4156SSadaf Ebrahimi自定义助记符 277*9a0e4156SSadaf Ebrahimi 278*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 279*9a0e4156SSadaf Ebrahimi 280*9a0e4156SSadaf Ebrahimi```cpp 281*9a0e4156SSadaf Ebrahimistruct cs_opt_mnem { 282*9a0e4156SSadaf Ebrahimi /// 需要自定义的指令ID 283*9a0e4156SSadaf Ebrahimi unsigned int id; 284*9a0e4156SSadaf Ebrahimi /// 自定义的助记符 285*9a0e4156SSadaf Ebrahimi const char *mnemonic; 286*9a0e4156SSadaf Ebrahimi} cs_opt_mnem; 287*9a0e4156SSadaf Ebrahimi``` 288*9a0e4156SSadaf Ebrahimi 289*9a0e4156SSadaf Ebrahimi</details> 290*9a0e4156SSadaf Ebrahimi 291*9a0e4156SSadaf Ebrahimi 292*9a0e4156SSadaf Ebrahimi### cs_opt_type 293*9a0e4156SSadaf Ebrahimi 294*9a0e4156SSadaf Ebrahimi反编译的运行时选项 295*9a0e4156SSadaf Ebrahimi 296*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 297*9a0e4156SSadaf Ebrahimi 298*9a0e4156SSadaf Ebrahimi```cpp 299*9a0e4156SSadaf Ebrahimienum cs_opt_type { 300*9a0e4156SSadaf Ebrahimi CS_OPT_INVALID = 0, ///< 无特殊要求 301*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX, ///< 汇编输出语法 302*9a0e4156SSadaf Ebrahimi CS_OPT_DETAIL, ///< 将指令结构分解为多个细节 303*9a0e4156SSadaf Ebrahimi CS_OPT_MODE, ///< 运行时改变引擎模式 304*9a0e4156SSadaf Ebrahimi CS_OPT_MEM, ///< 用户定义的动态内存相关函数 305*9a0e4156SSadaf Ebrahimi CS_OPT_SKIPDATA, ///< 在反汇编时跳过数据。然后引擎将处于SKIPDATA模式 306*9a0e4156SSadaf Ebrahimi CS_OPT_SKIPDATA_SETUP, ///< 为SKIPDATA选项设置用户定义函数 307*9a0e4156SSadaf Ebrahimi CS_OPT_MNEMONIC, ///<自定义指令助记符 308*9a0e4156SSadaf Ebrahimi CS_OPT_UNSIGNED, ///< 以无符号形式打印立即操作数 309*9a0e4156SSadaf Ebrahimi} cs_opt_type; 310*9a0e4156SSadaf Ebrahimi``` 311*9a0e4156SSadaf Ebrahimi 312*9a0e4156SSadaf Ebrahimi</details> 313*9a0e4156SSadaf Ebrahimi 314*9a0e4156SSadaf Ebrahimi> 用法:API cs_option(csh handle, cs_opt_type type, size_t value);中第二个参数 315*9a0e4156SSadaf Ebrahimi 316*9a0e4156SSadaf Ebrahimi 317*9a0e4156SSadaf Ebrahimi### cs_opt_value 318*9a0e4156SSadaf Ebrahimi 319*9a0e4156SSadaf Ebrahimi运行时选项值(与cs_opt_type关联) 320*9a0e4156SSadaf Ebrahimi 321*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 322*9a0e4156SSadaf Ebrahimi 323*9a0e4156SSadaf Ebrahimi```cpp 324*9a0e4156SSadaf Ebrahimienum cs_opt_value { 325*9a0e4156SSadaf Ebrahimi CS_OPT_OFF = 0, ///< 关闭一个选项 - 默认为CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED. 326*9a0e4156SSadaf Ebrahimi CS_OPT_ON = 3, ///< 打开一个选项 (CS_OPT_DETAIL, CS_OPT_SKIPDATA). 327*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX_DEFAULT = 0, ///< 默认asm语法 (CS_OPT_SYNTAX). 328*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX_INTEL, ///< X86 Intel asm语法 - 默认开启 X86 (CS_OPT_SYNTAX). 329*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX_ATT, ///< X86 ATT 汇编语法 (CS_OPT_SYNTAX). 330*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX_NOREGNAME, ///< 只打印寄存器名和编号 (CS_OPT_SYNTAX) 331*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX_MASM, ///< X86 Intel Masm 语法 (CS_OPT_SYNTAX). 332*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX_MOTOROLA, ///< MOS65XX 用 $ 作为hex头 333*9a0e4156SSadaf Ebrahimi} cs_opt_value; 334*9a0e4156SSadaf Ebrahimi``` 335*9a0e4156SSadaf Ebrahimi 336*9a0e4156SSadaf Ebrahimi</details> 337*9a0e4156SSadaf Ebrahimi 338*9a0e4156SSadaf Ebrahimi> 用法:API cs_option(csh handle, cs_opt_type type, size_t value);中第三个参数 339*9a0e4156SSadaf Ebrahimi 340*9a0e4156SSadaf Ebrahimi 341*9a0e4156SSadaf Ebrahimi### cs_op_type 342*9a0e4156SSadaf Ebrahimi 343*9a0e4156SSadaf Ebrahimi通用指令操作数类型,在所有架构中保持一致 344*9a0e4156SSadaf Ebrahimi 345*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 346*9a0e4156SSadaf Ebrahimi 347*9a0e4156SSadaf Ebrahimi```cpp 348*9a0e4156SSadaf Ebrahimienum cs_op_type { 349*9a0e4156SSadaf Ebrahimi CS_OP_INVALID = 0, ///< 未初始化/无效的操作数 350*9a0e4156SSadaf Ebrahimi CS_OP_REG, ///< 寄存器操作数 351*9a0e4156SSadaf Ebrahimi CS_OP_IMM, ///< 立即操作数 352*9a0e4156SSadaf Ebrahimi CS_OP_MEM, ///< 内存操作数 353*9a0e4156SSadaf Ebrahimi CS_OP_FP, ///< 浮点数 354*9a0e4156SSadaf Ebrahimi} cs_op_type; 355*9a0e4156SSadaf Ebrahimi``` 356*9a0e4156SSadaf Ebrahimi 357*9a0e4156SSadaf Ebrahimi</details> 358*9a0e4156SSadaf Ebrahimi 359*9a0e4156SSadaf Ebrahimi> 目前开放的API中未调用 360*9a0e4156SSadaf Ebrahimi 361*9a0e4156SSadaf Ebrahimi 362*9a0e4156SSadaf Ebrahimi### cs_ac_type 363*9a0e4156SSadaf Ebrahimi 364*9a0e4156SSadaf Ebrahimi通用指令操作数访问类型,在所有架构中保持一致 365*9a0e4156SSadaf Ebrahimi可以组合访问类型,例如:CS_AC_READ | CS_AC_WRITE 366*9a0e4156SSadaf Ebrahimi 367*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 368*9a0e4156SSadaf Ebrahimi 369*9a0e4156SSadaf Ebrahimi```cpp 370*9a0e4156SSadaf Ebrahimienum cs_ac_type { 371*9a0e4156SSadaf Ebrahimi CS_AC_INVALID = 0, ///< 未初始化/无效的访问类型 372*9a0e4156SSadaf Ebrahimi CS_AC_READ = 1 << 0, ///< 操作数从内存或寄存器中读取 373*9a0e4156SSadaf Ebrahimi CS_AC_WRITE = 1 << 1, ///< 操作数从内存或寄存器中写入 374*9a0e4156SSadaf Ebrahimi} cs_ac_type; 375*9a0e4156SSadaf Ebrahimi``` 376*9a0e4156SSadaf Ebrahimi 377*9a0e4156SSadaf Ebrahimi</details> 378*9a0e4156SSadaf Ebrahimi 379*9a0e4156SSadaf Ebrahimi> 目前开放的API中未调用 380*9a0e4156SSadaf Ebrahimi 381*9a0e4156SSadaf Ebrahimi 382*9a0e4156SSadaf Ebrahimi### cs_group_type 383*9a0e4156SSadaf Ebrahimi 384*9a0e4156SSadaf Ebrahimi公共指令组,在所有架构中保持一致 385*9a0e4156SSadaf Ebrahimi 386*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 387*9a0e4156SSadaf Ebrahimi 388*9a0e4156SSadaf Ebrahimi```cpp 389*9a0e4156SSadaf Ebrahimics_group_type { 390*9a0e4156SSadaf Ebrahimi CS_GRP_INVALID = 0, ///< 未初始化/无效指令组 391*9a0e4156SSadaf Ebrahimi CS_GRP_JUMP, ///< 所有跳转指令(条件跳转+直接跳转+间接跳转) 392*9a0e4156SSadaf Ebrahimi CS_GRP_CALL, ///< 所有调用指令 393*9a0e4156SSadaf Ebrahimi CS_GRP_RET, ///< 所有返回指令 394*9a0e4156SSadaf Ebrahimi CS_GRP_INT, ///< 所有中断指令(int+syscall) 395*9a0e4156SSadaf Ebrahimi CS_GRP_IRET, ///< 所有中断返回指令 396*9a0e4156SSadaf Ebrahimi CS_GRP_PRIVILEGE, ///< 所有特权指令 397*9a0e4156SSadaf Ebrahimi CS_GRP_BRANCH_RELATIVE, ///< 所有相关分支指令 398*9a0e4156SSadaf Ebrahimi} cs_group_type; 399*9a0e4156SSadaf Ebrahimi``` 400*9a0e4156SSadaf Ebrahimi 401*9a0e4156SSadaf Ebrahimi</details> 402*9a0e4156SSadaf Ebrahimi 403*9a0e4156SSadaf Ebrahimi> 目前开放的API中未调用 404*9a0e4156SSadaf Ebrahimi 405*9a0e4156SSadaf Ebrahimi 406*9a0e4156SSadaf Ebrahimi### cs_opt_skipdata 407*9a0e4156SSadaf Ebrahimi 408*9a0e4156SSadaf Ebrahimi用户自定义设置SKIPDATA选项 409*9a0e4156SSadaf Ebrahimi 410*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 411*9a0e4156SSadaf Ebrahimi 412*9a0e4156SSadaf Ebrahimi```cpp 413*9a0e4156SSadaf Ebrahimistruct cs_opt_skipdata { 414*9a0e4156SSadaf Ebrahimi /// Capstone认为要跳过的数据是特殊的“指令” 415*9a0e4156SSadaf Ebrahimi /// 用户可以在这里指定该指令的“助记符”字符串 416*9a0e4156SSadaf Ebrahimi /// 默认情况下(@mnemonic为NULL), Capstone使用“.byte” 417*9a0e4156SSadaf Ebrahimi const char *mnemonic; 418*9a0e4156SSadaf Ebrahimi 419*9a0e4156SSadaf Ebrahimi /// 用户定义的回调函数,当Capstone命中数据时调用 420*9a0e4156SSadaf Ebrahimi /// 如果这个回调返回的值是正数(>0),Capstone将跳过这个字节数并继续。如果回调返回0,Capstone将停止反汇编并立即从cs_disasm()返回 421*9a0e4156SSadaf Ebrahimi /// 注意:如果这个回调指针为空,Capstone会根据架构跳过一些字节,如下所示: 422*9a0e4156SSadaf Ebrahimi /// Arm: 2 bytes (Thumb mode) or 4 bytes. 423*9a0e4156SSadaf Ebrahimi /// Arm64: 4 bytes. 424*9a0e4156SSadaf Ebrahimi /// Mips: 4 bytes. 425*9a0e4156SSadaf Ebrahimi /// M680x: 1 byte. 426*9a0e4156SSadaf Ebrahimi /// PowerPC: 4 bytes. 427*9a0e4156SSadaf Ebrahimi /// Sparc: 4 bytes. 428*9a0e4156SSadaf Ebrahimi /// SystemZ: 2 bytes. 429*9a0e4156SSadaf Ebrahimi /// X86: 1 bytes. 430*9a0e4156SSadaf Ebrahimi /// XCore: 2 bytes. 431*9a0e4156SSadaf Ebrahimi /// EVM: 1 bytes. 432*9a0e4156SSadaf Ebrahimi /// RISCV: 4 bytes. 433*9a0e4156SSadaf Ebrahimi /// WASM: 1 bytes. 434*9a0e4156SSadaf Ebrahimi /// MOS65XX: 1 bytes. 435*9a0e4156SSadaf Ebrahimi /// BPF: 8 bytes. 436*9a0e4156SSadaf Ebrahimi cs_skipdata_cb_t callback; // 默认值为 NULL 437*9a0e4156SSadaf Ebrahimi 438*9a0e4156SSadaf Ebrahimi /// 用户自定义数据将被传递给@callback函数指针 439*9a0e4156SSadaf Ebrahimi void *user_data; 440*9a0e4156SSadaf Ebrahimi} cs_opt_skipdata; 441*9a0e4156SSadaf Ebrahimi``` 442*9a0e4156SSadaf Ebrahimi 443*9a0e4156SSadaf Ebrahimi</details> 444*9a0e4156SSadaf Ebrahimi 445*9a0e4156SSadaf Ebrahimi> 目前开放的API中未调用 446*9a0e4156SSadaf Ebrahimi 447*9a0e4156SSadaf Ebrahimi 448*9a0e4156SSadaf Ebrahimi### cs_detail 449*9a0e4156SSadaf Ebrahimi 450*9a0e4156SSadaf Ebrahimi注意:只有当CS_OPT_DETAIL = CS_OPT_ON时,cs_detail中的所有信息才可用 451*9a0e4156SSadaf Ebrahimi 452*9a0e4156SSadaf Ebrahimi在arch/ARCH/ARCHDisassembler.c的ARCH_getInstruction中初始化为memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH)) 453*9a0e4156SSadaf Ebrahimi 454*9a0e4156SSadaf Ebrahimi如果cs_detail发生了变化,特别是在union之后添加了字段,那么相应地更新arch/ arch/ archdisassembly.c 455*9a0e4156SSadaf Ebrahimi 456*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 457*9a0e4156SSadaf Ebrahimi 458*9a0e4156SSadaf Ebrahimi```cpp 459*9a0e4156SSadaf Ebrahimistruct cs_detail { 460*9a0e4156SSadaf Ebrahimi uint16_t regs_read[16]; ///< 这个参数读取隐式寄存器列表 461*9a0e4156SSadaf Ebrahimi uint8_t regs_read_count; ///< 这个参数读取隐式寄存器计数 462*9a0e4156SSadaf Ebrahimi 463*9a0e4156SSadaf Ebrahimi uint16_t regs_write[20]; ///< 这个参数修改隐式寄存器列表 464*9a0e4156SSadaf Ebrahimi uint8_t regs_write_count; ///< 这个参数修改隐式寄存器计数 465*9a0e4156SSadaf Ebrahimi 466*9a0e4156SSadaf Ebrahimi uint8_t groups[8]; ///< 此指令所属的指令组的列表 467*9a0e4156SSadaf Ebrahimi uint8_t groups_count; ///< 此指令所属的组的数 468*9a0e4156SSadaf Ebrahimi 469*9a0e4156SSadaf Ebrahimi /// 特定于体系结构的信息 470*9a0e4156SSadaf Ebrahimi union { 471*9a0e4156SSadaf Ebrahimi cs_x86 x86; ///< X86 架构, 包括 16-bit, 32-bit & 64-bit 模式 472*9a0e4156SSadaf Ebrahimi cs_arm64 arm64; ///< ARM64 架构 (aka AArch64) 473*9a0e4156SSadaf Ebrahimi cs_arm arm; ///< ARM 架构 (包括 Thumb/Thumb2) 474*9a0e4156SSadaf Ebrahimi cs_m68k m68k; ///< M68K 架构 475*9a0e4156SSadaf Ebrahimi cs_mips mips; ///< MIPS 架构 476*9a0e4156SSadaf Ebrahimi cs_ppc ppc; ///< PowerPC 架构 477*9a0e4156SSadaf Ebrahimi cs_sparc sparc; ///< Sparc 架构 478*9a0e4156SSadaf Ebrahimi cs_sysz sysz; ///< SystemZ 架构 479*9a0e4156SSadaf Ebrahimi cs_xcore xcore; ///< XCore 架构 480*9a0e4156SSadaf Ebrahimi cs_tms320c64x tms320c64x; ///< TMS320C64x 架构 481*9a0e4156SSadaf Ebrahimi cs_m680x m680x; ///< M680X 架构 482*9a0e4156SSadaf Ebrahimi cs_evm evm; ///< Ethereum 架构 483*9a0e4156SSadaf Ebrahimi cs_mos65xx mos65xx; ///< MOS65XX 架构 (包含 MOS6502) 484*9a0e4156SSadaf Ebrahimi cs_wasm wasm; ///< Web Assembly 架构 485*9a0e4156SSadaf Ebrahimi cs_bpf bpf; ///< Berkeley Packet Filter 架构 (包含 eBPF) 486*9a0e4156SSadaf Ebrahimi cs_riscv riscv; ///< RISCV 架构 487*9a0e4156SSadaf Ebrahimi }; 488*9a0e4156SSadaf Ebrahimi} cs_detail; 489*9a0e4156SSadaf Ebrahimi``` 490*9a0e4156SSadaf Ebrahimi 491*9a0e4156SSadaf Ebrahimi</details> 492*9a0e4156SSadaf Ebrahimi 493*9a0e4156SSadaf Ebrahimi 494*9a0e4156SSadaf Ebrahimi### cs_insn 495*9a0e4156SSadaf Ebrahimi 496*9a0e4156SSadaf Ebrahimi指令的详细信息 497*9a0e4156SSadaf Ebrahimi 498*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 499*9a0e4156SSadaf Ebrahimi 500*9a0e4156SSadaf Ebrahimi```cpp 501*9a0e4156SSadaf Ebrahimistruct cs_insn { 502*9a0e4156SSadaf Ebrahimi /// 指令ID(基本上是一个用于指令助记符的数字ID) 503*9a0e4156SSadaf Ebrahimi /// 应在相应架构的头文件中查找'[ARCH]_insn' enum中的指令id,如ARM.h中的'arm_insn'代表ARM, X86.h中的'x86_insn'代表X86等… 504*9a0e4156SSadaf Ebrahimi /// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息 505*9a0e4156SSadaf Ebrahimi /// 注意:在Skipdata模式下,这个id字段的“data”指令为0 506*9a0e4156SSadaf Ebrahimi unsigned int id; 507*9a0e4156SSadaf Ebrahimi 508*9a0e4156SSadaf Ebrahimi /// 指令地址 (EIP) 509*9a0e4156SSadaf Ebrahimi /// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息 510*9a0e4156SSadaf Ebrahimi uint64_t address; 511*9a0e4156SSadaf Ebrahimi 512*9a0e4156SSadaf Ebrahimi /// 指令长度 513*9a0e4156SSadaf Ebrahimi /// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息 514*9a0e4156SSadaf Ebrahimi uint16_t size; 515*9a0e4156SSadaf Ebrahimi 516*9a0e4156SSadaf Ebrahimi /// 此指令的机器码,其字节数由上面的@size表示 517*9a0e4156SSadaf Ebrahimi /// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息 518*9a0e4156SSadaf Ebrahimi uint8_t bytes[24]; 519*9a0e4156SSadaf Ebrahimi 520*9a0e4156SSadaf Ebrahimi /// 指令的Ascii文本助记符 521*9a0e4156SSadaf Ebrahimi /// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息 522*9a0e4156SSadaf Ebrahimi char mnemonic[CS_MNEMONIC_SIZE]; 523*9a0e4156SSadaf Ebrahimi 524*9a0e4156SSadaf Ebrahimi /// 指令操作数的Ascii文本 525*9a0e4156SSadaf Ebrahimi /// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息 526*9a0e4156SSadaf Ebrahimi char op_str[160]; 527*9a0e4156SSadaf Ebrahimi 528*9a0e4156SSadaf Ebrahimi /// cs_detail指针 529*9a0e4156SSadaf Ebrahimi /// 注意:只有同时满足以下两个要求时,detail指针才有效: 530*9a0e4156SSadaf Ebrahimi /// (1) CS_OP_DETAIL = CS_OPT_ON 531*9a0e4156SSadaf Ebrahimi /// (2) 引擎未处于Skipdata模式(CS_OP_SKIPDATA选项设置为CS_OPT_ON) 532*9a0e4156SSadaf Ebrahimi /// 533*9a0e4156SSadaf Ebrahimi /// 注意2:当处于Skipdata模式或detail模式关闭时,即使这个指针不是NULL,它的内容仍然是不相关的。 534*9a0e4156SSadaf Ebrahimi cs_detail *detail; 535*9a0e4156SSadaf Ebrahimi} cs_insn; 536*9a0e4156SSadaf Ebrahimi``` 537*9a0e4156SSadaf Ebrahimi 538*9a0e4156SSadaf Ebrahimi</details> 539*9a0e4156SSadaf Ebrahimi 540*9a0e4156SSadaf Ebrahimi 541*9a0e4156SSadaf Ebrahimi### cs_err 542*9a0e4156SSadaf Ebrahimi 543*9a0e4156SSadaf EbrahimiCapstone API遇到的各类型的错误时cs_errno()的返回值 544*9a0e4156SSadaf Ebrahimi 545*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary> 546*9a0e4156SSadaf Ebrahimi 547*9a0e4156SSadaf Ebrahimi```cpp 548*9a0e4156SSadaf Ebrahimitypedef enum cs_err { 549*9a0e4156SSadaf Ebrahimi CS_ERR_OK = 0, ///< 无错误 550*9a0e4156SSadaf Ebrahimi CS_ERR_MEM, ///< 内存不足: cs_open(), cs_disasm(), cs_disasm_iter() 551*9a0e4156SSadaf Ebrahimi CS_ERR_ARCH, ///< 不支持的架构: cs_open() 552*9a0e4156SSadaf Ebrahimi CS_ERR_HANDLE, ///<句柄不可用: cs_op_count(), cs_op_index() 553*9a0e4156SSadaf Ebrahimi CS_ERR_CSH, ///< csh参数不可用: cs_close(), cs_errno(), cs_option() 554*9a0e4156SSadaf Ebrahimi CS_ERR_MODE, ///< 无效的或不支持的模式: cs_open() 555*9a0e4156SSadaf Ebrahimi CS_ERR_OPTION, ///< 无效的或不支持的选项: cs_option() 556*9a0e4156SSadaf Ebrahimi CS_ERR_DETAIL, ///< 信息不可用,因为detail选项是关闭的 557*9a0e4156SSadaf Ebrahimi CS_ERR_MEMSETUP, ///< 动态内存管理未初始化(见 CS_OPT_MEM) 558*9a0e4156SSadaf Ebrahimi CS_ERR_VERSION, ///< 不支持版本 (bindings) 559*9a0e4156SSadaf Ebrahimi CS_ERR_DIET, ///< 在“diet”引擎中访问不相关的数据 560*9a0e4156SSadaf Ebrahimi CS_ERR_SKIPDATA, ///< 在SKIPDATA模式下访问与“数据”指令无关的数据 561*9a0e4156SSadaf Ebrahimi CS_ERR_X86_ATT, ///< X86 AT&T 语法不支持(在编译时退出) 562*9a0e4156SSadaf Ebrahimi CS_ERR_X86_INTEL, ///< X86 Intel 语法不支持(在编译时退出) 563*9a0e4156SSadaf Ebrahimi CS_ERR_X86_MASM, ///< X86 Intel 语法不支持(在编译时退出) 564*9a0e4156SSadaf Ebrahimi} cs_err; 565*9a0e4156SSadaf Ebrahimi``` 566*9a0e4156SSadaf Ebrahimi 567*9a0e4156SSadaf Ebrahimi</details> 568*9a0e4156SSadaf Ebrahimi 569*9a0e4156SSadaf Ebrahimi 570*9a0e4156SSadaf Ebrahimi## 0x2 API 571*9a0e4156SSadaf Ebrahimi 572*9a0e4156SSadaf Ebrahimi### cs_version 573*9a0e4156SSadaf Ebrahimi 574*9a0e4156SSadaf Ebrahimi`unsigned int CAPSTONE_API cs_version(int *major, int *minor);` 575*9a0e4156SSadaf Ebrahimi 576*9a0e4156SSadaf Ebrahimi用来输出capstone版本号 577*9a0e4156SSadaf Ebrahimi 578*9a0e4156SSadaf Ebrahimi``` 579*9a0e4156SSadaf Ebrahimimajor: API主版本 580*9a0e4156SSadaf Ebrahimiminor: API次版本 581*9a0e4156SSadaf Ebrahimireturn: 返回主次版本的16进制,如4.0版本返回 0x0400 582*9a0e4156SSadaf Ebrahimi``` 583*9a0e4156SSadaf Ebrahimi 584*9a0e4156SSadaf Ebrahimi该版本定义于cs.c中,编译后不可更改,不接受自定义版本 585*9a0e4156SSadaf Ebrahimi 586*9a0e4156SSadaf Ebrahimi 587*9a0e4156SSadaf Ebrahimi 588*9a0e4156SSadaf Ebrahimi 589*9a0e4156SSadaf Ebrahimi 590*9a0e4156SSadaf Ebrahimi 591*9a0e4156SSadaf Ebrahimi<details><summary> 示例1 </summary> 592*9a0e4156SSadaf Ebrahimi 593*9a0e4156SSadaf Ebrahimi```c 594*9a0e4156SSadaf Ebrahimi#include <stdio.h> 595*9a0e4156SSadaf Ebrahimi#include <stdlib.h> 596*9a0e4156SSadaf Ebrahimi 597*9a0e4156SSadaf Ebrahimi#include "platform.h" 598*9a0e4156SSadaf Ebrahimi#include "capstone.h" 599*9a0e4156SSadaf Ebrahimi 600*9a0e4156SSadaf Ebrahimistatic int test() 601*9a0e4156SSadaf Ebrahimi{ 602*9a0e4156SSadaf Ebrahimi return cs_version(NULL, NULL); 603*9a0e4156SSadaf Ebrahimi} 604*9a0e4156SSadaf Ebrahimi 605*9a0e4156SSadaf Ebrahimiint main() 606*9a0e4156SSadaf Ebrahimi{ 607*9a0e4156SSadaf Ebrahimi int version = test(); 608*9a0e4156SSadaf Ebrahimi printf("%X", version); 609*9a0e4156SSadaf Ebrahimi return 0; 610*9a0e4156SSadaf Ebrahimi} 611*9a0e4156SSadaf Ebrahimi``` 612*9a0e4156SSadaf Ebrahimi 613*9a0e4156SSadaf Ebrahimi</details> 614*9a0e4156SSadaf Ebrahimi 615*9a0e4156SSadaf Ebrahimi 616*9a0e4156SSadaf Ebrahimi 617*9a0e4156SSadaf Ebrahimi 618*9a0e4156SSadaf Ebrahimi<details><summary> 示例2,强行修改版本 </summary> 619*9a0e4156SSadaf Ebrahimi 620*9a0e4156SSadaf Ebrahimi```cpp 621*9a0e4156SSadaf Ebrahimi#include <stdio.h> 622*9a0e4156SSadaf Ebrahimi#include <stdlib.h> 623*9a0e4156SSadaf Ebrahimi 624*9a0e4156SSadaf Ebrahimi#include "platform.h" 625*9a0e4156SSadaf Ebrahimi#include "capstone.h" 626*9a0e4156SSadaf Ebrahimi 627*9a0e4156SSadaf Ebrahimistatic int test() 628*9a0e4156SSadaf Ebrahimi{ 629*9a0e4156SSadaf Ebrahimi int ma[] = { 5 }; 630*9a0e4156SSadaf Ebrahimi int mi[] = { 6 }; 631*9a0e4156SSadaf Ebrahimi 632*9a0e4156SSadaf Ebrahimi return cs_version(ma, mi); 633*9a0e4156SSadaf Ebrahimi} 634*9a0e4156SSadaf Ebrahimi 635*9a0e4156SSadaf Ebrahimiint main() 636*9a0e4156SSadaf Ebrahimi{ 637*9a0e4156SSadaf Ebrahimi int version = test(); 638*9a0e4156SSadaf Ebrahimi printf("%X", version); 639*9a0e4156SSadaf Ebrahimi return 0; 640*9a0e4156SSadaf Ebrahimi} 641*9a0e4156SSadaf Ebrahimi``` 642*9a0e4156SSadaf Ebrahimi 643*9a0e4156SSadaf Ebrahimi</details> 644*9a0e4156SSadaf Ebrahimi 645*9a0e4156SSadaf Ebrahimi 646*9a0e4156SSadaf Ebrahimi 647*9a0e4156SSadaf Ebrahimi可见并不能改变 648*9a0e4156SSadaf Ebrahimi 649*9a0e4156SSadaf Ebrahimi### cs_support 650*9a0e4156SSadaf Ebrahimi 651*9a0e4156SSadaf Ebrahimi`bool CAPSTONE_API cs_support(int query);` 652*9a0e4156SSadaf Ebrahimi 653*9a0e4156SSadaf Ebrahimi用来检查capstone库是否支持参数输入的架构或处于某编译选项 654*9a0e4156SSadaf Ebrahimi 655*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 656*9a0e4156SSadaf Ebrahimi 657*9a0e4156SSadaf Ebrahimi 658*9a0e4156SSadaf Ebrahimi```cpp 659*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_support(int query) 660*9a0e4156SSadaf Ebrahimi{ 661*9a0e4156SSadaf Ebrahimi if (query == CS_ARCH_ALL) 662*9a0e4156SSadaf Ebrahimi return all_arch == ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM64) | 663*9a0e4156SSadaf Ebrahimi (1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) | 664*9a0e4156SSadaf Ebrahimi (1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) | 665*9a0e4156SSadaf Ebrahimi (1 << CS_ARCH_SYSZ) | (1 << CS_ARCH_XCORE) | 666*9a0e4156SSadaf Ebrahimi (1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) | 667*9a0e4156SSadaf Ebrahimi (1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM)); 668*9a0e4156SSadaf Ebrahimi 669*9a0e4156SSadaf Ebrahimi if ((unsigned int)query < CS_ARCH_MAX) 670*9a0e4156SSadaf Ebrahimi return all_arch & (1 << query); 671*9a0e4156SSadaf Ebrahimi 672*9a0e4156SSadaf Ebrahimi if (query == CS_SUPPORT_DIET) { 673*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET 674*9a0e4156SSadaf Ebrahimi return true; 675*9a0e4156SSadaf Ebrahimi#else 676*9a0e4156SSadaf Ebrahimi return false; 677*9a0e4156SSadaf Ebrahimi#endif 678*9a0e4156SSadaf Ebrahimi } 679*9a0e4156SSadaf Ebrahimi 680*9a0e4156SSadaf Ebrahimi if (query == CS_SUPPORT_X86_REDUCE) { 681*9a0e4156SSadaf Ebrahimi#if defined(CAPSTONE_HAS_X86) && defined(CAPSTONE_X86_REDUCE) 682*9a0e4156SSadaf Ebrahimi return true; 683*9a0e4156SSadaf Ebrahimi#else 684*9a0e4156SSadaf Ebrahimi return false; 685*9a0e4156SSadaf Ebrahimi#endif 686*9a0e4156SSadaf Ebrahimi } 687*9a0e4156SSadaf Ebrahimi 688*9a0e4156SSadaf Ebrahimi // unsupported query 689*9a0e4156SSadaf Ebrahimi return false; 690*9a0e4156SSadaf Ebrahimi} 691*9a0e4156SSadaf Ebrahimi``` 692*9a0e4156SSadaf Ebrahimi 693*9a0e4156SSadaf Ebrahimi</details> 694*9a0e4156SSadaf Ebrahimi 695*9a0e4156SSadaf Ebrahimi示例1(CS_ARCH_ALL,检查是否支持所有架构) 696*9a0e4156SSadaf Ebrahimi 697*9a0e4156SSadaf Ebrahimi 698*9a0e4156SSadaf Ebrahimi 699*9a0e4156SSadaf Ebrahimi示例2(CS_ARCH_*,检查是否支持指定架构) 700*9a0e4156SSadaf Ebrahimi 701*9a0e4156SSadaf Ebrahimi 702*9a0e4156SSadaf Ebrahimi 703*9a0e4156SSadaf Ebrahimi示例3(检查是否处于DIET编译模式): 704*9a0e4156SSadaf Ebrahimi 705*9a0e4156SSadaf Ebrahimi 706*9a0e4156SSadaf Ebrahimi 707*9a0e4156SSadaf Ebrahimi示例4(检查是否处于X86_REDUCE编译模式) 708*9a0e4156SSadaf Ebrahimi 709*9a0e4156SSadaf Ebrahimi 710*9a0e4156SSadaf Ebrahimi 711*9a0e4156SSadaf Ebrahimi 712*9a0e4156SSadaf Ebrahimi### cs_malloc_t 713*9a0e4156SSadaf Ebrahimi 714*9a0e4156SSadaf Ebrahimi`void* (CAPSTONE_API *cs_malloc_t)(size_t size);` 715*9a0e4156SSadaf Ebrahimi 716*9a0e4156SSadaf Ebrahimics的动态内存分配,用于 717*9a0e4156SSadaf Ebrahimi 718*9a0e4156SSadaf Ebrahimi```cpp 719*9a0e4156SSadaf Ebrahimistruct cs_opt_mem { 720*9a0e4156SSadaf Ebrahimi cs_malloc_t malloc; 721*9a0e4156SSadaf Ebrahimi cs_calloc_t calloc; 722*9a0e4156SSadaf Ebrahimi cs_realloc_t realloc; 723*9a0e4156SSadaf Ebrahimi cs_free_t free; 724*9a0e4156SSadaf Ebrahimi cs_vsnprintf_t vsnprintf; 725*9a0e4156SSadaf Ebrahimi} cs_opt_mem; 726*9a0e4156SSadaf Ebrahimi``` 727*9a0e4156SSadaf Ebrahimi 728*9a0e4156SSadaf Ebrahimi在用户模式下,cs_mem_malloc默认使用系统malloc 729*9a0e4156SSadaf Ebrahimi 730*9a0e4156SSadaf EbrahimiWindows driver模式下,`cs_malloc_t cs_mem_malloc = cs_winkernel_malloc;` 731*9a0e4156SSadaf Ebrahimi 732*9a0e4156SSadaf Ebrahimics_winkernel_malloc定义于\capstone-4.0.1\windows\winkernel_mm.c, 733*9a0e4156SSadaf Ebrahimi 734*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 735*9a0e4156SSadaf Ebrahimi 736*9a0e4156SSadaf Ebrahimi```cpp 737*9a0e4156SSadaf Ebrahimivoid * CAPSTONE_API cs_winkernel_malloc(size_t size) 738*9a0e4156SSadaf Ebrahimi{ 739*9a0e4156SSadaf Ebrahimi // 长度不能分配为0 740*9a0e4156SSadaf Ebrahimi NT_ASSERT(size); 741*9a0e4156SSadaf Ebrahimi 742*9a0e4156SSadaf Ebrahimi // FP; NonPagedPool用于支持 Windows 7 743*9a0e4156SSadaf Ebrahimi#pragma prefast(suppress : 30030) // 分配可执行的POOL_TYPE内存 744*9a0e4156SSadaf Ebrahimi size_t number_of_bytes = 0; 745*9a0e4156SSadaf Ebrahimi CS_WINKERNEL_MEMBLOCK *block = NULL; 746*9a0e4156SSadaf Ebrahimi // 特定的值能造成溢出 747*9a0e4156SSadaf Ebrahimi // 如果value中的和超出或低于类型容量,函数将返回NULL。 748*9a0e4156SSadaf Ebrahimi if (!NT_SUCCESS(RtlSizeTAdd(size, sizeof(CS_WINKERNEL_MEMBLOCK), &number_of_bytes))) { 749*9a0e4156SSadaf Ebrahimi return NULL; 750*9a0e4156SSadaf Ebrahimi } 751*9a0e4156SSadaf Ebrahimi block = (CS_WINKERNEL_MEMBLOCK *)ExAllocatePoolWithTag( 752*9a0e4156SSadaf Ebrahimi NonPagedPool, number_of_bytes, CS_WINKERNEL_POOL_TAG); 753*9a0e4156SSadaf Ebrahimi if (!block) { 754*9a0e4156SSadaf Ebrahimi return NULL; 755*9a0e4156SSadaf Ebrahimi } 756*9a0e4156SSadaf Ebrahimi block->size = size; 757*9a0e4156SSadaf Ebrahimi 758*9a0e4156SSadaf Ebrahimi return block->data; 759*9a0e4156SSadaf Ebrahimi} 760*9a0e4156SSadaf Ebrahimi``` 761*9a0e4156SSadaf Ebrahimi 762*9a0e4156SSadaf Ebrahimi</details> 763*9a0e4156SSadaf Ebrahimi 764*9a0e4156SSadaf Ebrahimi> OSX kernel模式下,`cs_malloc_t cs_mem_malloc = kern_os_malloc;`,这里暂且不探讨。 765*9a0e4156SSadaf Ebrahimi 766*9a0e4156SSadaf Ebrahimi 767*9a0e4156SSadaf Ebrahimi### cs_calloc_t 768*9a0e4156SSadaf Ebrahimi 769*9a0e4156SSadaf Ebrahimi`void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size);` 770*9a0e4156SSadaf Ebrahimi 771*9a0e4156SSadaf Ebrahimics申请内存并初始化 772*9a0e4156SSadaf Ebrahimi 773*9a0e4156SSadaf Ebrahimi用于`struct cs_opt_mem`,定义于cs.c 774*9a0e4156SSadaf Ebrahimi 775*9a0e4156SSadaf Ebrahimi用户模式: `cs_calloc_t cs_mem_calloc = calloc;`,使用系统calloc 776*9a0e4156SSadaf Ebrahimi 777*9a0e4156SSadaf EbrahimiWindows driver模式: `cs_calloc_t cs_mem_calloc = cs_winkernel_calloc;` 778*9a0e4156SSadaf Ebrahimi 779*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 780*9a0e4156SSadaf Ebrahimi 781*9a0e4156SSadaf Ebrahimi```cpp 782*9a0e4156SSadaf Ebrahimivoid * CAPSTONE_API cs_winkernel_calloc(size_t n, size_t size) 783*9a0e4156SSadaf Ebrahimi{ 784*9a0e4156SSadaf Ebrahimi size_t total = n * size; 785*9a0e4156SSadaf Ebrahimi 786*9a0e4156SSadaf Ebrahimi void *new_ptr = cs_winkernel_malloc(total); 787*9a0e4156SSadaf Ebrahimi if (!new_ptr) { 788*9a0e4156SSadaf Ebrahimi return NULL; 789*9a0e4156SSadaf Ebrahimi } 790*9a0e4156SSadaf Ebrahimi 791*9a0e4156SSadaf Ebrahimi return RtlFillMemory(new_ptr, total, 0); 792*9a0e4156SSadaf Ebrahimi} 793*9a0e4156SSadaf Ebrahimi``` 794*9a0e4156SSadaf Ebrahimi 795*9a0e4156SSadaf Ebrahimi</details> 796*9a0e4156SSadaf Ebrahimi 797*9a0e4156SSadaf Ebrahimi> OSX kernel模式: `cs_calloc_t cs_mem_calloc = cs_kern_os_calloc;` 直接调用kern_os_malloc 798*9a0e4156SSadaf Ebrahimi 799*9a0e4156SSadaf Ebrahimi 800*9a0e4156SSadaf Ebrahimi### cs_realloc_t 801*9a0e4156SSadaf Ebrahimi 802*9a0e4156SSadaf Ebrahimi`void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size);` 803*9a0e4156SSadaf Ebrahimi 804*9a0e4156SSadaf Ebrahimics重新分配内存 805*9a0e4156SSadaf Ebrahimi 806*9a0e4156SSadaf Ebrahimi用于`struct cs_opt_mem`,定义于cs.c 807*9a0e4156SSadaf Ebrahimi 808*9a0e4156SSadaf Ebrahimi用户模式: `cs_realloc_t cs_mem_realloc = realloc;`,调用系统realloc 809*9a0e4156SSadaf Ebrahimi 810*9a0e4156SSadaf EbrahimiWindows driver模式: `cs_realloc_t cs_mem_realloc = cs_winkernel_realloc;` 811*9a0e4156SSadaf Ebrahimi 812*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 813*9a0e4156SSadaf Ebrahimi 814*9a0e4156SSadaf Ebrahimi```cpp 815*9a0e4156SSadaf Ebrahimivoid * CAPSTONE_API cs_winkernel_realloc(void *ptr, size_t size) 816*9a0e4156SSadaf Ebrahimi{ 817*9a0e4156SSadaf Ebrahimi void *new_ptr = NULL; 818*9a0e4156SSadaf Ebrahimi size_t current_size = 0; 819*9a0e4156SSadaf Ebrahimi size_t smaller_size = 0; 820*9a0e4156SSadaf Ebrahimi 821*9a0e4156SSadaf Ebrahimi if (!ptr) { 822*9a0e4156SSadaf Ebrahimi return cs_winkernel_malloc(size); 823*9a0e4156SSadaf Ebrahimi } 824*9a0e4156SSadaf Ebrahimi 825*9a0e4156SSadaf Ebrahimi new_ptr = cs_winkernel_malloc(size); 826*9a0e4156SSadaf Ebrahimi if (!new_ptr) { 827*9a0e4156SSadaf Ebrahimi return NULL; 828*9a0e4156SSadaf Ebrahimi } 829*9a0e4156SSadaf Ebrahimi 830*9a0e4156SSadaf Ebrahimi current_size = CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data)->size; 831*9a0e4156SSadaf Ebrahimi smaller_size = (current_size < size) ? current_size : size; 832*9a0e4156SSadaf Ebrahimi RtlCopyMemory(new_ptr, ptr, smaller_size); 833*9a0e4156SSadaf Ebrahimi cs_winkernel_free(ptr); 834*9a0e4156SSadaf Ebrahimi 835*9a0e4156SSadaf Ebrahimi return new_ptr; 836*9a0e4156SSadaf Ebrahimi} 837*9a0e4156SSadaf Ebrahimi``` 838*9a0e4156SSadaf Ebrahimi 839*9a0e4156SSadaf Ebrahimi</details> 840*9a0e4156SSadaf Ebrahimi 841*9a0e4156SSadaf Ebrahimi> OSX kernel模式: `cs_realloc_t cs_mem_realloc = kern_os_realloc;` 842*9a0e4156SSadaf Ebrahimi 843*9a0e4156SSadaf Ebrahimi 844*9a0e4156SSadaf Ebrahimi### cs_free_t 845*9a0e4156SSadaf Ebrahimi 846*9a0e4156SSadaf Ebrahimi`typedef void (CAPSTONE_API *cs_free_t)(void *ptr);` 847*9a0e4156SSadaf Ebrahimi 848*9a0e4156SSadaf Ebrahimics释放内存 849*9a0e4156SSadaf Ebrahimi 850*9a0e4156SSadaf Ebrahimi用于`struct cs_opt_mem`,定义于cs.c 851*9a0e4156SSadaf Ebrahimi 852*9a0e4156SSadaf Ebrahimi用户模式: `cs_free_t cs_mem_free = free;`,调用系统free 853*9a0e4156SSadaf Ebrahimi 854*9a0e4156SSadaf EbrahimiWindows driver模式: `cs_free_t cs_mem_free = cs_winkernel_free;` 855*9a0e4156SSadaf Ebrahimi 856*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 857*9a0e4156SSadaf Ebrahimi 858*9a0e4156SSadaf Ebrahimi```cpp 859*9a0e4156SSadaf Ebrahimivoid CAPSTONE_API cs_winkernel_free(void *ptr) 860*9a0e4156SSadaf Ebrahimi{ 861*9a0e4156SSadaf Ebrahimi if (ptr) { 862*9a0e4156SSadaf Ebrahimi ExFreePoolWithTag(CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data), CS_WINKERNEL_POOL_TAG); 863*9a0e4156SSadaf Ebrahimi } 864*9a0e4156SSadaf Ebrahimi} 865*9a0e4156SSadaf Ebrahimi``` 866*9a0e4156SSadaf Ebrahimi 867*9a0e4156SSadaf Ebrahimi</details> 868*9a0e4156SSadaf Ebrahimi 869*9a0e4156SSadaf Ebrahimi> OSX kernel模式: `cs_free_t cs_mem_free = kern_os_free;` 870*9a0e4156SSadaf Ebrahimi 871*9a0e4156SSadaf Ebrahimi 872*9a0e4156SSadaf Ebrahimi 873*9a0e4156SSadaf Ebrahimi### cs_vsnprintf_t 874*9a0e4156SSadaf Ebrahimi 875*9a0e4156SSadaf Ebrahimi`int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap);` 876*9a0e4156SSadaf Ebrahimi 877*9a0e4156SSadaf Ebrahimi按size大小输出到字符串str中 878*9a0e4156SSadaf Ebrahimi 879*9a0e4156SSadaf Ebrahimi如果系统为wince,将使用_vsnprintf函数 880*9a0e4156SSadaf Ebrahimi 881*9a0e4156SSadaf Ebrahimivsnprintf ()和_vsnprintf()对于驱动程序都是可用的,但是它们有一些不同 882*9a0e4156SSadaf Ebrahimi 883*9a0e4156SSadaf Ebrahimi在需要返回值和设置空终止符时应使用vsnprintf() 884*9a0e4156SSadaf Ebrahimi 885*9a0e4156SSadaf EbrahimiWindows driver模式: `cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf;` 886*9a0e4156SSadaf Ebrahimi 887*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 888*9a0e4156SSadaf Ebrahimi 889*9a0e4156SSadaf Ebrahimi```cpp 890*9a0e4156SSadaf Ebrahimiint CAPSTONE_API cs_winkernel_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) 891*9a0e4156SSadaf Ebrahimi{ 892*9a0e4156SSadaf Ebrahimi int result = _vsnprintf(buffer, count, format, argptr); 893*9a0e4156SSadaf Ebrahimi 894*9a0e4156SSadaf Ebrahimi // _vsnprintf()在字符串被截断时返回-1,在整个字符串被存储但“buffer”末尾没有“\0”时返回“count”。在这两种情况下,都需要手动添加空终止符。 895*9a0e4156SSadaf Ebrahimi if (result == -1 || (size_t)result == count) { 896*9a0e4156SSadaf Ebrahimi buffer[count - 1] = '\0'; 897*9a0e4156SSadaf Ebrahimi } 898*9a0e4156SSadaf Ebrahimi 899*9a0e4156SSadaf Ebrahimi if (result == -1) { 900*9a0e4156SSadaf Ebrahimi // 在返回-1时,函数必须获取并返回一些本来要写入的字符。因此,通过重试使用temp buffer进行相同的转换,这个缓冲区就可能足够大来完成格式化,并且获得很多本应写入的字符。 901*9a0e4156SSadaf Ebrahimi char* tmp = cs_winkernel_malloc(0x1000); 902*9a0e4156SSadaf Ebrahimi if (!tmp) { 903*9a0e4156SSadaf Ebrahimi return result; 904*9a0e4156SSadaf Ebrahimi } 905*9a0e4156SSadaf Ebrahimi 906*9a0e4156SSadaf Ebrahimi result = _vsnprintf(tmp, 0x1000, format, argptr); 907*9a0e4156SSadaf Ebrahimi NT_ASSERT(result != -1); 908*9a0e4156SSadaf Ebrahimi cs_winkernel_free(tmp); 909*9a0e4156SSadaf Ebrahimi } 910*9a0e4156SSadaf Ebrahimi 911*9a0e4156SSadaf Ebrahimi return result; 912*9a0e4156SSadaf Ebrahimi} 913*9a0e4156SSadaf Ebrahimi``` 914*9a0e4156SSadaf Ebrahimi 915*9a0e4156SSadaf Ebrahimi</details> 916*9a0e4156SSadaf Ebrahimi 917*9a0e4156SSadaf Ebrahimi> OSX kernel模式: `cs_vsnprintf_t cs_vsnprintf = vsnprintf;`,使用默认vsnprintf 918*9a0e4156SSadaf Ebrahimi 919*9a0e4156SSadaf Ebrahimi 920*9a0e4156SSadaf Ebrahimi 921*9a0e4156SSadaf Ebrahimi### cs_skipdata_cb_t 922*9a0e4156SSadaf Ebrahimi 923*9a0e4156SSadaf Ebrahimi`size_t (CAPSTONE_API *cs_skipdata_cb_t)(const uint8_t *code, size_t code_size, size_t offset, void *user_data);` 924*9a0e4156SSadaf Ebrahimi 925*9a0e4156SSadaf EbrahimiSKIPDATA选项的用户自定义回调函数。 926*9a0e4156SSadaf Ebrahimi 927*9a0e4156SSadaf Ebrahimi``` 928*9a0e4156SSadaf Ebrahimicode:包含要分解的代码的输入缓冲区。和传递给cs_disasm()的缓冲区相同。 929*9a0e4156SSadaf Ebrahimicode_size:上面的code缓冲区的大小(以字节为单位)。 930*9a0e4156SSadaf Ebrahimioffset:上面提到的输入缓冲区code中当前检查字节的位置。 931*9a0e4156SSadaf Ebrahimiuser_data:用户数据通过cs_opt_skipdata结构中的@user_data字段传递给cs_option()。 932*9a0e4156SSadaf Ebrahimireturn:返回要跳过的字节数,或者0表示立即停止反汇编。 933*9a0e4156SSadaf Ebrahimi``` 934*9a0e4156SSadaf Ebrahimi 935*9a0e4156SSadaf Ebrahimics_skipdata_cb_t在`struct cs_opt_skipdata`中调用 936*9a0e4156SSadaf Ebrahimi 937*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary> 938*9a0e4156SSadaf Ebrahimi 939*9a0e4156SSadaf Ebrahimi```cpp 940*9a0e4156SSadaf Ebrahimi#include <stdio.h> 941*9a0e4156SSadaf Ebrahimi#include <stdlib.h> 942*9a0e4156SSadaf Ebrahimi 943*9a0e4156SSadaf Ebrahimi#include "platform.h" 944*9a0e4156SSadaf Ebrahimi#include "capstone.h" 945*9a0e4156SSadaf Ebrahimi 946*9a0e4156SSadaf Ebrahimistruct platform { 947*9a0e4156SSadaf Ebrahimi cs_arch arch; 948*9a0e4156SSadaf Ebrahimi cs_mode mode; 949*9a0e4156SSadaf Ebrahimi unsigned char* code; 950*9a0e4156SSadaf Ebrahimi size_t size; 951*9a0e4156SSadaf Ebrahimi const char* comment; 952*9a0e4156SSadaf Ebrahimi cs_opt_type opt_type; 953*9a0e4156SSadaf Ebrahimi cs_opt_value opt_value; 954*9a0e4156SSadaf Ebrahimi cs_opt_type opt_skipdata; 955*9a0e4156SSadaf Ebrahimi size_t skipdata; 956*9a0e4156SSadaf Ebrahimi}; 957*9a0e4156SSadaf Ebrahimi 958*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len) //输出机器码 959*9a0e4156SSadaf Ebrahimi{ 960*9a0e4156SSadaf Ebrahimi unsigned char* c; 961*9a0e4156SSadaf Ebrahimi 962*9a0e4156SSadaf Ebrahimi printf("Code: "); 963*9a0e4156SSadaf Ebrahimi for (c = str; c < str + len; c++) { 964*9a0e4156SSadaf Ebrahimi printf("0x%02x ", *c & 0xff); 965*9a0e4156SSadaf Ebrahimi } 966*9a0e4156SSadaf Ebrahimi printf("\n"); 967*9a0e4156SSadaf Ebrahimi} 968*9a0e4156SSadaf Ebrahimi 969*9a0e4156SSadaf Ebrahimistatic void test() 970*9a0e4156SSadaf Ebrahimi{ 971*9a0e4156SSadaf Ebrahimi 972*9a0e4156SSadaf Ebrahimi#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x00\x91\x92" //测试用机器码 973*9a0e4156SSadaf Ebrahimi 974*9a0e4156SSadaf Ebrahimi#define RANDOM_CODE "\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78" 975*9a0e4156SSadaf Ebrahimi 976*9a0e4156SSadaf Ebrahimi cs_opt_skipdata skipdata = { 977*9a0e4156SSadaf Ebrahimi // 把默认 "data" 描述符从 ".byte" 重命名为 "db" 978*9a0e4156SSadaf Ebrahimi "db", 979*9a0e4156SSadaf Ebrahimi }; 980*9a0e4156SSadaf Ebrahimi 981*9a0e4156SSadaf Ebrahimi struct platform platforms[2] = { //以默认描述符和自定义描述符两种方式建立一个数组 982*9a0e4156SSadaf Ebrahimi { 983*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 984*9a0e4156SSadaf Ebrahimi CS_MODE_32, 985*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE32, 986*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE32) - 1, 987*9a0e4156SSadaf Ebrahimi "X86 32 (Intel syntax) - Skip data", 988*9a0e4156SSadaf Ebrahimi }, 989*9a0e4156SSadaf Ebrahimi { 990*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 991*9a0e4156SSadaf Ebrahimi CS_MODE_32, 992*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE32, 993*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE32) - 1, 994*9a0e4156SSadaf Ebrahimi "X86 32 (Intel syntax) - Skip data with custom mnemonic", 995*9a0e4156SSadaf Ebrahimi CS_OPT_INVALID, 996*9a0e4156SSadaf Ebrahimi CS_OPT_OFF, 997*9a0e4156SSadaf Ebrahimi CS_OPT_SKIPDATA_SETUP, 998*9a0e4156SSadaf Ebrahimi (size_t)& skipdata, 999*9a0e4156SSadaf Ebrahimi }, 1000*9a0e4156SSadaf Ebrahimi 1001*9a0e4156SSadaf Ebrahimi }; 1002*9a0e4156SSadaf Ebrahimi 1003*9a0e4156SSadaf Ebrahimi csh handle; //建立capstone句柄 1004*9a0e4156SSadaf Ebrahimi uint64_t address = 0x1000; //设置起始地址 1005*9a0e4156SSadaf Ebrahimi cs_insn* insn; //具体信息结构体 1006*9a0e4156SSadaf Ebrahimi cs_err err; //错误枚举 1007*9a0e4156SSadaf Ebrahimi int i; 1008*9a0e4156SSadaf Ebrahimi size_t count; //成功反汇编行数 1009*9a0e4156SSadaf Ebrahimi 1010*9a0e4156SSadaf Ebrahimi for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) { 1011*9a0e4156SSadaf Ebrahimi printf("****************\n"); 1012*9a0e4156SSadaf Ebrahimi printf("Platform: %s\n", platforms[i].comment); 1013*9a0e4156SSadaf Ebrahimi err = cs_open(platforms[i].arch, platforms[i].mode, &handle); //错误检查 1014*9a0e4156SSadaf Ebrahimi if (err) { 1015*9a0e4156SSadaf Ebrahimi printf("Failed on cs_open() with error returned: %u\n", err); 1016*9a0e4156SSadaf Ebrahimi abort(); 1017*9a0e4156SSadaf Ebrahimi } 1018*9a0e4156SSadaf Ebrahimi 1019*9a0e4156SSadaf Ebrahimi if (platforms[i].opt_type) 1020*9a0e4156SSadaf Ebrahimi cs_option(handle, platforms[i].opt_type, platforms[i].opt_value); 1021*9a0e4156SSadaf Ebrahimi 1022*9a0e4156SSadaf Ebrahimi // 打开SKIPDATA 模式 1023*9a0e4156SSadaf Ebrahimi cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON); 1024*9a0e4156SSadaf Ebrahimi cs_option(handle, platforms[i].opt_skipdata, platforms[i].skipdata); 1025*9a0e4156SSadaf Ebrahimi 1026*9a0e4156SSadaf Ebrahimi count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn); 1027*9a0e4156SSadaf Ebrahimi if (count) { 1028*9a0e4156SSadaf Ebrahimi size_t j; 1029*9a0e4156SSadaf Ebrahimi 1030*9a0e4156SSadaf Ebrahimi print_string_hex(platforms[i].code, platforms[i].size); 1031*9a0e4156SSadaf Ebrahimi printf("Disasm:\n"); 1032*9a0e4156SSadaf Ebrahimi 1033*9a0e4156SSadaf Ebrahimi for (j = 0; j < count; j++) { //输出汇编 1034*9a0e4156SSadaf Ebrahimi printf("0x%" PRIx64 ":\t%s\t\t%s\n", 1035*9a0e4156SSadaf Ebrahimi insn[j].address, insn[j].mnemonic, insn[j].op_str); 1036*9a0e4156SSadaf Ebrahimi } 1037*9a0e4156SSadaf Ebrahimi 1038*9a0e4156SSadaf Ebrahimi // 最后一行代码后打印偏移 1039*9a0e4156SSadaf Ebrahimi printf("0x%" PRIx64 ":\n", insn[j - 1].address + insn[j - 1].size); 1040*9a0e4156SSadaf Ebrahimi 1041*9a0e4156SSadaf Ebrahimi // 释放cs_disasm()申请的内存 1042*9a0e4156SSadaf Ebrahimi cs_free(insn, count); 1043*9a0e4156SSadaf Ebrahimi } 1044*9a0e4156SSadaf Ebrahimi else { 1045*9a0e4156SSadaf Ebrahimi printf("****************\n"); 1046*9a0e4156SSadaf Ebrahimi printf("Platform: %s\n", platforms[i].comment); 1047*9a0e4156SSadaf Ebrahimi print_string_hex(platforms[i].code, platforms[i].size); 1048*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to disasm given code!\n"); 1049*9a0e4156SSadaf Ebrahimi abort(); 1050*9a0e4156SSadaf Ebrahimi } 1051*9a0e4156SSadaf Ebrahimi 1052*9a0e4156SSadaf Ebrahimi printf("\n"); 1053*9a0e4156SSadaf Ebrahimi 1054*9a0e4156SSadaf Ebrahimi cs_close(&handle); 1055*9a0e4156SSadaf Ebrahimi } 1056*9a0e4156SSadaf Ebrahimi} 1057*9a0e4156SSadaf Ebrahimi 1058*9a0e4156SSadaf Ebrahimiint main() 1059*9a0e4156SSadaf Ebrahimi{ 1060*9a0e4156SSadaf Ebrahimi test(); 1061*9a0e4156SSadaf Ebrahimi 1062*9a0e4156SSadaf Ebrahimi return 0; 1063*9a0e4156SSadaf Ebrahimi} 1064*9a0e4156SSadaf Ebrahimi``` 1065*9a0e4156SSadaf Ebrahimi 1066*9a0e4156SSadaf Ebrahimi</details> 1067*9a0e4156SSadaf Ebrahimi 1068*9a0e4156SSadaf Ebrahimi运行结果如下,默认的.byte数据类型被改为db描述符 1069*9a0e4156SSadaf Ebrahimi 1070*9a0e4156SSadaf Ebrahimi 1071*9a0e4156SSadaf Ebrahimi 1072*9a0e4156SSadaf Ebrahimi 1073*9a0e4156SSadaf Ebrahimi 1074*9a0e4156SSadaf Ebrahimi 1075*9a0e4156SSadaf Ebrahimi### cs_open 1076*9a0e4156SSadaf Ebrahimi 1077*9a0e4156SSadaf Ebrahimi`cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle);` 1078*9a0e4156SSadaf Ebrahimi 1079*9a0e4156SSadaf Ebrahimi初始化cs句柄 1080*9a0e4156SSadaf Ebrahimi 1081*9a0e4156SSadaf Ebrahimi``` 1082*9a0e4156SSadaf Ebrahimiarch: 架构类型 (CS_ARCH_*) 1083*9a0e4156SSadaf Ebrahimimode: 硬件模式. CS_MODE_*在cs_mode数据类型中可查 1084*9a0e4156SSadaf Ebrahimihandle: 指向句柄, 返回时更新 1085*9a0e4156SSadaf Ebrahimireturn: 创建成功返回CS_ERR_OK,否则返回cs_err枚举中对应的错误信息 1086*9a0e4156SSadaf Ebrahimi``` 1087*9a0e4156SSadaf Ebrahimi 1088*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 1089*9a0e4156SSadaf Ebrahimi 1090*9a0e4156SSadaf Ebrahimi```cpp 1091*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle) 1092*9a0e4156SSadaf Ebrahimi{ 1093*9a0e4156SSadaf Ebrahimi cs_err err; 1094*9a0e4156SSadaf Ebrahimi struct cs_struct *ud; 1095*9a0e4156SSadaf Ebrahimi if (!cs_mem_malloc || !cs_mem_calloc || !cs_mem_realloc || !cs_mem_free || !cs_vsnprintf) 1096*9a0e4156SSadaf Ebrahimi // Error: 使用cs_open()前, 必须使用cs_option(CS_OPT_MEM)进行动态内存管理的初始化 1097*9a0e4156SSadaf Ebrahimi return CS_ERR_MEMSETUP; 1098*9a0e4156SSadaf Ebrahimi 1099*9a0e4156SSadaf Ebrahimi if (arch < CS_ARCH_MAX && cs_arch_init[arch]) { 1100*9a0e4156SSadaf Ebrahimi // 验证架构是否使用,方式:架构在枚举中且可初始化 1101*9a0e4156SSadaf Ebrahimi if (mode & cs_arch_disallowed_mode_mask[arch]) { 1102*9a0e4156SSadaf Ebrahimi *handle = 0; 1103*9a0e4156SSadaf Ebrahimi return CS_ERR_MODE; 1104*9a0e4156SSadaf Ebrahimi } 1105*9a0e4156SSadaf Ebrahimi 1106*9a0e4156SSadaf Ebrahimi ud = cs_mem_calloc(1, sizeof(*ud)); 1107*9a0e4156SSadaf Ebrahimi if (!ud) { 1108*9a0e4156SSadaf Ebrahimi // 内存不足 1109*9a0e4156SSadaf Ebrahimi return CS_ERR_MEM; 1110*9a0e4156SSadaf Ebrahimi } 1111*9a0e4156SSadaf Ebrahimi 1112*9a0e4156SSadaf Ebrahimi ud->errnum = CS_ERR_OK; 1113*9a0e4156SSadaf Ebrahimi ud->arch = arch; 1114*9a0e4156SSadaf Ebrahimi ud->mode = mode; 1115*9a0e4156SSadaf Ebrahimi // 默认情况指令不打开detail模式 1116*9a0e4156SSadaf Ebrahimi ud->detail = CS_OPT_OFF; 1117*9a0e4156SSadaf Ebrahimi 1118*9a0e4156SSadaf Ebrahimi // 默认skipdata设置 1119*9a0e4156SSadaf Ebrahimi ud->skipdata_setup.mnemonic = SKIPDATA_MNEM; 1120*9a0e4156SSadaf Ebrahimi 1121*9a0e4156SSadaf Ebrahimi err = cs_arch_init[ud->arch](ud); 1122*9a0e4156SSadaf Ebrahimi if (err) { 1123*9a0e4156SSadaf Ebrahimi cs_mem_free(ud); 1124*9a0e4156SSadaf Ebrahimi *handle = 0; 1125*9a0e4156SSadaf Ebrahimi return err; 1126*9a0e4156SSadaf Ebrahimi } 1127*9a0e4156SSadaf Ebrahimi 1128*9a0e4156SSadaf Ebrahimi *handle = (uintptr_t)ud; 1129*9a0e4156SSadaf Ebrahimi 1130*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1131*9a0e4156SSadaf Ebrahimi } else { 1132*9a0e4156SSadaf Ebrahimi *handle = 0; 1133*9a0e4156SSadaf Ebrahimi return CS_ERR_ARCH; 1134*9a0e4156SSadaf Ebrahimi } 1135*9a0e4156SSadaf Ebrahimi} 1136*9a0e4156SSadaf Ebrahimi``` 1137*9a0e4156SSadaf Ebrahimi 1138*9a0e4156SSadaf Ebrahimi其中,cs_struct结构体包含更多细节设定,如下 1139*9a0e4156SSadaf Ebrahimi 1140*9a0e4156SSadaf Ebrahimi```cpp 1141*9a0e4156SSadaf Ebrahimistruct cs_struct { 1142*9a0e4156SSadaf Ebrahimi cs_arch arch; 1143*9a0e4156SSadaf Ebrahimi cs_mode mode; 1144*9a0e4156SSadaf Ebrahimi Printer_t printer; // 打印asm 1145*9a0e4156SSadaf Ebrahimi void *printer_info; // 打印信息 1146*9a0e4156SSadaf Ebrahimi Disasm_t disasm; // 反编译 1147*9a0e4156SSadaf Ebrahimi void *getinsn_info; // 打印辅助信息 1148*9a0e4156SSadaf Ebrahimi GetName_t reg_name; 1149*9a0e4156SSadaf Ebrahimi GetName_t insn_name; 1150*9a0e4156SSadaf Ebrahimi GetName_t group_name; 1151*9a0e4156SSadaf Ebrahimi GetID_t insn_id; 1152*9a0e4156SSadaf Ebrahimi PostPrinter_t post_printer; 1153*9a0e4156SSadaf Ebrahimi cs_err errnum; 1154*9a0e4156SSadaf Ebrahimi ARM_ITStatus ITBlock; // ARM特殊选项 1155*9a0e4156SSadaf Ebrahimi cs_opt_value detail, imm_unsigned; 1156*9a0e4156SSadaf Ebrahimi int syntax; //ARM, Mips & PPC等架构的基本asm语法打印 1157*9a0e4156SSadaf Ebrahimi bool doing_mem; // 在InstPrinter代码中处理内存操作数 1158*9a0e4156SSadaf Ebrahimi unsigned short *insn_cache; //为mapping.c建立缓存索引 1159*9a0e4156SSadaf Ebrahimi GetRegisterName_t get_regname; 1160*9a0e4156SSadaf Ebrahimi bool skipdata; // 如果反编译时要跳过数据,该项设置为True 1161*9a0e4156SSadaf Ebrahimi uint8_t skipdata_size; //要跳过bytes的数量 1162*9a0e4156SSadaf Ebrahimi cs_opt_skipdata skipdata_setup; // 自定义skipdata设置 1163*9a0e4156SSadaf Ebrahimi const uint8_t *regsize_map; //映射register大小 (目前仅支持x86) 1164*9a0e4156SSadaf Ebrahimi GetRegisterAccess_t reg_access; 1165*9a0e4156SSadaf Ebrahimi struct insn_mnem *mnem_list; // 自定义指令助记符的链接list 1166*9a0e4156SSadaf Ebrahimi}; 1167*9a0e4156SSadaf Ebrahimi``` 1168*9a0e4156SSadaf Ebrahimi 1169*9a0e4156SSadaf Ebrahimi</details> 1170*9a0e4156SSadaf Ebrahimi 1171*9a0e4156SSadaf Ebrahimi示例(创建一个x86_64类型的cs句柄) 1172*9a0e4156SSadaf Ebrahimi 1173*9a0e4156SSadaf Ebrahimi`cs_open(CS_ARCH_X86, CS_MODE_64, &handle)` 1174*9a0e4156SSadaf Ebrahimi 1175*9a0e4156SSadaf Ebrahimi 1176*9a0e4156SSadaf Ebrahimi### cs_close 1177*9a0e4156SSadaf Ebrahimi 1178*9a0e4156SSadaf Ebrahimi`cs_err CAPSTONE_API cs_close(csh *handle);` 1179*9a0e4156SSadaf Ebrahimi 1180*9a0e4156SSadaf Ebrahimi释放句柄 1181*9a0e4156SSadaf Ebrahimi 1182*9a0e4156SSadaf Ebrahimi``` 1183*9a0e4156SSadaf Ebrahimihandle: 指向一个cs_open()打开的句柄 1184*9a0e4156SSadaf Ebrahimireturn: 释放成功返回CS_ERR_OK,否则返回cs_err枚举的错误信息 1185*9a0e4156SSadaf Ebrahimi``` 1186*9a0e4156SSadaf Ebrahimi 1187*9a0e4156SSadaf Ebrahimi释放句柄实质为将句柄值设置为0 1188*9a0e4156SSadaf Ebrahimi 1189*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 1190*9a0e4156SSadaf Ebrahimi 1191*9a0e4156SSadaf Ebrahimi```cpp 1192*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_close(csh *handle) 1193*9a0e4156SSadaf Ebrahimi{ 1194*9a0e4156SSadaf Ebrahimi struct cs_struct *ud; 1195*9a0e4156SSadaf Ebrahimi struct insn_mnem *next, *tmp; 1196*9a0e4156SSadaf Ebrahimi 1197*9a0e4156SSadaf Ebrahimi if (*handle == 0) 1198*9a0e4156SSadaf Ebrahimi // 句柄不可用 1199*9a0e4156SSadaf Ebrahimi return CS_ERR_CSH; 1200*9a0e4156SSadaf Ebrahimi 1201*9a0e4156SSadaf Ebrahimi ud = (struct cs_struct *)(*handle); 1202*9a0e4156SSadaf Ebrahimi 1203*9a0e4156SSadaf Ebrahimi if (ud->printer_info) 1204*9a0e4156SSadaf Ebrahimi cs_mem_free(ud->printer_info); 1205*9a0e4156SSadaf Ebrahimi 1206*9a0e4156SSadaf Ebrahimi // 释放自定义助记符的链接list 1207*9a0e4156SSadaf Ebrahimi tmp = ud->mnem_list; 1208*9a0e4156SSadaf Ebrahimi while(tmp) { 1209*9a0e4156SSadaf Ebrahimi next = tmp->next; 1210*9a0e4156SSadaf Ebrahimi cs_mem_free(tmp); 1211*9a0e4156SSadaf Ebrahimi tmp = next; 1212*9a0e4156SSadaf Ebrahimi } 1213*9a0e4156SSadaf Ebrahimi 1214*9a0e4156SSadaf Ebrahimi cs_mem_free(ud->insn_cache); 1215*9a0e4156SSadaf Ebrahimi 1216*9a0e4156SSadaf Ebrahimi memset(ud, 0, sizeof(*ud)); 1217*9a0e4156SSadaf Ebrahimi cs_mem_free(ud); 1218*9a0e4156SSadaf Ebrahimi 1219*9a0e4156SSadaf Ebrahimi // handle值设置为0,保证这个句柄在cs_close()释放后不可使用 1220*9a0e4156SSadaf Ebrahimi *handle = 0; 1221*9a0e4156SSadaf Ebrahimi 1222*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1223*9a0e4156SSadaf Ebrahimi} 1224*9a0e4156SSadaf Ebrahimi``` 1225*9a0e4156SSadaf Ebrahimi 1226*9a0e4156SSadaf Ebrahimi</details> 1227*9a0e4156SSadaf Ebrahimi 1228*9a0e4156SSadaf Ebrahimi示例 1229*9a0e4156SSadaf Ebrahimi 1230*9a0e4156SSadaf Ebrahimi`cs_close(&handle);` 1231*9a0e4156SSadaf Ebrahimi 1232*9a0e4156SSadaf Ebrahimi 1233*9a0e4156SSadaf Ebrahimi### cs_option 1234*9a0e4156SSadaf Ebrahimi 1235*9a0e4156SSadaf Ebrahimi`cs_err CAPSTONE_API cs_option(csh handle, cs_opt_type type, size_t value);` 1236*9a0e4156SSadaf Ebrahimi 1237*9a0e4156SSadaf Ebrahimi反编译引擎的运行时选项 1238*9a0e4156SSadaf Ebrahimi 1239*9a0e4156SSadaf Ebrahimi``` 1240*9a0e4156SSadaf Ebrahimihandle: cs_open()打开的句柄 1241*9a0e4156SSadaf Ebrahimitype: 设置选项的类型 1242*9a0e4156SSadaf Ebrahimivalue: 与type对应的选项值 1243*9a0e4156SSadaf Ebrahimireturn: 设置成功返回CS_ERR_OK,否则返回cs_err枚举的错误信息 1244*9a0e4156SSadaf Ebrahimi``` 1245*9a0e4156SSadaf Ebrahimi 1246*9a0e4156SSadaf Ebrahimi注意: 在CS_OPT_MEM的情况下,handle可以是任何值,因此cs_option(handle, CS_OPT_MEM, value)必须在cs_open()之前被调用 1247*9a0e4156SSadaf Ebrahimi 1248*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 1249*9a0e4156SSadaf Ebrahimi 1250*9a0e4156SSadaf Ebrahimi```cpp 1251*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value) 1252*9a0e4156SSadaf Ebrahimi{ 1253*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 1254*9a0e4156SSadaf Ebrahimi cs_opt_mnem *opt; 1255*9a0e4156SSadaf Ebrahimi 1256*9a0e4156SSadaf Ebrahimi // 支持在所有API前支持 (even cs_open()) 1257*9a0e4156SSadaf Ebrahimi if (type == CS_OPT_MEM) { 1258*9a0e4156SSadaf Ebrahimi cs_opt_mem *mem = (cs_opt_mem *)value; 1259*9a0e4156SSadaf Ebrahimi 1260*9a0e4156SSadaf Ebrahimi cs_mem_malloc = mem->malloc; 1261*9a0e4156SSadaf Ebrahimi cs_mem_calloc = mem->calloc; 1262*9a0e4156SSadaf Ebrahimi cs_mem_realloc = mem->realloc; 1263*9a0e4156SSadaf Ebrahimi cs_mem_free = mem->free; 1264*9a0e4156SSadaf Ebrahimi cs_vsnprintf = mem->vsnprintf; 1265*9a0e4156SSadaf Ebrahimi 1266*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1267*9a0e4156SSadaf Ebrahimi } 1268*9a0e4156SSadaf Ebrahimi 1269*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 1270*9a0e4156SSadaf Ebrahimi if (!handle) 1271*9a0e4156SSadaf Ebrahimi return CS_ERR_CSH; 1272*9a0e4156SSadaf Ebrahimi 1273*9a0e4156SSadaf Ebrahimi switch(type) { 1274*9a0e4156SSadaf Ebrahimi default: 1275*9a0e4156SSadaf Ebrahimi break; 1276*9a0e4156SSadaf Ebrahimi 1277*9a0e4156SSadaf Ebrahimi case CS_OPT_UNSIGNED: 1278*9a0e4156SSadaf Ebrahimi handle->imm_unsigned = (cs_opt_value)value; 1279*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1280*9a0e4156SSadaf Ebrahimi 1281*9a0e4156SSadaf Ebrahimi case CS_OPT_DETAIL: 1282*9a0e4156SSadaf Ebrahimi handle->detail = (cs_opt_value)value; 1283*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1284*9a0e4156SSadaf Ebrahimi 1285*9a0e4156SSadaf Ebrahimi case CS_OPT_SKIPDATA: 1286*9a0e4156SSadaf Ebrahimi handle->skipdata = (value == CS_OPT_ON); 1287*9a0e4156SSadaf Ebrahimi if (handle->skipdata) { 1288*9a0e4156SSadaf Ebrahimi if (handle->skipdata_size == 0) { 1289*9a0e4156SSadaf Ebrahimi handle->skipdata_size = skipdata_size(handle); 1290*9a0e4156SSadaf Ebrahimi } 1291*9a0e4156SSadaf Ebrahimi } 1292*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1293*9a0e4156SSadaf Ebrahimi 1294*9a0e4156SSadaf Ebrahimi case CS_OPT_SKIPDATA_SETUP: 1295*9a0e4156SSadaf Ebrahimi if (value) 1296*9a0e4156SSadaf Ebrahimi handle->skipdata_setup = *((cs_opt_skipdata *)value); 1297*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1298*9a0e4156SSadaf Ebrahimi 1299*9a0e4156SSadaf Ebrahimi case CS_OPT_MNEMONIC: 1300*9a0e4156SSadaf Ebrahimi opt = (cs_opt_mnem *)value; 1301*9a0e4156SSadaf Ebrahimi if (opt->id) { 1302*9a0e4156SSadaf Ebrahimi if (opt->mnemonic) { 1303*9a0e4156SSadaf Ebrahimi struct insn_mnem *tmp; 1304*9a0e4156SSadaf Ebrahimi 1305*9a0e4156SSadaf Ebrahimi // 添加新指令或替换现有指令 1306*9a0e4156SSadaf Ebrahimi // 查看当前insn释放在list中 1307*9a0e4156SSadaf Ebrahimi tmp = handle->mnem_list; 1308*9a0e4156SSadaf Ebrahimi while(tmp) { 1309*9a0e4156SSadaf Ebrahimi if (tmp->insn.id == opt->id) { 1310*9a0e4156SSadaf Ebrahimi // f找到指令,替换助记符 1311*9a0e4156SSadaf Ebrahimi (void)strncpy(tmp->insn.mnemonic, opt->mnemonic, sizeof(tmp->insn.mnemonic) - 1); 1312*9a0e4156SSadaf Ebrahimi tmp->insn.mnemonic[sizeof(tmp->insn.mnemonic) - 1] = '\0'; 1313*9a0e4156SSadaf Ebrahimi break; 1314*9a0e4156SSadaf Ebrahimi } 1315*9a0e4156SSadaf Ebrahimi tmp = tmp->next; 1316*9a0e4156SSadaf Ebrahimi } 1317*9a0e4156SSadaf Ebrahimi 1318*9a0e4156SSadaf Ebrahimi // 2. 如果没有就添加这条指令 1319*9a0e4156SSadaf Ebrahimi if (!tmp) { 1320*9a0e4156SSadaf Ebrahimi tmp = cs_mem_malloc(sizeof(*tmp)); 1321*9a0e4156SSadaf Ebrahimi tmp->insn.id = opt->id; 1322*9a0e4156SSadaf Ebrahimi (void)strncpy(tmp->insn.mnemonic, opt->mnemonic, sizeof(tmp->insn.mnemonic) - 1); 1323*9a0e4156SSadaf Ebrahimi tmp->insn.mnemonic[sizeof(tmp->insn.mnemonic) - 1] = '\0'; 1324*9a0e4156SSadaf Ebrahimi // 新指令放在list最前面 1325*9a0e4156SSadaf Ebrahimi tmp->next = handle->mnem_list; 1326*9a0e4156SSadaf Ebrahimi handle->mnem_list = tmp; 1327*9a0e4156SSadaf Ebrahimi } 1328*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1329*9a0e4156SSadaf Ebrahimi } else { 1330*9a0e4156SSadaf Ebrahimi struct insn_mnem *prev, *tmp; 1331*9a0e4156SSadaf Ebrahimi 1332*9a0e4156SSadaf Ebrahimi tmp = handle->mnem_list; 1333*9a0e4156SSadaf Ebrahimi prev = tmp; 1334*9a0e4156SSadaf Ebrahimi while(tmp) { 1335*9a0e4156SSadaf Ebrahimi if (tmp->insn.id == opt->id) { 1336*9a0e4156SSadaf Ebrahimi // 删除指令 1337*9a0e4156SSadaf Ebrahimi if (tmp == prev) { 1338*9a0e4156SSadaf Ebrahimi handle->mnem_list = tmp->next; 1339*9a0e4156SSadaf Ebrahimi } else { 1340*9a0e4156SSadaf Ebrahimi prev->next = tmp->next; 1341*9a0e4156SSadaf Ebrahimi } 1342*9a0e4156SSadaf Ebrahimi cs_mem_free(tmp); 1343*9a0e4156SSadaf Ebrahimi break; 1344*9a0e4156SSadaf Ebrahimi } 1345*9a0e4156SSadaf Ebrahimi prev = tmp; 1346*9a0e4156SSadaf Ebrahimi tmp = tmp->next; 1347*9a0e4156SSadaf Ebrahimi } 1348*9a0e4156SSadaf Ebrahimi } 1349*9a0e4156SSadaf Ebrahimi } 1350*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 1351*9a0e4156SSadaf Ebrahimi 1352*9a0e4156SSadaf Ebrahimi case CS_OPT_MODE: 1353*9a0e4156SSadaf Ebrahimi // 验证所请求的模式是否有效 1354*9a0e4156SSadaf Ebrahimi if (value & cs_arch_disallowed_mode_mask[handle->arch]) { 1355*9a0e4156SSadaf Ebrahimi return CS_ERR_OPTION; 1356*9a0e4156SSadaf Ebrahimi } 1357*9a0e4156SSadaf Ebrahimi break; 1358*9a0e4156SSadaf Ebrahimi } 1359*9a0e4156SSadaf Ebrahimi 1360*9a0e4156SSadaf Ebrahimi return cs_arch_option[handle->arch](handle, type, value); 1361*9a0e4156SSadaf Ebrahimi} 1362*9a0e4156SSadaf Ebrahimi``` 1363*9a0e4156SSadaf Ebrahimi</details> 1364*9a0e4156SSadaf Ebrahimi 1365*9a0e4156SSadaf Ebrahimi 1366*9a0e4156SSadaf Ebrahimi<details><summary> 示例,更改反汇编后显示的语法 </summary> 1367*9a0e4156SSadaf Ebrahimi 1368*9a0e4156SSadaf Ebrahimi```cpp 1369*9a0e4156SSadaf Ebrahimi#include <iostream> 1370*9a0e4156SSadaf Ebrahimi#include <stdio.h> 1371*9a0e4156SSadaf Ebrahimi 1372*9a0e4156SSadaf Ebrahimi#include "capstone.h" 1373*9a0e4156SSadaf Ebrahimi#include "platform.h" 1374*9a0e4156SSadaf Ebrahimi 1375*9a0e4156SSadaf Ebrahimiusing namespace std; 1376*9a0e4156SSadaf Ebrahimi 1377*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00" 1378*9a0e4156SSadaf Ebrahimi 1379*9a0e4156SSadaf Ebrahimiint main(void) 1380*9a0e4156SSadaf Ebrahimi{ 1381*9a0e4156SSadaf Ebrahimi csh handle; 1382*9a0e4156SSadaf Ebrahimi cs_insn* insn; 1383*9a0e4156SSadaf Ebrahimi size_t count; 1384*9a0e4156SSadaf Ebrahimi 1385*9a0e4156SSadaf Ebrahimi if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) { 1386*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to initialize engine!\n"); 1387*9a0e4156SSadaf Ebrahimi return -1; 1388*9a0e4156SSadaf Ebrahimi } 1389*9a0e4156SSadaf Ebrahimi cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); // 以AT&T语法显示 1390*9a0e4156SSadaf Ebrahimi count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn); 1391*9a0e4156SSadaf Ebrahimi if (count) { 1392*9a0e4156SSadaf Ebrahimi size_t j; 1393*9a0e4156SSadaf Ebrahimi 1394*9a0e4156SSadaf Ebrahimi for (j = 0; j < count; j++) { 1395*9a0e4156SSadaf Ebrahimi printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); 1396*9a0e4156SSadaf Ebrahimi } 1397*9a0e4156SSadaf Ebrahimi 1398*9a0e4156SSadaf Ebrahimi cs_free(insn, count); 1399*9a0e4156SSadaf Ebrahimi } 1400*9a0e4156SSadaf Ebrahimi else 1401*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to disassemble given code!\n"); 1402*9a0e4156SSadaf Ebrahimi 1403*9a0e4156SSadaf Ebrahimi cs_close(&handle); 1404*9a0e4156SSadaf Ebrahimi 1405*9a0e4156SSadaf Ebrahimi return 0; 1406*9a0e4156SSadaf Ebrahimi} 1407*9a0e4156SSadaf Ebrahimi``` 1408*9a0e4156SSadaf Ebrahimi 1409*9a0e4156SSadaf Ebrahimi</details> 1410*9a0e4156SSadaf Ebrahimi 1411*9a0e4156SSadaf Ebrahimi输出 1412*9a0e4156SSadaf Ebrahimi 1413*9a0e4156SSadaf Ebrahimi 1414*9a0e4156SSadaf Ebrahimi 1415*9a0e4156SSadaf Ebrahimi 1416*9a0e4156SSadaf Ebrahimi### cs_errno 1417*9a0e4156SSadaf Ebrahimi 1418*9a0e4156SSadaf Ebrahimi`cs_err CAPSTONE_API cs_errno(csh handle);` 1419*9a0e4156SSadaf Ebrahimi 1420*9a0e4156SSadaf EbrahimiAPI出错时返回错误消息 1421*9a0e4156SSadaf Ebrahimi 1422*9a0e4156SSadaf Ebrahimi``` 1423*9a0e4156SSadaf Ebrahimihandle: cs_open()打开的句柄 1424*9a0e4156SSadaf Ebrahimireturn: 无错误返回CS_ERR_OK,否则返回cs_err枚举的错误信息 1425*9a0e4156SSadaf Ebrahimi``` 1426*9a0e4156SSadaf Ebrahimi 1427*9a0e4156SSadaf Ebrahimi判断到句柄不存在直接返回CS_ERR_CSH 1428*9a0e4156SSadaf Ebrahimi 1429*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary> 1430*9a0e4156SSadaf Ebrahimi 1431*9a0e4156SSadaf Ebrahimi```cpp 1432*9a0e4156SSadaf Ebrahimi#include <iostream> 1433*9a0e4156SSadaf Ebrahimi#include <stdio.h> 1434*9a0e4156SSadaf Ebrahimi 1435*9a0e4156SSadaf Ebrahimi#include "capstone.h" 1436*9a0e4156SSadaf Ebrahimi#include "platform.h" 1437*9a0e4156SSadaf Ebrahimi 1438*9a0e4156SSadaf Ebrahimiusing namespace std; 1439*9a0e4156SSadaf Ebrahimi 1440*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00" 1441*9a0e4156SSadaf Ebrahimi 1442*9a0e4156SSadaf Ebrahimiint main(void) 1443*9a0e4156SSadaf Ebrahimi{ 1444*9a0e4156SSadaf Ebrahimi csh handle = 0; 1445*9a0e4156SSadaf Ebrahimi cs_insn* insn; 1446*9a0e4156SSadaf Ebrahimi size_t count; 1447*9a0e4156SSadaf Ebrahimi 1448*9a0e4156SSadaf Ebrahimi if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) { 1449*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to initialize engine!\n"); 1450*9a0e4156SSadaf Ebrahimi return -1; 1451*9a0e4156SSadaf Ebrahimi } 1452*9a0e4156SSadaf Ebrahimi 1453*9a0e4156SSadaf Ebrahimi cs_close(&handle); 1454*9a0e4156SSadaf Ebrahimi std::cout << cs_errno(handle); //关闭句柄后检查将报错 1455*9a0e4156SSadaf Ebrahimi return 0; 1456*9a0e4156SSadaf Ebrahimi} 1457*9a0e4156SSadaf Ebrahimi``` 1458*9a0e4156SSadaf Ebrahimi 1459*9a0e4156SSadaf Ebrahimi</details> 1460*9a0e4156SSadaf Ebrahimi 1461*9a0e4156SSadaf Ebrahimi输出,错误码4即CS_ERR_CSH 1462*9a0e4156SSadaf Ebrahimi 1463*9a0e4156SSadaf Ebrahimi 1464*9a0e4156SSadaf Ebrahimi 1465*9a0e4156SSadaf Ebrahimi 1466*9a0e4156SSadaf Ebrahimi### cs_strerror 1467*9a0e4156SSadaf Ebrahimi 1468*9a0e4156SSadaf Ebrahimi`const char * CAPSTONE_API cs_strerror(cs_err code);` 1469*9a0e4156SSadaf Ebrahimi 1470*9a0e4156SSadaf Ebrahimi将上个API输出的错误码转换为详细错误信息 1471*9a0e4156SSadaf Ebrahimi 1472*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 1473*9a0e4156SSadaf Ebrahimi 1474*9a0e4156SSadaf Ebrahimi```cpp 1475*9a0e4156SSadaf Ebrahimiconst char * CAPSTONE_API cs_strerror(cs_err code) 1476*9a0e4156SSadaf Ebrahimi{ 1477*9a0e4156SSadaf Ebrahimi switch(code) { 1478*9a0e4156SSadaf Ebrahimi default: 1479*9a0e4156SSadaf Ebrahimi return "Unknown error code"; 1480*9a0e4156SSadaf Ebrahimi case CS_ERR_OK: 1481*9a0e4156SSadaf Ebrahimi return "OK (CS_ERR_OK)"; 1482*9a0e4156SSadaf Ebrahimi case CS_ERR_MEM: 1483*9a0e4156SSadaf Ebrahimi return "Out of memory (CS_ERR_MEM)"; 1484*9a0e4156SSadaf Ebrahimi case CS_ERR_ARCH: 1485*9a0e4156SSadaf Ebrahimi return "Invalid/unsupported architecture(CS_ERR_ARCH)"; 1486*9a0e4156SSadaf Ebrahimi case CS_ERR_HANDLE: 1487*9a0e4156SSadaf Ebrahimi return "Invalid handle (CS_ERR_HANDLE)"; 1488*9a0e4156SSadaf Ebrahimi case CS_ERR_CSH: 1489*9a0e4156SSadaf Ebrahimi return "Invalid csh (CS_ERR_CSH)"; 1490*9a0e4156SSadaf Ebrahimi case CS_ERR_MODE: 1491*9a0e4156SSadaf Ebrahimi return "Invalid mode (CS_ERR_MODE)"; 1492*9a0e4156SSadaf Ebrahimi case CS_ERR_OPTION: 1493*9a0e4156SSadaf Ebrahimi return "Invalid option (CS_ERR_OPTION)"; 1494*9a0e4156SSadaf Ebrahimi case CS_ERR_DETAIL: 1495*9a0e4156SSadaf Ebrahimi return "Details are unavailable (CS_ERR_DETAIL)"; 1496*9a0e4156SSadaf Ebrahimi case CS_ERR_MEMSETUP: 1497*9a0e4156SSadaf Ebrahimi return "Dynamic memory management uninitialized (CS_ERR_MEMSETUP)"; 1498*9a0e4156SSadaf Ebrahimi case CS_ERR_VERSION: 1499*9a0e4156SSadaf Ebrahimi return "Different API version between core & binding (CS_ERR_VERSION)"; 1500*9a0e4156SSadaf Ebrahimi case CS_ERR_DIET: 1501*9a0e4156SSadaf Ebrahimi return "Information irrelevant in diet engine (CS_ERR_DIET)"; 1502*9a0e4156SSadaf Ebrahimi case CS_ERR_SKIPDATA: 1503*9a0e4156SSadaf Ebrahimi return "Information irrelevant for 'data' instruction in SKIPDATA mode (CS_ERR_SKIPDATA)"; 1504*9a0e4156SSadaf Ebrahimi case CS_ERR_X86_ATT: 1505*9a0e4156SSadaf Ebrahimi return "AT&T syntax is unavailable (CS_ERR_X86_ATT)"; 1506*9a0e4156SSadaf Ebrahimi case CS_ERR_X86_INTEL: 1507*9a0e4156SSadaf Ebrahimi return "INTEL syntax is unavailable (CS_ERR_X86_INTEL)"; 1508*9a0e4156SSadaf Ebrahimi case CS_ERR_X86_MASM: 1509*9a0e4156SSadaf Ebrahimi return "MASM syntax is unavailable (CS_ERR_X86_MASM)"; 1510*9a0e4156SSadaf Ebrahimi } 1511*9a0e4156SSadaf Ebrahimi} 1512*9a0e4156SSadaf Ebrahimi``` 1513*9a0e4156SSadaf Ebrahimi</details> 1514*9a0e4156SSadaf Ebrahimi 1515*9a0e4156SSadaf Ebrahimi 1516*9a0e4156SSadaf Ebrahimi<details><summary> 示例,结合cs_errno使用 </summary> 1517*9a0e4156SSadaf Ebrahimi 1518*9a0e4156SSadaf Ebrahimi```cpp 1519*9a0e4156SSadaf Ebrahimi#include <iostream> 1520*9a0e4156SSadaf Ebrahimi#include <stdio.h> 1521*9a0e4156SSadaf Ebrahimi 1522*9a0e4156SSadaf Ebrahimi#include "capstone.h" 1523*9a0e4156SSadaf Ebrahimi#include "platform.h" 1524*9a0e4156SSadaf Ebrahimi 1525*9a0e4156SSadaf Ebrahimiusing namespace std; 1526*9a0e4156SSadaf Ebrahimi 1527*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00" 1528*9a0e4156SSadaf Ebrahimi 1529*9a0e4156SSadaf Ebrahimiint main(void) 1530*9a0e4156SSadaf Ebrahimi{ 1531*9a0e4156SSadaf Ebrahimi csh handle = 0; 1532*9a0e4156SSadaf Ebrahimi cs_insn* insn; 1533*9a0e4156SSadaf Ebrahimi size_t count; 1534*9a0e4156SSadaf Ebrahimi 1535*9a0e4156SSadaf Ebrahimi if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) { 1536*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to initialize engine!\n"); 1537*9a0e4156SSadaf Ebrahimi return -1; 1538*9a0e4156SSadaf Ebrahimi } 1539*9a0e4156SSadaf Ebrahimi 1540*9a0e4156SSadaf Ebrahimi cs_close(&handle); 1541*9a0e4156SSadaf Ebrahimi std::cout << cs_strerror(cs_errno(handle)); //直接输出报错信息 1542*9a0e4156SSadaf Ebrahimi return 0; 1543*9a0e4156SSadaf Ebrahimi} 1544*9a0e4156SSadaf Ebrahimi``` 1545*9a0e4156SSadaf Ebrahimi 1546*9a0e4156SSadaf Ebrahimi</details> 1547*9a0e4156SSadaf Ebrahimi 1548*9a0e4156SSadaf Ebrahimi输出 1549*9a0e4156SSadaf Ebrahimi 1550*9a0e4156SSadaf Ebrahimi 1551*9a0e4156SSadaf Ebrahimi 1552*9a0e4156SSadaf Ebrahimi 1553*9a0e4156SSadaf Ebrahimi### cs_disasm 1554*9a0e4156SSadaf Ebrahimi 1555*9a0e4156SSadaf Ebrahimi```cpp 1556*9a0e4156SSadaf Ebrahimisize_t CAPSTONE_API cs_disasm(csh handle, 1557*9a0e4156SSadaf Ebrahimi const uint8_t *code, size_t code_size, 1558*9a0e4156SSadaf Ebrahimi uint64_t address, 1559*9a0e4156SSadaf Ebrahimi size_t count, 1560*9a0e4156SSadaf Ebrahimi cs_insn **insn); 1561*9a0e4156SSadaf Ebrahimi``` 1562*9a0e4156SSadaf Ebrahimi 1563*9a0e4156SSadaf Ebrahimi给定缓冲区、大小、地址和编号,反编译机器码 1564*9a0e4156SSadaf Ebrahimi 1565*9a0e4156SSadaf EbrahimiAPI动态地分配内存来包含分解的指令,生成的指令将放在*insn中 1566*9a0e4156SSadaf Ebrahimi 1567*9a0e4156SSadaf Ebrahimi注意: 必须释放分配的内存,以避免内存泄漏。对于需要动态分配稀缺内存的系统(如OS内核或固件),API cs_disasm_iter()可能是比cs_disasm()更好的选择。原因是,使用cs_disasm()时,基于有限的可用内存,必须预先计算要分解多少条指令。 1568*9a0e4156SSadaf Ebrahimi 1569*9a0e4156SSadaf Ebrahimi``` 1570*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 1571*9a0e4156SSadaf Ebrahimicode: 包含要反汇编的机器码的缓冲区。 1572*9a0e4156SSadaf Ebrahimicode_size:上面代码缓冲区的大小。 1573*9a0e4156SSadaf Ebrahimiaddress:给定原始代码缓冲区中的第一条指令的地址。 1574*9a0e4156SSadaf Ebrahimiinsn: 由这个API填写的指令数组。注意: insn将由这个函数分配,应该用cs_free () API释放 1575*9a0e4156SSadaf Ebrahimicount: 需要分解的指令数量,或输入0分解所有指令 1576*9a0e4156SSadaf Ebrahimireturn:成功反汇编指令的数量,如果该函数未能反汇编给定的代码,则为0,失败时,调用cs_errno()获取错误代码。 1577*9a0e4156SSadaf Ebrahimi``` 1578*9a0e4156SSadaf Ebrahimi 1579*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 1580*9a0e4156SSadaf Ebrahimi 1581*9a0e4156SSadaf Ebrahimi```cpp 1582*9a0e4156SSadaf Ebrahimisize_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn) 1583*9a0e4156SSadaf Ebrahimi{ 1584*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 1585*9a0e4156SSadaf Ebrahimi MCInst mci; 1586*9a0e4156SSadaf Ebrahimi uint16_t insn_size; 1587*9a0e4156SSadaf Ebrahimi size_t c = 0, i; 1588*9a0e4156SSadaf Ebrahimi unsigned int f = 0; // 缓存中下一条指令的索引 1589*9a0e4156SSadaf Ebrahimi cs_insn *insn_cache; // 缓存反汇编后的指令 1590*9a0e4156SSadaf Ebrahimi void *total = NULL; 1591*9a0e4156SSadaf Ebrahimi size_t total_size = 0; //所有insn的输出缓冲区的总大小 1592*9a0e4156SSadaf Ebrahimi bool r; 1593*9a0e4156SSadaf Ebrahimi void *tmp; 1594*9a0e4156SSadaf Ebrahimi size_t skipdata_bytes; 1595*9a0e4156SSadaf Ebrahimi uint64_t offset_org; // 保存缓冲区的所有原始信息 1596*9a0e4156SSadaf Ebrahimi size_t size_org; 1597*9a0e4156SSadaf Ebrahimi const uint8_t *buffer_org; 1598*9a0e4156SSadaf Ebrahimi unsigned int cache_size = INSN_CACHE_SIZE; 1599*9a0e4156SSadaf Ebrahimi size_t next_offset; 1600*9a0e4156SSadaf Ebrahimi 1601*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 1602*9a0e4156SSadaf Ebrahimi if (!handle) { 1603*9a0e4156SSadaf Ebrahimi // 修复方式: 1604*9a0e4156SSadaf Ebrahimi // handle->errnum = CS_ERR_HANDLE; 1605*9a0e4156SSadaf Ebrahimi return 0; 1606*9a0e4156SSadaf Ebrahimi } 1607*9a0e4156SSadaf Ebrahimi 1608*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_OK; 1609*9a0e4156SSadaf Ebrahimi 1610*9a0e4156SSadaf Ebrahimi // 重设ARM架构的IT block 1611*9a0e4156SSadaf Ebrahimi if (handle->arch == CS_ARCH_ARM) 1612*9a0e4156SSadaf Ebrahimi handle->ITBlock.size = 0; 1613*9a0e4156SSadaf Ebrahimi 1614*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_USE_SYS_DYN_MEM 1615*9a0e4156SSadaf Ebrahimi if (count > 0 && count <= INSN_CACHE_SIZE) 1616*9a0e4156SSadaf Ebrahimi cache_size = (unsigned int) count; 1617*9a0e4156SSadaf Ebrahimi#endif 1618*9a0e4156SSadaf Ebrahimi 1619*9a0e4156SSadaf Ebrahimi // 保存SKIPDATA原始偏移量 1620*9a0e4156SSadaf Ebrahimi buffer_org = buffer; 1621*9a0e4156SSadaf Ebrahimi offset_org = offset; 1622*9a0e4156SSadaf Ebrahimi size_org = size; 1623*9a0e4156SSadaf Ebrahimi 1624*9a0e4156SSadaf Ebrahimi total_size = sizeof(cs_insn) * cache_size; 1625*9a0e4156SSadaf Ebrahimi total = cs_mem_malloc(total_size); 1626*9a0e4156SSadaf Ebrahimi if (total == NULL) { 1627*9a0e4156SSadaf Ebrahimi // 内存不足 1628*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_MEM; 1629*9a0e4156SSadaf Ebrahimi return 0; 1630*9a0e4156SSadaf Ebrahimi } 1631*9a0e4156SSadaf Ebrahimi 1632*9a0e4156SSadaf Ebrahimi insn_cache = total; 1633*9a0e4156SSadaf Ebrahimi 1634*9a0e4156SSadaf Ebrahimi while (size > 0) { 1635*9a0e4156SSadaf Ebrahimi MCInst_Init(&mci); 1636*9a0e4156SSadaf Ebrahimi mci.csh = handle; 1637*9a0e4156SSadaf Ebrahimi 1638*9a0e4156SSadaf Ebrahimi mci.address = offset; 1639*9a0e4156SSadaf Ebrahimi 1640*9a0e4156SSadaf Ebrahimi if (handle->detail) { 1641*9a0e4156SSadaf Ebrahimi //给detail指针分配内存 1642*9a0e4156SSadaf Ebrahimi insn_cache->detail = cs_mem_malloc(sizeof(cs_detail)); 1643*9a0e4156SSadaf Ebrahimi } else { 1644*9a0e4156SSadaf Ebrahimi insn_cache->detail = NULL; 1645*9a0e4156SSadaf Ebrahimi } 1646*9a0e4156SSadaf Ebrahimi 1647*9a0e4156SSadaf Ebrahimi // 为non-detailed模式保存所有信息 1648*9a0e4156SSadaf Ebrahimi mci.flat_insn = insn_cache; 1649*9a0e4156SSadaf Ebrahimi mci.flat_insn->address = offset; 1650*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET 1651*9a0e4156SSadaf Ebrahimi //mnemonic & op_str0填充 1652*9a0e4156SSadaf Ebrahimi mci.flat_insn->mnemonic[0] = '\0'; 1653*9a0e4156SSadaf Ebrahimi mci.flat_insn->op_str[0] = '\0'; 1654*9a0e4156SSadaf Ebrahimi#endif 1655*9a0e4156SSadaf Ebrahimi 1656*9a0e4156SSadaf Ebrahimi r = handle->disasm(ud, buffer, size, &mci, &insn_size, offset, handle->getinsn_info); 1657*9a0e4156SSadaf Ebrahimi if (r) { 1658*9a0e4156SSadaf Ebrahimi SStream ss; 1659*9a0e4156SSadaf Ebrahimi SStream_Init(&ss); 1660*9a0e4156SSadaf Ebrahimi 1661*9a0e4156SSadaf Ebrahimi mci.flat_insn->size = insn_size; 1662*9a0e4156SSadaf Ebrahimi 1663*9a0e4156SSadaf Ebrahimi //将内部指令操作码映射到公共insn ID 1664*9a0e4156SSadaf Ebrahimi handle->insn_id(handle, insn_cache, mci.Opcode); 1665*9a0e4156SSadaf Ebrahimi 1666*9a0e4156SSadaf Ebrahimi handle->printer(&mci, &ss, handle->printer_info); 1667*9a0e4156SSadaf Ebrahimi fill_insn(handle, insn_cache, ss.buffer, &mci, handle->post_printer, buffer); 1668*9a0e4156SSadaf Ebrahimi 1669*9a0e4156SSadaf Ebrahimi // 调整opcode (X86) 1670*9a0e4156SSadaf Ebrahimi if (handle->arch == CS_ARCH_X86) 1671*9a0e4156SSadaf Ebrahimi insn_cache->id += mci.popcode_adjust; 1672*9a0e4156SSadaf Ebrahimi 1673*9a0e4156SSadaf Ebrahimi next_offset = insn_size; 1674*9a0e4156SSadaf Ebrahimi } else { 1675*9a0e4156SSadaf Ebrahimi // 遇到中断指令 1676*9a0e4156SSadaf Ebrahimi 1677*9a0e4156SSadaf Ebrahimi // 为detail指针释放内存 1678*9a0e4156SSadaf Ebrahimi if (handle->detail) { 1679*9a0e4156SSadaf Ebrahimi cs_mem_free(insn_cache->detail); 1680*9a0e4156SSadaf Ebrahimi } 1681*9a0e4156SSadaf Ebrahimi 1682*9a0e4156SSadaf Ebrahimi if (!handle->skipdata || handle->skipdata_size > size) 1683*9a0e4156SSadaf Ebrahimi break; 1684*9a0e4156SSadaf Ebrahimi 1685*9a0e4156SSadaf Ebrahimi if (handle->skipdata_setup.callback) { 1686*9a0e4156SSadaf Ebrahimi skipdata_bytes = handle->skipdata_setup.callback(buffer_org, size_org, 1687*9a0e4156SSadaf Ebrahimi (size_t)(offset - offset_org), handle->skipdata_setup.user_data); 1688*9a0e4156SSadaf Ebrahimi if (skipdata_bytes > size) 1689*9a0e4156SSadaf Ebrahimi break; 1690*9a0e4156SSadaf Ebrahimi 1691*9a0e4156SSadaf Ebrahimi if (!skipdata_bytes) 1692*9a0e4156SSadaf Ebrahimi break; 1693*9a0e4156SSadaf Ebrahimi } else 1694*9a0e4156SSadaf Ebrahimi skipdata_bytes = handle->skipdata_size; 1695*9a0e4156SSadaf Ebrahimi 1696*9a0e4156SSadaf Ebrahimi insn_cache->id = 0; 1697*9a0e4156SSadaf Ebrahimi insn_cache->address = offset; 1698*9a0e4156SSadaf Ebrahimi insn_cache->size = (uint16_t)skipdata_bytes; 1699*9a0e4156SSadaf Ebrahimi memcpy(insn_cache->bytes, buffer, skipdata_bytes); 1700*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET 1701*9a0e4156SSadaf Ebrahimi insn_cache->mnemonic[0] = '\0'; 1702*9a0e4156SSadaf Ebrahimi insn_cache->op_str[0] = '\0'; 1703*9a0e4156SSadaf Ebrahimi#else 1704*9a0e4156SSadaf Ebrahimi strncpy(insn_cache->mnemonic, handle->skipdata_setup.mnemonic, 1705*9a0e4156SSadaf Ebrahimi sizeof(insn_cache->mnemonic) - 1); 1706*9a0e4156SSadaf Ebrahimi skipdata_opstr(insn_cache->op_str, buffer, skipdata_bytes); 1707*9a0e4156SSadaf Ebrahimi#endif 1708*9a0e4156SSadaf Ebrahimi insn_cache->detail = NULL; 1709*9a0e4156SSadaf Ebrahimi 1710*9a0e4156SSadaf Ebrahimi next_offset = skipdata_bytes; 1711*9a0e4156SSadaf Ebrahimi } 1712*9a0e4156SSadaf Ebrahimi 1713*9a0e4156SSadaf Ebrahimi // 一条新指令进入缓存 1714*9a0e4156SSadaf Ebrahimi f++; 1715*9a0e4156SSadaf Ebrahimi 1716*9a0e4156SSadaf Ebrahimi // 反汇编了一条指令 1717*9a0e4156SSadaf Ebrahimi c++; 1718*9a0e4156SSadaf Ebrahimi if (count > 0 && c == count) 1719*9a0e4156SSadaf Ebrahimi break; 1720*9a0e4156SSadaf Ebrahimi 1721*9a0e4156SSadaf Ebrahimi if (f == cache_size) { 1722*9a0e4156SSadaf Ebrahimi cache_size = cache_size * 8 / 5; 1723*9a0e4156SSadaf Ebrahimi total_size += (sizeof(cs_insn) * cache_size); 1724*9a0e4156SSadaf Ebrahimi tmp = cs_mem_realloc(total, total_size); 1725*9a0e4156SSadaf Ebrahimi if (tmp == NULL) { //内存不足 1726*9a0e4156SSadaf Ebrahimi if (handle->detail) { 1727*9a0e4156SSadaf Ebrahimi insn_cache = (cs_insn *)total; 1728*9a0e4156SSadaf Ebrahimi for (i = 0; i < c; i++, insn_cache++) 1729*9a0e4156SSadaf Ebrahimi cs_mem_free(insn_cache->detail); 1730*9a0e4156SSadaf Ebrahimi } 1731*9a0e4156SSadaf Ebrahimi 1732*9a0e4156SSadaf Ebrahimi cs_mem_free(total); 1733*9a0e4156SSadaf Ebrahimi *insn = NULL; 1734*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_MEM; 1735*9a0e4156SSadaf Ebrahimi return 0; 1736*9a0e4156SSadaf Ebrahimi } 1737*9a0e4156SSadaf Ebrahimi 1738*9a0e4156SSadaf Ebrahimi total = tmp; 1739*9a0e4156SSadaf Ebrahimi //在最后一条指令之后继续填充缓存 1740*9a0e4156SSadaf Ebrahimi insn_cache = (cs_insn *)((char *)total + sizeof(cs_insn) * c); 1741*9a0e4156SSadaf Ebrahimi 1742*9a0e4156SSadaf Ebrahimi // 将f重置为0,从一开始就填入缓存 1743*9a0e4156SSadaf Ebrahimi f = 0; 1744*9a0e4156SSadaf Ebrahimi } else 1745*9a0e4156SSadaf Ebrahimi insn_cache++; 1746*9a0e4156SSadaf Ebrahimi 1747*9a0e4156SSadaf Ebrahimi buffer += next_offset; 1748*9a0e4156SSadaf Ebrahimi size -= next_offset; 1749*9a0e4156SSadaf Ebrahimi offset += next_offset; 1750*9a0e4156SSadaf Ebrahimi } 1751*9a0e4156SSadaf Ebrahimi 1752*9a0e4156SSadaf Ebrahimi if (!c) { 1753*9a0e4156SSadaf Ebrahimi //未反汇编任何指令 1754*9a0e4156SSadaf Ebrahimi cs_mem_free(total); 1755*9a0e4156SSadaf Ebrahimi total = NULL; 1756*9a0e4156SSadaf Ebrahimi } else if (f != cache_size) { 1757*9a0e4156SSadaf Ebrahimi // 没有完全使用最后一个缓存,缩小大小 1758*9a0e4156SSadaf Ebrahimi tmp = cs_mem_realloc(total, total_size - (cache_size - f) * sizeof(*insn_cache)); 1759*9a0e4156SSadaf Ebrahimi if (tmp == NULL) { // 内存不足 1760*9a0e4156SSadaf Ebrahimi // 释放所有detail指针 1761*9a0e4156SSadaf Ebrahimi if (handle->detail) { 1762*9a0e4156SSadaf Ebrahimi insn_cache = (cs_insn *)total; 1763*9a0e4156SSadaf Ebrahimi for (i = 0; i < c; i++, insn_cache++) 1764*9a0e4156SSadaf Ebrahimi cs_mem_free(insn_cache->detail); 1765*9a0e4156SSadaf Ebrahimi } 1766*9a0e4156SSadaf Ebrahimi 1767*9a0e4156SSadaf Ebrahimi cs_mem_free(total); 1768*9a0e4156SSadaf Ebrahimi *insn = NULL; 1769*9a0e4156SSadaf Ebrahimi 1770*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_MEM; 1771*9a0e4156SSadaf Ebrahimi return 0; 1772*9a0e4156SSadaf Ebrahimi } 1773*9a0e4156SSadaf Ebrahimi 1774*9a0e4156SSadaf Ebrahimi total = tmp; 1775*9a0e4156SSadaf Ebrahimi } 1776*9a0e4156SSadaf Ebrahimi 1777*9a0e4156SSadaf Ebrahimi *insn = total; 1778*9a0e4156SSadaf Ebrahimi 1779*9a0e4156SSadaf Ebrahimi return c; 1780*9a0e4156SSadaf Ebrahimi} 1781*9a0e4156SSadaf Ebrahimi``` 1782*9a0e4156SSadaf Ebrahimi 1783*9a0e4156SSadaf Ebrahimi</details> 1784*9a0e4156SSadaf Ebrahimi 1785*9a0e4156SSadaf Ebrahimi 1786*9a0e4156SSadaf Ebrahimi<details><summary> 示例,x86_64 </summary> 1787*9a0e4156SSadaf Ebrahimi 1788*9a0e4156SSadaf Ebrahimi```cpp 1789*9a0e4156SSadaf Ebrahimi#include <iostream> 1790*9a0e4156SSadaf Ebrahimi#include <stdio.h> 1791*9a0e4156SSadaf Ebrahimi 1792*9a0e4156SSadaf Ebrahimi#include "capstone.h" 1793*9a0e4156SSadaf Ebrahimi#include "platform.h" 1794*9a0e4156SSadaf Ebrahimi 1795*9a0e4156SSadaf Ebrahimiusing namespace std; 1796*9a0e4156SSadaf Ebrahimi 1797*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff" 1798*9a0e4156SSadaf Ebrahimi 1799*9a0e4156SSadaf Ebrahimiint main(void) 1800*9a0e4156SSadaf Ebrahimi{ 1801*9a0e4156SSadaf Ebrahimi csh handle = 0; 1802*9a0e4156SSadaf Ebrahimi cs_insn* insn; 1803*9a0e4156SSadaf Ebrahimi size_t count; 1804*9a0e4156SSadaf Ebrahimi 1805*9a0e4156SSadaf Ebrahimi if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) { 1806*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to initialize engine!\n"); 1807*9a0e4156SSadaf Ebrahimi return -1; 1808*9a0e4156SSadaf Ebrahimi } 1809*9a0e4156SSadaf Ebrahimi 1810*9a0e4156SSadaf Ebrahimi count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn); //所有指令,基址0x1000,放入insn 1811*9a0e4156SSadaf Ebrahimi if (count) { 1812*9a0e4156SSadaf Ebrahimi size_t j; 1813*9a0e4156SSadaf Ebrahimi 1814*9a0e4156SSadaf Ebrahimi for (j = 0; j < count; j++) { 1815*9a0e4156SSadaf Ebrahimi printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); 1816*9a0e4156SSadaf Ebrahimi } 1817*9a0e4156SSadaf Ebrahimi 1818*9a0e4156SSadaf Ebrahimi cs_free(insn, count); 1819*9a0e4156SSadaf Ebrahimi } 1820*9a0e4156SSadaf Ebrahimi else 1821*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to disassemble given code!\n"); 1822*9a0e4156SSadaf Ebrahimi 1823*9a0e4156SSadaf Ebrahimi cs_close(&handle); 1824*9a0e4156SSadaf Ebrahimi 1825*9a0e4156SSadaf Ebrahimi return 0; 1826*9a0e4156SSadaf Ebrahimi} 1827*9a0e4156SSadaf Ebrahimi``` 1828*9a0e4156SSadaf Ebrahimi 1829*9a0e4156SSadaf Ebrahimi</details> 1830*9a0e4156SSadaf Ebrahimi 1831*9a0e4156SSadaf Ebrahimi输出 1832*9a0e4156SSadaf Ebrahimi 1833*9a0e4156SSadaf Ebrahimi 1834*9a0e4156SSadaf Ebrahimi 1835*9a0e4156SSadaf Ebrahimi 1836*9a0e4156SSadaf Ebrahimi### cs_free 1837*9a0e4156SSadaf Ebrahimi 1838*9a0e4156SSadaf Ebrahimi`void CAPSTONE_API cs_free(cs_insn *insn, size_t count);` 1839*9a0e4156SSadaf Ebrahimi 1840*9a0e4156SSadaf Ebrahimi释放被 cs_malloc() 或 cs_disasm() 分配的内存(insn参数) 1841*9a0e4156SSadaf Ebrahimi 1842*9a0e4156SSadaf Ebrahimi``` 1843*9a0e4156SSadaf Ebrahimiinsn: 由cs_disasm()或cs_malloc()中的@insn参数返回的指针 1844*9a0e4156SSadaf Ebrahimicount: 赋值由cs_disasm()返回的cs_insn结构的数量,或赋值为1表示由cs_malloc()分配给空闲内存的数量 1845*9a0e4156SSadaf Ebrahimi``` 1846*9a0e4156SSadaf Ebrahimi 1847*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 1848*9a0e4156SSadaf Ebrahimi 1849*9a0e4156SSadaf Ebrahimi```cpp 1850*9a0e4156SSadaf Ebrahimivoid CAPSTONE_API cs_free(cs_insn *insn, size_t count) 1851*9a0e4156SSadaf Ebrahimi{ 1852*9a0e4156SSadaf Ebrahimi size_t i; 1853*9a0e4156SSadaf Ebrahimi 1854*9a0e4156SSadaf Ebrahimi // free 所有 detail 指针 1855*9a0e4156SSadaf Ebrahimi for (i = 0; i < count; i++) 1856*9a0e4156SSadaf Ebrahimi cs_mem_free(insn[i].detail); 1857*9a0e4156SSadaf Ebrahimi 1858*9a0e4156SSadaf Ebrahimi cs_mem_free(insn); 1859*9a0e4156SSadaf Ebrahimi} 1860*9a0e4156SSadaf Ebrahimi``` 1861*9a0e4156SSadaf Ebrahimi 1862*9a0e4156SSadaf Ebrahimi直接调用cs_mem_free,也就是默认的free 1863*9a0e4156SSadaf Ebrahimi 1864*9a0e4156SSadaf Ebrahimi</details> 1865*9a0e4156SSadaf Ebrahimi 1866*9a0e4156SSadaf Ebrahimi 1867*9a0e4156SSadaf Ebrahimi<details><summary> 示例(释放cs_disasm申请的内存) </summary> 1868*9a0e4156SSadaf Ebrahimi 1869*9a0e4156SSadaf Ebrahimi```cpp 1870*9a0e4156SSadaf Ebrahimi count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn); //计数由cs_disasm申请的内存 1871*9a0e4156SSadaf Ebrahimi if (count) { 1872*9a0e4156SSadaf Ebrahimi size_t j; 1873*9a0e4156SSadaf Ebrahimi 1874*9a0e4156SSadaf Ebrahimi for (j = 0; j < count; j++) { 1875*9a0e4156SSadaf Ebrahimi printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); 1876*9a0e4156SSadaf Ebrahimi } 1877*9a0e4156SSadaf Ebrahimi 1878*9a0e4156SSadaf Ebrahimi cs_free(insn, count); //循环依次释放每条insn的内存 1879*9a0e4156SSadaf Ebrahimi } 1880*9a0e4156SSadaf Ebrahimi``` 1881*9a0e4156SSadaf Ebrahimi 1882*9a0e4156SSadaf Ebrahimi</details> 1883*9a0e4156SSadaf Ebrahimi 1884*9a0e4156SSadaf Ebrahimi 1885*9a0e4156SSadaf Ebrahimi### cs_malloc 1886*9a0e4156SSadaf Ebrahimi 1887*9a0e4156SSadaf Ebrahimi`cs_insn * CAPSTONE_API cs_malloc(csh handle);` 1888*9a0e4156SSadaf Ebrahimi 1889*9a0e4156SSadaf Ebrahimi被用于在API cs_disasm_iter()中为一条指令分配内存 1890*9a0e4156SSadaf Ebrahimi 1891*9a0e4156SSadaf Ebrahimi``` 1892*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 1893*9a0e4156SSadaf Ebrahimi``` 1894*9a0e4156SSadaf Ebrahimi 1895*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 1896*9a0e4156SSadaf Ebrahimi 1897*9a0e4156SSadaf Ebrahimi```cpp 1898*9a0e4156SSadaf Ebrahimics_insn * CAPSTONE_API cs_malloc(csh ud) 1899*9a0e4156SSadaf Ebrahimi{ 1900*9a0e4156SSadaf Ebrahimi cs_insn *insn; 1901*9a0e4156SSadaf Ebrahimi struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; 1902*9a0e4156SSadaf Ebrahimi 1903*9a0e4156SSadaf Ebrahimi insn = cs_mem_malloc(sizeof(cs_insn)); 1904*9a0e4156SSadaf Ebrahimi if (!insn) { 1905*9a0e4156SSadaf Ebrahimi // insufficient memory 1906*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_MEM; 1907*9a0e4156SSadaf Ebrahimi return NULL; 1908*9a0e4156SSadaf Ebrahimi } else { 1909*9a0e4156SSadaf Ebrahimi if (handle->detail) { 1910*9a0e4156SSadaf Ebrahimi // allocate memory for @detail pointer 1911*9a0e4156SSadaf Ebrahimi insn->detail = cs_mem_malloc(sizeof(cs_detail)); 1912*9a0e4156SSadaf Ebrahimi if (insn->detail == NULL) { // insufficient memory 1913*9a0e4156SSadaf Ebrahimi cs_mem_free(insn); 1914*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_MEM; 1915*9a0e4156SSadaf Ebrahimi return NULL; 1916*9a0e4156SSadaf Ebrahimi } 1917*9a0e4156SSadaf Ebrahimi } else 1918*9a0e4156SSadaf Ebrahimi insn->detail = NULL; 1919*9a0e4156SSadaf Ebrahimi } 1920*9a0e4156SSadaf Ebrahimi 1921*9a0e4156SSadaf Ebrahimi return insn; 1922*9a0e4156SSadaf Ebrahimi} 1923*9a0e4156SSadaf Ebrahimi``` 1924*9a0e4156SSadaf Ebrahimi 1925*9a0e4156SSadaf Ebrahimi</details> 1926*9a0e4156SSadaf Ebrahimi 1927*9a0e4156SSadaf Ebrahimi当这条指令所占的内存不再使用时,使用cs_free(insn, 1)释放,示例在下面cs_disasm_iter处 1928*9a0e4156SSadaf Ebrahimi 1929*9a0e4156SSadaf Ebrahimi 1930*9a0e4156SSadaf Ebrahimi### cs_disasm_iter 1931*9a0e4156SSadaf Ebrahimi 1932*9a0e4156SSadaf Ebrahimi```cpp 1933*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_disasm_iter(csh handle, 1934*9a0e4156SSadaf Ebrahimi const uint8_t **code, size_t *size, 1935*9a0e4156SSadaf Ebrahimi uint64_t *address, cs_insn *insn); 1936*9a0e4156SSadaf Ebrahimi``` 1937*9a0e4156SSadaf Ebrahimi 1938*9a0e4156SSadaf Ebrahimi给定buff、大小、地址和要解码的指令数,更快速的反汇编机器码, 1939*9a0e4156SSadaf Ebrahimi这个API将生成的指令放入insn中的给定的缓存中。 1940*9a0e4156SSadaf Ebrahimi 1941*9a0e4156SSadaf Ebrahimi注意1: 此API将更新code、size和address以指向输入缓冲区中的下一条指令。所以,虽然每次反汇编一条指令可以使用cs_disasm(count=1)来实现,但一些基准测试显示,在循环中使用cs_disasm_iter()可以方便地快速迭代所有指令,在随机输入时可以快30%。 1942*9a0e4156SSadaf Ebrahimi 1943*9a0e4156SSadaf Ebrahimi注意2:可以使用cs_malloc()创建insn中的缓存。 1944*9a0e4156SSadaf Ebrahimi 1945*9a0e4156SSadaf Ebrahimi注意3:对于动态分配内存可能产生内存不足的系统(比如OS内核或固件),建议使用cs_disasm()这个API, 因为cs_disasm()是根据要分解的指令的数量来分配内存。 1946*9a0e4156SSadaf Ebrahimi 1947*9a0e4156SSadaf Ebrahimi``` 1948*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 1949*9a0e4156SSadaf Ebrahimicode: 要反汇编的机器码所在的缓冲区 1950*9a0e4156SSadaf Ebrahimisize: 机器码缓冲区的大小 1951*9a0e4156SSadaf Ebrahimiaddress: 所给机器码缓冲区中第一个insn的地址 1952*9a0e4156SSadaf Ebrahimiinsn: 指向这个API要填充的指令的指针。 1953*9a0e4156SSadaf Ebrahimireturn:如果这个API成功反汇编了一条指令返回true,否则将返回false。 1954*9a0e4156SSadaf Ebrahimi``` 1955*9a0e4156SSadaf Ebrahimi 1956*9a0e4156SSadaf Ebrahimi失败时,调用cs_errno()获取错误代码。 1957*9a0e4156SSadaf Ebrahimi 1958*9a0e4156SSadaf Ebrahimi<details><summary> 代码实现,在cs_disasm基础上使用动态内存分配 </summary> 1959*9a0e4156SSadaf Ebrahimi 1960*9a0e4156SSadaf Ebrahimi```cpp 1961*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_disasm_iter(csh ud, const uint8_t **code, size_t *size, 1962*9a0e4156SSadaf Ebrahimi uint64_t *address, cs_insn *insn) 1963*9a0e4156SSadaf Ebrahimi{ 1964*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 1965*9a0e4156SSadaf Ebrahimi uint16_t insn_size; 1966*9a0e4156SSadaf Ebrahimi MCInst mci; 1967*9a0e4156SSadaf Ebrahimi bool r; 1968*9a0e4156SSadaf Ebrahimi 1969*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 1970*9a0e4156SSadaf Ebrahimi if (!handle) { 1971*9a0e4156SSadaf Ebrahimi return false; 1972*9a0e4156SSadaf Ebrahimi } 1973*9a0e4156SSadaf Ebrahimi 1974*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_OK; 1975*9a0e4156SSadaf Ebrahimi 1976*9a0e4156SSadaf Ebrahimi MCInst_Init(&mci); 1977*9a0e4156SSadaf Ebrahimi mci.csh = handle; 1978*9a0e4156SSadaf Ebrahimi 1979*9a0e4156SSadaf Ebrahimi mci.address = *address; 1980*9a0e4156SSadaf Ebrahimi 1981*9a0e4156SSadaf Ebrahimi // 为无detail模式保存相关信息 1982*9a0e4156SSadaf Ebrahimi mci.flat_insn = insn; 1983*9a0e4156SSadaf Ebrahimi mci.flat_insn->address = *address; 1984*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET 1985*9a0e4156SSadaf Ebrahimi mci.flat_insn->mnemonic[0] = '\0'; 1986*9a0e4156SSadaf Ebrahimi mci.flat_insn->op_str[0] = '\0'; 1987*9a0e4156SSadaf Ebrahimi#endif 1988*9a0e4156SSadaf Ebrahimi 1989*9a0e4156SSadaf Ebrahimi r = handle->disasm(ud, *code, *size, &mci, &insn_size, *address, handle->getinsn_info); 1990*9a0e4156SSadaf Ebrahimi if (r) { 1991*9a0e4156SSadaf Ebrahimi SStream ss; 1992*9a0e4156SSadaf Ebrahimi SStream_Init(&ss); 1993*9a0e4156SSadaf Ebrahimi 1994*9a0e4156SSadaf Ebrahimi mci.flat_insn->size = insn_size; 1995*9a0e4156SSadaf Ebrahimi 1996*9a0e4156SSadaf Ebrahimi // 将内部指令操作码映射到公共insn ID 1997*9a0e4156SSadaf Ebrahimi handle->insn_id(handle, insn, mci.Opcode); 1998*9a0e4156SSadaf Ebrahimi 1999*9a0e4156SSadaf Ebrahimi handle->printer(&mci, &ss, handle->printer_info); 2000*9a0e4156SSadaf Ebrahimi 2001*9a0e4156SSadaf Ebrahimi fill_insn(handle, insn, ss.buffer, &mci, handle->post_printer, *code); 2002*9a0e4156SSadaf Ebrahimi 2003*9a0e4156SSadaf Ebrahimi // 调整伪操作码(X86) 2004*9a0e4156SSadaf Ebrahimi if (handle->arch == CS_ARCH_X86) 2005*9a0e4156SSadaf Ebrahimi insn->id += mci.popcode_adjust; 2006*9a0e4156SSadaf Ebrahimi 2007*9a0e4156SSadaf Ebrahimi *code += insn_size; 2008*9a0e4156SSadaf Ebrahimi *size -= insn_size; 2009*9a0e4156SSadaf Ebrahimi *address += insn_size; 2010*9a0e4156SSadaf Ebrahimi } else { // 遇到中断指令 2011*9a0e4156SSadaf Ebrahimi size_t skipdata_bytes; 2012*9a0e4156SSadaf Ebrahimi 2013*9a0e4156SSadaf Ebrahimi // 如果没有跳过数据的请求,或者剩余数据太小,则退出 2014*9a0e4156SSadaf Ebrahimi if (!handle->skipdata || handle->skipdata_size > *size) 2015*9a0e4156SSadaf Ebrahimi return false; 2016*9a0e4156SSadaf Ebrahimi 2017*9a0e4156SSadaf Ebrahimi if (handle->skipdata_setup.callback) { 2018*9a0e4156SSadaf Ebrahimi skipdata_bytes = handle->skipdata_setup.callback(*code, *size, 2019*9a0e4156SSadaf Ebrahimi 0, handle->skipdata_setup.user_data); 2020*9a0e4156SSadaf Ebrahimi if (skipdata_bytes > *size) 2021*9a0e4156SSadaf Ebrahimi // 剩余数据太小 2022*9a0e4156SSadaf Ebrahimi return false; 2023*9a0e4156SSadaf Ebrahimi 2024*9a0e4156SSadaf Ebrahimi if (!skipdata_bytes) 2025*9a0e4156SSadaf Ebrahimi return false; 2026*9a0e4156SSadaf Ebrahimi } else 2027*9a0e4156SSadaf Ebrahimi skipdata_bytes = handle->skipdata_size; 2028*9a0e4156SSadaf Ebrahimi 2029*9a0e4156SSadaf Ebrahimi // 基于架构和模式跳过一些数据 2030*9a0e4156SSadaf Ebrahimi insn->id = 0; // 此“数据”指令的ID无效 2031*9a0e4156SSadaf Ebrahimi insn->address = *address; 2032*9a0e4156SSadaf Ebrahimi insn->size = (uint16_t)skipdata_bytes; 2033*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET 2034*9a0e4156SSadaf Ebrahimi insn->mnemonic[0] = '\0'; 2035*9a0e4156SSadaf Ebrahimi insn->op_str[0] = '\0'; 2036*9a0e4156SSadaf Ebrahimi#else 2037*9a0e4156SSadaf Ebrahimi memcpy(insn->bytes, *code, skipdata_bytes); 2038*9a0e4156SSadaf Ebrahimi strncpy(insn->mnemonic, handle->skipdata_setup.mnemonic, 2039*9a0e4156SSadaf Ebrahimi sizeof(insn->mnemonic) - 1); 2040*9a0e4156SSadaf Ebrahimi skipdata_opstr(insn->op_str, *code, skipdata_bytes); 2041*9a0e4156SSadaf Ebrahimi#endif 2042*9a0e4156SSadaf Ebrahimi 2043*9a0e4156SSadaf Ebrahimi *code += skipdata_bytes; 2044*9a0e4156SSadaf Ebrahimi *size -= skipdata_bytes; 2045*9a0e4156SSadaf Ebrahimi *address += skipdata_bytes; 2046*9a0e4156SSadaf Ebrahimi } 2047*9a0e4156SSadaf Ebrahimi 2048*9a0e4156SSadaf Ebrahimi return true; 2049*9a0e4156SSadaf Ebrahimi} 2050*9a0e4156SSadaf Ebrahimi``` 2051*9a0e4156SSadaf Ebrahimi 2052*9a0e4156SSadaf Ebrahimi</details> 2053*9a0e4156SSadaf Ebrahimi 2054*9a0e4156SSadaf Ebrahimi 2055*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary> 2056*9a0e4156SSadaf Ebrahimi 2057*9a0e4156SSadaf Ebrahimi```cpp 2058*9a0e4156SSadaf Ebrahimi#include <iostream> 2059*9a0e4156SSadaf Ebrahimi#include <stdio.h> 2060*9a0e4156SSadaf Ebrahimi 2061*9a0e4156SSadaf Ebrahimi#include "capstone.h" 2062*9a0e4156SSadaf Ebrahimi#include "platform.h" 2063*9a0e4156SSadaf Ebrahimi 2064*9a0e4156SSadaf Ebrahimiusing namespace std; 2065*9a0e4156SSadaf Ebrahimi 2066*9a0e4156SSadaf Ebrahimistruct platform { 2067*9a0e4156SSadaf Ebrahimi cs_arch arch; 2068*9a0e4156SSadaf Ebrahimi cs_mode mode; 2069*9a0e4156SSadaf Ebrahimi unsigned char* code; 2070*9a0e4156SSadaf Ebrahimi size_t size; 2071*9a0e4156SSadaf Ebrahimi const char* comment; 2072*9a0e4156SSadaf Ebrahimi cs_opt_type opt_type; 2073*9a0e4156SSadaf Ebrahimi cs_opt_value opt_value; 2074*9a0e4156SSadaf Ebrahimi}; 2075*9a0e4156SSadaf Ebrahimi 2076*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len) 2077*9a0e4156SSadaf Ebrahimi{ 2078*9a0e4156SSadaf Ebrahimi unsigned char* c; 2079*9a0e4156SSadaf Ebrahimi 2080*9a0e4156SSadaf Ebrahimi printf("Code: "); 2081*9a0e4156SSadaf Ebrahimi for (c = str; c < str + len; c++) { 2082*9a0e4156SSadaf Ebrahimi printf("0x%02x ", *c & 0xff); 2083*9a0e4156SSadaf Ebrahimi } 2084*9a0e4156SSadaf Ebrahimi printf("\n"); 2085*9a0e4156SSadaf Ebrahimi} 2086*9a0e4156SSadaf Ebrahimi 2087*9a0e4156SSadaf Ebrahimistatic void test() 2088*9a0e4156SSadaf Ebrahimi{ 2089*9a0e4156SSadaf Ebrahimi#define X86_CODE16 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00" 2090*9a0e4156SSadaf Ebrahimi#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00" 2091*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00" 2092*9a0e4156SSadaf Ebrahimi 2093*9a0e4156SSadaf Ebrahimi struct platform platforms[4] = { //架构及模式 2094*9a0e4156SSadaf Ebrahimi { 2095*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 2096*9a0e4156SSadaf Ebrahimi CS_MODE_16, 2097*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE16, 2098*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE32) - 1, 2099*9a0e4156SSadaf Ebrahimi "X86 16bit (Intel syntax)" 2100*9a0e4156SSadaf Ebrahimi }, 2101*9a0e4156SSadaf Ebrahimi { 2102*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 2103*9a0e4156SSadaf Ebrahimi CS_MODE_32, 2104*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE32, 2105*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE32) - 1, 2106*9a0e4156SSadaf Ebrahimi "X86 32bit (ATT syntax)", 2107*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX, 2108*9a0e4156SSadaf Ebrahimi CS_OPT_SYNTAX_ATT, 2109*9a0e4156SSadaf Ebrahimi }, 2110*9a0e4156SSadaf Ebrahimi { 2111*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 2112*9a0e4156SSadaf Ebrahimi CS_MODE_32, 2113*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE32, 2114*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE32) - 1, 2115*9a0e4156SSadaf Ebrahimi "X86 32 (Intel syntax)" 2116*9a0e4156SSadaf Ebrahimi }, 2117*9a0e4156SSadaf Ebrahimi { 2118*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 2119*9a0e4156SSadaf Ebrahimi CS_MODE_64, 2120*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE64, 2121*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE64) - 1, 2122*9a0e4156SSadaf Ebrahimi "X86 64 (Intel syntax)" 2123*9a0e4156SSadaf Ebrahimi }, 2124*9a0e4156SSadaf Ebrahimi 2125*9a0e4156SSadaf Ebrahimi csh handle; 2126*9a0e4156SSadaf Ebrahimi uint64_t address; 2127*9a0e4156SSadaf Ebrahimi cs_insn* insn; 2128*9a0e4156SSadaf Ebrahimi cs_detail* detail; 2129*9a0e4156SSadaf Ebrahimi int i; 2130*9a0e4156SSadaf Ebrahimi cs_err err; 2131*9a0e4156SSadaf Ebrahimi const uint8_t* code; 2132*9a0e4156SSadaf Ebrahimi size_t size; 2133*9a0e4156SSadaf Ebrahimi 2134*9a0e4156SSadaf Ebrahimi for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) { 2135*9a0e4156SSadaf Ebrahimi printf("****************\n"); 2136*9a0e4156SSadaf Ebrahimi printf("Platform: %s\n", platforms[i].comment); 2137*9a0e4156SSadaf Ebrahimi err = cs_open(platforms[i].arch, platforms[i].mode, &handle); 2138*9a0e4156SSadaf Ebrahimi if (err) { 2139*9a0e4156SSadaf Ebrahimi printf("Failed on cs_open() with error returned: %u\n", err); 2140*9a0e4156SSadaf Ebrahimi abort(); 2141*9a0e4156SSadaf Ebrahimi } 2142*9a0e4156SSadaf Ebrahimi 2143*9a0e4156SSadaf Ebrahimi if (platforms[i].opt_type) 2144*9a0e4156SSadaf Ebrahimi cs_option(handle, platforms[i].opt_type, platforms[i].opt_value); 2145*9a0e4156SSadaf Ebrahimi 2146*9a0e4156SSadaf Ebrahimi cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); 2147*9a0e4156SSadaf Ebrahimi 2148*9a0e4156SSadaf Ebrahimi // 为cs_disasm_iter()分配内存 2149*9a0e4156SSadaf Ebrahimi insn = cs_malloc(handle); 2150*9a0e4156SSadaf Ebrahimi 2151*9a0e4156SSadaf Ebrahimi print_string_hex(platforms[i].code, platforms[i].size); //原机器码 2152*9a0e4156SSadaf Ebrahimi printf("Disasm:\n"); 2153*9a0e4156SSadaf Ebrahimi 2154*9a0e4156SSadaf Ebrahimi address = 0x1000; 2155*9a0e4156SSadaf Ebrahimi code = platforms[i].code; 2156*9a0e4156SSadaf Ebrahimi size = platforms[i].size; 2157*9a0e4156SSadaf Ebrahimi while (cs_disasm_iter(handle, &code, &size, &address, insn)) { //cs_disasm_iter反汇编 2158*9a0e4156SSadaf Ebrahimi int n; 2159*9a0e4156SSadaf Ebrahimi 2160*9a0e4156SSadaf Ebrahimi printf("0x%" PRIx64 ":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", 2161*9a0e4156SSadaf Ebrahimi insn->address, insn->mnemonic, insn->op_str, 2162*9a0e4156SSadaf Ebrahimi insn->id, cs_insn_name(handle, insn->id)); 2163*9a0e4156SSadaf Ebrahimi 2164*9a0e4156SSadaf Ebrahimi // 打印此指令使用的隐式寄存器 2165*9a0e4156SSadaf Ebrahimi detail = insn->detail; 2166*9a0e4156SSadaf Ebrahimi 2167*9a0e4156SSadaf Ebrahimi if (detail->regs_read_count > 0) { 2168*9a0e4156SSadaf Ebrahimi printf("\tImplicit registers read: "); 2169*9a0e4156SSadaf Ebrahimi for (n = 0; n < detail->regs_read_count; n++) { 2170*9a0e4156SSadaf Ebrahimi printf("%s ", cs_reg_name(handle, detail->regs_read[n])); 2171*9a0e4156SSadaf Ebrahimi } 2172*9a0e4156SSadaf Ebrahimi printf("\n"); 2173*9a0e4156SSadaf Ebrahimi } 2174*9a0e4156SSadaf Ebrahimi 2175*9a0e4156SSadaf Ebrahimi // 打印此指令修改的隐式寄存器 2176*9a0e4156SSadaf Ebrahimi if (detail->regs_write_count > 0) { 2177*9a0e4156SSadaf Ebrahimi printf("\tImplicit registers modified: "); 2178*9a0e4156SSadaf Ebrahimi for (n = 0; n < detail->regs_write_count; n++) { 2179*9a0e4156SSadaf Ebrahimi printf("%s ", cs_reg_name(handle, detail->regs_write[n])); 2180*9a0e4156SSadaf Ebrahimi } 2181*9a0e4156SSadaf Ebrahimi printf("\n"); 2182*9a0e4156SSadaf Ebrahimi } 2183*9a0e4156SSadaf Ebrahimi 2184*9a0e4156SSadaf Ebrahimi // 打印此指令所属指令集 2185*9a0e4156SSadaf Ebrahimi if (detail->groups_count > 0) { 2186*9a0e4156SSadaf Ebrahimi printf("\tThis instruction belongs to groups: "); 2187*9a0e4156SSadaf Ebrahimi for (n = 0; n < detail->groups_count; n++) { 2188*9a0e4156SSadaf Ebrahimi printf("%s ", cs_group_name(handle, detail->groups[n])); 2189*9a0e4156SSadaf Ebrahimi } 2190*9a0e4156SSadaf Ebrahimi printf("\n"); 2191*9a0e4156SSadaf Ebrahimi } 2192*9a0e4156SSadaf Ebrahimi } 2193*9a0e4156SSadaf Ebrahimi 2194*9a0e4156SSadaf Ebrahimi printf("\n"); 2195*9a0e4156SSadaf Ebrahimi 2196*9a0e4156SSadaf Ebrahimi // 释放cs_malloc()分配的内存 2197*9a0e4156SSadaf Ebrahimi cs_free(insn, 1); 2198*9a0e4156SSadaf Ebrahimi 2199*9a0e4156SSadaf Ebrahimi cs_close(&handle); 2200*9a0e4156SSadaf Ebrahimi } 2201*9a0e4156SSadaf Ebrahimi} 2202*9a0e4156SSadaf Ebrahimi 2203*9a0e4156SSadaf Ebrahimiint main() 2204*9a0e4156SSadaf Ebrahimi{ 2205*9a0e4156SSadaf Ebrahimi test(); 2206*9a0e4156SSadaf Ebrahimi 2207*9a0e4156SSadaf Ebrahimi return 0; 2208*9a0e4156SSadaf Ebrahimi} 2209*9a0e4156SSadaf Ebrahimi``` 2210*9a0e4156SSadaf Ebrahimi 2211*9a0e4156SSadaf Ebrahimi</details> 2212*9a0e4156SSadaf Ebrahimi 2213*9a0e4156SSadaf Ebrahimi输出 2214*9a0e4156SSadaf Ebrahimi 2215*9a0e4156SSadaf Ebrahimi 2216*9a0e4156SSadaf Ebrahimi 2217*9a0e4156SSadaf Ebrahimi 2218*9a0e4156SSadaf Ebrahimi### cs_reg_name 2219*9a0e4156SSadaf Ebrahimi 2220*9a0e4156SSadaf Ebrahimi`const char * CAPSTONE_API cs_reg_name(csh handle, unsigned int reg_id);` 2221*9a0e4156SSadaf Ebrahimi 2222*9a0e4156SSadaf Ebrahimi获取寄存器的名字(string类型) 2223*9a0e4156SSadaf Ebrahimi寄存器id可在相关架构的头文件(建立项目时复制到项目文件夹的那些头文件)内找到 2224*9a0e4156SSadaf Ebrahimi 2225*9a0e4156SSadaf Ebrahimi注意: 当处于diet模式时此API不可用,因为引擎不会存储寄存器名 2226*9a0e4156SSadaf Ebrahimi 2227*9a0e4156SSadaf Ebrahimi``` 2228*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 2229*9a0e4156SSadaf Ebrahimireg_id: 寄存器id 2230*9a0e4156SSadaf Ebrahimireturn: 寄存器的字符名, 如果reg_id不可用返回NULL 2231*9a0e4156SSadaf Ebrahimi``` 2232*9a0e4156SSadaf Ebrahimi 2233*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 2234*9a0e4156SSadaf Ebrahimi 2235*9a0e4156SSadaf Ebrahimi```cpp 2236*9a0e4156SSadaf Ebrahimiconst char * CAPSTONE_API cs_reg_name(csh ud, unsigned int reg) 2237*9a0e4156SSadaf Ebrahimi{ 2238*9a0e4156SSadaf Ebrahimi struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; 2239*9a0e4156SSadaf Ebrahimi 2240*9a0e4156SSadaf Ebrahimi if (!handle || handle->reg_name == NULL) { 2241*9a0e4156SSadaf Ebrahimi return NULL; 2242*9a0e4156SSadaf Ebrahimi } 2243*9a0e4156SSadaf Ebrahimi 2244*9a0e4156SSadaf Ebrahimi return handle->reg_name(ud, reg); 2245*9a0e4156SSadaf Ebrahimi} 2246*9a0e4156SSadaf Ebrahimi``` 2247*9a0e4156SSadaf Ebrahimi 2248*9a0e4156SSadaf Ebrahimi</details> 2249*9a0e4156SSadaf Ebrahimi 2250*9a0e4156SSadaf Ebrahimi 2251*9a0e4156SSadaf Ebrahimi<details><summary> 示例(打印RAX) </summary> 2252*9a0e4156SSadaf Ebrahimi 2253*9a0e4156SSadaf Ebrahimi```cpp 2254*9a0e4156SSadaf Ebrahimi#include <iostream> 2255*9a0e4156SSadaf Ebrahimi#include <stdio.h> 2256*9a0e4156SSadaf Ebrahimi 2257*9a0e4156SSadaf Ebrahimi#include "capstone.h" 2258*9a0e4156SSadaf Ebrahimi#include "platform.h" 2259*9a0e4156SSadaf Ebrahimi 2260*9a0e4156SSadaf Ebrahimiusing namespace std; 2261*9a0e4156SSadaf Ebrahimi 2262*9a0e4156SSadaf Ebrahimiint main(void) 2263*9a0e4156SSadaf Ebrahimi{ 2264*9a0e4156SSadaf Ebrahimi csh handle = 0; 2265*9a0e4156SSadaf Ebrahimi cs_insn* insn; 2266*9a0e4156SSadaf Ebrahimi size_t count; 2267*9a0e4156SSadaf Ebrahimi 2268*9a0e4156SSadaf Ebrahimi if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) { 2269*9a0e4156SSadaf Ebrahimi printf("ERROR: Failed to initialize engine!\n"); 2270*9a0e4156SSadaf Ebrahimi return -1; 2271*9a0e4156SSadaf Ebrahimi } 2272*9a0e4156SSadaf Ebrahimi 2273*9a0e4156SSadaf Ebrahimi printf("%s", cs_reg_name(handle, X86_REG_RAX)); 2274*9a0e4156SSadaf Ebrahimi cs_close(&handle); 2275*9a0e4156SSadaf Ebrahimi 2276*9a0e4156SSadaf Ebrahimi return 0; 2277*9a0e4156SSadaf Ebrahimi} 2278*9a0e4156SSadaf Ebrahimi``` 2279*9a0e4156SSadaf Ebrahimi 2280*9a0e4156SSadaf Ebrahimi</details> 2281*9a0e4156SSadaf Ebrahimi 2282*9a0e4156SSadaf Ebrahimi输出 2283*9a0e4156SSadaf Ebrahimi 2284*9a0e4156SSadaf Ebrahimi 2285*9a0e4156SSadaf Ebrahimi 2286*9a0e4156SSadaf Ebrahimi 2287*9a0e4156SSadaf Ebrahimi### cs_insn_name 2288*9a0e4156SSadaf Ebrahimi 2289*9a0e4156SSadaf Ebrahimi`const char * CAPSTONE_API cs_insn_name(csh handle, unsigned int insn_id);` 2290*9a0e4156SSadaf Ebrahimi 2291*9a0e4156SSadaf Ebrahimi获取指令的名字(string类型) 2292*9a0e4156SSadaf Ebrahimi 2293*9a0e4156SSadaf Ebrahimi指令id可在相关架构的头文件(建立项目时复制到项目文件夹的那些头文件)内找到 2294*9a0e4156SSadaf Ebrahimi 2295*9a0e4156SSadaf Ebrahimi注意: 当处于diet模式时此API不可用,因为引擎不会存储寄存器名 2296*9a0e4156SSadaf Ebrahimi 2297*9a0e4156SSadaf Ebrahimi``` 2298*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 2299*9a0e4156SSadaf Ebrahimiinsn_id: 指令id 2300*9a0e4156SSadaf Ebrahimireturn: 指令的字符名, 如果insn_id不可用返回NULL 2301*9a0e4156SSadaf Ebrahimi``` 2302*9a0e4156SSadaf Ebrahimi 2303*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 2304*9a0e4156SSadaf Ebrahimi 2305*9a0e4156SSadaf Ebrahimi```cpp 2306*9a0e4156SSadaf Ebrahimiconst char * CAPSTONE_API cs_insn_name(csh ud, unsigned int insn) 2307*9a0e4156SSadaf Ebrahimi{ 2308*9a0e4156SSadaf Ebrahimi struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; 2309*9a0e4156SSadaf Ebrahimi 2310*9a0e4156SSadaf Ebrahimi if (!handle || handle->insn_name == NULL) { 2311*9a0e4156SSadaf Ebrahimi return NULL; 2312*9a0e4156SSadaf Ebrahimi } 2313*9a0e4156SSadaf Ebrahimi 2314*9a0e4156SSadaf Ebrahimi return handle->insn_name(ud, insn); 2315*9a0e4156SSadaf Ebrahimi} 2316*9a0e4156SSadaf Ebrahimi``` 2317*9a0e4156SSadaf Ebrahimi 2318*9a0e4156SSadaf Ebrahimi</details> 2319*9a0e4156SSadaf Ebrahimi 2320*9a0e4156SSadaf Ebrahimi 2321*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary> 2322*9a0e4156SSadaf Ebrahimi 2323*9a0e4156SSadaf Ebrahimi```cpp 2324*9a0e4156SSadaf Ebrahimi#include <iostream> 2325*9a0e4156SSadaf Ebrahimi#include <stdio.h> 2326*9a0e4156SSadaf Ebrahimi 2327*9a0e4156SSadaf Ebrahimi#include "capstone.h" 2328*9a0e4156SSadaf Ebrahimi#include "platform.h" 2329*9a0e4156SSadaf Ebrahimi 2330*9a0e4156SSadaf Ebrahimiusing namespace std; 2331*9a0e4156SSadaf Ebrahimi 2332*9a0e4156SSadaf Ebrahimistruct platform { 2333*9a0e4156SSadaf Ebrahimi cs_arch arch; 2334*9a0e4156SSadaf Ebrahimi cs_mode mode; 2335*9a0e4156SSadaf Ebrahimi unsigned char* code; 2336*9a0e4156SSadaf Ebrahimi size_t size; 2337*9a0e4156SSadaf Ebrahimi const char* comment; 2338*9a0e4156SSadaf Ebrahimi cs_opt_type opt_type; 2339*9a0e4156SSadaf Ebrahimi cs_opt_value opt_value; 2340*9a0e4156SSadaf Ebrahimi}; 2341*9a0e4156SSadaf Ebrahimi 2342*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len) 2343*9a0e4156SSadaf Ebrahimi{ 2344*9a0e4156SSadaf Ebrahimi unsigned char* c; 2345*9a0e4156SSadaf Ebrahimi 2346*9a0e4156SSadaf Ebrahimi printf("Code: "); 2347*9a0e4156SSadaf Ebrahimi for (c = str; c < str + len; c++) { 2348*9a0e4156SSadaf Ebrahimi printf("0x%02x ", *c & 0xff); 2349*9a0e4156SSadaf Ebrahimi } 2350*9a0e4156SSadaf Ebrahimi printf("\n"); 2351*9a0e4156SSadaf Ebrahimi} 2352*9a0e4156SSadaf Ebrahimi 2353*9a0e4156SSadaf Ebrahimistatic void test() 2354*9a0e4156SSadaf Ebrahimi{ 2355*9a0e4156SSadaf Ebrahimi 2356*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff" 2357*9a0e4156SSadaf Ebrahimi 2358*9a0e4156SSadaf Ebrahimi struct platform platforms[] = { 2359*9a0e4156SSadaf Ebrahimi { 2360*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 2361*9a0e4156SSadaf Ebrahimi CS_MODE_64, 2362*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE64, 2363*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE64) - 1, 2364*9a0e4156SSadaf Ebrahimi "X86 64 (Intel syntax)" 2365*9a0e4156SSadaf Ebrahimi }, 2366*9a0e4156SSadaf Ebrahimi }; 2367*9a0e4156SSadaf Ebrahimi 2368*9a0e4156SSadaf Ebrahimi csh handle; 2369*9a0e4156SSadaf Ebrahimi uint64_t address; 2370*9a0e4156SSadaf Ebrahimi cs_insn* insn; 2371*9a0e4156SSadaf Ebrahimi cs_detail* detail; 2372*9a0e4156SSadaf Ebrahimi int i; 2373*9a0e4156SSadaf Ebrahimi cs_err err; 2374*9a0e4156SSadaf Ebrahimi const uint8_t* code; 2375*9a0e4156SSadaf Ebrahimi size_t size; 2376*9a0e4156SSadaf Ebrahimi 2377*9a0e4156SSadaf Ebrahimi for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) { 2378*9a0e4156SSadaf Ebrahimi printf("****************\n"); 2379*9a0e4156SSadaf Ebrahimi printf("Platform: %s\n", platforms[i].comment); 2380*9a0e4156SSadaf Ebrahimi err = cs_open(platforms[i].arch, platforms[i].mode, &handle); 2381*9a0e4156SSadaf Ebrahimi if (err) { 2382*9a0e4156SSadaf Ebrahimi printf("Failed on cs_open() with error returned: %u\n", err); 2383*9a0e4156SSadaf Ebrahimi abort(); 2384*9a0e4156SSadaf Ebrahimi } 2385*9a0e4156SSadaf Ebrahimi 2386*9a0e4156SSadaf Ebrahimi if (platforms[i].opt_type) 2387*9a0e4156SSadaf Ebrahimi cs_option(handle, platforms[i].opt_type, platforms[i].opt_value); 2388*9a0e4156SSadaf Ebrahimi 2389*9a0e4156SSadaf Ebrahimi cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); 2390*9a0e4156SSadaf Ebrahimi 2391*9a0e4156SSadaf Ebrahimi insn = cs_malloc(handle); 2392*9a0e4156SSadaf Ebrahimi 2393*9a0e4156SSadaf Ebrahimi print_string_hex(platforms[i].code, platforms[i].size); 2394*9a0e4156SSadaf Ebrahimi printf("Disasm:\n"); 2395*9a0e4156SSadaf Ebrahimi 2396*9a0e4156SSadaf Ebrahimi address = 0x1000; 2397*9a0e4156SSadaf Ebrahimi code = platforms[i].code; 2398*9a0e4156SSadaf Ebrahimi size = platforms[i].size; 2399*9a0e4156SSadaf Ebrahimi while (cs_disasm_iter(handle, &code, &size, &address, insn)) { 2400*9a0e4156SSadaf Ebrahimi int n; 2401*9a0e4156SSadaf Ebrahimi 2402*9a0e4156SSadaf Ebrahimi printf("0x%" PRIx64 ":\t%s\t\t%s", 2403*9a0e4156SSadaf Ebrahimi insn->address, insn->mnemonic, insn->op_str); 2404*9a0e4156SSadaf Ebrahimi printf(" instruction: %s", cs_insn_name(handle, insn->id)); //输出该行的操作指令 2405*9a0e4156SSadaf Ebrahimi cout << endl; 2406*9a0e4156SSadaf Ebrahimi 2407*9a0e4156SSadaf Ebrahimi printf("\n"); 2408*9a0e4156SSadaf Ebrahimi cs_free(insn, 1); 2409*9a0e4156SSadaf Ebrahimi cs_close(&handle); 2410*9a0e4156SSadaf Ebrahimi } 2411*9a0e4156SSadaf Ebrahimi} 2412*9a0e4156SSadaf Ebrahimi 2413*9a0e4156SSadaf Ebrahimiint main() 2414*9a0e4156SSadaf Ebrahimi{ 2415*9a0e4156SSadaf Ebrahimi test(); 2416*9a0e4156SSadaf Ebrahimi 2417*9a0e4156SSadaf Ebrahimi return 0; 2418*9a0e4156SSadaf Ebrahimi} 2419*9a0e4156SSadaf Ebrahimi``` 2420*9a0e4156SSadaf Ebrahimi 2421*9a0e4156SSadaf Ebrahimi</details> 2422*9a0e4156SSadaf Ebrahimi 2423*9a0e4156SSadaf Ebrahimi输出 2424*9a0e4156SSadaf Ebrahimi 2425*9a0e4156SSadaf Ebrahimi 2426*9a0e4156SSadaf Ebrahimi 2427*9a0e4156SSadaf Ebrahimi 2428*9a0e4156SSadaf Ebrahimi### cs_group_name 2429*9a0e4156SSadaf Ebrahimi 2430*9a0e4156SSadaf Ebrahimi`const char * CAPSTONE_API cs_group_name(csh handle, unsigned int group_id);` 2431*9a0e4156SSadaf Ebrahimi 2432*9a0e4156SSadaf Ebrahimi输出指令类型名字 2433*9a0e4156SSadaf Ebrahimi 2434*9a0e4156SSadaf Ebrahimi指令id可在相关架构的头文件(建立项目时复制到项目文件夹的那些头文件)内找到 2435*9a0e4156SSadaf Ebrahimi 2436*9a0e4156SSadaf Ebrahimi注意: 当处于diet模式时此API不可用,因为引擎不会存储寄存器名 2437*9a0e4156SSadaf Ebrahimi 2438*9a0e4156SSadaf Ebrahimi``` 2439*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 2440*9a0e4156SSadaf Ebrahimiinsn_id: 指令类型id 2441*9a0e4156SSadaf Ebrahimireturn: 指令类型的字符名, 如果insn_id不可用返回NULL 2442*9a0e4156SSadaf Ebrahimi``` 2443*9a0e4156SSadaf Ebrahimi 2444*9a0e4156SSadaf Ebrahimi示例都与上面类似,略。 2445*9a0e4156SSadaf Ebrahimi 2446*9a0e4156SSadaf Ebrahimi 2447*9a0e4156SSadaf Ebrahimi### cs_insn_group 2448*9a0e4156SSadaf Ebrahimi 2449*9a0e4156SSadaf Ebrahimi`bool CAPSTONE_API cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id);` 2450*9a0e4156SSadaf Ebrahimi 2451*9a0e4156SSadaf Ebrahimi检查反汇编后的指令是否属于某个特定指令类型 2452*9a0e4156SSadaf Ebrahimi 2453*9a0e4156SSadaf Ebrahimi注意:只有当detail选项为ON时这个API可用 (默认OFF). 2454*9a0e4156SSadaf Ebrahimi 2455*9a0e4156SSadaf Ebrahimi在“diet”模式下,此API没有用,因为引擎不更新insn->groups数组 2456*9a0e4156SSadaf Ebrahimi 2457*9a0e4156SSadaf Ebrahimi``` 2458*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 2459*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构 2460*9a0e4156SSadaf Ebrahimigroup_id: 要检查此指令是否属于的指令类型。 2461*9a0e4156SSadaf Ebrahimireturn: 如果该指令确实属于给定的指令类型,则为true,否则为false。 2462*9a0e4156SSadaf Ebrahimi``` 2463*9a0e4156SSadaf Ebrahimi 2464*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 2465*9a0e4156SSadaf Ebrahimi 2466*9a0e4156SSadaf Ebrahimi```cpp 2467*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id) 2468*9a0e4156SSadaf Ebrahimi{ 2469*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 2470*9a0e4156SSadaf Ebrahimi if (!ud) 2471*9a0e4156SSadaf Ebrahimi return false; 2472*9a0e4156SSadaf Ebrahimi 2473*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 2474*9a0e4156SSadaf Ebrahimi 2475*9a0e4156SSadaf Ebrahimi if (!handle->detail) { 2476*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2477*9a0e4156SSadaf Ebrahimi return false; 2478*9a0e4156SSadaf Ebrahimi } 2479*9a0e4156SSadaf Ebrahimi 2480*9a0e4156SSadaf Ebrahimi if (!insn->id) { 2481*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_SKIPDATA; 2482*9a0e4156SSadaf Ebrahimi return false; 2483*9a0e4156SSadaf Ebrahimi } 2484*9a0e4156SSadaf Ebrahimi 2485*9a0e4156SSadaf Ebrahimi if (!insn->detail) { 2486*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2487*9a0e4156SSadaf Ebrahimi return false; 2488*9a0e4156SSadaf Ebrahimi } 2489*9a0e4156SSadaf Ebrahimi 2490*9a0e4156SSadaf Ebrahimi return arr_exist8(insn->detail->groups, insn->detail->groups_count, group_id); 2491*9a0e4156SSadaf Ebrahimi} 2492*9a0e4156SSadaf Ebrahimi``` 2493*9a0e4156SSadaf Ebrahimi 2494*9a0e4156SSadaf Ebrahimi</details> 2495*9a0e4156SSadaf Ebrahimi 2496*9a0e4156SSadaf Ebrahimi 2497*9a0e4156SSadaf Ebrahimi<details><summary> 示例(判断是否属于跳转指令) </summary> 2498*9a0e4156SSadaf Ebrahimi 2499*9a0e4156SSadaf Ebrahimi```cpp 2500*9a0e4156SSadaf Ebrahimi#include <iostream> 2501*9a0e4156SSadaf Ebrahimi#include <stdio.h> 2502*9a0e4156SSadaf Ebrahimi 2503*9a0e4156SSadaf Ebrahimi#include "capstone.h" 2504*9a0e4156SSadaf Ebrahimi#include "platform.h" 2505*9a0e4156SSadaf Ebrahimi 2506*9a0e4156SSadaf Ebrahimiusing namespace std; 2507*9a0e4156SSadaf Ebrahimi 2508*9a0e4156SSadaf Ebrahimistruct platform { 2509*9a0e4156SSadaf Ebrahimi cs_arch arch; 2510*9a0e4156SSadaf Ebrahimi cs_mode mode; 2511*9a0e4156SSadaf Ebrahimi unsigned char* code; 2512*9a0e4156SSadaf Ebrahimi size_t size; 2513*9a0e4156SSadaf Ebrahimi const char* comment; 2514*9a0e4156SSadaf Ebrahimi cs_opt_type opt_type; 2515*9a0e4156SSadaf Ebrahimi cs_opt_value opt_value; 2516*9a0e4156SSadaf Ebrahimi}; 2517*9a0e4156SSadaf Ebrahimi 2518*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len) 2519*9a0e4156SSadaf Ebrahimi{ 2520*9a0e4156SSadaf Ebrahimi unsigned char* c; 2521*9a0e4156SSadaf Ebrahimi 2522*9a0e4156SSadaf Ebrahimi printf("Code: "); 2523*9a0e4156SSadaf Ebrahimi for (c = str; c < str + len; c++) { 2524*9a0e4156SSadaf Ebrahimi printf("0x%02x ", *c & 0xff); 2525*9a0e4156SSadaf Ebrahimi } 2526*9a0e4156SSadaf Ebrahimi printf("\n"); 2527*9a0e4156SSadaf Ebrahimi} 2528*9a0e4156SSadaf Ebrahimi 2529*9a0e4156SSadaf Ebrahimistatic void test() 2530*9a0e4156SSadaf Ebrahimi{ 2531*9a0e4156SSadaf Ebrahimi 2532*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff" 2533*9a0e4156SSadaf Ebrahimi 2534*9a0e4156SSadaf Ebrahimi struct platform platforms[] = { 2535*9a0e4156SSadaf Ebrahimi { 2536*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 2537*9a0e4156SSadaf Ebrahimi CS_MODE_64, 2538*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE64, 2539*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE64) - 1, 2540*9a0e4156SSadaf Ebrahimi "X86 64 (Intel syntax)" 2541*9a0e4156SSadaf Ebrahimi }, 2542*9a0e4156SSadaf Ebrahimi }; 2543*9a0e4156SSadaf Ebrahimi 2544*9a0e4156SSadaf Ebrahimi csh handle; 2545*9a0e4156SSadaf Ebrahimi uint64_t address; 2546*9a0e4156SSadaf Ebrahimi cs_insn* insn; 2547*9a0e4156SSadaf Ebrahimi cs_detail* detail; 2548*9a0e4156SSadaf Ebrahimi int i; 2549*9a0e4156SSadaf Ebrahimi cs_err err; 2550*9a0e4156SSadaf Ebrahimi const uint8_t* code; 2551*9a0e4156SSadaf Ebrahimi size_t size; 2552*9a0e4156SSadaf Ebrahimi 2553*9a0e4156SSadaf Ebrahimi for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) { 2554*9a0e4156SSadaf Ebrahimi printf("****************\n"); 2555*9a0e4156SSadaf Ebrahimi printf("Platform: %s\n", platforms[i].comment); 2556*9a0e4156SSadaf Ebrahimi err = cs_open(platforms[i].arch, platforms[i].mode, &handle); 2557*9a0e4156SSadaf Ebrahimi if (err) { 2558*9a0e4156SSadaf Ebrahimi printf("Failed on cs_open() with error returned: %u\n", err); 2559*9a0e4156SSadaf Ebrahimi abort(); 2560*9a0e4156SSadaf Ebrahimi } 2561*9a0e4156SSadaf Ebrahimi 2562*9a0e4156SSadaf Ebrahimi if (platforms[i].opt_type) 2563*9a0e4156SSadaf Ebrahimi cs_option(handle, platforms[i].opt_type, platforms[i].opt_value); 2564*9a0e4156SSadaf Ebrahimi 2565*9a0e4156SSadaf Ebrahimi cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); 2566*9a0e4156SSadaf Ebrahimi 2567*9a0e4156SSadaf Ebrahimi insn = cs_malloc(handle); 2568*9a0e4156SSadaf Ebrahimi 2569*9a0e4156SSadaf Ebrahimi print_string_hex(platforms[i].code, platforms[i].size); 2570*9a0e4156SSadaf Ebrahimi printf("Disasm:\n"); 2571*9a0e4156SSadaf Ebrahimi 2572*9a0e4156SSadaf Ebrahimi address = 0x1000; 2573*9a0e4156SSadaf Ebrahimi code = platforms[i].code; 2574*9a0e4156SSadaf Ebrahimi size = platforms[i].size; 2575*9a0e4156SSadaf Ebrahimi while (cs_disasm_iter(handle, &code, &size, &address, insn)) { 2576*9a0e4156SSadaf Ebrahimi int n; 2577*9a0e4156SSadaf Ebrahimi 2578*9a0e4156SSadaf Ebrahimi printf("0x%" PRIx64 ":\t%s\t\t%s ", 2579*9a0e4156SSadaf Ebrahimi insn->address, insn->mnemonic, insn->op_str); 2580*9a0e4156SSadaf Ebrahimi cout << "is JUMP: " <<cs_insn_group(handle, insn, CS_GRP_JUMP) << endl; //判断是否为跳转指令 2581*9a0e4156SSadaf Ebrahimi cout << endl; 2582*9a0e4156SSadaf Ebrahimi 2583*9a0e4156SSadaf Ebrahimi printf("\n"); 2584*9a0e4156SSadaf Ebrahimi cs_free(insn, 1); 2585*9a0e4156SSadaf Ebrahimi cs_close(&handle); 2586*9a0e4156SSadaf Ebrahimi } 2587*9a0e4156SSadaf Ebrahimi} 2588*9a0e4156SSadaf Ebrahimi 2589*9a0e4156SSadaf Ebrahimiint main() 2590*9a0e4156SSadaf Ebrahimi{ 2591*9a0e4156SSadaf Ebrahimi test(); 2592*9a0e4156SSadaf Ebrahimi 2593*9a0e4156SSadaf Ebrahimi return 0; 2594*9a0e4156SSadaf Ebrahimi} 2595*9a0e4156SSadaf Ebrahimi``` 2596*9a0e4156SSadaf Ebrahimi 2597*9a0e4156SSadaf Ebrahimi</details> 2598*9a0e4156SSadaf Ebrahimi 2599*9a0e4156SSadaf Ebrahimi输出 2600*9a0e4156SSadaf Ebrahimi 2601*9a0e4156SSadaf Ebrahimi 2602*9a0e4156SSadaf Ebrahimi 2603*9a0e4156SSadaf Ebrahimi 2604*9a0e4156SSadaf Ebrahimi### cs_reg_read 2605*9a0e4156SSadaf Ebrahimi 2606*9a0e4156SSadaf Ebrahimi`bool CAPSTONE_API cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id);` 2607*9a0e4156SSadaf Ebrahimi 2608*9a0e4156SSadaf Ebrahimi检查反汇编指令是否隐式使用特定寄存器。 2609*9a0e4156SSadaf Ebrahimi 2610*9a0e4156SSadaf Ebrahimi注意:此API仅在启用detail选项时有效(默认为关闭) 2611*9a0e4156SSadaf Ebrahimi 2612*9a0e4156SSadaf Ebrahimi在“diet”模式下,此API没有用,因为引擎不更新insn->regs_read数组 2613*9a0e4156SSadaf Ebrahimi 2614*9a0e4156SSadaf Ebrahimi``` 2615*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构 2616*9a0e4156SSadaf Ebrahimireg_id: 标注想要检查的这个指令是否使用了它。 2617*9a0e4156SSadaf Ebrahimireturn: 如果该指令确实隐式使用了给定寄存器,则为true,否则为false。 2618*9a0e4156SSadaf Ebrahimi``` 2619*9a0e4156SSadaf Ebrahimi 2620*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 2621*9a0e4156SSadaf Ebrahimi 2622*9a0e4156SSadaf Ebrahimi```cpp 2623*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id) 2624*9a0e4156SSadaf Ebrahimi{ 2625*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 2626*9a0e4156SSadaf Ebrahimi if (!ud) 2627*9a0e4156SSadaf Ebrahimi return false; 2628*9a0e4156SSadaf Ebrahimi 2629*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 2630*9a0e4156SSadaf Ebrahimi 2631*9a0e4156SSadaf Ebrahimi if (!handle->detail) { 2632*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2633*9a0e4156SSadaf Ebrahimi return false; 2634*9a0e4156SSadaf Ebrahimi } 2635*9a0e4156SSadaf Ebrahimi 2636*9a0e4156SSadaf Ebrahimi if (!insn->id) { 2637*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_SKIPDATA; 2638*9a0e4156SSadaf Ebrahimi return false; 2639*9a0e4156SSadaf Ebrahimi } 2640*9a0e4156SSadaf Ebrahimi 2641*9a0e4156SSadaf Ebrahimi if (!insn->detail) { 2642*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2643*9a0e4156SSadaf Ebrahimi return false; 2644*9a0e4156SSadaf Ebrahimi } 2645*9a0e4156SSadaf Ebrahimi 2646*9a0e4156SSadaf Ebrahimi return arr_exist(insn->detail->regs_read, insn->detail->regs_read_count, reg_id); 2647*9a0e4156SSadaf Ebrahimi} 2648*9a0e4156SSadaf Ebrahimi``` 2649*9a0e4156SSadaf Ebrahimi</details> 2650*9a0e4156SSadaf Ebrahimi 2651*9a0e4156SSadaf Ebrahimi示例同API cs_disasm_iter 2652*9a0e4156SSadaf Ebrahimi 2653*9a0e4156SSadaf Ebrahimi 2654*9a0e4156SSadaf Ebrahimi### cs_reg_write 2655*9a0e4156SSadaf Ebrahimi 2656*9a0e4156SSadaf Ebrahimi`bool CAPSTONE_API cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id);` 2657*9a0e4156SSadaf Ebrahimi 2658*9a0e4156SSadaf Ebrahimi检查反汇编指令是否隐式修改了特定寄存器。 2659*9a0e4156SSadaf Ebrahimi 2660*9a0e4156SSadaf Ebrahimi注意:此API仅在启用detail选项时有效(默认为关闭) 2661*9a0e4156SSadaf Ebrahimi 2662*9a0e4156SSadaf Ebrahimi在“diet”模式下,此API没有用,因为引擎不更新insn->regs_read数组 2663*9a0e4156SSadaf Ebrahimi 2664*9a0e4156SSadaf Ebrahimi``` 2665*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构 2666*9a0e4156SSadaf Ebrahimireg_id: 标注想要检查的这个指令是否修改了它。 2667*9a0e4156SSadaf Ebrahimireturn: 如果该指令确实隐式修改了给定寄存器,则为true,否则为false。 2668*9a0e4156SSadaf Ebrahimi``` 2669*9a0e4156SSadaf Ebrahimi 2670*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 2671*9a0e4156SSadaf Ebrahimi 2672*9a0e4156SSadaf Ebrahimi```cpp 2673*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id) 2674*9a0e4156SSadaf Ebrahimi{ 2675*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 2676*9a0e4156SSadaf Ebrahimi if (!ud) 2677*9a0e4156SSadaf Ebrahimi return false; 2678*9a0e4156SSadaf Ebrahimi 2679*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 2680*9a0e4156SSadaf Ebrahimi 2681*9a0e4156SSadaf Ebrahimi if (!handle->detail) { 2682*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2683*9a0e4156SSadaf Ebrahimi return false; 2684*9a0e4156SSadaf Ebrahimi } 2685*9a0e4156SSadaf Ebrahimi 2686*9a0e4156SSadaf Ebrahimi if (!insn->id) { 2687*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_SKIPDATA; 2688*9a0e4156SSadaf Ebrahimi return false; 2689*9a0e4156SSadaf Ebrahimi } 2690*9a0e4156SSadaf Ebrahimi 2691*9a0e4156SSadaf Ebrahimi if (!insn->detail) { 2692*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2693*9a0e4156SSadaf Ebrahimi return false; 2694*9a0e4156SSadaf Ebrahimi } 2695*9a0e4156SSadaf Ebrahimi 2696*9a0e4156SSadaf Ebrahimi return arr_exist(insn->detail->regs_write, insn->detail->regs_write_count, reg_id); 2697*9a0e4156SSadaf Ebrahimi} 2698*9a0e4156SSadaf Ebrahimi``` 2699*9a0e4156SSadaf Ebrahimi</details> 2700*9a0e4156SSadaf Ebrahimi 2701*9a0e4156SSadaf Ebrahimi示例同API cs_disasm_iter 2702*9a0e4156SSadaf Ebrahimi 2703*9a0e4156SSadaf Ebrahimi 2704*9a0e4156SSadaf Ebrahimi### cs_op_count 2705*9a0e4156SSadaf Ebrahimi 2706*9a0e4156SSadaf Ebrahimi`int CAPSTONE_API cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type);` 2707*9a0e4156SSadaf Ebrahimi 2708*9a0e4156SSadaf Ebrahimi计算给定类型的操作数的数量 2709*9a0e4156SSadaf Ebrahimi 2710*9a0e4156SSadaf Ebrahimi注意:只有当detail选项为ON时这个API可用 (默认OFF). 2711*9a0e4156SSadaf Ebrahimi 2712*9a0e4156SSadaf Ebrahimi``` 2713*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 2714*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构 2715*9a0e4156SSadaf Ebrahimiop_type: 要找到的操作数类型。 2716*9a0e4156SSadaf Ebrahimireturn: 指令insn中给定类型op_type的操作数的数量,返回-1表示查找失败。 2717*9a0e4156SSadaf Ebrahimi``` 2718*9a0e4156SSadaf Ebrahimi 2719*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 2720*9a0e4156SSadaf Ebrahimi 2721*9a0e4156SSadaf Ebrahimi```cpp 2722*9a0e4156SSadaf Ebrahimiint CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type) 2723*9a0e4156SSadaf Ebrahimi{ 2724*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 2725*9a0e4156SSadaf Ebrahimi unsigned int count = 0, i; 2726*9a0e4156SSadaf Ebrahimi if (!ud) 2727*9a0e4156SSadaf Ebrahimi return -1; 2728*9a0e4156SSadaf Ebrahimi 2729*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 2730*9a0e4156SSadaf Ebrahimi 2731*9a0e4156SSadaf Ebrahimi if (!handle->detail) { 2732*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2733*9a0e4156SSadaf Ebrahimi return -1; 2734*9a0e4156SSadaf Ebrahimi } 2735*9a0e4156SSadaf Ebrahimi 2736*9a0e4156SSadaf Ebrahimi if (!insn->id) { 2737*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_SKIPDATA; 2738*9a0e4156SSadaf Ebrahimi return -1; 2739*9a0e4156SSadaf Ebrahimi } 2740*9a0e4156SSadaf Ebrahimi 2741*9a0e4156SSadaf Ebrahimi if (!insn->detail) { 2742*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2743*9a0e4156SSadaf Ebrahimi return -1; 2744*9a0e4156SSadaf Ebrahimi } 2745*9a0e4156SSadaf Ebrahimi 2746*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_OK; 2747*9a0e4156SSadaf Ebrahimi 2748*9a0e4156SSadaf Ebrahimi switch (handle->arch) { 2749*9a0e4156SSadaf Ebrahimi default: 2750*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_HANDLE; 2751*9a0e4156SSadaf Ebrahimi return -1; 2752*9a0e4156SSadaf Ebrahimi case CS_ARCH_ARM: 2753*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->arm.op_count; i++) 2754*9a0e4156SSadaf Ebrahimi if (insn->detail->arm.operands[i].type == (arm_op_type)op_type) 2755*9a0e4156SSadaf Ebrahimi count++; 2756*9a0e4156SSadaf Ebrahimi break; 2757*9a0e4156SSadaf Ebrahimi case CS_ARCH_ARM64: 2758*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->arm64.op_count; i++) 2759*9a0e4156SSadaf Ebrahimi if (insn->detail->arm64.operands[i].type == (arm64_op_type)op_type) 2760*9a0e4156SSadaf Ebrahimi count++; 2761*9a0e4156SSadaf Ebrahimi break; 2762*9a0e4156SSadaf Ebrahimi case CS_ARCH_X86: 2763*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->x86.op_count; i++) 2764*9a0e4156SSadaf Ebrahimi if (insn->detail->x86.operands[i].type == (x86_op_type)op_type) 2765*9a0e4156SSadaf Ebrahimi count++; 2766*9a0e4156SSadaf Ebrahimi break; 2767*9a0e4156SSadaf Ebrahimi case CS_ARCH_MIPS: 2768*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->mips.op_count; i++) 2769*9a0e4156SSadaf Ebrahimi if (insn->detail->mips.operands[i].type == (mips_op_type)op_type) 2770*9a0e4156SSadaf Ebrahimi count++; 2771*9a0e4156SSadaf Ebrahimi break; 2772*9a0e4156SSadaf Ebrahimi case CS_ARCH_PPC: 2773*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->ppc.op_count; i++) 2774*9a0e4156SSadaf Ebrahimi if (insn->detail->ppc.operands[i].type == (ppc_op_type)op_type) 2775*9a0e4156SSadaf Ebrahimi count++; 2776*9a0e4156SSadaf Ebrahimi break; 2777*9a0e4156SSadaf Ebrahimi case CS_ARCH_SPARC: 2778*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->sparc.op_count; i++) 2779*9a0e4156SSadaf Ebrahimi if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type) 2780*9a0e4156SSadaf Ebrahimi count++; 2781*9a0e4156SSadaf Ebrahimi break; 2782*9a0e4156SSadaf Ebrahimi case CS_ARCH_SYSZ: 2783*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->sysz.op_count; i++) 2784*9a0e4156SSadaf Ebrahimi if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type) 2785*9a0e4156SSadaf Ebrahimi count++; 2786*9a0e4156SSadaf Ebrahimi break; 2787*9a0e4156SSadaf Ebrahimi case CS_ARCH_XCORE: 2788*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->xcore.op_count; i++) 2789*9a0e4156SSadaf Ebrahimi if (insn->detail->xcore.operands[i].type == (xcore_op_type)op_type) 2790*9a0e4156SSadaf Ebrahimi count++; 2791*9a0e4156SSadaf Ebrahimi break; 2792*9a0e4156SSadaf Ebrahimi case CS_ARCH_M68K: 2793*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->m68k.op_count; i++) 2794*9a0e4156SSadaf Ebrahimi if (insn->detail->m68k.operands[i].type == (m68k_op_type)op_type) 2795*9a0e4156SSadaf Ebrahimi count++; 2796*9a0e4156SSadaf Ebrahimi break; 2797*9a0e4156SSadaf Ebrahimi case CS_ARCH_TMS320C64X: 2798*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->tms320c64x.op_count; i++) 2799*9a0e4156SSadaf Ebrahimi if (insn->detail->tms320c64x.operands[i].type == (tms320c64x_op_type)op_type) 2800*9a0e4156SSadaf Ebrahimi count++; 2801*9a0e4156SSadaf Ebrahimi break; 2802*9a0e4156SSadaf Ebrahimi case CS_ARCH_M680X: 2803*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->m680x.op_count; i++) 2804*9a0e4156SSadaf Ebrahimi if (insn->detail->m680x.operands[i].type == (m680x_op_type)op_type) 2805*9a0e4156SSadaf Ebrahimi count++; 2806*9a0e4156SSadaf Ebrahimi break; 2807*9a0e4156SSadaf Ebrahimi case CS_ARCH_EVM: 2808*9a0e4156SSadaf Ebrahimi#if 0 2809*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->evm.op_count; i++) 2810*9a0e4156SSadaf Ebrahimi if (insn->detail->evm.operands[i].type == (evm_op_type)op_type) 2811*9a0e4156SSadaf Ebrahimi count++; 2812*9a0e4156SSadaf Ebrahimi#endif 2813*9a0e4156SSadaf Ebrahimi break; 2814*9a0e4156SSadaf Ebrahimi } 2815*9a0e4156SSadaf Ebrahimi 2816*9a0e4156SSadaf Ebrahimi return count; 2817*9a0e4156SSadaf Ebrahimi} 2818*9a0e4156SSadaf Ebrahimi``` 2819*9a0e4156SSadaf Ebrahimi 2820*9a0e4156SSadaf Ebrahimi</details> 2821*9a0e4156SSadaf Ebrahimi 2822*9a0e4156SSadaf Ebrahimi 2823*9a0e4156SSadaf Ebrahimi<details><summary> x86指令操作码类型示例(判断寄存操作码) </summary> 2824*9a0e4156SSadaf Ebrahimi 2825*9a0e4156SSadaf Ebrahimi```cpp 2826*9a0e4156SSadaf Ebrahimitypedef enum x86_op_type { 2827*9a0e4156SSadaf Ebrahimi X86_OP_INVALID = 0, ///< = CS_OP_INVALID (未初始化). 2828*9a0e4156SSadaf Ebrahimi X86_OP_REG, ///< = CS_OP_REG (寄存操作码). 2829*9a0e4156SSadaf Ebrahimi X86_OP_IMM, ///< = CS_OP_IMM (立即操作码). 2830*9a0e4156SSadaf Ebrahimi X86_OP_MEM, ///< = CS_OP_MEM (内存操作码). 2831*9a0e4156SSadaf Ebrahimi} x86_op_type; 2832*9a0e4156SSadaf Ebrahimi``` 2833*9a0e4156SSadaf Ebrahimi 2834*9a0e4156SSadaf Ebrahimi```cpp 2835*9a0e4156SSadaf Ebrahimi#include <iostream> 2836*9a0e4156SSadaf Ebrahimi#include <stdio.h> 2837*9a0e4156SSadaf Ebrahimi 2838*9a0e4156SSadaf Ebrahimi#include "capstone.h" 2839*9a0e4156SSadaf Ebrahimi#include "platform.h" 2840*9a0e4156SSadaf Ebrahimi 2841*9a0e4156SSadaf Ebrahimiusing namespace std; 2842*9a0e4156SSadaf Ebrahimi 2843*9a0e4156SSadaf Ebrahimistruct platform { 2844*9a0e4156SSadaf Ebrahimi cs_arch arch; 2845*9a0e4156SSadaf Ebrahimi cs_mode mode; 2846*9a0e4156SSadaf Ebrahimi unsigned char* code; 2847*9a0e4156SSadaf Ebrahimi size_t size; 2848*9a0e4156SSadaf Ebrahimi const char* comment; 2849*9a0e4156SSadaf Ebrahimi cs_opt_type opt_type; 2850*9a0e4156SSadaf Ebrahimi cs_opt_value opt_value; 2851*9a0e4156SSadaf Ebrahimi}; 2852*9a0e4156SSadaf Ebrahimi 2853*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len) 2854*9a0e4156SSadaf Ebrahimi{ 2855*9a0e4156SSadaf Ebrahimi unsigned char* c; 2856*9a0e4156SSadaf Ebrahimi 2857*9a0e4156SSadaf Ebrahimi printf("Code: "); 2858*9a0e4156SSadaf Ebrahimi for (c = str; c < str + len; c++) { 2859*9a0e4156SSadaf Ebrahimi printf("0x%02x ", *c & 0xff); 2860*9a0e4156SSadaf Ebrahimi } 2861*9a0e4156SSadaf Ebrahimi printf("\n"); 2862*9a0e4156SSadaf Ebrahimi} 2863*9a0e4156SSadaf Ebrahimi 2864*9a0e4156SSadaf Ebrahimistatic void test() 2865*9a0e4156SSadaf Ebrahimi{ 2866*9a0e4156SSadaf Ebrahimi 2867*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff" 2868*9a0e4156SSadaf Ebrahimi 2869*9a0e4156SSadaf Ebrahimi struct platform platforms[] = { 2870*9a0e4156SSadaf Ebrahimi { 2871*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 2872*9a0e4156SSadaf Ebrahimi CS_MODE_64, 2873*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE64, 2874*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE64) - 1, 2875*9a0e4156SSadaf Ebrahimi "X86 64 (Intel syntax)" 2876*9a0e4156SSadaf Ebrahimi }, 2877*9a0e4156SSadaf Ebrahimi }; 2878*9a0e4156SSadaf Ebrahimi 2879*9a0e4156SSadaf Ebrahimi csh handle; 2880*9a0e4156SSadaf Ebrahimi uint64_t address; 2881*9a0e4156SSadaf Ebrahimi cs_insn* insn; 2882*9a0e4156SSadaf Ebrahimi cs_detail* detail; 2883*9a0e4156SSadaf Ebrahimi int i; 2884*9a0e4156SSadaf Ebrahimi cs_err err; 2885*9a0e4156SSadaf Ebrahimi const uint8_t* code; 2886*9a0e4156SSadaf Ebrahimi size_t size; 2887*9a0e4156SSadaf Ebrahimi 2888*9a0e4156SSadaf Ebrahimi for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) { 2889*9a0e4156SSadaf Ebrahimi printf("****************\n"); 2890*9a0e4156SSadaf Ebrahimi printf("Platform: %s\n", platforms[i].comment); 2891*9a0e4156SSadaf Ebrahimi err = cs_open(platforms[i].arch, platforms[i].mode, &handle); 2892*9a0e4156SSadaf Ebrahimi if (err) { 2893*9a0e4156SSadaf Ebrahimi printf("Failed on cs_open() with error returned: %u\n", err); 2894*9a0e4156SSadaf Ebrahimi abort(); 2895*9a0e4156SSadaf Ebrahimi } 2896*9a0e4156SSadaf Ebrahimi 2897*9a0e4156SSadaf Ebrahimi if (platforms[i].opt_type) 2898*9a0e4156SSadaf Ebrahimi cs_option(handle, platforms[i].opt_type, platforms[i].opt_value); 2899*9a0e4156SSadaf Ebrahimi 2900*9a0e4156SSadaf Ebrahimi cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); 2901*9a0e4156SSadaf Ebrahimi 2902*9a0e4156SSadaf Ebrahimi insn = cs_malloc(handle); 2903*9a0e4156SSadaf Ebrahimi 2904*9a0e4156SSadaf Ebrahimi print_string_hex(platforms[i].code, platforms[i].size); 2905*9a0e4156SSadaf Ebrahimi printf("Disasm:\n"); 2906*9a0e4156SSadaf Ebrahimi 2907*9a0e4156SSadaf Ebrahimi address = 0x1000; 2908*9a0e4156SSadaf Ebrahimi code = platforms[i].code; 2909*9a0e4156SSadaf Ebrahimi size = platforms[i].size; 2910*9a0e4156SSadaf Ebrahimi while (cs_disasm_iter(handle, &code, &size, &address, insn)) { 2911*9a0e4156SSadaf Ebrahimi int n; 2912*9a0e4156SSadaf Ebrahimi 2913*9a0e4156SSadaf Ebrahimi printf("0x%" PRIx64 ":\t%s\t\t%s ", 2914*9a0e4156SSadaf Ebrahimi insn->address, insn->mnemonic, insn->op_str); 2915*9a0e4156SSadaf Ebrahimi cout << "is REG: " << cs_op_count(handle, insn, X86_OP_REG) << endl; //判断是否为寄存操作码 2916*9a0e4156SSadaf Ebrahimi cout << endl; 2917*9a0e4156SSadaf Ebrahimi 2918*9a0e4156SSadaf Ebrahimi printf("\n"); 2919*9a0e4156SSadaf Ebrahimi cs_free(insn, 1); 2920*9a0e4156SSadaf Ebrahimi cs_close(&handle); 2921*9a0e4156SSadaf Ebrahimi } 2922*9a0e4156SSadaf Ebrahimi} 2923*9a0e4156SSadaf Ebrahimi 2924*9a0e4156SSadaf Ebrahimiint main() 2925*9a0e4156SSadaf Ebrahimi{ 2926*9a0e4156SSadaf Ebrahimi test(); 2927*9a0e4156SSadaf Ebrahimi 2928*9a0e4156SSadaf Ebrahimi return 0; 2929*9a0e4156SSadaf Ebrahimi} 2930*9a0e4156SSadaf Ebrahimi``` 2931*9a0e4156SSadaf Ebrahimi 2932*9a0e4156SSadaf Ebrahimi</details> 2933*9a0e4156SSadaf Ebrahimi 2934*9a0e4156SSadaf Ebrahimi输出 2935*9a0e4156SSadaf Ebrahimi 2936*9a0e4156SSadaf Ebrahimi 2937*9a0e4156SSadaf Ebrahimi 2938*9a0e4156SSadaf Ebrahimi 2939*9a0e4156SSadaf Ebrahimi### cs_op_index 2940*9a0e4156SSadaf Ebrahimi 2941*9a0e4156SSadaf Ebrahimi`int CAPSTONE_API cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type, unsigned int position);` 2942*9a0e4156SSadaf Ebrahimi 2943*9a0e4156SSadaf Ebrahimi检索给定类型的操作数在`<arch>.operands[]`数组中的位置, 使用返回的位置访问操作数 2944*9a0e4156SSadaf Ebrahimi 2945*9a0e4156SSadaf Ebrahimi注意:只有当detail选项为ON时这个API可用 (默认OFF). 2946*9a0e4156SSadaf Ebrahimi 2947*9a0e4156SSadaf Ebrahimi``` 2948*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 2949*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构 2950*9a0e4156SSadaf Ebrahimiop_type: 要找到的操作数类型。 2951*9a0e4156SSadaf Ebrahimiposition: 要查找的操作数的位置。范围一定在`[1, cs_op_count(handle, insn, op_type)]`内 2952*9a0e4156SSadaf Ebrahimireturn: 指令insn的`<arch>.operands[]`数组中给定类型op_type的操作数的索引,失败时返回-1。 2953*9a0e4156SSadaf Ebrahimi``` 2954*9a0e4156SSadaf Ebrahimi 2955*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 2956*9a0e4156SSadaf Ebrahimi 2957*9a0e4156SSadaf Ebrahimi```cpp 2958*9a0e4156SSadaf Ebrahimiint CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type, 2959*9a0e4156SSadaf Ebrahimi unsigned int post) 2960*9a0e4156SSadaf Ebrahimi{ 2961*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 2962*9a0e4156SSadaf Ebrahimi unsigned int count = 0, i; 2963*9a0e4156SSadaf Ebrahimi if (!ud) 2964*9a0e4156SSadaf Ebrahimi return -1; 2965*9a0e4156SSadaf Ebrahimi 2966*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 2967*9a0e4156SSadaf Ebrahimi 2968*9a0e4156SSadaf Ebrahimi if (!handle->detail) { 2969*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2970*9a0e4156SSadaf Ebrahimi return -1; 2971*9a0e4156SSadaf Ebrahimi } 2972*9a0e4156SSadaf Ebrahimi 2973*9a0e4156SSadaf Ebrahimi if (!insn->id) { 2974*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_SKIPDATA; 2975*9a0e4156SSadaf Ebrahimi return -1; 2976*9a0e4156SSadaf Ebrahimi } 2977*9a0e4156SSadaf Ebrahimi 2978*9a0e4156SSadaf Ebrahimi if (!insn->detail) { 2979*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 2980*9a0e4156SSadaf Ebrahimi return -1; 2981*9a0e4156SSadaf Ebrahimi } 2982*9a0e4156SSadaf Ebrahimi 2983*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_OK; 2984*9a0e4156SSadaf Ebrahimi 2985*9a0e4156SSadaf Ebrahimi switch (handle->arch) { 2986*9a0e4156SSadaf Ebrahimi default: 2987*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_HANDLE; 2988*9a0e4156SSadaf Ebrahimi return -1; 2989*9a0e4156SSadaf Ebrahimi case CS_ARCH_ARM: 2990*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->arm.op_count; i++) { 2991*9a0e4156SSadaf Ebrahimi if (insn->detail->arm.operands[i].type == (arm_op_type)op_type) 2992*9a0e4156SSadaf Ebrahimi count++; 2993*9a0e4156SSadaf Ebrahimi if (count == post) 2994*9a0e4156SSadaf Ebrahimi return i; 2995*9a0e4156SSadaf Ebrahimi } 2996*9a0e4156SSadaf Ebrahimi break; 2997*9a0e4156SSadaf Ebrahimi case CS_ARCH_ARM64: 2998*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->arm64.op_count; i++) { 2999*9a0e4156SSadaf Ebrahimi if (insn->detail->arm64.operands[i].type == (arm64_op_type)op_type) 3000*9a0e4156SSadaf Ebrahimi count++; 3001*9a0e4156SSadaf Ebrahimi if (count == post) 3002*9a0e4156SSadaf Ebrahimi return i; 3003*9a0e4156SSadaf Ebrahimi } 3004*9a0e4156SSadaf Ebrahimi break; 3005*9a0e4156SSadaf Ebrahimi case CS_ARCH_X86: 3006*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->x86.op_count; i++) { 3007*9a0e4156SSadaf Ebrahimi if (insn->detail->x86.operands[i].type == (x86_op_type)op_type) 3008*9a0e4156SSadaf Ebrahimi count++; 3009*9a0e4156SSadaf Ebrahimi if (count == post) 3010*9a0e4156SSadaf Ebrahimi return i; 3011*9a0e4156SSadaf Ebrahimi } 3012*9a0e4156SSadaf Ebrahimi break; 3013*9a0e4156SSadaf Ebrahimi case CS_ARCH_MIPS: 3014*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->mips.op_count; i++) { 3015*9a0e4156SSadaf Ebrahimi if (insn->detail->mips.operands[i].type == (mips_op_type)op_type) 3016*9a0e4156SSadaf Ebrahimi count++; 3017*9a0e4156SSadaf Ebrahimi if (count == post) 3018*9a0e4156SSadaf Ebrahimi return i; 3019*9a0e4156SSadaf Ebrahimi } 3020*9a0e4156SSadaf Ebrahimi break; 3021*9a0e4156SSadaf Ebrahimi case CS_ARCH_PPC: 3022*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->ppc.op_count; i++) { 3023*9a0e4156SSadaf Ebrahimi if (insn->detail->ppc.operands[i].type == (ppc_op_type)op_type) 3024*9a0e4156SSadaf Ebrahimi count++; 3025*9a0e4156SSadaf Ebrahimi if (count == post) 3026*9a0e4156SSadaf Ebrahimi return i; 3027*9a0e4156SSadaf Ebrahimi } 3028*9a0e4156SSadaf Ebrahimi break; 3029*9a0e4156SSadaf Ebrahimi case CS_ARCH_SPARC: 3030*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->sparc.op_count; i++) { 3031*9a0e4156SSadaf Ebrahimi if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type) 3032*9a0e4156SSadaf Ebrahimi count++; 3033*9a0e4156SSadaf Ebrahimi if (count == post) 3034*9a0e4156SSadaf Ebrahimi return i; 3035*9a0e4156SSadaf Ebrahimi } 3036*9a0e4156SSadaf Ebrahimi break; 3037*9a0e4156SSadaf Ebrahimi case CS_ARCH_SYSZ: 3038*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->sysz.op_count; i++) { 3039*9a0e4156SSadaf Ebrahimi if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type) 3040*9a0e4156SSadaf Ebrahimi count++; 3041*9a0e4156SSadaf Ebrahimi if (count == post) 3042*9a0e4156SSadaf Ebrahimi return i; 3043*9a0e4156SSadaf Ebrahimi } 3044*9a0e4156SSadaf Ebrahimi break; 3045*9a0e4156SSadaf Ebrahimi case CS_ARCH_XCORE: 3046*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->xcore.op_count; i++) { 3047*9a0e4156SSadaf Ebrahimi if (insn->detail->xcore.operands[i].type == (xcore_op_type)op_type) 3048*9a0e4156SSadaf Ebrahimi count++; 3049*9a0e4156SSadaf Ebrahimi if (count == post) 3050*9a0e4156SSadaf Ebrahimi return i; 3051*9a0e4156SSadaf Ebrahimi } 3052*9a0e4156SSadaf Ebrahimi break; 3053*9a0e4156SSadaf Ebrahimi case CS_ARCH_M68K: 3054*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->m68k.op_count; i++) { 3055*9a0e4156SSadaf Ebrahimi if (insn->detail->m68k.operands[i].type == (m68k_op_type)op_type) 3056*9a0e4156SSadaf Ebrahimi count++; 3057*9a0e4156SSadaf Ebrahimi if (count == post) 3058*9a0e4156SSadaf Ebrahimi return i; 3059*9a0e4156SSadaf Ebrahimi } 3060*9a0e4156SSadaf Ebrahimi break; 3061*9a0e4156SSadaf Ebrahimi case CS_ARCH_TMS320C64X: 3062*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->tms320c64x.op_count; i++) { 3063*9a0e4156SSadaf Ebrahimi if (insn->detail->tms320c64x.operands[i].type == (tms320c64x_op_type)op_type) 3064*9a0e4156SSadaf Ebrahimi count++; 3065*9a0e4156SSadaf Ebrahimi if (count == post) 3066*9a0e4156SSadaf Ebrahimi return i; 3067*9a0e4156SSadaf Ebrahimi } 3068*9a0e4156SSadaf Ebrahimi break; 3069*9a0e4156SSadaf Ebrahimi case CS_ARCH_M680X: 3070*9a0e4156SSadaf Ebrahimi for (i = 0; i < insn->detail->m680x.op_count; i++) { 3071*9a0e4156SSadaf Ebrahimi if (insn->detail->m680x.operands[i].type == (m680x_op_type)op_type) 3072*9a0e4156SSadaf Ebrahimi count++; 3073*9a0e4156SSadaf Ebrahimi if (count == post) 3074*9a0e4156SSadaf Ebrahimi return i; 3075*9a0e4156SSadaf Ebrahimi } 3076*9a0e4156SSadaf Ebrahimi break; 3077*9a0e4156SSadaf Ebrahimi } 3078*9a0e4156SSadaf Ebrahimi 3079*9a0e4156SSadaf Ebrahimi return -1; 3080*9a0e4156SSadaf Ebrahimi} 3081*9a0e4156SSadaf Ebrahimi``` 3082*9a0e4156SSadaf Ebrahimi</details> 3083*9a0e4156SSadaf Ebrahimi 3084*9a0e4156SSadaf Ebrahimi 3085*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary> 3086*9a0e4156SSadaf Ebrahimi 3087*9a0e4156SSadaf Ebrahimi```cpp 3088*9a0e4156SSadaf Ebrahimi#include <iostream> 3089*9a0e4156SSadaf Ebrahimi#include <stdio.h> 3090*9a0e4156SSadaf Ebrahimi 3091*9a0e4156SSadaf Ebrahimi#include "capstone.h" 3092*9a0e4156SSadaf Ebrahimi#include "platform.h" 3093*9a0e4156SSadaf Ebrahimi 3094*9a0e4156SSadaf Ebrahimiusing namespace std; 3095*9a0e4156SSadaf Ebrahimi 3096*9a0e4156SSadaf Ebrahimistruct platform { 3097*9a0e4156SSadaf Ebrahimi cs_arch arch; 3098*9a0e4156SSadaf Ebrahimi cs_mode mode; 3099*9a0e4156SSadaf Ebrahimi unsigned char* code; 3100*9a0e4156SSadaf Ebrahimi size_t size; 3101*9a0e4156SSadaf Ebrahimi const char* comment; 3102*9a0e4156SSadaf Ebrahimi cs_opt_type opt_type; 3103*9a0e4156SSadaf Ebrahimi cs_opt_value opt_value; 3104*9a0e4156SSadaf Ebrahimi}; 3105*9a0e4156SSadaf Ebrahimi 3106*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len) 3107*9a0e4156SSadaf Ebrahimi{ 3108*9a0e4156SSadaf Ebrahimi unsigned char* c; 3109*9a0e4156SSadaf Ebrahimi 3110*9a0e4156SSadaf Ebrahimi printf("Code: "); 3111*9a0e4156SSadaf Ebrahimi for (c = str; c < str + len; c++) { 3112*9a0e4156SSadaf Ebrahimi printf("0x%02x ", *c & 0xff); 3113*9a0e4156SSadaf Ebrahimi } 3114*9a0e4156SSadaf Ebrahimi printf("\n"); 3115*9a0e4156SSadaf Ebrahimi} 3116*9a0e4156SSadaf Ebrahimi 3117*9a0e4156SSadaf Ebrahimistatic void test() 3118*9a0e4156SSadaf Ebrahimi{ 3119*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff" 3120*9a0e4156SSadaf Ebrahimi struct platform platforms[] = { 3121*9a0e4156SSadaf Ebrahimi { 3122*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 3123*9a0e4156SSadaf Ebrahimi CS_MODE_64, 3124*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE64, 3125*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE64) - 1, 3126*9a0e4156SSadaf Ebrahimi "X86 64 (Intel syntax)" 3127*9a0e4156SSadaf Ebrahimi }, 3128*9a0e4156SSadaf Ebrahimi }; 3129*9a0e4156SSadaf Ebrahimi 3130*9a0e4156SSadaf Ebrahimi csh handle; 3131*9a0e4156SSadaf Ebrahimi uint64_t address; 3132*9a0e4156SSadaf Ebrahimi cs_insn* insn; 3133*9a0e4156SSadaf Ebrahimi cs_detail* detail; 3134*9a0e4156SSadaf Ebrahimi int i; 3135*9a0e4156SSadaf Ebrahimi cs_err err; 3136*9a0e4156SSadaf Ebrahimi const uint8_t* code; 3137*9a0e4156SSadaf Ebrahimi size_t size; 3138*9a0e4156SSadaf Ebrahimi 3139*9a0e4156SSadaf Ebrahimi cs_x86* x86; 3140*9a0e4156SSadaf Ebrahimi 3141*9a0e4156SSadaf Ebrahimi int count; 3142*9a0e4156SSadaf Ebrahimi 3143*9a0e4156SSadaf Ebrahimi for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) { 3144*9a0e4156SSadaf Ebrahimi printf("****************\n"); 3145*9a0e4156SSadaf Ebrahimi printf("Platform: %s\n", platforms[i].comment); 3146*9a0e4156SSadaf Ebrahimi err = cs_open(platforms[i].arch, platforms[i].mode, &handle); 3147*9a0e4156SSadaf Ebrahimi if (err) { 3148*9a0e4156SSadaf Ebrahimi printf("Failed on cs_open() with error returned: %u\n", err); 3149*9a0e4156SSadaf Ebrahimi abort(); 3150*9a0e4156SSadaf Ebrahimi } 3151*9a0e4156SSadaf Ebrahimi 3152*9a0e4156SSadaf Ebrahimi if (platforms[i].opt_type) 3153*9a0e4156SSadaf Ebrahimi cs_option(handle, platforms[i].opt_type, platforms[i].opt_value); 3154*9a0e4156SSadaf Ebrahimi 3155*9a0e4156SSadaf Ebrahimi cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); 3156*9a0e4156SSadaf Ebrahimi 3157*9a0e4156SSadaf Ebrahimi insn = cs_malloc(handle); 3158*9a0e4156SSadaf Ebrahimi x86 = &(insn->detail->x86); 3159*9a0e4156SSadaf Ebrahimi print_string_hex(platforms[i].code, platforms[i].size); 3160*9a0e4156SSadaf Ebrahimi printf("Disasm:\n"); 3161*9a0e4156SSadaf Ebrahimi 3162*9a0e4156SSadaf Ebrahimi address = 0x1000; 3163*9a0e4156SSadaf Ebrahimi code = platforms[i].code; 3164*9a0e4156SSadaf Ebrahimi size = platforms[i].size; 3165*9a0e4156SSadaf Ebrahimi while (cs_disasm_iter(handle, &code, &size, &address, insn)) { 3166*9a0e4156SSadaf Ebrahimi int n; 3167*9a0e4156SSadaf Ebrahimi 3168*9a0e4156SSadaf Ebrahimi printf("0x%" PRIx64 ":\t%s\t\t%s ", 3169*9a0e4156SSadaf Ebrahimi insn->address, insn->mnemonic, insn->op_str); 3170*9a0e4156SSadaf Ebrahimi cout << endl; 3171*9a0e4156SSadaf Ebrahimi 3172*9a0e4156SSadaf Ebrahimi count = cs_op_count(handle, insn, X86_OP_IMM); //查找立即数 3173*9a0e4156SSadaf Ebrahimi if (count) { 3174*9a0e4156SSadaf Ebrahimi printf("\timm_count: %u\n", count); 3175*9a0e4156SSadaf Ebrahimi for (i = 1; i < count + 1; i++) { 3176*9a0e4156SSadaf Ebrahimi int index = cs_op_index(handle, insn, X86_OP_IMM, i); 3177*9a0e4156SSadaf Ebrahimi printf("\timms[%u]: 0x%" PRIx64 "\n", i, x86->operands[index].imm); 3178*9a0e4156SSadaf Ebrahimi if (x86->encoding.imm_offset != 0) { 3179*9a0e4156SSadaf Ebrahimi printf("\timm_offset: 0x%x\n", x86->encoding.imm_offset); 3180*9a0e4156SSadaf Ebrahimi } 3181*9a0e4156SSadaf Ebrahimi if (x86->encoding.imm_size != 0) { 3182*9a0e4156SSadaf Ebrahimi printf("\timm_size: 0x%x\n", x86->encoding.imm_size); 3183*9a0e4156SSadaf Ebrahimi } 3184*9a0e4156SSadaf Ebrahimi } 3185*9a0e4156SSadaf Ebrahimi } 3186*9a0e4156SSadaf Ebrahimi } 3187*9a0e4156SSadaf Ebrahimi 3188*9a0e4156SSadaf Ebrahimi printf("\n"); 3189*9a0e4156SSadaf Ebrahimi cs_free(insn, 1); 3190*9a0e4156SSadaf Ebrahimi cs_close(&handle); 3191*9a0e4156SSadaf Ebrahimi } 3192*9a0e4156SSadaf Ebrahimi} 3193*9a0e4156SSadaf Ebrahimi 3194*9a0e4156SSadaf Ebrahimiint main() 3195*9a0e4156SSadaf Ebrahimi{ 3196*9a0e4156SSadaf Ebrahimi test(); 3197*9a0e4156SSadaf Ebrahimi return 0; 3198*9a0e4156SSadaf Ebrahimi} 3199*9a0e4156SSadaf Ebrahimi``` 3200*9a0e4156SSadaf Ebrahimi 3201*9a0e4156SSadaf Ebrahimi</details> 3202*9a0e4156SSadaf Ebrahimi 3203*9a0e4156SSadaf Ebrahimi输出 3204*9a0e4156SSadaf Ebrahimi 3205*9a0e4156SSadaf Ebrahimi 3206*9a0e4156SSadaf Ebrahimi 3207*9a0e4156SSadaf Ebrahimi### cs_regs_access 3208*9a0e4156SSadaf Ebrahimi 3209*9a0e4156SSadaf Ebrahimi```cpp 3210*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_regs_access(csh handle, const cs_insn *insn, 3211*9a0e4156SSadaf Ebrahimi cs_regs regs_read, uint8_t *regs_read_count, 3212*9a0e4156SSadaf Ebrahimi cs_regs regs_write, uint8_t *regs_write_count); 3213*9a0e4156SSadaf Ebrahimi``` 3214*9a0e4156SSadaf Ebrahimi 3215*9a0e4156SSadaf Ebrahimi检索由一条指令显式或隐式访问的所有寄存器 3216*9a0e4156SSadaf Ebrahimi 3217*9a0e4156SSadaf Ebrahimi注意: 在“diet”模式下,此API不可用,因为引擎不存储寄存器 3218*9a0e4156SSadaf Ebrahimi 3219*9a0e4156SSadaf Ebrahimi``` 3220*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄 3221*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()返回的反汇编指令结构 3222*9a0e4156SSadaf Ebrahimiregs_read:返回时,这个数组包含所有按指令读取的寄存器。 3223*9a0e4156SSadaf Ebrahimiregs_read_count:保存在regs_read数组中的寄存器数。 3224*9a0e4156SSadaf Ebrahimiregs_write:返回时,这个数组包含所有由指令修改的寄存器。 3225*9a0e4156SSadaf Ebrahimiregs_write_count:保存在regs_write数组中的寄存器数。 3226*9a0e4156SSadaf Ebrahimi成功时返回CS_ERR_OK,失败时返回其他值(详细错误请参阅cs_err enum)。 3227*9a0e4156SSadaf Ebrahimi``` 3228*9a0e4156SSadaf Ebrahimi 3229*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary> 3230*9a0e4156SSadaf Ebrahimi 3231*9a0e4156SSadaf Ebrahimi```cpp 3232*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_regs_access(csh ud, const cs_insn *insn, 3233*9a0e4156SSadaf Ebrahimi cs_regs regs_read, uint8_t *regs_read_count, 3234*9a0e4156SSadaf Ebrahimi cs_regs regs_write, uint8_t *regs_write_count) 3235*9a0e4156SSadaf Ebrahimi{ 3236*9a0e4156SSadaf Ebrahimi struct cs_struct *handle; 3237*9a0e4156SSadaf Ebrahimi 3238*9a0e4156SSadaf Ebrahimi if (!ud) 3239*9a0e4156SSadaf Ebrahimi return -1; 3240*9a0e4156SSadaf Ebrahimi 3241*9a0e4156SSadaf Ebrahimi handle = (struct cs_struct *)(uintptr_t)ud; 3242*9a0e4156SSadaf Ebrahimi 3243*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET 3244*9a0e4156SSadaf Ebrahimi // This API does not work in DIET mode 3245*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DIET; 3246*9a0e4156SSadaf Ebrahimi return CS_ERR_DIET; 3247*9a0e4156SSadaf Ebrahimi#else 3248*9a0e4156SSadaf Ebrahimi if (!handle->detail) { 3249*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 3250*9a0e4156SSadaf Ebrahimi return CS_ERR_DETAIL; 3251*9a0e4156SSadaf Ebrahimi } 3252*9a0e4156SSadaf Ebrahimi 3253*9a0e4156SSadaf Ebrahimi if (!insn->id) { 3254*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_SKIPDATA; 3255*9a0e4156SSadaf Ebrahimi return CS_ERR_SKIPDATA; 3256*9a0e4156SSadaf Ebrahimi } 3257*9a0e4156SSadaf Ebrahimi 3258*9a0e4156SSadaf Ebrahimi if (!insn->detail) { 3259*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_DETAIL; 3260*9a0e4156SSadaf Ebrahimi return CS_ERR_DETAIL; 3261*9a0e4156SSadaf Ebrahimi } 3262*9a0e4156SSadaf Ebrahimi 3263*9a0e4156SSadaf Ebrahimi if (handle->reg_access) { 3264*9a0e4156SSadaf Ebrahimi handle->reg_access(insn, regs_read, regs_read_count, regs_write, regs_write_count); 3265*9a0e4156SSadaf Ebrahimi } else { 3266*9a0e4156SSadaf Ebrahimi // this arch is unsupported yet 3267*9a0e4156SSadaf Ebrahimi handle->errnum = CS_ERR_ARCH; 3268*9a0e4156SSadaf Ebrahimi return CS_ERR_ARCH; 3269*9a0e4156SSadaf Ebrahimi } 3270*9a0e4156SSadaf Ebrahimi 3271*9a0e4156SSadaf Ebrahimi return CS_ERR_OK; 3272*9a0e4156SSadaf Ebrahimi#endif 3273*9a0e4156SSadaf Ebrahimi} 3274*9a0e4156SSadaf Ebrahimi``` 3275*9a0e4156SSadaf Ebrahimi 3276*9a0e4156SSadaf Ebrahimi</details> 3277*9a0e4156SSadaf Ebrahimi 3278*9a0e4156SSadaf Ebrahimi 3279*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary> 3280*9a0e4156SSadaf Ebrahimi 3281*9a0e4156SSadaf Ebrahimi```cpp 3282*9a0e4156SSadaf Ebrahimi#include <iostream> 3283*9a0e4156SSadaf Ebrahimi#include <stdio.h> 3284*9a0e4156SSadaf Ebrahimi 3285*9a0e4156SSadaf Ebrahimi#include "capstone.h" 3286*9a0e4156SSadaf Ebrahimi#include "platform.h" 3287*9a0e4156SSadaf Ebrahimi 3288*9a0e4156SSadaf Ebrahimiusing namespace std; 3289*9a0e4156SSadaf Ebrahimi 3290*9a0e4156SSadaf Ebrahimistruct platform { 3291*9a0e4156SSadaf Ebrahimi cs_arch arch; 3292*9a0e4156SSadaf Ebrahimi cs_mode mode; 3293*9a0e4156SSadaf Ebrahimi unsigned char* code; 3294*9a0e4156SSadaf Ebrahimi size_t size; 3295*9a0e4156SSadaf Ebrahimi const char* comment; 3296*9a0e4156SSadaf Ebrahimi cs_opt_type opt_type; 3297*9a0e4156SSadaf Ebrahimi cs_opt_value opt_value; 3298*9a0e4156SSadaf Ebrahimi}; 3299*9a0e4156SSadaf Ebrahimi 3300*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len) 3301*9a0e4156SSadaf Ebrahimi{ 3302*9a0e4156SSadaf Ebrahimi unsigned char* c; 3303*9a0e4156SSadaf Ebrahimi 3304*9a0e4156SSadaf Ebrahimi printf("Code: "); 3305*9a0e4156SSadaf Ebrahimi for (c = str; c < str + len; c++) { 3306*9a0e4156SSadaf Ebrahimi printf("0x%02x ", *c & 0xff); 3307*9a0e4156SSadaf Ebrahimi } 3308*9a0e4156SSadaf Ebrahimi printf("\n"); 3309*9a0e4156SSadaf Ebrahimi} 3310*9a0e4156SSadaf Ebrahimi 3311*9a0e4156SSadaf Ebrahimistatic void test() 3312*9a0e4156SSadaf Ebrahimi{ 3313*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff" 3314*9a0e4156SSadaf Ebrahimi struct platform platforms[] = { 3315*9a0e4156SSadaf Ebrahimi { 3316*9a0e4156SSadaf Ebrahimi CS_ARCH_X86, 3317*9a0e4156SSadaf Ebrahimi CS_MODE_64, 3318*9a0e4156SSadaf Ebrahimi (unsigned char*)X86_CODE64, 3319*9a0e4156SSadaf Ebrahimi sizeof(X86_CODE64) - 1, 3320*9a0e4156SSadaf Ebrahimi "X86 64 (Intel syntax)" 3321*9a0e4156SSadaf Ebrahimi }, 3322*9a0e4156SSadaf Ebrahimi }; 3323*9a0e4156SSadaf Ebrahimi 3324*9a0e4156SSadaf Ebrahimi csh handle; 3325*9a0e4156SSadaf Ebrahimi uint64_t address; 3326*9a0e4156SSadaf Ebrahimi cs_insn* insn; 3327*9a0e4156SSadaf Ebrahimi cs_detail* detail; 3328*9a0e4156SSadaf Ebrahimi int i; 3329*9a0e4156SSadaf Ebrahimi cs_err err; 3330*9a0e4156SSadaf Ebrahimi const uint8_t* code; 3331*9a0e4156SSadaf Ebrahimi size_t size; 3332*9a0e4156SSadaf Ebrahimi 3333*9a0e4156SSadaf Ebrahimi cs_x86* x86; 3334*9a0e4156SSadaf Ebrahimi cs_regs regs_read, regs_write; 3335*9a0e4156SSadaf Ebrahimi uint8_t regs_read_count, regs_write_count; 3336*9a0e4156SSadaf Ebrahimi 3337*9a0e4156SSadaf Ebrahimi int count; 3338*9a0e4156SSadaf Ebrahimi 3339*9a0e4156SSadaf Ebrahimi for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) { 3340*9a0e4156SSadaf Ebrahimi printf("****************\n"); 3341*9a0e4156SSadaf Ebrahimi printf("Platform: %s\n", platforms[i].comment); 3342*9a0e4156SSadaf Ebrahimi err = cs_open(platforms[i].arch, platforms[i].mode, &handle); 3343*9a0e4156SSadaf Ebrahimi if (err) { 3344*9a0e4156SSadaf Ebrahimi printf("Failed on cs_open() with error returned: %u\n", err); 3345*9a0e4156SSadaf Ebrahimi abort(); 3346*9a0e4156SSadaf Ebrahimi } 3347*9a0e4156SSadaf Ebrahimi 3348*9a0e4156SSadaf Ebrahimi if (platforms[i].opt_type) 3349*9a0e4156SSadaf Ebrahimi cs_option(handle, platforms[i].opt_type, platforms[i].opt_value); 3350*9a0e4156SSadaf Ebrahimi 3351*9a0e4156SSadaf Ebrahimi cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); 3352*9a0e4156SSadaf Ebrahimi 3353*9a0e4156SSadaf Ebrahimi insn = cs_malloc(handle); 3354*9a0e4156SSadaf Ebrahimi x86 = &(insn->detail->x86); 3355*9a0e4156SSadaf Ebrahimi print_string_hex(platforms[i].code, platforms[i].size); 3356*9a0e4156SSadaf Ebrahimi printf("Disasm:\n"); 3357*9a0e4156SSadaf Ebrahimi 3358*9a0e4156SSadaf Ebrahimi address = 0x1000; 3359*9a0e4156SSadaf Ebrahimi code = platforms[i].code; 3360*9a0e4156SSadaf Ebrahimi size = platforms[i].size; 3361*9a0e4156SSadaf Ebrahimi while (cs_disasm_iter(handle, &code, &size, &address, insn)) { 3362*9a0e4156SSadaf Ebrahimi int n; 3363*9a0e4156SSadaf Ebrahimi 3364*9a0e4156SSadaf Ebrahimi printf("0x%" PRIx64 ":\t%s\t\t%s ", 3365*9a0e4156SSadaf Ebrahimi insn->address, insn->mnemonic, insn->op_str); 3366*9a0e4156SSadaf Ebrahimi cout << endl; 3367*9a0e4156SSadaf Ebrahimi 3368*9a0e4156SSadaf Ebrahimi if (!cs_regs_access(handle, insn, //每条指令所有读取和修改的寄存器 3369*9a0e4156SSadaf Ebrahimi regs_read, ®s_read_count, 3370*9a0e4156SSadaf Ebrahimi regs_write, ®s_write_count)) { 3371*9a0e4156SSadaf Ebrahimi if (regs_read_count) { 3372*9a0e4156SSadaf Ebrahimi printf("\tRegisters read:"); 3373*9a0e4156SSadaf Ebrahimi for (i = 0; i < regs_read_count; i++) { 3374*9a0e4156SSadaf Ebrahimi printf(" %s", cs_reg_name(handle, regs_read[i])); 3375*9a0e4156SSadaf Ebrahimi } 3376*9a0e4156SSadaf Ebrahimi printf("\n"); 3377*9a0e4156SSadaf Ebrahimi } 3378*9a0e4156SSadaf Ebrahimi 3379*9a0e4156SSadaf Ebrahimi if (regs_write_count) { 3380*9a0e4156SSadaf Ebrahimi printf("\tRegisters modified:"); 3381*9a0e4156SSadaf Ebrahimi for (i = 0; i < regs_write_count; i++) { 3382*9a0e4156SSadaf Ebrahimi printf(" %s", cs_reg_name(handle, regs_write[i])); 3383*9a0e4156SSadaf Ebrahimi } 3384*9a0e4156SSadaf Ebrahimi printf("\n"); 3385*9a0e4156SSadaf Ebrahimi } 3386*9a0e4156SSadaf Ebrahimi } 3387*9a0e4156SSadaf Ebrahimi } 3388*9a0e4156SSadaf Ebrahimi 3389*9a0e4156SSadaf Ebrahimi printf("\n"); 3390*9a0e4156SSadaf Ebrahimi cs_free(insn, 1); 3391*9a0e4156SSadaf Ebrahimi cs_close(&handle); 3392*9a0e4156SSadaf Ebrahimi } 3393*9a0e4156SSadaf Ebrahimi} 3394*9a0e4156SSadaf Ebrahimi 3395*9a0e4156SSadaf Ebrahimiint main() 3396*9a0e4156SSadaf Ebrahimi{ 3397*9a0e4156SSadaf Ebrahimi test(); 3398*9a0e4156SSadaf Ebrahimi return 0; 3399*9a0e4156SSadaf Ebrahimi} 3400*9a0e4156SSadaf Ebrahimi``` 3401*9a0e4156SSadaf Ebrahimi 3402*9a0e4156SSadaf Ebrahimi</details> 3403*9a0e4156SSadaf Ebrahimi 3404*9a0e4156SSadaf Ebrahimi输出 3405*9a0e4156SSadaf Ebrahimi 3406*9a0e4156SSadaf Ebrahimi 3407