Capstone反汇编引擎数据类型及API分析及示例(二)
字数 1229 2025-08-04 08:17:33

Capstone反汇编引擎数据类型及API详解

一、内存管理相关API

1. cs_malloc_t

void* (CAPSTONE_API *cs_malloc_t)(size_t size);
  • 功能:动态内存分配函数
  • 实现差异:
    • 用户模式:默认使用系统malloc
    • Windows驱动模式:使用cs_winkernel_malloc
      void * CAPSTONE_API cs_winkernel_malloc(size_t size) {
          NT_ASSERT(size);
          size_t number_of_bytes = 0;
          CS_WINKERNEL_MEMBLOCK *block = NULL;
      
          if (!NT_SUCCESS(RtlSizeTAdd(size, sizeof(CS_WINKERNEL_MEMBLOCK), &number_of_bytes))) {
              return NULL;
          }
      
          block = (CS_WINKERNEL_MEMBLOCK *)ExAllocatePoolWithTag(NonPagedPool, number_of_bytes, CS_WINKERNEL_POOL_TAG);
          if (!block) {
              return NULL;
          }
      
          block->size = size;
          return block->data;
      }
      
    • OSX内核模式:使用kern_os_malloc

2. cs_calloc_t

void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size);
  • 功能:申请内存并初始化
  • 实现差异:
    • 用户模式:使用系统calloc
    • Windows驱动模式:使用cs_winkernel_calloc
      void * CAPSTONE_API cs_winkernel_calloc(size_t n, size_t size) {
          size_t total = n * size;
          void *new_ptr = cs_winkernel_malloc(total);
          if (!new_ptr) {
              return NULL;
          }
          return RtlFillMemory(new_ptr, total, 0);
      }
      
    • OSX内核模式:使用cs_kern_os_calloc

3. cs_realloc_t

void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size);
  • 功能:重新分配内存
  • 实现差异:
    • 用户模式:使用系统realloc
    • Windows驱动模式:使用cs_winkernel_realloc
      void * CAPSTONE_API cs_winkernel_realloc(void *ptr, size_t size) {
          void *new_ptr = NULL;
          size_t current_size = 0;
          size_t smaller_size = 0;
      
          if (!ptr) {
              return cs_winkernel_malloc(size);
          }
      
          new_ptr = cs_winkernel_malloc(size);
          if (!new_ptr) {
              return NULL;
          }
      
          current_size = CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data)->size;
          smaller_size = (current_size < size) ? current_size : size;
          RtlCopyMemory(new_ptr, ptr, smaller_size);
          cs_winkernel_free(ptr);
          return new_ptr;
      }
      
    • OSX内核模式:使用kern_os_realloc

4. cs_free_t

typedef void (CAPSTONE_API *cs_free_t)(void *ptr);
  • 功能:释放内存
  • 实现差异:
    • 用户模式:使用系统free
    • Windows驱动模式:使用cs_winkernel_free
      void CAPSTONE_API cs_winkernel_free(void *ptr) {
          if (ptr) {
              ExFreePoolWithTag(CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data), CS_WINKERNEL_POOL_TAG);
          }
      }
      
    • OSX内核模式:使用kern_os_free

5. cs_vsnprintf_t

int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap);
  • 功能:按size大小输出到字符串str中
  • 实现差异:
    • 用户模式
      • Windows CE系统使用_vsnprintf
      • 其他使用vsnprintf
    • Windows驱动模式:使用cs_winkernel_vsnprintf
      int CAPSTONE_API cs_winkernel_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) {
          int result = _vsnprintf(buffer, count, format, argptr);
      
          if (result == -1 || (size_t)result == count) {
              buffer[count - 1] = '\0';
          }
      
          if (result == -1) {
              char *tmp = cs_winkernel_malloc(0x1000);
              if (!tmp) {
                  return result;
              }
              result = _vsnprintf(tmp, 0x1000, format, argptr);
              NT_ASSERT(result != -1);
              cs_winkernel_free(tmp);
          }
      
          return result;
      }
      
    • OSX内核模式:使用默认vsnprintf

二、反汇编相关API

1. cs_skipdata_cb_t

