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; id: int;
address: int; address: int;
size: int; size: int;
bytes: int array;
mnemonic: string; mnemonic: string;
op_str: string; op_str: string;
regs_read: int array; regs_read: int array;
regs_read_count: int;
regs_write: int array; regs_write: int array;
regs_write_count: int;
groups: int array; groups: int array;
groups_count: int;
arch: cs_arch; arch: cs_arch;
} }
external cs_open: arch -> mode list -> Int64.t option = "ocaml_cs_open" 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_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_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" external cs_insn_name: Int64.t -> int -> string = "cs_instruction_name"
class cs_insn c a = class cs_insn c a =
let csh = c in let csh = c in
let (id, address, size, mnemonic, op_str, regs_read, regs_write, groups, arch) = let (id, address, size, bytes, mnemonic, op_str, regs_read, regs_read_count,
(a.id, a.address, a.size, a.mnemonic, a.op_str, a.regs_read, a.regs_write, regs_write, regs_write_count, groups, groups_count, arch) =
a.groups, a.arch) in (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 object
method id = id; method id = id;
method address = address; method address = address;
method size = size; method size = size;
method bytes = bytes;
method mnemonic = mnemonic; method mnemonic = mnemonic;
method op_str = op_str; method op_str = op_str;
method regs_read = regs_read; method regs_read = regs_read;
method regs_read_count = regs_read_count;
method regs_write = regs_write; method regs_write = regs_write;
method regs_write_count = regs_write_count;
method groups = groups; method groups = groups;
method groups_count = groups_count;
method arch = arch; method arch = arch;
method insn_name = cs_insn_name csh id; method insn_name = cs_insn_name csh id;
end;; end;;
@ -82,12 +92,15 @@ class cs a m =
let mode = m and arch = a in let mode = m and arch = a in
let csh = cs_open arch mode in let csh = cs_open arch mode in
object 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 = method disasm code offset count =
match csh with let insns = (cs_disasm_dyn arch handle code offset count) in
| None -> []; List.map (fun x -> new cs_insn handle x) insns;
| Some v ->
let insns = (cs_disasm_dyn arch v code offset count) in
List.map (fun x -> new cs_insn v x) insns;
end;; end;;

View File

@ -28,8 +28,9 @@ ARCH_LIST_COUNT(arm64, cs_arm64_op)
ARCH_LIST_COUNT(mips, cs_mips_op) ARCH_LIST_COUNT(mips, cs_mips_op)
ARCH_LIST_COUNT(x86, cs_x86_op) ARCH_LIST_COUNT(x86, cs_x86_op)
// count the number of positive members in @list // 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; unsigned int i;
@ -40,7 +41,7 @@ static unsigned int list_count(unsigned int *list, unsigned int max)
return 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(); CAMLparam0();
CAMLlocal5(list, cons, rec_insn, array, tmp); 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; 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) { if (c) {
//printf("Found %lu insn, addr: %lx\n", c, addr); //printf("Found %lu insn, addr: %lx\n", c, addr);
uint64_t j; uint64_t j;
for (j = c; j > 0; j--) { for (j = c; j > 0; j--) {
unsigned int lcount, i; unsigned int lcount, i;
cons = caml_alloc(2, 0); 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, 0, Val_int(insn[j-1].id));
Store_field(rec_insn, 1, Val_int(insn[j-1].address)); 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, 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) { if (lcount) {
array = caml_alloc(lcount, 0); array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) { 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 } else
array = Atom(0); array = Atom(0); // empty list
Store_field(rec_insn, 5, array); 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) { if (lcount) {
array = caml_alloc(lcount, 0); array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) { 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 } else
array = Atom(0); // empty list array = Atom(0); // empty list
Store_field(rec_insn, 6, array); 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) { if (lcount) {
array = caml_alloc(lcount, 0); array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) { 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 } else
array = Atom(0); // empty list 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) { switch(arch) {
default: break;
case CS_ARCH_ARM: case CS_ARCH_ARM:
arch_info = caml_alloc(1, 0); arch_info = caml_alloc(1, 0);
op_info_val = caml_alloc(5, 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, 0, Val_int(insn[j-1].detail->arm.cc));
Store_field(op_info_val, 1, Val_bool(insn[j-1].arm.update_flags)); 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].arm.writeback)); 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].arm.op_count)); 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));
lcount = arm_list_count(insn[j - 1].arm.operands, ARR_SIZE(insn[j - 1].arm.operands));
if (lcount > 0) { if (lcount > 0) {
array = caml_alloc(lcount, 0); array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) { for (i = 0; i < lcount; i++) {
tmp2 = caml_alloc(2, 0); 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: case ARM_OP_REG:
tmp = caml_alloc(1, 1); 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; break;
case ARM_OP_CIMM: case ARM_OP_CIMM:
tmp = caml_alloc(1, 2); 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; break;
case ARM_OP_PIMM: case ARM_OP_PIMM:
tmp = caml_alloc(1, 3); 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; break;
case ARM_OP_IMM: case ARM_OP_IMM:
tmp = caml_alloc(1, 4); 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; break;
case ARM_OP_FP: case ARM_OP_FP:
tmp = caml_alloc(1, 5); 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; break;
case ARM_OP_MEM: case ARM_OP_MEM:
tmp = caml_alloc(1, 6); tmp = caml_alloc(1, 6);
tmp3 = caml_alloc(4, 0); tmp3 = caml_alloc(4, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].arm.operands[i].mem.base)); Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].arm.operands[i].mem.index)); Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm.operands[i].mem.index));
Store_field(tmp3, 2, Val_int(insn[j-1].arm.operands[i].mem.scale)); Store_field(tmp3, 2, Val_int(insn[j-1].detail->arm.operands[i].mem.scale));
Store_field(tmp3, 3, Val_int(insn[j-1].arm.operands[i].mem.disp)); Store_field(tmp3, 3, Val_int(insn[j-1].detail->arm.operands[i].mem.disp));
Store_field(tmp, 0, tmp3); Store_field(tmp, 0, tmp3);
break; break;
default: break; default: break;
} }
tmp3 = caml_alloc(2, 0); tmp3 = caml_alloc(2, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].arm.operands[i].shift.type)); Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm.operands[i].shift.type));
Store_field(tmp3, 1, Val_int(insn[j-1].arm.operands[i].shift.value)); Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm.operands[i].shift.value));
Store_field(tmp2, 0, tmp3); Store_field(tmp2, 0, tmp3);
Store_field(tmp2, 1, tmp); Store_field(tmp2, 1, tmp);
Store_field(array, i, tmp2); 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 // finally, insert this into arch_info
Store_field(arch_info, 0, op_info_val); Store_field(arch_info, 0, op_info_val);
Store_field(rec_insn, 8, arch_info); Store_field(rec_insn, 12, arch_info);
break; break;
case CS_ARCH_ARM64: case CS_ARCH_ARM64:
arch_info = caml_alloc(1, 1); arch_info = caml_alloc(1, 1);
op_info_val = caml_alloc(5, 0); 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, 0, Val_int(insn[j-1].detail->arm64.cc));
Store_field(op_info_val, 1, Val_bool(insn[j-1].arm64.update_flags)); 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].arm64.writeback)); 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].arm64.op_count)); 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) { if (lcount > 0) {
array = caml_alloc(lcount, 0); array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) { for (i = 0; i < lcount; i++) {
tmp2 = caml_alloc(3, 0); 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: case ARM64_OP_REG:
tmp = caml_alloc(1, 1); 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; break;
case ARM64_OP_CIMM: case ARM64_OP_CIMM:
tmp = caml_alloc(1, 2); 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; break;
case ARM64_OP_IMM: case ARM64_OP_IMM:
tmp = caml_alloc(1, 3); 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; break;
case ARM64_OP_FP: case ARM64_OP_FP:
tmp = caml_alloc(1, 4); 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; break;
case ARM64_OP_MEM: case ARM64_OP_MEM:
tmp = caml_alloc(1, 5); tmp = caml_alloc(1, 5);
tmp3 = caml_alloc(3, 0); tmp3 = caml_alloc(3, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].arm64.operands[i].mem.base)); Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm64.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].arm64.operands[i].mem.index)); Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm64.operands[i].mem.index));
Store_field(tmp3, 2, Val_int(insn[j-1].arm64.operands[i].mem.disp)); Store_field(tmp3, 2, Val_int(insn[j-1].detail->arm64.operands[i].mem.disp));
Store_field(tmp, 0, tmp3); Store_field(tmp, 0, tmp3);
break; break;
default: break; default: break;
} }
tmp3 = caml_alloc(2, 0); tmp3 = caml_alloc(2, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].arm64.operands[i].shift.type)); Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm64.operands[i].shift.type));
Store_field(tmp3, 1, Val_int(insn[j-1].arm64.operands[i].shift.value)); Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm64.operands[i].shift.value));
Store_field(tmp2, 0, tmp3); 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(tmp2, 2, tmp);
Store_field(array, i, tmp2); 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 // finally, insert this into arch_info
Store_field(arch_info, 0, op_info_val); Store_field(arch_info, 0, op_info_val);
Store_field(rec_insn, 8, arch_info); Store_field(rec_insn, 12, arch_info);
break; break;
case CS_ARCH_MIPS: case CS_ARCH_MIPS:
arch_info = caml_alloc(1, 2); arch_info = caml_alloc(1, 2);
op_info_val = caml_alloc(2, 0); 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) { if (lcount > 0) {
array = caml_alloc(lcount, 0); array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) { for (i = 0; i < lcount; i++) {
tmp2 = caml_alloc(1, 0); 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: case MIPS_OP_REG:
tmp = caml_alloc(1, 1); 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; break;
case MIPS_OP_IMM: case MIPS_OP_IMM:
tmp = caml_alloc(1, 2); 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; break;
case MIPS_OP_MEM: case MIPS_OP_MEM:
tmp = caml_alloc(1, 3); tmp = caml_alloc(1, 3);
tmp3 = caml_alloc(2, 0); tmp3 = caml_alloc(2, 0);
Store_field(tmp3, 0, Val_int(insn[j-1].mips.operands[i].mem.base)); Store_field(tmp3, 0, Val_int(insn[j-1].detail->mips.operands[i].mem.base));
Store_field(tmp3, 1, Val_int(insn[j-1].mips.operands[i].mem.disp)); Store_field(tmp3, 1, Val_int(insn[j-1].detail->mips.operands[i].mem.disp));
Store_field(tmp, 0, tmp3); Store_field(tmp, 0, tmp3);
break; break;
default: 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 // finally, insert this into arch_info
Store_field(arch_info, 0, op_info_val); Store_field(arch_info, 0, op_info_val);
Store_field(rec_insn, 8, arch_info); Store_field(rec_insn, 12, arch_info);
break; break;
case CS_ARCH_X86: case CS_ARCH_X86:
arch_info = caml_alloc(1, 3); arch_info = caml_alloc(1, 3);
op_info_val = caml_alloc(15, 0); op_info_val = caml_alloc(15, 0);
array = caml_alloc(ARR_SIZE(insn[0].x86.prefix), 0); // fill prefix
for (i = 0; i < ARR_SIZE(insn[0].x86.prefix); i++) { lcount = list_count(insn[j-1].detail->x86.prefix, ARR_SIZE(insn[j-1].detail->x86.prefix));
Store_field(array, i, Val_int(insn[j-1].x86.prefix[i])); 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, 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); // fill opcode
for (i = 0; i < ARR_SIZE(insn[0].x86.opcode); i++) { lcount = list_count(insn[j-1].detail->x86.opcode, ARR_SIZE(insn[j-1].detail->x86.opcode));
Store_field(array, i, Val_int(insn[j-1].x86.opcode[i])); 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, 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].detail->x86.op_count));
lcount = x86_list_count(insn[j - 1].detail->x86.operands, ARR_SIZE(insn[j - 1].detail->x86.operands));
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));
if (lcount > 0) { if (lcount > 0) {
array = caml_alloc(lcount, 0); array = caml_alloc(lcount, 0);
for (i = 0; i < lcount; i++) { 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: case X86_OP_REG:
tmp = caml_alloc(1, 1); 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; break;
case X86_OP_IMM: case X86_OP_IMM:
tmp = caml_alloc(1, 2); 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; break;
case X86_OP_FP: case X86_OP_FP:
tmp = caml_alloc(1, 3); 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; break;
case X86_OP_MEM: case X86_OP_MEM:
tmp = caml_alloc(1, 4); tmp = caml_alloc(1, 4);
tmp2 = caml_alloc(4, 0); tmp2 = caml_alloc(4, 0);
Store_field(tmp2, 0, Val_int(insn[j-1].x86.operands[i].mem.base)); Store_field(tmp2, 0, Val_int(insn[j-1].detail->x86.operands[i].mem.base));
Store_field(tmp2, 1, Val_int(insn[j-1].x86.operands[i].mem.index)); Store_field(tmp2, 1, Val_int(insn[j-1].detail->x86.operands[i].mem.index));
Store_field(tmp2, 2, Val_int(insn[j-1].x86.operands[i].mem.scale)); Store_field(tmp2, 2, Val_int(insn[j-1].detail->x86.operands[i].mem.scale));
Store_field(tmp2, 3, Val_int(insn[j-1].x86.operands[i].mem.disp)); Store_field(tmp2, 3, Val_int(insn[j-1].detail->x86.operands[i].mem.disp));
Store_field(tmp, 0, tmp2); Store_field(tmp, 0, tmp2);
break; break;
default: 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 // finally, insert this into arch_info
Store_field(arch_info, 0, op_info_val); Store_field(arch_info, 0, op_info_val);
Store_field(rec_insn, 8, arch_info); Store_field(rec_insn, 12, arch_info);
break; break;
default: break;
} }
Store_field(cons, 0, rec_insn); // head Store_field(cons, 0, rec_insn); // head
Store_field(cons, 1, list); // tail Store_field(cons, 1, list); // tail
list = cons; list = cons;
} }
cs_free(insn, count);
cs_free(insn);
} }
// do not free the handle here
cs_close(handle); //cs_close(&handle);
CAMLreturn(list); CAMLreturn(list);
} }
@ -369,8 +398,9 @@ CAMLprim value ocaml_cs_disasm_quick(value _arch, value _mode, value _code, valu
csh handle; csh handle;
cs_arch arch; cs_arch arch;
cs_mode mode = 0; cs_mode mode = 0;
char *code; const uint8_t *code;
uint64_t addr, count, code_len; uint64_t addr;
size_t count, code_len;
switch (Int_val(_arch)) { switch (Int_val(_arch)) {
case 0: case 0:
@ -397,7 +427,7 @@ CAMLprim value ocaml_cs_disasm_quick(value _arch, value _mode, value _code, valu
mode |= CS_MODE_LITTLE_ENDIAN; mode |= CS_MODE_LITTLE_ENDIAN;
break; break;
case 1: case 1:
mode |= CS_MODE_SYNTAX_INTEL; mode |= CS_OPT_SYNTAX_INTEL;
break; break;
case 2: case 2:
mode |= CS_MODE_ARM; 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; mode |= CS_MODE_N64;
break; break;
case 9: case 9:
mode |= CS_MODE_SYNTAX_ATT; mode |= CS_OPT_SYNTAX_ATT;
break; break;
case 10: case 10:
mode |= CS_MODE_BIG_ENDIAN; 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 */ _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; 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); code_len = caml_string_length(_code);
addr = Int64_val(_addr); addr = Int64_val(_addr);
count = Int64_val(_count); 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); CAMLparam5(_arch, _handle, _code, _addr, _count);
csh handle; csh handle;
cs_arch arch; cs_arch arch;
char *code; const uint8_t *code;
uint64_t addr, count, code_len; uint64_t addr, count, code_len;
handle = Int64_val(_handle); handle = Int64_val(_handle);
arch = Int_val(_arch); arch = Int_val(_arch);
code = String_val(_code); code = (uint8_t *)String_val(_code);
code_len = caml_string_length(_code); code_len = caml_string_length(_code);
addr = Int64_val(_addr); addr = Int64_val(_addr);
count = Int64_val(_count); count = Int64_val(_count);
@ -491,6 +525,7 @@ CAMLprim value ocaml_cs_open(value _arch, value _mode)
return Val_emptylist; return Val_emptylist;
} }
while (_mode != Val_emptylist) { while (_mode != Val_emptylist) {
head = Field(_mode, 0); /* accessing the head */ head = Field(_mode, 0); /* accessing the head */
switch (Int_val(head)) { switch (Int_val(head)) {
@ -498,7 +533,7 @@ CAMLprim value ocaml_cs_open(value _arch, value _mode)
mode |= CS_MODE_LITTLE_ENDIAN; mode |= CS_MODE_LITTLE_ENDIAN;
break; break;
case 1: case 1:
mode |= CS_MODE_SYNTAX_INTEL; mode |= CS_OPT_SYNTAX_INTEL;
break; break;
case 2: case 2:
mode |= CS_MODE_ARM; mode |= CS_MODE_ARM;
@ -522,7 +557,7 @@ CAMLprim value ocaml_cs_open(value _arch, value _mode)
mode |= CS_MODE_N64; mode |= CS_MODE_N64;
break; break;
case 9: case 9:
mode |= CS_MODE_SYNTAX_ATT; mode |= CS_OPT_SYNTAX_ATT;
break; break;
case 10: case 10:
mode |= CS_MODE_BIG_ENDIAN; 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 */ _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)); CAMLreturn(Val_int(0));
else {
CAMLlocal1(result); if (cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON) != 0)
result = caml_alloc(1, 0); CAMLreturn(Val_int(0));
Store_field(result, 0, caml_copy_int64(handle));
CAMLreturn(result); 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; const char *name = cs_reg_name(Int64_val(_handle), Int_val(_reg));
if(!name) {
switch (Int_val(_arch)) { caml_invalid_argument("invalid reg_id");
case 0: name = "invalid";
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;
} }
char *name = cs_reg_name(arch, Int_val(_reg));
return caml_copy_string(name); return caml_copy_string(name);
} }
CAMLprim value cs_instruction_name(value _handle, value _insn) 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); return caml_copy_string(name);
} }

