I'm trying to get the Capstone engine to print out the raw binary opcodes that are disassembled by the call to cs_disasm(). Here is a snippet of my code but it only prints out a single byte of raw binary opcode (the first byte only) not the entire binary opcodes that is translated into assembly.
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK)
{
return;
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);// != CS_ERR_OK)
cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
count = cs_disasm(handle, (uint8_t*)startofcode, sizeofcode, startofcode, 0, &insn);
if (count > 0)
{
for (size_t j = 0; j < count; j++)
{
DbgPrint("0x%p\t%06x\t%s\t\t%s\n", (void*)(uintptr_t)insn[j].address, insn[j].bytes[0], insn[j].mnemonic, insn[j].op_str);
}
cs_free(insn, count);
}
cs_close(&handle);
For example take the following assembly line of code and its original raw binary opcode
0x0000000000391334 0875ff push qword ptr [rbp + 8]
But using the above call to DbgPrint I'm only able to output a single byte of opcode as shown in the following output.
0x0000000000391334 0000ff push qword ptr [rbp + 8]
The issue is that you're only printing the first byte of the opcode with insn[j].bytes[0]. The Capstone API provides the entire opcode in insn[j].bytes and its length in insn[j].size. You need to loop through those bytes to print the full machine code.
Here’s the corrected snippet:
if (count > 0) {
for (size_t j = 0; j < count; j++) {
// Print address
DbgPrint("0x%p\t", (void*)(uintptr_t)insn[j].address);
// Print full raw bytes
for (size_t k = 0; k < insn[j].size; k++) {
DbgPrint("%02x", insn[j].bytes[k]);
}
// Print mnemonic and operands
DbgPrint("\t%s\t%s\n", insn[j].mnemonic, insn[j].op_str);
}
cs_free(insn, count);
}
cs_close(&handle);