编译
让 ai 写个例子运行(capstone 中的 tests 不太容易跟):
编译运行这个例子看看:
输出
完美.
让我们从这个代码中的 cs_disasm 开始看, 前面的一些初始化的代码跳过:
核心流程概括一下就是: 初始化各种变量, 缓存, 架构信息等; 循环调用 handle->disasm 方法解码; 处理好缓存, 缓存扩容以及资源释放等. 我们继续跟入 handle->disasm:

可以看到各个架构都有实现, 我们只看 arm64 也就是 arch/AArch64/AArch64Module.c 中的:
跟入 AArch64_getInstruction:
跟入 getInstruction, 来到了 arch/AArch64/AArch64Disassembler.c 中:
首先要看看 const uint8_t *Tables[] = { DecoderTable32, DecoderTableFallback32 }; 这两个表:


一个非常长的文件, 其实还是 c 代码, 看注释像是状态转移表.
接着去看 decodeInstruction_4 如何来的, 跟进去发现:

, DecodeInstruction(decodeInstruction_4, fieldFromInstruction_4, decodeToMCInst_4, uint32_t) 这行定义了 decodeInstruction_4, 找到 DecodeInstruction 是一个宏:
实际上是在定义一个函数, 函数名就是传进来的第一个参数, 在看这个函数, 一个 while 大循环, 里面一些 case, 还定义了一个 DecodeStatus S = MCDisassembler_Success; 看着就是一个状态机.
其中 decodeULEB128:
将 ULEB128 编码的二进制数据转换为 64 位无符号整数, ULEB128 编码特点: 1. 小端序存储; 2. 每个字节最高位(bit7)为"延续位"(1=后续还有字节, 0=结束); 3. 低7位存储有效数据.
函数第一个参数 DecodeTable 就是上边那个表, 表中每一个宏(类似 MCD_OPC_SoftFail)都对应一个 case, 有相应的处理. 为了完全搞清楚这个函数, 我们还要在看看 fieldname 与 decoder, 回到:
这个函数就是 decodeInstruction_4 中的 fieldname.
发现与 DecodeInstruction 类似, 都是在定义一个函数, 函数名都是宏第一个参数. 这个函数的功能很简单, 就是通过位运算精准提取指令中的指定位段.
这个太长我就不贴全了, 这个函数就是 decodeInstruction_4 中的 decoder.
看着是在反汇编每条指令, 首先看下 Check:
将两个结果取 &, 看看是否失败. 其中 Out 传进来的 S, 即以往的状态, In 是本次解码的状态.
再跟入这些解码函数看一看:
再看 AArch64MCRegisterClasses:

又是一个大表, 存了一些这样的数组:

又找了一下 MCRegisterClass:
总结一下就是通过传进来的 RegNo 作为查表获取的字节数组的索引, 找到 Register, 对应了 MCInst 具体寄存器枚举, 跟入 MCOperand_CreateReg0:
那么 Operand 有了, Opcode 呢, 回到 DecodeInstruction, 找到 S = decoder(S, DecodeIdx, insn, MI, Address, Decoder, &DecodeComplete); 也就是 decoder 调用的地方:
发现它上边就有 MCInst_setOpcode(MI, Opc);, 已经在表中取出来了, 然后在根据 DecodeIdx 去填充寄存器.
现在举例说明一下这个状态机的运行过程, 蛋疼的是这个文件不能调试

