文章目录
- 前言
- 一、Capstone 简介
- 二、使用步骤
- 2.1 下载源码
- 2.2 编译源码
- 2.3 Linux安装Capstone
- 2.4 查看cstool工具
- 3.5 使用cstool工具
- 3.6 卸载cstool工具
- 三、C 使用Capstone
- 3.1 C 例程
- 3.2 API分析
- 总结
- 参考资料
前言
最近要研究一些反汇编工具,由于要考虑跨平台和架构兼容性,于是选择了Capstone反汇编引擎。
一、Capstone 简介
Capstone 是一个轻量级的多平台、多架构的反汇编框架,用纯 C 语言实现。
多平台:
Windows & *nix (with Mac OSX, iOS, Android, Linux, *BSD & Solaris.
多架构:
Arm, Arm64 (Armv8), BPF, Ethereum Virtual Machine, M68K, M680X, Mips, MOS65XX, PowerPC, RISCV, Sparc, SystemZ, TMS320C64X, Web Assembly, XCore & X86 (include X86_64).
Capstone的一些特点:
提供反汇编指令的详细信息,提供反汇编指令的一些语义,高性能且适用于恶意软件分析等等。详细信息请参考官网:http://www.capstone-engine.org/
二、使用步骤
2.1 下载源码
git clone -b next https://github.com/capstone-engine/capstone
github地址:https://github.com/capstone-engine/capstone
编译与安装请参考源码下 的 COMPILE.TXT 文件
2.2 编译源码
在下载的源码的路径下编译源码:
在当前平台编译
./make.sh
编译结束:
2.3 Linux安装Capstone
sudo ./make.sh install
2.4 查看cstool工具
cstool -v
Extra options:
-d show detailed information of the instructions
-s decode in SKIPDATA mode
-u show immediates as unsigned
-v show version & Capstone core build info
3.5 使用cstool工具
使用官方的例程:
cstool -u x64 "x55x48x8bx05xb8x13x00x00"
3.6 卸载cstool工具
sudo ./make.sh uninstall
三、C 使用Capstone
3.1 C 例程
这里使用官方给出的c例程
//test.c
#include
#include
#include
#define CODE "x55x48x8bx05xb8x13x00x00"
int main(void)
{
csh handle;
cs_insn *insn;
size_t count;
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK)
return -1;
count = cs_disasm(handle, CODE, sizeof(CODE)-1, 0x1000, 0, &insn);
if (count > 0) {
size_t j;
for (j = 0; j < count; j++) {
//汇编代码的 address地址,mnemonic是操作码,op_str是操作数
printf("0x%"PRIx64":t%stt%sn", insn[j].address, insn[j].mnemonic,
insn[j].op_str);
}
cs_free(insn, count);
} else
printf("ERROR: Failed to disassemble given code!n");
cs_close(&handle);
return 0;
}
//Makefile
# capstone library name (without prefix 'lib' and suffix '.so')
LIBNAME = capstone
test: test.o
${CC} $< -O3 -Wall -l$(LIBNAME) -o $@
%.o: %.c
${CC} -c $< -o $@
clean:
rm -rf test test.o
3.2 API分析
(1)csh
// Handle using with all API
typedef size_t csh;
声明一个csh类型的句柄变量。这个句柄将在Capstone的每个API中使用
csh handle;
(2)cs_insn
// Detail information of disassembled instruction
typedef struct cs_insn {
// 指令 ID(指令助记符的数字 ID)
// 在对应架构的头文件中的'[ARCH]_insn'枚举中找到指令id,如 ARM 的arm.h中的'arm_insn',
// x86 的x86.h中的'x86_insn'等等
unsigned int id;
//指令地址 (EIP)
uint64_t address;
//指令长度
uint16_t size;
//指令的机器码,其字节数由上面的size表示
uint8_t bytes[24];
//指令助记符的ASCII文本(指令操作码)
char mnemonic[CS_MNEMONIC_SIZE];
//指令操作数的ASCII文本(指令操作数)
char op_str[160];
/// Pointer to cs_detail.
cs_detail *detail;
} cs_insn;
cs_insn *insn;
声明insn,一个cs_insn类型的指针变量,指向一个包含所有反汇编指令的内存
(3)cs_open
cs_open(cs_arch arch, cs_mode mode, csh *handle);
使用函数 cs_open() 初始化 Capstone。 此 API 有 3 个参数:硬件架构、硬件模式和指向句柄的指针。 在这个示例中,我们要反汇编 X86 架构的 64 位代码:
cs_open(CS_ARCH_X86, CS_MODE_64, &handle)
(4)cs_disasm
cs_disasm(csh handle, const uint8_t *code, size_t code_size, uint64_t address, size_t count, cs_insn **insn);
使用 API cs_disasm() 和从 cs_open() 获得的句柄来反汇编二进制代码。 cs_disasm() 的第二和第三个参数是要反汇编的二进制代码及其长度。 第 4 个参数是第一条指令的地址,在本例中为 0x1000。
如果我们想反汇编所有的代码,直到没有更多的代码,或者它遇到一个broken instruction,使用0作为下一个参数。此 API 在最后一个参数 insn 中返回动态分配的内存,可用于在接下来的步骤中提取所有反汇编指令。 cs_disasm() 的结果是成功反汇编的指令数。
cs_disasm(handle, CODE, sizeof(CODE)-1, 0x1000, 0, &insn);
打印出所有反汇编指令及其地址、助记符和操作数。 cs_insn 结构暴露了我们正在查看的反汇编指令的所有内部信息。
for (j = 0; j < count; j++) {
printf("0x%"PRIx64":t%stt%sn", insn[j].address, insn[j].mnemonic, insn[j].op_str);
}
(5)cs_free
cs_free(cs_insn *insn, size_t count);
cs_free() 释放由 cs_disasm 分配的动态内存。
cs_free(insn, count);
(6)cs_close
cs_close(csh *handle);
关闭句柄
cs_close(&handle);
总结
本文章简单介绍了Capstone反汇编引擎,后面还会详细介绍一些API和其它的反汇编引擎。
参考资料
http://www.capstone-engine.org/
https://blog.csdn.net/qq_42931917/article/details/109201917
https://xz.aliyun.com/t/5753
https://xz.aliyun.com/t/5942
http://www.capstone-engine.org/lang_c.html