working OCaml bindings

This commit is contained in:
Guillaume Jeanne 2014-06-26 15:35:06 +02:00
parent 5a7f409dec
commit cece24e426
8 changed files with 277 additions and 219 deletions

View File

@ -36,34 +36,44 @@ type cs_insn0 = {
id: int;
address: int;
size: int;
bytes: int array;
mnemonic: string;
op_str: string;
regs_read: int array;
regs_read_count: int;
regs_write: int array;
regs_write_count: int;
groups: int array;
groups_count: int;
arch: cs_arch;
}
external cs_open: arch -> mode list -> Int64.t option = "ocaml_cs_open"
external cs_disasm_quick: arch -> mode list -> string -> Int64.t -> Int64.t -> cs_insn0 list = "ocaml_cs_disasm_quick"
external cs_disasm_dyn: arch -> Int64.t -> string -> Int64.t -> Int64.t -> cs_insn0 list = "ocaml_cs_disasm_dyn"
external cs_reg_name: arch -> int -> string = "cs_register_name"
external cs_reg_name: Int64.t -> int -> string = "cs_register_name"
external cs_insn_name: Int64.t -> int -> string = "cs_instruction_name"
class cs_insn c a =
let csh = c in
let (id, address, size, mnemonic, op_str, regs_read, regs_write, groups, arch) =
(a.id, a.address, a.size, a.mnemonic, a.op_str, a.regs_read, a.regs_write,
a.groups, a.arch) in
let (id, address, size, bytes, mnemonic, op_str, regs_read, regs_read_count,
regs_write, regs_write_count, groups, groups_count, arch) =
(a.id, a.address, a.size, a.bytes, a.mnemonic, a.op_str,
a.regs_read, a.regs_read_count, a.regs_write, a.regs_write_count,
a.groups, a.groups_count, a.arch) in
object
method id = id;
method address = address;
method size = size;
method bytes = bytes;
method mnemonic = mnemonic;
method op_str = op_str;
method regs_read = regs_read;
method regs_read_count = regs_read_count;
method regs_write = regs_write;
method regs_write_count = regs_write_count;
method groups = groups;
method groups_count = groups_count;
method arch = arch;
method insn_name = cs_insn_name csh id;
end;;
@ -82,12 +92,15 @@ class cs a m =
let mode = m and arch = a in
let csh = cs_open arch mode in
object
val handle = match csh with
| None -> failwith "impossible to open an handle\n"
| Some v -> v
method get_csh = handle
method disasm code offset count =
match csh with
| None -> [];
| Some v ->
let insns = (cs_disasm_dyn arch v code offset count) in
List.map (fun x -> new cs_insn v x) insns;
let insns = (cs_disasm_dyn arch handle code offset count) in
List.map (fun x -> new cs_insn handle x) insns;
end;;

View File