只能静态脑补一下了, 拿这个举例 0x8B, 0x02, 0x40, 0xF9, // ldr x11, [x0],
可以看到 capstone 是一个线性反汇编器而非递归下降反汇编器!
git clone git@github.com:capstone-engine/capstone.git
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build
sudo cmake --install build --prefix "/usr/local"
git clone git@github.com:capstone-engine/capstone.git
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build
sudo cmake --install build --prefix "/usr/local"
#include "capstone/aarch64.h"
#include <iostream>
#include <cstdint>
#include <capstone/capstone.h>
const uint8_t arm64_code[] = {
0x8B, 0x02, 0x40, 0xF9,
0x20, 0x08, 0x40, 0xF9,
0x00, 0x00, 0x00, 0x91,
0x01, 0x00, 0x00, 0x91,
0x02, 0x20, 0x40, 0xF9,
0x03, 0x30, 0x00, 0xB9,
0x04, 0x00, 0x00, 0x54,
0x00, 0x00, 0x00, 0x54,
0x00, 0x00, 0x00, 0x58,
0x00, 0x00, 0x1F, 0xD6
};
void print_error(const char* msg, cs_err err) {
std::cerr << "[ERROR] " << msg << ": " << cs_strerror(err) << std::endl;
}
int main() {
csh handle;
cs_insn* insns = nullptr;
size_t count;
cs_err err = cs_open(CS_ARCH_AARCH64, CS_MODE_LITTLE_ENDIAN, &handle);
if (err != CS_ERR_OK) {
print_error("cs_open failed", err);
return 1;
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
count = cs_disasm(handle, arm64_code, sizeof(arm64_code), 0x1000, 0, &insns);
if (count == 0) {
print_error("cs_disasm failed", cs_errno(handle));
cs_close(&handle);
return 1;
}
std::cout << "=== AARCH64 反汇编结果 ===" << std::endl;
std::cout << "地址\t\t机器码\t\t指令" << std::endl;
std::cout << "----------------------------------------" << std::endl;
for (size_t i = 0; i < count; ++i) {
cs_insn* ins = &insns[i];
std::printf("0x%lx\t", ins->address);
for (size_t j = 0; j < ins->size; ++j) {
std::printf("%02x ", ins->bytes[j]);
}
if (ins->size < 4) {
std::printf("\t");
}
if (ins->size < 8) {
std::printf("\t");
}
std::printf("%s\t%s\n", ins->mnemonic, ins->op_str);
if (ins->detail != nullptr) {
cs_aarch64* arm64 = &ins->detail->aarch64;
std::printf("\t\t\t操作数数量: %u\n", arm64->op_count);
for (size_t j = 0; j < arm64->op_count; ++j) {
cs_aarch64_op* op = &arm64->operands[j];
std::printf("\t\t\t操作数 %lu: ", j + 1);
switch (op->type) {
case AARCH64_OP_REG:
std::printf("寄存器 (x%u/w%u)",
op->reg - AARCH64_REG_X0,
op->reg - AARCH64_REG_W0);
break;
case AARCH64_OP_IMM:
std::printf("立即数 0x%lx", op->imm);
break;
case AARCH64_OP_MEM:
std::printf("内存 [x%u", op->mem.base - AARCH64_REG_X0);
if (op->mem.disp != 0) {
std::printf(", #0x%x", op->mem.disp);
}
std::printf("]");
break;
default:
std::printf("未知类型");
break;
}
std::printf("\n");
}
std::printf("\n");
}
}
cs_free(insns, count);
cs_close(&handle);
return 0;
}
#include "capstone/aarch64.h"
#include <iostream>
#include <cstdint>
#include <capstone/capstone.h>
const uint8_t arm64_code[] = {
0x8B, 0x02, 0x40, 0xF9,
0x20, 0x08, 0x40, 0xF9,
0x00, 0x00, 0x00, 0x91,
0x01, 0x00, 0x00, 0x91,
0x02, 0x20, 0x40, 0xF9,
0x03, 0x30, 0x00, 0xB9,
0x04, 0x00, 0x00, 0x54,
0x00, 0x00, 0x00, 0x54,
0x00, 0x00, 0x00, 0x58,
0x00, 0x00, 0x1F, 0xD6
};
void print_error(const char* msg, cs_err err) {
std::cerr << "[ERROR] " << msg << ": " << cs_strerror(err) << std::endl;
}
int main() {
csh handle;
cs_insn* insns = nullptr;
size_t count;
cs_err err = cs_open(CS_ARCH_AARCH64, CS_MODE_LITTLE_ENDIAN, &handle);
if (err != CS_ERR_OK) {
print_error("cs_open failed", err);
return 1;
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
count = cs_disasm(handle, arm64_code, sizeof(arm64_code), 0x1000, 0, &insns);
if (count == 0) {
print_error("cs_disasm failed", cs_errno(handle));
cs_close(&handle);
return 1;
}
std::cout << "=== AARCH64 反汇编结果 ===" << std::endl;
std::cout << "地址\t\t机器码\t\t指令" << std::endl;
std::cout << "----------------------------------------" << std::endl;
for (size_t i = 0; i < count; ++i) {
cs_insn* ins = &insns[i];
std::printf("0x%lx\t", ins->address);
for (size_t j = 0; j < ins->size; ++j) {
std::printf("%02x ", ins->bytes[j]);
}
if (ins->size < 4) {
std::printf("\t");
}
if (ins->size < 8) {
std::printf("\t");
}
std::printf("%s\t%s\n", ins->mnemonic, ins->op_str);
if (ins->detail != nullptr) {
cs_aarch64* arm64 = &ins->detail->aarch64;
std::printf("\t\t\t操作数数量: %u\n", arm64->op_count);
for (size_t j = 0; j < arm64->op_count; ++j) {
cs_aarch64_op* op = &arm64->operands[j];
std::printf("\t\t\t操作数 %lu: ", j + 1);
switch (op->type) {
case AARCH64_OP_REG:
std::printf("寄存器 (x%u/w%u)",
op->reg - AARCH64_REG_X0,
op->reg - AARCH64_REG_W0);
break;
case AARCH64_OP_IMM:
std::printf("立即数 0x%lx", op->imm);
break;
case AARCH64_OP_MEM:
std::printf("内存 [x%u", op->mem.base - AARCH64_REG_X0);
if (op->mem.disp != 0) {
std::printf(", #0x%x", op->mem.disp);
}
std::printf("]");
break;
default:
std::printf("未知类型");
break;
}
std::printf("\n");
}
std::printf("\n");
}
}
cs_free(insns, count);
cs_close(&handle);
return 0;
}
touch 111.cpp
g++ 111.cpp -o 111 -lcapstone
./111
touch 111.cpp
g++ 111.cpp -o 111 -lcapstone
./111
=== AARCH64 反汇编结果 ===
地址 机器码 指令
----------------------------------------
0x1000 8b 02 40 f9 ldr x11, [x20]
操作数数量: 2
操作数 1: 寄存器 (x11/w42)
操作数 2: 内存 [x20]
0x1004 20 08 40 f9 ldr x0, [x1,
操作数数量: 2
操作数 1: 寄存器 (x0/w31)
操作数 2: 内存 [x1,
0x1008 00 00 00 91 add x0, x0,
操作数数量: 3
操作数 1: 寄存器 (x0/w31)
操作数 2: 寄存器 (x0/w31)
操作数 3: 立即数 0x0
0x100c 01 00 00 91 add x1, x0,
操作数数量: 3
操作数 1: 寄存器 (x1/w32)
操作数 2: 寄存器 (x0/w31)
操作数 3: 立即数 0x0
0x1010 02 20 40 f9 ldr x2, [x0,
操作数数量: 2
操作数 1: 寄存器 (x2/w33)
操作数 2: 内存 [x0,
0x1014 03 30 00 b9 str w3, [x0,
操作数数量: 2
操作数 1: 寄存器 (x4294967268/w3)
操作数 2: 内存 [x0,
0x1018 04 00 00 54 b.mi 0x1018
操作数数量: 1
操作数 1: 立即数 0x1018
0x101c 00 00 00 54 b.eq 0x101c
操作数数量: 1
操作数 1: 立即数 0x101c
0x1020 00 00 00 58 ldr x0, 0x1020
操作数数量: 2
操作数 1: 寄存器 (x0/w31)
操作数 2: 内存 [x4294967058,
0x1024 00 00 1f d6 br x0
操作数数量: 1
操作数 1: 寄存器 (x0/w31)
=== AARCH64 反汇编结果 ===
地址 机器码 指令
----------------------------------------
0x1000 8b 02 40 f9 ldr x11, [x20]
操作数数量: 2
操作数 1: 寄存器 (x11/w42)
操作数 2: 内存 [x20]
0x1004 20 08 40 f9 ldr x0, [x1,
操作数数量: 2
操作数 1: 寄存器 (x0/w31)
操作数 2: 内存 [x1,
0x1008 00 00 00 91 add x0, x0,
操作数数量: 3
操作数 1: 寄存器 (x0/w31)
操作数 2: 寄存器 (x0/w31)
操作数 3: 立即数 0x0
0x100c 01 00 00 91 add x1, x0,
操作数数量: 3
操作数 1: 寄存器 (x1/w32)
操作数 2: 寄存器 (x0/w31)
操作数 3: 立即数 0x0
0x1010 02 20 40 f9 ldr x2, [x0,
操作数数量: 2
操作数 1: 寄存器 (x2/w33)
操作数 2: 内存 [x0,
0x1014 03 30 00 b9 str w3, [x0,
操作数数量: 2
操作数 1: 寄存器 (x4294967268/w3)
操作数 2: 内存 [x0,
0x1018 04 00 00 54 b.mi 0x1018
操作数数量: 1
操作数 1: 立即数 0x1018
0x101c 00 00 00 54 b.eq 0x101c
操作数数量: 1
操作数 1: 立即数 0x101c
0x1020 00 00 00 58 ldr x0, 0x1020
操作数数量: 2
操作数 1: 寄存器 (x0/w31)
操作数 2: 内存 [x4294967058,
0x1024 00 00 1f d6 br x0
操作数数量: 1
操作数 1: 寄存器 (x0/w31)
CAPSTONE_EXPORT
size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size,
uint64_t offset, size_t count, cs_insn **insn)
{
struct cs_struct *handle;
MCInst mci;
uint16_t insn_size;
size_t c = 0, i;
unsigned int f = 0;
cs_insn *insn_cache;
void *total = NULL;
size_t total_size = 0;
bool r;
void *tmp;
size_t skipdata_bytes;
uint64_t offset_org;
size_t size_org;
const uint8_t *buffer_org;
unsigned int cache_size = INSN_CACHE_SIZE;
size_t next_offset;
handle = (struct cs_struct *)(uintptr_t)ud;
if (!handle) {
return 0;
}
handle->errnum = CS_ERR_OK;
#ifdef CAPSTONE_USE_SYS_DYN_MEM
if (count > 0 && count <= INSN_CACHE_SIZE)
cache_size = (unsigned int)count;
#endif
buffer_org = buffer;
offset_org = offset;
size_org = size;
total_size = sizeof(cs_insn) * cache_size;
total = cs_mem_calloc(sizeof(cs_insn), cache_size);
if (total == NULL) {
handle->errnum = CS_ERR_MEM;
return 0;
}
insn_cache = total;
while (size > 0) {
MCInst_Init(&mci, handle->arch);
mci.csh = handle;
mci.address = offset;
if (handle->detail_opt) {
insn_cache->detail = cs_mem_calloc(1, sizeof(cs_detail));
} else {
insn_cache->detail = NULL;
}
mci.flat_insn = insn_cache;
mci.flat_insn->address = offset;
#ifdef CAPSTONE_DIET
mci.flat_insn->mnemonic[0] = '\0';
mci.flat_insn->op_str[0] = '\0';
#endif
r = handle->disasm(ud, buffer, size, &mci, &insn_size, offset,
handle->getinsn_info);
if (r) {
SStream ss;
SStream_Init(&ss);
mci.flat_insn->size = insn_size;
handle->insn_id(handle, insn_cache, mci.Opcode);
SStream_opt_unum(&ss, handle->imm_unsigned);
handle->printer(&mci, &ss, handle->printer_info);
fill_insn(handle, insn_cache, &ss, &mci,
handle->post_printer, buffer);
if (handle->arch == CS_ARCH_X86 &&
insn_cache->id != X86_INS_VCMP)
insn_cache->id += mci.popcode_adjust;
next_offset = insn_size;
} else {
if (handle->detail_opt) {
cs_mem_free(insn_cache->detail);
}
if (!handle->skipdata || handle->skipdata_size > size)
break;
if (handle->skipdata_setup.callback) {
skipdata_bytes = handle->skipdata_setup.callback(
buffer_org, size_org,
(size_t)(offset - offset_org),
handle->skipdata_setup.user_data);
if (skipdata_bytes > size)
break;
if (!skipdata_bytes)
break;
} else {
skipdata_bytes = handle->skipdata_size;
}
insn_cache->id = 0;
insn_cache->address = offset;
insn_cache->size = (uint16_t)skipdata_bytes;
memcpy(insn_cache->bytes, buffer, skipdata_bytes);
#ifdef CAPSTONE_DIET
insn_cache->mnemonic[0] = '\0';
insn_cache->op_str[0] = '\0';
#else
strncpy(insn_cache->mnemonic,
handle->skipdata_setup.mnemonic,
sizeof(insn_cache->mnemonic) - 1);
skipdata_opstr(insn_cache->op_str, buffer, skipdata_bytes);
#endif
insn_cache->detail = NULL;
next_offset = skipdata_bytes;
}
f++;
c++;
if (count > 0 && c == count)
break;
if (f == cache_size) {
cache_size = cache_size * 8 / 5;
total_size += (sizeof(cs_insn) * cache_size);
tmp = cs_mem_realloc(total, total_size);
if (tmp == NULL) {
if (handle->detail_opt) {
insn_cache = (cs_insn *)total;
for (i = 0; i < c; i++, insn_cache++)
cs_mem_free(insn_cache->detail);
}
cs_mem_free(total);
*insn = NULL;
handle->errnum = CS_ERR_MEM;
return 0;
}
total = tmp;
insn_cache = (cs_insn *)((char *)total + sizeof(cs_insn) * c);
f = 0;
} else {
insn_cache++;
}
buffer += next_offset;
size -= next_offset;
offset += next_offset;
}
if (!c) {
cs_mem_free(total);
total = NULL;
} else if (f != cache_size) {
tmp = cs_mem_realloc(total,
total_size - (cache_size - f) * sizeof(*insn_cache));
if (tmp == NULL) {
if (handle->detail_opt) {
insn_cache = (cs_insn *)total;
for (i = 0; i < c; i++, insn_cache++)
cs_mem_free(insn_cache->detail);
}
cs_mem_free(total);
*insn = NULL;
handle->errnum = CS_ERR_MEM;
return 0;
}
total = tmp;
}
*insn = total;
return c;
}
CAPSTONE_EXPORT
size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size,
uint64_t offset, size_t count, cs_insn **insn)
{
struct cs_struct *handle;
MCInst mci;
uint16_t insn_size;
size_t c = 0, i;
unsigned int f = 0;
cs_insn *insn_cache;
void *total = NULL;
size_t total_size = 0;
bool r;
void *tmp;
size_t skipdata_bytes;
uint64_t offset_org;
size_t size_org;
const uint8_t *buffer_org;
unsigned int cache_size = INSN_CACHE_SIZE;
size_t next_offset;
handle = (struct cs_struct *)(uintptr_t)ud;
if (!handle) {
return 0;
}
handle->errnum = CS_ERR_OK;
#ifdef CAPSTONE_USE_SYS_DYN_MEM
if (count > 0 && count <= INSN_CACHE_SIZE)
cache_size = (unsigned int)count;
#endif
buffer_org = buffer;
offset_org = offset;
size_org = size;
total_size = sizeof(cs_insn) * cache_size;
total = cs_mem_calloc(sizeof(cs_insn), cache_size);
if (total == NULL) {
handle->errnum = CS_ERR_MEM;
return 0;
}
insn_cache = total;
while (size > 0) {
MCInst_Init(&mci, handle->arch);
mci.csh = handle;
mci.address = offset;
if (handle->detail_opt) {
insn_cache->detail = cs_mem_calloc(1, sizeof(cs_detail));
} else {
insn_cache->detail = NULL;
}
mci.flat_insn = insn_cache;
mci.flat_insn->address = offset;
#ifdef CAPSTONE_DIET
mci.flat_insn->mnemonic[0] = '\0';
mci.flat_insn->op_str[0] = '\0';
#endif
r = handle->disasm(ud, buffer, size, &mci, &insn_size, offset,
handle->getinsn_info);
if (r) {
SStream ss;
SStream_Init(&ss);
mci.flat_insn->size = insn_size;
handle->insn_id(handle, insn_cache, mci.Opcode);
SStream_opt_unum(&ss, handle->imm_unsigned);
handle->printer(&mci, &ss, handle->printer_info);
fill_insn(handle, insn_cache, &ss, &mci,
handle->post_printer, buffer);
if (handle->arch == CS_ARCH_X86 &&
insn_cache->id != X86_INS_VCMP)
insn_cache->id += mci.popcode_adjust;
next_offset = insn_size;
} else {
if (handle->detail_opt) {
cs_mem_free(insn_cache->detail);
}
if (!handle->skipdata || handle->skipdata_size > size)
break;
if (handle->skipdata_setup.callback) {
skipdata_bytes = handle->skipdata_setup.callback(
buffer_org, size_org,
(size_t)(offset - offset_org),
handle->skipdata_setup.user_data);
if (skipdata_bytes > size)
break;
if (!skipdata_bytes)
break;
} else {
skipdata_bytes = handle->skipdata_size;
}
insn_cache->id = 0;
insn_cache->address = offset;
insn_cache->size = (uint16_t)skipdata_bytes;
memcpy(insn_cache->bytes, buffer, skipdata_bytes);
#ifdef CAPSTONE_DIET
insn_cache->mnemonic[0] = '\0';
insn_cache->op_str[0] = '\0';
#else
strncpy(insn_cache->mnemonic,
handle->skipdata_setup.mnemonic,
sizeof(insn_cache->mnemonic) - 1);
skipdata_opstr(insn_cache->op_str, buffer, skipdata_bytes);
#endif
insn_cache->detail = NULL;
next_offset = skipdata_bytes;
}
f++;
c++;
if (count > 0 && c == count)
break;
if (f == cache_size) {
cache_size = cache_size * 8 / 5;
total_size += (sizeof(cs_insn) * cache_size);
tmp = cs_mem_realloc(total, total_size);
if (tmp == NULL) {
if (handle->detail_opt) {
insn_cache = (cs_insn *)total;
for (i = 0; i < c; i++, insn_cache++)
cs_mem_free(insn_cache->detail);
}
cs_mem_free(total);
*insn = NULL;
handle->errnum = CS_ERR_MEM;
return 0;
}
total = tmp;
insn_cache = (cs_insn *)((char *)total + sizeof(cs_insn) * c);
f = 0;
} else {
insn_cache++;
}
buffer += next_offset;
size -= next_offset;
offset += next_offset;
}
if (!c) {
cs_mem_free(total);
total = NULL;
} else if (f != cache_size) {
tmp = cs_mem_realloc(total,
total_size - (cache_size - f) * sizeof(*insn_cache));
if (tmp == NULL) {
if (handle->detail_opt) {
insn_cache = (cs_insn *)total;
for (i = 0; i < c; i++, insn_cache++)
cs_mem_free(insn_cache->detail);
}
cs_mem_free(total);
*insn = NULL;
handle->errnum = CS_ERR_MEM;
return 0;
}
total = tmp;
}
*insn = total;
return c;
}
cs_err AArch64_global_init(cs_struct *ud)
{
MCRegisterInfo *mri;
mri = cs_mem_malloc(sizeof(*mri));
AArch64_init_mri(mri);
ud->printer = AArch64_printer;
ud->printer_info = mri;
ud->getinsn_info = mri;
ud->disasm = AArch64_getInstruction;
ud->reg_name = AArch64_reg_name;
ud->insn_id = AArch64_get_insn_id;
ud->insn_name = AArch64_insn_name;
ud->group_name = AArch64_group_name;
ud->post_printer = NULL;
#ifndef CAPSTONE_DIET
ud->reg_access = AArch64_reg_access;
#endif
return CS_ERR_OK;
}
cs_err AArch64_global_init(cs_struct *ud)
{
MCRegisterInfo *mri;
mri = cs_mem_malloc(sizeof(*mri));
AArch64_init_mri(mri);
ud->printer = AArch64_printer;
ud->printer_info = mri;
ud->getinsn_info = mri;
ud->disasm = AArch64_getInstruction;
ud->reg_name = AArch64_reg_name;
ud->insn_id = AArch64_get_insn_id;
ud->insn_name = AArch64_insn_name;
ud->group_name = AArch64_group_name;
ud->post_printer = NULL;
#ifndef CAPSTONE_DIET
ud->reg_access = AArch64_reg_access;
#endif
return CS_ERR_OK;
}
bool AArch64_getInstruction(csh handle, const uint8_t *code, size_t code_len,
MCInst *MI, uint16_t *size, uint64_t address,
void *info)
{
AArch64_init_cs_detail(MI);
DecodeStatus Result = AArch64_LLVM_getInstruction(
handle, code, code_len, MI, size, address, info);
AArch64_set_instr_map_data(MI);
if (Result == MCDisassembler_SoftFail) {
MCInst_setSoftFail(MI);
}
return Result != MCDisassembler_Fail;
}
DecodeStatus AArch64_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
size_t ByteLen, MCInst *MI,
uint16_t *Size, uint64_t Address,
void *Info)
{
DecodeStatus Result = MCDisassembler_Fail;
Result =
getInstruction(handle, Bytes, ByteLen, MI, Size, Address, Info);
MCInst_handleWriteback(MI, AArch64Descs.Insts,
ARR_SIZE(AArch64Descs.Insts));
return Result;
}
bool AArch64_getInstruction(csh handle, const uint8_t *code, size_t code_len,
MCInst *MI, uint16_t *size, uint64_t address,
void *info)
{
AArch64_init_cs_detail(MI);
DecodeStatus Result = AArch64_LLVM_getInstruction(
handle, code, code_len, MI, size, address, info);
AArch64_set_instr_map_data(MI);
if (Result == MCDisassembler_SoftFail) {
MCInst_setSoftFail(MI);
}
return Result != MCDisassembler_Fail;
}
DecodeStatus AArch64_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
最后于 2025-11-18 09:27
被nothing233编辑
,原因: 补充