Skip to content

New APIs: cs_disasm_alloc() & cs_disasm_buf()

aquynh edited this page Oct 10, 2014 · 21 revisions

Currently the API cs_disasm allocates memory internally for disassembled instructions, which is expensive if we need to decode a lot of instructions.

Here are some proposals to eliminate this issue to achieve better performance for Capstone.


Proposal 1

This proposal proposes 2 new API:

  • cs_disasm_malloc: pre-allocate buffer for instructions

  • cs_disasm_buf: disassemble instructions into pre-allocated buffer provided by cs_disasm_malloc


Prototype:

// pre-allocate memory for @count instructions
cs_err cs_disasm_malloc(csh handle, size_t count, cs_insn **insn);

// disassemble @count instructions using buffer pre-allocated
// by cs_disasm_malloc()
size_t cs_disasm_buf(csh handle,
                const uint8_t *code, size_t code_size,
                uint64_t address,
                size_t count,
                cs_insn *insn);

Sample code will be like below (C-pseudo)

if (cs_disasm_malloc(h, count, &insns) == CS_ERR_OK) {
    // mycount <= count
    while(c = cs_disasm_buf(h, code, size, address, mycount, insns)) {
        // analyze *c* instructions in @insns ...

        // then update input code/size/address for the next iteration
        length = CS_INSN_OFFSET(insns, c);
        code += length;
        size -= length;
        address += length;
    }

    // free memory when done
    cs_free(insns, count);
}

Proposal 2 (by @danghvu)

This proposal proposes 3 new API:

  • cs_disasm_malloc: pre-allocate buffer for 1 instruction

  • cs_disasm_free: free memory allocated by cs_disasm_malloc. Or we can just use cs_free(insn, 1) instead.

  • cs_disasm_iter: disassemble one instruction a time into pre-allocated buffer provided by cs_disasm_malloc, and update code/size/address at the same time.


Prototype:

// pre-allocate memory for 1 instruction
cs_err cs_disasm_malloc(csh handle, cs_insn **insn);

// disassemble 1 instruction using buffer pre-allocated
// by cs_disasm_malloc()
bool cs_disasm_iter(csh handle,
                const uint8_t **code, size_t *code_size,
                uint64_t *address,
                cs_insn *insn);

Sample code will be like below (C-pseudo)

if (cs_disasm_malloc(h, &insn) == CS_ERR_OK) {
    while(cs_disasm_iter(h, &code, &size, &address, insn)) {
        // analyze instruction in @insn ...
    }

    // free memory when done
    cs_disasm_free(insn);
}