View File

@ -41,9 +41,9 @@ let print_arch x =
printf "Platform: %s\n" comment; printf "Platform: %s\n" comment;
List.iter print_insn insns;; List.iter print_insn insns;;
(*
List.iter print_arch all_tests;; List.iter print_arch all_tests;;
*)
let print_insn_cls insn = let print_insn_cls insn =
printf "0x%x\t%s\t%s\n" insn#address insn#mnemonic insn#op_str;; 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;; 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 ( match op.value with
| ARM_OP_INVALID _ -> (); (* this would never happens *) | 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_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_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_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_FP fp -> printf "\t\top[%d]: FP = %f\n" i fp;
| ARM_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i; | ARM_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i;
if mem.base != 0 then 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 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 if mem.scale != 1 then
printf "\t\t\toperands[%u].mem.scale: %d\n" i mem.scale; printf "\t\t\toperands[%u].mem.scale: %d\n" i mem.scale;
if mem.displ != 0 then 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 match arch with
| CS_INFO_ARM64 _ -> (); | CS_INFO_ARM64 _ -> ();
| CS_INFO_X86 _ -> (); | CS_INFO_X86 _ -> ();
@ -72,14 +72,17 @@ let print_detail arch =
(* print all operands info (type & value) *) (* print all operands info (type & value) *)
if (Array.length arm.operands) > 0 then ( if (Array.length arm.operands) > 0 then (
printf "\top_count: %d\n" (Array.length arm.operands); printf "\top_count: %d\n" (Array.length arm.operands);
Array.iteri print_op arm.operands; Array.iteri (print_op csh) arm.operands;
); );
printf "\n";; 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; 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 = let print_arch x =
@ -87,18 +90,18 @@ let print_arch x =
let insns = cs_disasm_quick arch mode code 0x1000L 0L in let insns = cs_disasm_quick arch mode code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; printf "Platform: %s\n" comment;
List.iter print_insn insns;; List.iter (print_insn mode) insns;;
(*
List.iter print_arch all_tests;; List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *) (* 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; 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 = let print_arch_cls x =
@ -107,7 +110,7 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in let insns = d#disasm code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; 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"); (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 ( match op.value with
| ARM64_OP_INVALID _ -> (); (* this would never happens *) | 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_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_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_FP fp -> printf "\t\top[%d]: FP = %f\n" i fp;
| ARM64_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i; | ARM64_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i;
if mem.base != 0 then 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 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 if mem.displ != 0 then
printf "\t\t\toperands[%u].mem.disp: 0x%x\n" i mem.displ; 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 match arch with
| CS_INFO_ARM _ -> (); | CS_INFO_ARM _ -> ();
| CS_INFO_MIPS _ -> (); | CS_INFO_MIPS _ -> ();
@ -64,14 +64,17 @@ let print_detail arch =
(* print all operands info (type & value) *) (* print all operands info (type & value) *)
if (Array.length arm64.operands) > 0 then ( if (Array.length arm64.operands) > 0 then (
printf "\top_count: %d\n" (Array.length arm64.operands); printf "\top_count: %d\n" (Array.length arm64.operands);
Array.iteri print_op arm64.operands; Array.iteri (print_op csh) arm64.operands;
); );
printf "\n";; 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; 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 = let print_arch x =
@ -79,18 +82,18 @@ let print_arch x =
let insns = cs_disasm_quick arch mode code 0x1000L 0L in let insns = cs_disasm_quick arch mode code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; printf "Platform: %s\n" comment;
List.iter print_insn insns;; List.iter (print_insn mode) insns;;
(*
List.iter print_arch all_tests;; List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *) (* 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; 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 = let print_arch_cls x =
@ -99,7 +102,7 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in let insns = d#disasm code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; 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;; 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 *) (* print immediate operands *)
if (Array.length insn.regs_read) > 0 then begin if (Array.length insn.regs_read) > 0 then begin
printf "\tImplicit registers read: "; 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"; printf "\n";
end; end;
if (Array.length insn.regs_write) > 0 then begin if (Array.length insn.regs_write) > 0 then begin
printf "\tImplicit registers written: "; 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"; printf "\n";
end; end;
@ -53,9 +53,12 @@ let print_detail arch insn =
printf "\n";; 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; 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 = let print_arch x =
@ -63,24 +66,24 @@ let print_arch x =
let insns = cs_disasm_quick arch mode code 0x1000L 0L in let insns = cs_disasm_quick arch mode code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; printf "Platform: %s\n" comment;
List.iter (print_insn arch) insns;; List.iter (print_insn mode arch) insns;;
(*
List.iter print_arch all_tests;; List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *) (* all below code use OO class of Capstone *)
let print_detail_cls arch insn = let print_detail_cls arch csh insn =
(* print immediate operands *) (* print immediate operands *)
if (Array.length insn#regs_read) > 0 then begin if (Array.length insn#regs_read) > 0 then begin
printf "\tImplicit registers read: "; 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"; printf "\n";
end; end;
if (Array.length insn#regs_write) > 0 then begin if (Array.length insn#regs_write) > 0 then begin
printf "\tImplicit registers written: "; 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"; printf "\n";
end; end;
@ -92,9 +95,9 @@ let print_detail_cls arch insn =
printf "\n";; 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; 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 = let print_arch_cls x =
@ -103,7 +106,8 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in let insns = d#disasm code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; 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;; 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)"); (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 ( match op.value with
| MIPS_OP_INVALID _ -> (); (* this would never happens *) | 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_IMM imm -> printf "\t\top[%d]: IMM = 0x%x\n" i imm;
| MIPS_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i; | MIPS_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i;
if mem.base != 0 then 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 if mem.displ != 0 then
printf "\t\t\toperands[%u].mem.disp: 0x%x\n" i mem.displ; 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 match arch with
| CS_INFO_ARM _ -> (); | CS_INFO_ARM _ -> ();
| CS_INFO_ARM64 _ -> (); | CS_INFO_ARM64 _ -> ();
@ -48,14 +48,17 @@ let print_detail arch =
(* print all operands info (type & value) *) (* print all operands info (type & value) *)
if (Array.length mips.operands) > 0 then ( if (Array.length mips.operands) > 0 then (
printf "\top_count: %d\n" (Array.length mips.operands); printf "\top_count: %d\n" (Array.length mips.operands);
Array.iteri print_op mips.operands; Array.iteri (print_op csh) mips.operands;
); );
printf "\n";; 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; 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 = let print_arch x =
@ -63,18 +66,18 @@ let print_arch x =
let insns = cs_disasm_quick arch mode code 0x1000L 0L in let insns = cs_disasm_quick arch mode code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; printf "Platform: %s\n" comment;
List.iter print_insn insns;; List.iter (print_insn mode) insns;;
(*
List.iter print_arch all_tests;; List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *) (* 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; 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 = let print_arch_cls x =
@ -83,7 +86,7 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in let insns = d#disasm code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; 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;; 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)"); (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 ( match op with
| X86_OP_INVALID _ -> (); (* this would never happens *) | 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_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_FP fp -> printf "\t\top[%d]: FP = %f\n" i fp;
| X86_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i; | X86_OP_MEM mem -> ( printf "\t\top[%d]: MEM\n" i;
if mem.base != 0 then 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 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 if mem.scale != 1 then
printf "\t\t\toperands[%u].mem.scale: %d\n" i mem.scale; printf "\t\t\toperands[%u].mem.scale: %d\n" i mem.scale;
if mem.displ != 0 then 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 match arch with
| CS_INFO_ARM64 _ -> (); | CS_INFO_ARM64 _ -> ();
| CS_INFO_ARM _ -> (); | CS_INFO_ARM _ -> ();
@ -56,7 +56,8 @@ let print_detail mode arch =
(* print segment override (if applicable) *) (* print segment override (if applicable) *)
if x86.segment != _X86_REG_INVALID then 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 instruction's opcode *)
print_string_hex "\tOpcode: " x86.opcode; print_string_hex "\tOpcode: " x86.opcode;
@ -81,22 +82,25 @@ let print_detail mode arch =
(* print sib index/scale/base (if applicable) *) (* print sib index/scale/base (if applicable) *)
if x86.sib_index != _X86_REG_INVALID then if x86.sib_index != _X86_REG_INVALID then
printf "\tsib_index: %s, sib_scale: %u, sib_base: %s\n" 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 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) *) (* print all operands info (type & value) *)
if (Array.length x86.operands) > 0 then ( if (Array.length x86.operands) > 0 then (
printf "\top_count: %d\n" (Array.length x86.operands); printf "\top_count: %d\n" (Array.length x86.operands);
Array.iteri print_op x86.operands; Array.iteri (print_op csh) x86.operands;
); );
printf "\n";; printf "\n";;
let print_insn mode insn = let print_insn mode insn =
printf "0x%x\t%s\t%s\n" insn.address insn.mnemonic insn.op_str; 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 = let print_arch x =
@ -107,14 +111,15 @@ let print_arch x =
List.iter (print_insn mode) insns;; List.iter (print_insn mode) insns;;
(*
List.iter print_arch all_tests;; List.iter print_arch all_tests;;
*)
(* all below code use OO class of Capstone *) (* 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; 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 = let print_arch_cls x =
@ -123,8 +128,9 @@ let print_arch_cls x =
let insns = d#disasm code 0x1000L 0L in let insns = d#disasm code 0x1000L 0L in
printf "*************\n"; printf "*************\n";
printf "Platform: %s\n" comment; 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;; List.iter print_arch_cls all_tests;;