size_t (CAPSTONE_API cs_skipdata_cb_t)(const uint8_t code, size_t code_size, size_t offset, void *user_data);
  • 功能:SKIPDATA选项的用户自定义回调函数
  • 参数:
    • code:包含要分解的代码的输入缓冲区
    • code_size:缓冲区的大小(字节)
    • offset:输入缓冲区中当前检查字节的位置
    • user_data:用户数据通过cs_opt_skipdata结构传递
  • 返回值:要跳过的字节数,0表示立即停止反汇编

示例代码

#include <stdio.h>
#include <stdlib.h>
#include "platform.h"
#include "capstone.h"

struct platform {
    cs_arch arch;
    cs_mode mode;
    unsigned char *code;
    size_t size;
    const char *comment;
    cs_opt_type opt_type;
    cs_opt_value opt_value;
    cs_opt_type opt_skipdata;
    size_t skipdata;
};

static void print_string_hex(unsigned char *str, size_t len) {
    unsigned char *c;
    printf("Code: ");
    for (c = str; c < str + len; c++) {
        printf("0x%02x ", *c & 0xff);
    }
    printf("\n");
}

static void test() {
    #define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x00\x91\x92"
    #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"
    
    cs_opt_skipdata skipdata = {
        .mnemonic = "db",  // 把默认".byte"描述符重命名为"db"
    };
    
    struct platform platforms[2] = {
        {
            CS_ARCH_X86,
            CS_MODE_32,
            (unsigned char *)X86_CODE32,
            sizeof(X86_CODE32) - 1,
            "X86 32 (Intel syntax) - Skip data",
        },
        {
            CS_ARCH_X86,
            CS_MODE_32,
            (unsigned char *)X86_CODE32,
            sizeof(X86_CODE32) - 1,
            "X86 32 (Intel syntax) - Skip data with custom mnemonic",
            CS_OPT_INVALID,
            CS_OPT_OFF,
            CS_OPT_SKIPDATA_SETUP,
            (size_t)&skipdata,
        },
    };
    
    csh handle;
    uint64_t address = 0x1000;
    cs_insn *insn;
    cs_err err;
    int i;
    size_t count;
    
    for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
        printf("*\n");
        printf("Platform: %s\n", platforms[i].comment);
        
        err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
        if (err) {
            printf("Failed on cs_open() with error returned: %u\n", err);
            abort();
        }
        
        if (platforms[i].opt_type)
            cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
        
        cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
        cs_option(handle, platforms[i].opt_skipdata, platforms[i].skipdata);
        
        count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
        if (count) {
            size_t j;
            print_string_hex(platforms[i].code, platforms[i].size);
            printf("Disasm:\n");
            
            for (j = 0; j < count; j++) {
                printf("0x%" PRIx64 ":\t%s\t\t%s\n", 
                       insn[j].address, insn[j].mnemonic, insn[j].op_str);
            }
            
            printf("0x%" PRIx64 ":\n", insn[j - 1].address + insn[j - 1].size);
            cs_free(insn, count);
        } else {
            printf("*\n");
            printf("Platform: %s\n", platforms[i].comment);
            print_string_hex(platforms[i].code, platforms[i].size);
            printf("ERROR: Failed to disasm given code!\n");
            abort();
        }
        
        printf("\n");
        cs_close(&handle);
    }
}

int main() {
    test();
    return 0;
}

2. cs_version

unsigned int CAPSTONE_API cs_version(int *major, int *minor);
  • 功能:获取Capstone版本号
  • 参数:
    • major:API主版本号
    • minor:API次版本号
  • 返回值:主次版本的16进制表示(如4.0版本返回0x0400)

示例1:获取版本号

#include <stdio.h>
#include <stdlib.h>
#include "platform.h"
#include "capstone.h"

static int test() {
    return cs_version(NULL, NULL);
}

int main() {
    int version = test();
    printf("%X", version);
    return 0;
}

示例2:尝试修改版本号(无效)

#include <stdio.h>
#include <stdlib.h>
#include "platform.h"
#include "capstone.h"

static int test() {
    int ma[] = {5};
    int mi[] = {6};
    return cs_version(ma, mi);
}

int main() {
    int version = test();
    printf("%X", version);
    return 0;
}

3. cs_support

bool CAPSTONE_API cs_support(int query);
  • 功能:检查Capstone库是否支持特定架构或编译选项
  • 查询参数:
    • CS_ARCH_ALL:检查是否支持所有架构
    • CS_ARCH_*:检查是否支持特定架构
    • CS_SUPPORT_DIET:检查是否处于DIET编译模式
    • CS_SUPPORT_X86_REDUCE:检查是否处于X86_REDUCE编译模式

