mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-23 13:39:46 +00:00
working OCaml bindings
This commit is contained in:
parent
5a7f409dec
commit
cece24e426
@ -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;;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;;
|
||||
|
||||
|
@ -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;
|
||||
);;
|
||||
|
||||
|
||||
|
@ -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;;
|
||||
|
@ -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;;
|
||||
|
||||
|
@ -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;;
|
||||
|
@ -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;;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user