@ -28,8 +28,9 @@ ARCH_LIST_COUNT(arm64, cs_arm64_op)
ARCH_LIST_COUNT(mips, cs_mips_op)
ARCH_LIST_COUNT(x86, cs_x86_op)
// count the number of positive members in @list
static unsigned int list_count(unsigned int *list, unsigned int max)
static unsigned int list_count(uint8_t *list, unsigned int max)
{
unsigned int i;
@ -40,7 +41,7 @@ static unsigned int list_count(unsigned int *list, unsigned int max)
return max;
}
static CAMLprim value _cs_disasm(cs_arch arch, csh handle, char *code, uint64_t code_len, uint64_t addr, uint64_t count)
CAMLprim value _cs_disasm(cs_arch arch, csh handle, const uint8_t * code, size_t code_len, uint64_t addr, size_t count)
{
CAMLparam0();
CAMLlocal5(list, cons, rec_insn, array, tmp);
@ -49,103 +50,122 @@ static CAMLprim value _cs_disasm(cs_arch arch, csh handle, char *code, uint64_t
list = Val_emptylist;
uint64_t c = cs_disasm_dyn(handle, code, code_len, addr, count, &insn);
size_t c = cs_disasm_ex(handle, code, code_len, addr, count, &insn);
if (c) {
//printf("Found %lu insn, addr: %lx\n", c, addr);
uint64_t j;
for (j = c; j > 0; j--) {
unsigned int lcount, i;
cons = caml_alloc(2, 0);
rec_insn = caml_alloc(9, 0);
rec_insn = caml_alloc(13, 0);
Store_field(rec_insn, 0, Val_int(insn[j-1].id));
Store_field(rec_insn, 1, Val_int(insn[j-1].address));
Store_field(rec_insn, 2, Val_int(insn[j-1].size));
Store_field(rec_insn, 3, caml_copy_string(insn[j-1].mnemonic));
Store_field(rec_insn, 4, caml_copy_string(insn[j-1].op_str));
Store_field(rec_insn, 4, caml_copy_string(insn[j-1].mnemonic));
Store_field(rec_insn, 5, caml_copy_string(insn[j-1].op_str));
lcount = list_count(insn[j-1].regs_read, ARR_SIZE(insn[j-1].regs_read));
// copy raw bytes of instruction
lcount = insn[j-1].size;
if (lcount) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
Store_field(array, i, Val_int(insn[j-1].regs_read[i]));
Store_field(array, i, Val_int(insn[j-1].bytes[i]));
}
} else // empty list
array = Atom(0);
Store_field(rec_insn, 5, array);
} else
array = Atom(0); // empty list
Store_field(rec_insn, 3, array);
lcount = list_count(insn[j-1].regs_write, ARR_SIZE(insn[j-1].regs_write));
// copy read registers
lcount = (insn[j-1]).detail->regs_read_count;
if (lcount) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
Store_field(array, i, Val_int(insn[j-1].regs_write[i]));
Store_field(array, i, Val_int(insn[j-1].detail->regs_read[i]));
}
} else
array = Atom(0); // empty list
Store_field(rec_insn, 6, array);
Store_field(rec_insn, 7, Val_int(lcount));
lcount = list_count(insn[j-1].groups, ARR_SIZE(insn[j-1].groups));
lcount = (insn[j-1]).detail->regs_write_count;
if (lcount) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
Store_field(array, i, Val_int(insn[j-1].groups[i]));
Store_field(array, i, Val_int(insn[j-1].detail->regs_write[i]));
}
} else
array = Atom(0); // empty list
Store_field(rec_insn, 7, array);
Store_field(rec_insn, 8, array);
Store_field(rec_insn, 9, Val_int(lcount));
lcount = (insn[j-1]).detail->groups_count;
if (lcount) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
Store_field(array, i, Val_int(insn[j-1].detail->groups[i]));
}
} else
array = Atom(0); // empty list
Store_field(rec_insn, 10, array);
Store_field(rec_insn, 11, Val_int(lcount));
if(insn[j-1].detail)
switch(arch) {
default: break;
case CS_ARCH_ARM:
arch_info = caml_alloc(1, 0);
op_info_val = caml_alloc(5, 0);
Store_field(op_info_val, 0, Val_int(insn[j-1].arm.cc));
Store_field(op_info_val, 1, Val_bool(insn[j-1].arm.update_flags));
Store_field(op_info_val, 2, Val_bool(insn[j-1].arm.writeback));
Store_field(op_info_val, 3, Val_int(insn[j-1].arm.op_count));
lcount = arm_list_count(insn[j - 1].arm.operands, ARR_SIZE(insn[j - 1].arm.operands));
Store_field(op_info_val, 0, Val_int(insn[j-1].detail->arm.cc));
Store_field(op_info_val, 1, Val_bool(insn[j-1].detail->arm.update_flags));
Store_field(op_info_val, 2, Val_bool(insn[j-1].detail->arm.writeback));
Store_field(op_info_val, 3, Val_int(insn[j-1].detail->arm.op_count));
lcount = arm_list_count(insn[j - 1].detail->arm.operands, ARR_SIZE(insn[j - 1].detail->arm.operands));
if (lcount > 0) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
tmp2 = caml_alloc(2, 0);
switch(insn[j-1].arm.operands[i].type) {
switch(insn[j-1].detail->arm.operands[i].type) {
case ARM_OP_REG:
tmp = caml_alloc(1, 1);
Store_field(tmp, 0, Val_int(insn[j-1].arm.operands[i].reg));
Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].reg));
break;
case ARM_OP_CIMM:
tmp = caml_alloc(1, 2);
Store_field(tmp, 0, Val_int(insn[j-1].arm.operands[i].imm));
Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].imm));
break;
case ARM_OP_PIMM:
tmp = caml_alloc(1, 3);
Store_field(tmp, 0, Val_int(insn[j-1].arm.operands[i].imm));
Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].imm));
break;
case ARM_OP_IMM:
tmp = caml_alloc(1, 4);
Store_field(tmp, 0, Val_int(insn[j-1].arm.operands[i].imm));
Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].imm));
break;
case ARM_OP_FP:
tmp = caml_alloc(1, 5);
Store_field(tmp, 0, caml_copy_double(insn[j-1].arm.operands[i].fp));
Store_field(tmp, 0, caml_copy_double(insn[j-1].detail->arm.operands[i].fp));
break;
case ARM_OP_MEM:
tmp = caml_alloc(1, 6);
tmp3 = caml_alloc(4, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].arm.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].arm.operands[i].mem.index));
Store_field(tmp3, 2, Val_int(insn[j-1].arm.operands[i].mem.scale));
Store_field(tmp3, 3, Val_int(insn[j-1].arm.operands[i].mem.disp));
Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm.operands[i].mem.index));
Store_field(tmp3, 2, Val_int(insn[j-1].detail->arm.operands[i].mem.scale));
Store_field(tmp3, 3, Val_int(insn[j-1].detail->arm.operands[i].mem.disp));
Store_field(tmp, 0, tmp3);
break;
default: break;
}
tmp3 = caml_alloc(2, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].arm.operands[i].shift.type));
Store_field(tmp3, 1, Val_int(insn[j-1].arm.operands[i].shift.value));
Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm.operands[i].shift.type));
Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm.operands[i].shift.value));
Store_field(tmp2, 0, tmp3);
Store_field(tmp2, 1, tmp);
Store_field(array, i, tmp2);
@ -158,55 +178,55 @@ static CAMLprim value _cs_disasm(cs_arch arch, csh handle, char *code, uint64_t
// finally, insert this into arch_info
Store_field(arch_info, 0, op_info_val);
Store_field(rec_insn, 8, arch_info);
Store_field(rec_insn, 12, arch_info);
break;
case CS_ARCH_ARM64:
arch_info = caml_alloc(1, 1);
op_info_val = caml_alloc(5, 0);
Store_field(op_info_val, 0, Val_int(insn[j-1].arm64.cc));
Store_field(op_info_val, 1, Val_bool(insn[j-1].arm64.update_flags));
Store_field(op_info_val, 2, Val_bool(insn[j-1].arm64.writeback));
Store_field(op_info_val, 3, Val_int(insn[j-1].arm64.op_count));
Store_field(op_info_val, 0, Val_int(insn[j-1].detail->arm64.cc));
Store_field(op_info_val, 1, Val_bool(insn[j-1].detail->arm64.update_flags));
Store_field(op_info_val, 2, Val_bool(insn[j-1].detail->arm64.writeback));
Store_field(op_info_val, 3, Val_int(insn[j-1].detail->arm64.op_count));
lcount = arm64_list_count(insn[j - 1].arm64.operands, ARR_SIZE(insn[j - 1].arm64.operands));
lcount = arm64_list_count(insn[j - 1].detail->arm64.operands, ARR_SIZE(insn[j - 1].detail->arm64.operands));
if (lcount > 0) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
tmp2 = caml_alloc(3, 0);
switch(insn[j-1].arm64.operands[i].type) {
switch(insn[j-1].detail->arm64.operands[i].type) {
case ARM64_OP_REG:
tmp = caml_alloc(1, 1);
Store_field(tmp, 0, Val_int(insn[j-1].arm64.operands[i].reg));
Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].reg));
break;
case ARM64_OP_CIMM:
tmp = caml_alloc(1, 2);
Store_field(tmp, 0, Val_int(insn[j-1].arm64.operands[i].imm));
Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].imm));
break;
case ARM64_OP_IMM:
tmp = caml_alloc(1, 3);
Store_field(tmp, 0, Val_int(insn[j-1].arm64.operands[i].imm));
Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].imm));
break;
case ARM64_OP_FP:
tmp = caml_alloc(1, 4);
Store_field(tmp, 0, caml_copy_double(insn[j-1].arm64.operands[i].fp));
Store_field(tmp, 0, caml_copy_double(insn[j-1].detail->arm64.operands[i].fp));
break;
case ARM64_OP_MEM:
tmp = caml_alloc(1, 5);
tmp3 = caml_alloc(3, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].arm64.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].arm64.operands[i].mem.index));
Store_field(tmp3, 2, Val_int(insn[j-1].arm64.operands[i].mem.disp));
Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm64.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm64.operands[i].mem.index));
Store_field(tmp3, 2, Val_int(insn[j-1].detail->arm64.operands[i].mem.disp));
Store_field(tmp, 0, tmp3);
break;
default: break;
}
tmp3 = caml_alloc(2, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].arm64.operands[i].shift.type));
Store_field(tmp3, 1, Val_int(insn[j-1].arm64.operands[i].shift.value));
Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm64.operands[i].shift.type));
Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm64.operands[i].shift.value));
Store_field(tmp2, 0, tmp3);
Store_field(tmp2, 1, Val_int(insn[j-1].arm64.operands[i].ext));
Store_field(tmp2, 1, Val_int(insn[j-1].detail->arm64.operands[i].ext));
Store_field(tmp2, 2, tmp);
Store_field(array, i, tmp2);
@ -219,34 +239,34 @@ static CAMLprim value _cs_disasm(cs_arch arch, csh handle, char *code, uint64_t
// finally, insert this into arch_info
Store_field(arch_info, 0, op_info_val);
Store_field(rec_insn, 8, arch_info);
Store_field(rec_insn, 12, arch_info);
break;
case CS_ARCH_MIPS:
arch_info = caml_alloc(1, 2);
op_info_val = caml_alloc(2, 0);
Store_field(op_info_val, 0, Val_int(insn[j-1].mips.op_count));
Store_field(op_info_val, 0, Val_int(insn[j-1].detail->mips.op_count));
lcount = mips_list_count(insn[j - 1].mips.operands, ARR_SIZE(insn[j - 1].mips.operands));
lcount = mips_list_count(insn[j - 1].detail->mips.operands, ARR_SIZE(insn[j - 1].detail->mips.operands));
if (lcount > 0) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
tmp2 = caml_alloc(1, 0);
switch(insn[j-1].mips.operands[i].type) {
switch(insn[j-1].detail->mips.operands[i].type) {
case MIPS_OP_REG:
tmp = caml_alloc(1, 1);
Store_field(tmp, 0, Val_int(insn[j-1].mips.operands[i].reg));
Store_field(tmp, 0, Val_int(insn[j-1].detail->mips.operands[i].reg));
break;
case MIPS_OP_IMM:
tmp = caml_alloc(1, 2);
Store_field(tmp, 0, Val_int(insn[j-1].mips.operands[i].imm));
Store_field(tmp, 0, Val_int(insn[j-1].detail->mips.operands[i].imm));
break;
case MIPS_OP_MEM:
tmp = caml_alloc(1, 3);
tmp3 = caml_alloc(2, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].mips.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].mips.operands[i].mem.disp));
Store_field(tmp3, 0, Val_int(insn[j-1].detail->mips.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].detail->mips.operands[i].mem.disp));
Store_field(tmp, 0, tmp3);
break;
default: break;
@ -262,74 +282,83 @@ static CAMLprim value _cs_disasm(cs_arch arch, csh handle, char *code, uint64_t
// finally, insert this into arch_info
Store_field(arch_info, 0, op_info_val);
Store_field(rec_insn, 8, arch_info);
Store_field(rec_insn, 12, arch_info);
break;
case CS_ARCH_X86:
arch_info = caml_alloc(1, 3);
op_info_val = caml_alloc(15, 0);
array = caml_alloc(ARR_SIZE(insn[0].x86.prefix), 0);
for (i = 0; i < ARR_SIZE(insn[0].x86.prefix); i++) {
Store_field(array, i, Val_int(insn[j-1].x86.prefix[i]));
}
// fill prefix
lcount = list_count(insn[j-1].detail->x86.prefix, ARR_SIZE(insn[j-1].detail->x86.prefix));
if(lcount) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
Store_field(array, i, Val_int(insn[j-1].detail->x86.prefix[i]));
}
} else
array = Atom(0);
Store_field(op_info_val, 0, array);
Store_field(op_info_val, 1, Val_int(insn[j-1].x86.segment));
Store_field(op_info_val, 1, Val_int(insn[j-1].detail->x86.segment));
array = caml_alloc(ARR_SIZE(insn[0].x86.opcode), 0);
for (i = 0; i < ARR_SIZE(insn[0].x86.opcode); i++) {
Store_field(array, i, Val_int(insn[j-1].x86.opcode[i]));
}
// fill opcode
lcount = list_count(insn[j-1].detail->x86.opcode, ARR_SIZE(insn[j-1].detail->x86.opcode));
if(lcount) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
Store_field(array, i, Val_int(insn[j-1].detail->x86.opcode[i]));
}
} else
array = Atom(0);
Store_field(op_info_val, 2, array);
Store_field(op_info_val, 3, Val_int(insn[j-1].detail->x86.op_size));
Store_field(op_info_val, 3, Val_int(insn[j-1].x86.op_size));
Store_field(op_info_val, 4, Val_int(insn[j-1].detail->x86.addr_size));
Store_field(op_info_val, 4, Val_int(insn[j-1].x86.addr_size));
Store_field(op_info_val, 5, Val_int(insn[j-1].detail->x86.disp_size));
Store_field(op_info_val, 5, Val_int(insn[j-1].x86.disp_size));
Store_field(op_info_val, 6, Val_int(insn[j-1].detail->x86.imm_size));
Store_field(op_info_val, 6, Val_int(insn[j-1].x86.imm_size));
Store_field(op_info_val, 7, Val_int(insn[j-1].detail->x86.modrm));
Store_field(op_info_val, 7, Val_int(insn[j-1].x86.modrm));
Store_field(op_info_val, 8, Val_int(insn[j-1].detail->x86.sib));
Store_field(op_info_val, 8, Val_int(insn[j-1].x86.sib));
Store_field(op_info_val, 9, Val_int(insn[j-1].detail->x86.disp));
Store_field(op_info_val, 9, Val_int(insn[j-1].x86.disp));
Store_field(op_info_val, 10, Val_int(insn[j-1].detail->x86.sib_index));
Store_field(op_info_val, 10, Val_int(insn[j-1].x86.sib_index));
Store_field(op_info_val, 11, Val_int(insn[j-1].detail->x86.sib_scale));
Store_field(op_info_val, 11, Val_int(insn[j-1].x86.sib_scale));
Store_field(op_info_val, 12, Val_int(insn[j-1].detail->x86.sib_base));
Store_field(op_info_val, 12, Val_int(insn[j-1].x86.sib_base));
Store_field(op_info_val, 13, Val_int(insn[j-1].x86.op_count));
lcount = x86_list_count(insn[j - 1].x86.operands, ARR_SIZE(insn[j - 1].x86.operands));
Store_field(op_info_val, 13, Val_int(insn[j-1].detail->x86.op_count));
lcount = x86_list_count(insn[j - 1].detail->x86.operands, ARR_SIZE(insn[j - 1].detail->x86.operands));
if (lcount > 0) {
array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) {
switch(insn[j-1].x86.operands[i].type) {
switch(insn[j-1].detail->x86.operands[i].type) {
case X86_OP_REG:
tmp = caml_alloc(1, 1);
Store_field(tmp, 0, Val_int(insn[j-1].x86.operands[i].reg));
Store_field(tmp, 0, Val_int(insn[j-1].detail->x86.operands[i].reg));
break;
case X86_OP_IMM:
tmp = caml_alloc(1, 2);
Store_field(tmp, 0, Val_int(insn[j-1].x86.operands[i].imm));
Store_field(tmp, 0, Val_int(insn[j-1].detail->x86.operands[i].imm));
break;
case X86_OP_FP:
tmp = caml_alloc(1, 3);
Store_field(tmp, 0, caml_copy_double(insn[j-1].x86.operands[i].fp));
Store_field(tmp, 0, caml_copy_double(insn[j-1].detail->x86.operands[i].fp));
break;
case X86_OP_MEM:
tmp = caml_alloc(1, 4);
tmp2 = caml_alloc(4, 0);
Store_field(tmp2, 0, Val_int(insn[j-1].x86.operands[i].mem.base));
Store_field(tmp2, 1, Val_int(insn[j-1].x86.operands[i].mem.index));
Store_field(tmp2, 2, Val_int(insn[j-1].x86.operands[i].mem.scale));
Store_field(tmp2, 3, Val_int(insn[j-1].x86.operands[i].mem.disp));
Store_field(tmp2, 0, Val_int(insn[j-1].detail->x86.operands[i].mem.base));
Store_field(tmp2, 1, Val_int(insn[j-1].detail->x86.operands[i].mem.index));
Store_field(tmp2, 2, Val_int(insn[j-1].detail->x86.operands[i].mem.scale));
Store_field(tmp2, 3, Val_int(insn[j-1].detail->x86.operands[i].mem.disp));
Store_field(tmp, 0, tmp2);
break;
default:
@ -345,20 +374,20 @@ static CAMLprim value _cs_disasm(cs_arch arch, csh handle, char *code, uint64_t
// finally, insert this into arch_info
Store_field(arch_info, 0, op_info_val);
Store_field(rec_insn, 8, arch_info);
Store_field(rec_insn, 12, arch_info);
break;
default: break;
}
Store_field(cons, 0, rec_insn); // head
Store_field(cons, 1, list); // tail
list = cons;
}
cs_free(insn);
cs_free(insn, count);
}
cs_close(handle);
// do not free the handle here
//cs_close(&handle);
CAMLreturn(list);
}
@ -369,8 +398,9 @@ CAMLprim value ocaml_cs_disasm_quick(value _arch, value _mode, value _code, valu
csh handle;
cs_arch arch;
cs_mode mode = 0;
char *code;
uint64_t addr, count, code_len;
const uint8_t *code;
uint64_t addr;
size_t count, code_len;
switch (Int_val(_arch)) {
case 0:
@ -397,7 +427,7 @@ CAMLprim value ocaml_cs_disasm_quick(value _arch, value _mode, value _code, valu
mode |= CS_MODE_LITTLE_ENDIAN;
break;
case 1:
mode |= CS_MODE_SYNTAX_INTEL;
mode |= CS_OPT_SYNTAX_INTEL;
break;
case 2:
mode |= CS_MODE_ARM;
@ -421,7 +451,7 @@ CAMLprim value ocaml_cs_disasm_quick(value _arch, value _mode, value _code, valu
mode |= CS_MODE_N64;
break;
case 9:
mode |= CS_MODE_SYNTAX_ATT;
mode |= CS_OPT_SYNTAX_ATT;
break;
case 10:
mode |= CS_MODE_BIG_ENDIAN;
@ -433,10 +463,14 @@ CAMLprim value ocaml_cs_disasm_quick(value _arch, value _mode, value _code, valu
_mode = Field(_mode, 1); /* point to the tail for next loop */
}
if (cs_open(arch, mode, &handle) == false)
//CS_ERR_OK = 0, // No error: everything was fine
if (cs_open(arch, mode, &handle) != 0)
return Val_emptylist;
code = String_val(_code);
if (cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON) != 0)
CAMLreturn(Val_int(0));
code = (uint8_t *)String_val(_code);
code_len = caml_string_length(_code);
addr = Int64_val(_addr);
count = Int64_val(_count);
@ -449,13 +483,13 @@ CAMLprim value ocaml_cs_disasm_dyn(value _arch, value _handle, value _code, valu
CAMLparam5(_arch, _handle, _code, _addr, _count);
csh handle;
cs_arch arch;
char *code;
const uint8_t *code;
uint64_t addr, count, code_len;
handle = Int64_val(_handle);
arch = Int_val(_arch);
code = String_val(_code);
code = (uint8_t *)String_val(_code);
code_len = caml_string_length(_code);
addr = Int64_val(_addr);
count = Int64_val(_count);
@ -491,6 +525,7 @@ CAMLprim value ocaml_cs_open(value _arch, value _mode)
return Val_emptylist;
}
while (_mode != Val_emptylist) {
head = Field(_mode, 0); /* accessing the head */
switch (Int_val(head)) {
@ -498,7 +533,7 @@ CAMLprim value ocaml_cs_open(value _arch, value _mode)
mode |= CS_MODE_LITTLE_ENDIAN;
break;
case 1:
mode |= CS_MODE_SYNTAX_INTEL;
mode |= CS_OPT_SYNTAX_INTEL;
break;
case 2:
mode |= CS_MODE_ARM;
@ -522,7 +557,7 @@ CAMLprim value ocaml_cs_open(value _arch, value _mode)
mode |= CS_MODE_N64;
break;
case 9:
mode |= CS_MODE_SYNTAX_ATT;
mode |= CS_OPT_SYNTAX_ATT;
break;
case 10:
mode |= CS_MODE_BIG_ENDIAN;
@ -534,44 +569,34 @@ CAMLprim value ocaml_cs_open(value _arch, value _mode)
_mode = Field(_mode, 1); /* point to the tail for next loop */
}
if (cs_open(arch, mode, &handle) == false)
if (cs_open(arch, mode, &handle) != 0)
CAMLreturn(Val_int(0));
else {
CAMLlocal1(result);
result = caml_alloc(1, 0);
Store_field(result, 0, caml_copy_int64(handle));
CAMLreturn(result);
}
if (cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON) != 0)
CAMLreturn(Val_int(0));
CAMLlocal1(result);
result = caml_alloc(1, 0);
Store_field(result, 0, caml_copy_int64(handle));
CAMLreturn(result);
}
CAMLprim value cs_register_name(value _arch, value _reg)
CAMLprim value cs_register_name(value _handle, value _reg)
{
cs_arch arch;
switch (Int_val(_arch)) {
case 0:
arch = CS_ARCH_ARM;
break;
case 1:
arch = CS_ARCH_ARM64;
break;
case 2:
arch = CS_ARCH_MIPS;
break;
case 3:
arch = CS_ARCH_X86;
break;
default:
arch = Int_val(_arch);
break;
const char *name = cs_reg_name(Int64_val(_handle), Int_val(_reg));
if(!name) {
caml_invalid_argument("invalid reg_id");
name = "invalid";
}
char *name = cs_reg_name(arch, Int_val(_reg));
return caml_copy_string(name);
}
CAMLprim value cs_instruction_name(value _handle, value _insn)
{
char *name = cs_insn_name(Int64_val(_handle), Int_val(_insn));
const char *name = cs_insn_name(Int64_val(_handle), Int_val(_insn));
if(!name) {
caml_invalid_argument("invalid insn_id");
name = "invalid";
}
return caml_copy_string(name);
}

View File

@ -41,9 +41,9 @@ let print_arch x =
printf "Platform: %s\n" comment;
List.iter print_insn insns;;
(*
List.iter print_arch all_tests;;
*)
let print_insn_cls insn =
printf "0x%x\t%s\t%s\n" insn#address insn#mnemonic insn#op_str;;
@ -58,3 +58,4 @@ let print_arch_cls x =
);;
List.iter print_arch_cls all_tests;;

View File

@ -28,19 +28,19 @@ let all_tests = [
];;
let print_op i op =
let print_op csh i op =
( match op.value with
| ARM_OP_INVALID _ -> (); (* this would never happens *)
| ARM_OP_REG reg -> printf "\t\top[%d]: REG = %s\n" i (cs_reg_name CS_ARCH_ARM reg);
| ARM_OP_REG reg -> printf "\t\top[%d]: REG = %s\n" i (cs_reg_name csh reg);
| ARM_OP_CIMM imm -> printf "\t\top[%d]: C-IMM = %u\n" i imm;
| ARM_OP_PIMM imm -> printf "\t\top[%d]: P-IMM = %u\n" i imm;
| ARM_OP_IMM imm -> printf "\t\top[%d]: IMM = 0x%x\n" i imm;
| ARM_OP_FP fp -> printf "\t\top[%d]: FP = %f\n" i fp;
| ARM_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i;
if mem.base != 0 then
printf "\t\t\toperands[%u].mem.base: REG = %s\n" i (cs_reg_name CS_ARCH_ARM mem.base);
printf "\t\t\toperands[%u].mem.base: REG = %s\n" i (cs_reg_name csh mem.base);
if mem.index != 0 then
printf "\t\t\toperands[%u].mem.index: REG = %s\n" i (cs_reg_name CS_ARCH_ARM mem.index);
printf "\t\t\toperands[%u].mem.index: REG = %s\n" i (cs_reg_name csh mem.index);
if mem.scale != 1 then
printf "\t\t\toperands[%u].mem.scale: %d\n" i mem.scale;
if mem.displ != 0 then
@ -54,7 +54,7 @@ let print_op i op =
();;
let print_detail arch =
let print_detail csh arch =
match arch with
| CS_INFO_ARM64 _ -> ();
| CS_INFO_X86 _ -> ();
@ -72,14 +72,17 @@ let print_detail arch =
(* print all operands info (type & value) *)
if (Array.length arm.operands) > 0 then (
printf "\top_count: %d\n" (Array.length arm.operands);
Array.iteri print_op arm.operands;
Array.iteri (print_op csh) arm.operands;
);
printf "\n";;
let print_insn insn =
let print_insn mode insn =
printf "0x%x\t%s\t%s\n" insn.address insn.mnemonic insn.op_str;
print_detail insn.arch;;
let csh = cs_open CS_ARCH_ARM mode in
match csh with
| None -> ()
| Some v -> print_detail v insn.arch
let print_arch x =
@ -87,18 +90,18 @@ let print_arch x =
let insns = cs_disasm_quick arch mode code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter print_insn insns;;
List.iter (print_insn mode) insns;;
(*
List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *)
let print_insn_cls insn =
let print_insn_cls csh insn =
printf "0x%x\t%s\t%s\n" insn#address insn#mnemonic insn#op_str;
print_detail insn#arch;;
print_detail csh insn#arch;;
let print_arch_cls x =
@ -107,7 +110,7 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter print_insn_cls insns;
List.iter (print_insn_cls d#get_csh) insns;
);;

View File

@ -20,18 +20,18 @@ let all_tests = [
(CS_ARCH_ARM64, [CS_MODE_ARM], _ARM64_CODE, "ARM-64");
];;
let print_op i op =
let print_op csh i op =
( match op.value with
| ARM64_OP_INVALID _ -> (); (* this would never happens *)
| ARM64_OP_REG reg -> printf "\t\top[%d]: REG = %s\n" i (cs_reg_name CS_ARCH_ARM64 reg);
| ARM64_OP_REG reg -> printf "\t\top[%d]: REG = %s\n" i (cs_reg_name csh reg);
| ARM64_OP_CIMM imm -> printf "\t\top[%d]: C-IMM = %u\n" i imm;
| ARM64_OP_IMM imm -> printf "\t\top[%d]: IMM = 0x%x\n" i imm;
| ARM64_OP_FP fp -> printf "\t\top[%d]: FP = %f\n" i fp;
| ARM64_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i;
if mem.base != 0 then
printf "\t\t\toperands[%u].mem.base: REG = %s\n" i (cs_reg_name CS_ARCH_ARM64 mem.base);
printf "\t\t\toperands[%u].mem.base: REG = %s\n" i (cs_reg_name csh mem.base);
if mem.index != 0 then
printf "\t\t\toperands[%u].mem.index: REG = %s\n" i (cs_reg_name CS_ARCH_ARM64 mem.index);
printf "\t\t\toperands[%u].mem.index: REG = %s\n" i (cs_reg_name csh mem.index);
if mem.displ != 0 then
printf "\t\t\toperands[%u].mem.disp: 0x%x\n" i mem.displ;
);
@ -46,7 +46,7 @@ let print_op i op =
();;
let print_detail arch =
let print_detail csh arch =
match arch with
| CS_INFO_ARM _ -> ();
| CS_INFO_MIPS _ -> ();
@ -64,14 +64,17 @@ let print_detail arch =
(* print all operands info (type & value) *)
if (Array.length arm64.operands) > 0 then (
printf "\top_count: %d\n" (Array.length arm64.operands);
Array.iteri print_op arm64.operands;
Array.iteri (print_op csh) arm64.operands;
);
printf "\n";;
let print_insn insn =
let print_insn mode insn =
printf "0x%x\t%s\t%s\n" insn.address insn.mnemonic insn.op_str;
print_detail insn.arch;;
let csh = cs_open CS_ARCH_ARM64 mode in
match csh with
| None -> ()
| Some v -> print_detail v insn.arch
let print_arch x =
@ -79,18 +82,18 @@ let print_arch x =
let insns = cs_disasm_quick arch mode code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter print_insn insns;;
List.iter (print_insn mode) insns;;
(*
List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *)
let print_insn_cls insn =
let print_insn_cls csh insn =
printf "0x%x\t%s\t%s\n" insn#address insn#mnemonic insn#op_str;
print_detail insn#arch;;
print_detail csh insn#arch;;
let print_arch_cls x =
@ -99,7 +102,7 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter print_insn_cls insns;
List.iter (print_insn_cls d#get_csh) insns;
);;
List.iter print_arch_cls all_tests;;

View File

@ -31,17 +31,17 @@ let all_tests = [
];;
let print_detail arch insn =
let print_detail csh insn =
(* print immediate operands *)
if (Array.length insn.regs_read) > 0 then begin
printf "\tImplicit registers read: ";
Array.iter (fun x -> printf "%s "(cs_reg_name arch x)) insn.regs_read;
Array.iter (fun x -> printf "%s "(cs_reg_name csh x)) insn.regs_read;
printf "\n";
end;
if (Array.length insn.regs_write) > 0 then begin
printf "\tImplicit registers written: ";
Array.iter (fun x -> printf "%s "(cs_reg_name arch x)) insn.regs_write;
Array.iter (fun x -> printf "%s "(cs_reg_name csh x)) insn.regs_write;
printf "\n";
end;
@ -53,9 +53,12 @@ let print_detail arch insn =
printf "\n";;
let print_insn arch insn =
let print_insn mode arch insn =
printf "0x%x\t%s\t%s\n" insn.address insn.mnemonic insn.op_str;
print_detail arch insn;;
let csh = cs_open arch mode in
match csh with
| None -> ()
| Some v -> print_detail v insn
let print_arch x =
@ -63,24 +66,24 @@ let print_arch x =
let insns = cs_disasm_quick arch mode code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter (print_insn arch) insns;;
List.iter (print_insn mode arch) insns;;
(*
List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *)
let print_detail_cls arch insn =
let print_detail_cls arch csh insn =
(* print immediate operands *)
if (Array.length insn#regs_read) > 0 then begin
printf "\tImplicit registers read: ";
Array.iter (fun x -> printf "%s "(cs_reg_name arch x)) insn#regs_read;
Array.iter (fun x -> printf "%s "(cs_reg_name csh x)) insn#regs_read;
printf "\n";
end;
if (Array.length insn#regs_write) > 0 then begin
printf "\tImplicit registers written: ";
Array.iter (fun x -> printf "%s "(cs_reg_name arch x)) insn#regs_write;
Array.iter (fun x -> printf "%s "(cs_reg_name csh x)) insn#regs_write;
printf "\n";
end;
@ -92,9 +95,9 @@ let print_detail_cls arch insn =
printf "\n";;
let print_insn_cls arch insn =
let print_insn_cls arch csh insn =
printf "0x%x\t%s\t%s\n" insn#address insn#mnemonic insn#op_str;
print_detail_cls arch insn;;
print_detail_cls arch csh insn;;
let print_arch_cls x =
@ -103,7 +106,8 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter (print_insn_cls arch) insns;
List.iter (print_insn_cls arch (d#get_csh)) insns;
();;
List.iter print_arch_cls all_tests;;

View File

@ -22,14 +22,14 @@ let all_tests = [
(CS_ARCH_MIPS, [CS_MODE_64; CS_MODE_LITTLE_ENDIAN], _MIPS_CODE2, "MIPS-64-EL (Little-endian)");
];;
let print_op i op =
let print_op csh i op =
( match op.value with
| MIPS_OP_INVALID _ -> (); (* this would never happens *)
| MIPS_OP_REG reg -> printf "\t\top[%d]: REG = %s\n" i (cs_reg_name CS_ARCH_MIPS reg);
| MIPS_OP_REG reg -> printf "\t\top[%d]: REG = %s\n" i (cs_reg_name csh reg);
| MIPS_OP_IMM imm -> printf "\t\top[%d]: IMM = 0x%x\n" i imm;
| MIPS_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i;
if mem.base != 0 then
printf "\t\t\toperands[%u].mem.base: REG = %s\n" i (cs_reg_name CS_ARCH_MIPS mem.base);
printf "\t\t\toperands[%u].mem.base: REG = %s\n" i (cs_reg_name csh mem.base);
if mem.displ != 0 then
printf "\t\t\toperands[%u].mem.disp: 0x%x\n" i mem.displ;
);
@ -38,7 +38,7 @@ let print_op i op =
();;
let print_detail arch =
let print_detail csh arch =
match arch with
| CS_INFO_ARM _ -> ();
| CS_INFO_ARM64 _ -> ();
@ -48,14 +48,17 @@ let print_detail arch =
(* print all operands info (type & value) *)
if (Array.length mips.operands) > 0 then (
printf "\top_count: %d\n" (Array.length mips.operands);
Array.iteri print_op mips.operands;
Array.iteri (print_op csh) mips.operands;
);
printf "\n";;
let print_insn insn =
let print_insn mode insn =
printf "0x%x\t%s\t%s\n" insn.address insn.mnemonic insn.op_str;
print_detail insn.arch;;
let csh = cs_open CS_ARCH_MIPS mode in
match csh with
| None -> ()
| Some v -> print_detail v insn.arch
let print_arch x =
@ -63,18 +66,18 @@ let print_arch x =
let insns = cs_disasm_quick arch mode code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter print_insn insns;;
List.iter (print_insn mode) insns;;
(*
List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *)
let print_insn_cls insn =
let print_insn_cls csh insn =
printf "0x%x\t%s\t%s\n" insn#address insn#mnemonic insn#op_str;
print_detail insn#arch;;
print_detail csh insn#arch;;
let print_arch_cls x =
@ -83,7 +86,7 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter print_insn_cls insns;
List.iter (print_insn_cls d#get_csh) insns;
);;
List.iter print_arch_cls all_tests;;

View File

@ -26,17 +26,17 @@ let all_tests = [
(CS_ARCH_X86, [CS_MODE_64], _X86_CODE64, "X86 64 (Intel syntax)");
];;
let print_op i op =
let print_op csh i op =
( match op with
| X86_OP_INVALID _ -> (); (* this would never happens *)
| X86_OP_REG reg -> printf "\t\top[%d]: REG = %s\n" i (cs_reg_name CS_ARCH_X86 reg);
| X86_OP_REG reg -> printf "\t\top[%d]: REG = %s\n" i (cs_reg_name csh reg);
| X86_OP_IMM imm -> printf "\t\top[%d]: IMM = 0x%x\n" i imm;
| X86_OP_FP fp -> printf "\t\top[%d]: FP = %f\n" i fp;
| X86_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i;
if mem.base != 0 then
printf "\t\t\toperands[%u].mem.base: REG = %s\n" i (cs_reg_name CS_ARCH_X86 mem.base);
printf "\t\t\toperands[%u].mem.base: REG = %s\n" i (cs_reg_name csh mem.base);
if mem.index != 0 then
printf "\t\t\toperands[%u].mem.index: REG = %s\n" i (cs_reg_name CS_ARCH_X86 mem.index);
printf "\t\t\toperands[%u].mem.index: REG = %s\n" i (cs_reg_name csh mem.index);
if mem.scale != 1 then
printf "\t\t\toperands[%u].mem.scale: %d\n" i mem.scale;
if mem.displ != 0 then
@ -46,7 +46,7 @@ let print_op i op =
();;
let print_detail mode arch =
let print_detail mode csh arch =
match arch with
| CS_INFO_ARM64 _ -> ();
| CS_INFO_ARM _ -> ();
@ -56,7 +56,8 @@ let print_detail mode arch =
(* print segment override (if applicable) *)
if x86.segment != _X86_REG_INVALID then
printf "\tsegment = %s\n" (cs_reg_name CS_ARCH_X86 x86.segment);
printf "\tsegment = %s\n" (cs_reg_name csh x86.segment);
(* print instruction's opcode *)
print_string_hex "\tOpcode: " x86.opcode;
@ -81,22 +82,25 @@ let print_detail mode arch =
(* print sib index/scale/base (if applicable) *)
if x86.sib_index != _X86_REG_INVALID then
printf "\tsib_index: %s, sib_scale: %u, sib_base: %s\n"
(cs_reg_name CS_ARCH_X86 x86.sib_index)
(cs_reg_name csh x86.sib_index)
x86.sib_scale
(cs_reg_name CS_ARCH_X86 x86.sib_base);
(cs_reg_name csh x86.sib_base);
);
(* print all operands info (type & value) *)
if (Array.length x86.operands) > 0 then (
printf "\top_count: %d\n" (Array.length x86.operands);
Array.iteri print_op x86.operands;
Array.iteri (print_op csh) x86.operands;
);
printf "\n";;
let print_insn mode insn =
printf "0x%x\t%s\t%s\n" insn.address insn.mnemonic insn.op_str;
print_detail mode insn.arch;;
let csh = cs_open CS_ARCH_X86 mode in
match csh with
| None -> ()
| Some v -> print_detail mode v insn.arch
let print_arch x =
@ -107,14 +111,15 @@ let print_arch x =
List.iter (print_insn mode) insns;;
(*
List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *)
let print_insn_cls mode insn =
let print_insn_cls mode csh insn =
printf "0x%x\t%s\t%s\n" insn#address insn#mnemonic insn#op_str;
print_detail mode insn#arch;;
print_string_hex "\tbytes: " insn#bytes;
print_detail mode csh insn#arch;;
let print_arch_cls x =
@ -123,8 +128,9 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in
printf "*************\n";
printf "Platform: %s\n" comment;
List.iter (print_insn_cls mode) insns;
List.iter (print_insn_cls mode d#get_csh) insns;
);;
List.iter print_arch_cls all_tests;;