示例1:检查是否支持所有架构

bool result = cs_support(CS_ARCH_ALL);

示例2:检查是否支持特定架构

bool result = cs_support(CS_ARCH_X86);

示例3:检查是否处于DIET编译模式

bool result = cs_support(CS_SUPPORT_DIET);

示例4:检查是否处于X86_REDUCE编译模式

bool result = cs_support(CS_SUPPORT_X86_REDUCE);

三、架构枚举定义

typedef enum cs_arch {
    CS_ARCH_ARM = 0,        ///< ARM架构(包括Thumb, Thumb-2)
    CS_ARCH_ARM64,          ///< ARM-64, 也称为AArch64
    CS_ARCH_MIPS,           ///< Mips架构
    CS_ARCH_X86,            ///< X86架构(包括x86 & x86-64)
    CS_ARCH_PPC,            ///< PowerPC架构
    CS_ARCH_SPARC,          ///< Sparc架构
    CS_ARCH_SYSZ,           ///< SystemZ架构
    CS_ARCH_XCORE,          ///< XCore架构
    CS_ARCH_M68K,           ///< 68K架构
    CS_ARCH_TMS320C64X,     ///< TMS320C64x架构
    CS_ARCH_M680X,          ///< 680X架构
    CS_ARCH_EVM,            ///< Ethereum架构
    CS_ARCH_MOS65XX,        ///< MOS65XX架构(包括MOS6502)
    CS_ARCH_MAX,
    CS_ARCH_ALL = 0xFFFF,   // 所有架构 - 用于cs_support()
} cs_arch;

#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1)
#define CS_SUPPORT_X86_REDUCE (CS_ARCH_ALL + 2)
Capstone反汇编引擎数据类型及API详解 一、内存管理相关API 1. cs_ malloc_ t 功能:动态内存分配函数 实现差异: 用户模式 :默认使用系统 malloc Windows驱动模式 :使用 cs_winkernel_malloc OSX内核模式 :使用 kern_os_malloc 2. cs_ calloc_ t 功能:申请内存并初始化 实现差异: 用户模式 :使用系统 calloc Windows驱动模式 :使用 cs_winkernel_calloc OSX内核模式 :使用 cs_kern_os_calloc 3. cs_ realloc_ t 功能:重新分配内存 实现差异: 用户模式 :使用系统 realloc Windows驱动模式 :使用 cs_winkernel_realloc OSX内核模式 :使用 kern_os_realloc 4. cs_ free_ t 功能:释放内存 实现差异: 用户模式 :使用系统 free Windows驱动模式 :使用 cs_winkernel_free OSX内核模式 :使用 kern_os_free 5. cs_ vsnprintf_ t 功能:按size大小输出到字符串str中 实现差异: 用户模式 : Windows CE系统使用 _vsnprintf 其他使用 vsnprintf Windows驱动模式 :使用 cs_winkernel_vsnprintf OSX内核模式 :使用默认 vsnprintf 二、反汇编相关API 1. cs_ skipdata_ cb_ t 功能:SKIPDATA选项的用户自定义回调函数 参数: code :包含要分解的代码的输入缓冲区 code_size :缓冲区的大小(字节) offset :输入缓冲区中当前检查字节的位置 user_data :用户数据通过 cs_opt_skipdata 结构传递 返回值:要跳过的字节数,0表示立即停止反汇编 示例代码 2. cs_ version 功能:获取Capstone版本号 参数: major :API主版本号 minor :API次版本号 返回值:主次版本的16进制表示(如4.0版本返回0x0400) 示例1:获取版本号 示例2:尝试修改版本号(无效) 3. cs_ support 功能:检查Capstone库是否支持特定架构或编译选项 查询参数: CS_ARCH_ALL :检查是否支持所有架构 CS_ARCH_* :检查是否支持特定架构 CS_SUPPORT_DIET :检查是否处于DIET编译模式 CS_SUPPORT_X86_REDUCE :检查是否处于X86_ REDUCE编译模式 示例1:检查是否支持所有架构 示例2:检查是否支持特定架构 示例3:检查是否处于DIET编译模式 示例4:检查是否处于X86_ REDUCE编译模式 三、架构枚举定义