diff --git a/cstool/cstool.c b/cstool/cstool.c index 910e3ffa..f2f5e70b 100644 --- a/cstool/cstool.c +++ b/cstool/cstool.c @@ -10,6 +10,13 @@ #define VERSION "1.0" void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins); +void print_insn_detail_arm(csh handle, cs_insn *ins); +void print_insn_detail_arm64(csh handle, cs_insn *ins); +void print_insn_detail_mips(csh handle, cs_insn *ins); +void print_insn_detail_ppc(csh handle, cs_insn *ins); +void print_insn_detail_sparc(csh handle, cs_insn *ins); +void print_insn_detail_sysz(csh handle, cs_insn *ins); +void print_insn_detail_xcore(csh handle, cs_insn *ins); // convert hexchar to hexnum static uint8_t char_to_hexnum(char c) @@ -117,8 +124,8 @@ int main(int argc, char **argv) cs_insn *insn; cs_err err; cs_mode md; - char *platform; - bool x86_arch = false, debug_flag = false; + char *arch; + bool debug_flag = false; if (argc != 3 && argc != 4 && argc != 5) { usage(argv[0]); @@ -166,68 +173,80 @@ int main(int argc, char **argv) } if (!strcmp(mode, "arm")) { + arch = "arm"; err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &handle); } if (!strcmp(mode, "armb")) { + arch = "arm"; err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_BIG_ENDIAN, &handle); } if (!strcmp(mode, "arml")) { + arch = "arm"; err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle); } if (!strcmp(mode, "thumb")) { - err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN, &handle); + arch = "arm"; + err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN, &handle); } if (!strcmp(mode, "thumbbe")) { + arch = "arm"; err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_BIG_ENDIAN, &handle); } if (!strcmp(mode, "thumble")) { + arch = "arm"; err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle); } if (!strcmp(mode, "arm64")) { + arch = "arm64"; err = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle); } if (!strcmp(mode, "mips")) { + arch = "mips"; err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN, &handle); } if (!strcmp(mode, "mipsbe")) { + arch = "mips"; err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, &handle); } if (!strcmp(mode, "mips64")) { + arch = "mips"; err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle); } if (!strcmp(mode, "mips64be")) { + arch = "mips"; err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle); } if (!strcmp(mode, "x16")) { - x86_arch = true; + arch = "x86"; err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle); } if (!strcmp(mode, "x32")) { md = CS_MODE_32; - platform = "x32"; - x86_arch = true; + arch = "x86"; err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle); } if (!strcmp(mode, "x64")) { - x86_arch = true; + md = CS_MODE_64; + arch = "x86"; err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle); } if (!strcmp(mode, "x16att")) { - x86_arch = true; + md = CS_MODE_16; + arch = "x86"; err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle); if (!err) { cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); @@ -235,7 +254,8 @@ int main(int argc, char **argv) } if (!strcmp(mode,"x32att")) { - x86_arch = true; + md = CS_MODE_32; + arch = "x86"; err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle); if (!err) { cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); @@ -243,7 +263,8 @@ int main(int argc, char **argv) } if (!strcmp(mode,"x64att")) { - x86_arch = true; + md = CS_MODE_64; + arch = "x86"; err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle); if (!err) { cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); @@ -251,22 +272,27 @@ int main(int argc, char **argv) } if (!strcmp(mode,"ppc64")) { + arch = "ppc"; err = cs_open(CS_ARCH_PPC, CS_MODE_64+CS_MODE_LITTLE_ENDIAN, &handle); } if (!strcmp(mode,"ppc64be")) { + arch = "ppc"; err = cs_open(CS_ARCH_PPC,CS_MODE_64+CS_MODE_BIG_ENDIAN, &handle); } if (!strcmp(mode,"sparc")) { + arch = "sparc"; err = cs_open(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, &handle); } if (!strcmp(mode, "systemz") || !strcmp(mode, "sysz") || !strcmp(mode, "s390x")) { + arch = "sysz"; err = cs_open(CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN, &handle); } if (!strcmp(mode,"xcore")) { + arch = "xcore"; err = cs_open(CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN, &handle); } @@ -292,16 +318,44 @@ int main(int argc, char **argv) } // X86 instruction size is variable. // align assembly instruction after the opcode - if (x86_arch) { + if (!strcmp(arch, "x86")) { for (; j < 16; j++) { printf(" "); } } printf(" %s\t%s\n", insn[i].mnemonic, insn[i].op_str); - if (debug_flag) { - if (x86_arch) { + if (debug_flag) {//different mode should call different print functions + if (!strcmp(arch, "x86")) { print_insn_detail_x86(handle, md, &insn[i]); } + + if (!strcmp(arch, "arm")) { + print_insn_detail_arm(handle, &insn[i]); + } + + if (!strcmp(arch,"arm64")) { + print_insn_detail_arm64(handle,&insn[i]); + } + + if (!strcmp(arch, "mips")) { + print_insn_detail_mips(handle, &insn[i]); + } + + if (!strcmp(arch, "ppc")) { + print_insn_detail_ppc(handle, &insn[i]); + } + + if (!strcmp(arch, "sparc")) { + print_insn_detail_sparc(handle, &insn[i]); + } + + if (!strcmp(arch, "sysz")) { + print_insn_detail_sysz(handle, &insn[i]); + } + + if (!strcmp(arch, "xcore")) { + print_insn_detail_xcore(handle, &insn[i]); + } } } cs_free(insn, count); diff --git a/cstool/cstool_arm.c b/cstool/cstool_arm.c new file mode 100644 index 00000000..7f4f8147 --- /dev/null +++ b/cstool/cstool_arm.c @@ -0,0 +1,127 @@ +#include +#include + +#include +#include + + +static void print_string_hex(char *comment, unsigned char *str, size_t len) +{ + unsigned char *c; + + printf("%s", comment); + for (c = str; c < str + len; c++) { + printf("0x%02x ", *c & 0xff); + } + + printf("\n"); +} + +void print_insn_detail_arm(csh handle, cs_insn *ins) +{ + cs_arm *arm; + int i; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + arm = &(ins->detail->arm); + + if (arm->op_count) + printf("\top_count: %u\n", arm->op_count); + + for (i = 0; i < arm->op_count; i++) { + cs_arm_op *op = &(arm->operands[i]); + switch((int)op->type) { + default: + break; + case ARM_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case ARM_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); + break; + case ARM_OP_FP: +#if defined(_KERNEL_MODE) + // Issue #681: Windows kernel does not support formatting float point + printf("\t\toperands[%u].type: FP = \n", i); +#else + printf("\t\toperands[%u].type: FP = %f\n", i, op->fp); +#endif + break; + case ARM_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != X86_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base)); + if (op->mem.index != X86_REG_INVALID) + printf("\t\t\toperands[%u].mem.index: REG = %s\n", + i, cs_reg_name(handle, op->mem.index)); + if (op->mem.scale != 1) + printf("\t\t\toperands[%u].mem.scale: %u\n", i, op->mem.scale); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); + + break; + case ARM_OP_PIMM: + printf("\t\toperands[%u].type: P-IMM = %u\n", i, op->imm); + break; + case ARM_OP_CIMM: + printf("\t\toperands[%u].type: C-IMM = %u\n", i, op->imm); + break; + case ARM_OP_SETEND: + printf("\t\toperands[%u].type: SETEND = %s\n", i, op->setend == ARM_SETEND_BE? "be" : "le"); + break; + case ARM_OP_SYSREG: + printf("\t\toperands[%u].type: SYSREG = %u\n", i, op->reg); + break; + } + + if (op->shift.type != ARM_SFT_INVALID && op->shift.value) { + if (op->shift.type < ARM_SFT_ASR_REG) + // shift with constant value + printf("\t\t\tShift: %u = %u\n", op->shift.type, op->shift.value); + else + // shift with register + printf("\t\t\tShift: %u = %s\n", op->shift.type, + cs_reg_name(handle, op->shift.value)); + } + + if (op->vector_index != -1) { + printf("\t\toperands[%u].vector_index = %u\n", i, op->vector_index); + } + + if (op->subtracted) + printf("\t\tSubtracted: True\n"); + } + + if (arm->cc != ARM_CC_AL && arm->cc != ARM_CC_INVALID) + printf("\tCode condition: %u\n", arm->cc); + + if (arm->update_flags) + printf("\tUpdate-flags: True\n"); + + if (arm->writeback) + printf("\tWrite-back: True\n"); + + if (arm->cps_mode) + printf("\tCPSI-mode: %u\n", arm->cps_mode); + + if (arm->cps_flag) + printf("\tCPSI-flag: %u\n", arm->cps_flag); + + if (arm->vector_data) + printf("\tVector-data: %u\n", arm->vector_data); + + if (arm->vector_size) + printf("\tVector-size: %u\n", arm->vector_size); + + if (arm->usermode) + printf("\tUser-mode: True\n"); + + if (arm->mem_barrier) + printf("\tMemory-barrier: %u\n", arm->mem_barrier); + + printf("\n"); +} diff --git a/cstool/cstool_arm64.c b/cstool/cstool_arm64.c new file mode 100644 index 00000000..138e7bb6 --- /dev/null +++ b/cstool/cstool_arm64.c @@ -0,0 +1,116 @@ +/* Capstone Disassembler Engine */ +/* By Nguyen Anh Quynh , 2013> */ + +#include +#include + +#include +#include + + +static void print_string_hex(char *comment, unsigned char *str, size_t len) +{ + unsigned char *c; + + printf("%s", comment); + for (c = str; c < str + len; c++) { + printf("0x%02x ", *c & 0xff); + } + + printf("\n"); +} + +void print_insn_detail_arm64(csh handle, cs_insn *ins) +{ + cs_arm64 *arm64; + int i; + + // detail can be NULL if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + arm64 = &(ins->detail->arm64); + if (arm64->op_count) + printf("\top_count: %u\n", arm64->op_count); + + for (i = 0; i < arm64->op_count; i++) { + cs_arm64_op *op = &(arm64->operands[i]); + switch(op->type) { + default: + break; + case ARM64_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case ARM64_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm); + break; + case ARM64_OP_FP: +#if defined(_KERNEL_MODE) + // Issue #681: Windows kernel does not support formatting float point + printf("\t\toperands[%u].type: FP = \n", i); +#else + printf("\t\toperands[%u].type: FP = %f\n", i, op->fp); +#endif + break; + case ARM64_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != ARM64_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(handle, op->mem.base)); + if (op->mem.index != ARM64_REG_INVALID) + printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(handle, op->mem.index)); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); + + break; + case ARM64_OP_CIMM: + printf("\t\toperands[%u].type: C-IMM = %u\n", i, (int)op->imm); + break; + case ARM64_OP_REG_MRS: + printf("\t\toperands[%u].type: REG_MRS = 0x%x\n", i, op->reg); + break; + case ARM64_OP_REG_MSR: + printf("\t\toperands[%u].type: REG_MSR = 0x%x\n", i, op->reg); + break; + case ARM64_OP_PSTATE: + printf("\t\toperands[%u].type: PSTATE = 0x%x\n", i, op->pstate); + break; + case ARM64_OP_SYS: + printf("\t\toperands[%u].type: SYS = 0x%x\n", i, op->sys); + break; + case ARM64_OP_PREFETCH: + printf("\t\toperands[%u].type: PREFETCH = 0x%x\n", i, op->prefetch); + break; + case ARM64_OP_BARRIER: + printf("\t\toperands[%u].type: BARRIER = 0x%x\n", i, op->barrier); + break; + } + + if (op->shift.type != ARM64_SFT_INVALID && + op->shift.value) + printf("\t\t\tShift: type = %u, value = %u\n", + op->shift.type, op->shift.value); + + if (op->ext != ARM64_EXT_INVALID) + printf("\t\t\tExt: %u\n", op->ext); + + if (op->vas != ARM64_VAS_INVALID) + printf("\t\t\tVector Arrangement Specifier: 0x%x\n", op->vas); + + if (op->vess != ARM64_VESS_INVALID) + printf("\t\t\tVector Element Size Specifier: %u\n", op->vess); + + if (op->vector_index != -1) + printf("\t\t\tVector Index: %u\n", op->vector_index); + } + + if (arm64->update_flags) + printf("\tUpdate-flags: True\n"); + + if (arm64->writeback) + printf("\tWrite-back: True\n"); + + if (arm64->cc) + printf("\tCode-condition: %u\n", arm64->cc); + + printf("\n"); +} diff --git a/cstool/cstool_mips.c b/cstool/cstool_mips.c new file mode 100644 index 00000000..07a362f6 --- /dev/null +++ b/cstool/cstool_mips.c @@ -0,0 +1,61 @@ +/* Capstone Disassembler Engine */ +/* By Nguyen Anh Quynh , 2013> */ + +#include +#include + +#include +#include + + +static void print_string_hex(char *comment, unsigned char *str, size_t len) +{ + unsigned char *c; + + printf("%s", comment); + for (c = str; c < str + len; c++) { + printf("0x%02x ", *c & 0xff); + } + + printf("\n"); +} + +void print_insn_detail_mips(csh handle, cs_insn *ins) +{ + int i; + cs_mips *mips; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + mips = &(ins->detail->mips); + if (mips->op_count) + printf("\top_count: %u\n", mips->op_count); + + for (i = 0; i < mips->op_count; i++) { + cs_mips_op *op = &(mips->operands[i]); + switch((int)op->type) { + default: + break; + case MIPS_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case MIPS_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm); + break; + case MIPS_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != X86_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base)); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp); + + break; + } + + } + + printf("\n"); +} diff --git a/cstool/cstool_ppc.c b/cstool/cstool_ppc.c new file mode 100644 index 00000000..3f639f18 --- /dev/null +++ b/cstool/cstool_ppc.c @@ -0,0 +1,104 @@ +/* Capstone Disassembler Engine */ +/* By Nguyen Anh Quynh , 2013> */ + +#include + +#include +#include + +static csh handle; + +static void print_string_hex(char *comment, unsigned char *str, size_t len) +{ + unsigned char *c; + + printf("%s", comment); + for (c = str; c < str + len; c++) { + printf("0x%02x ", *c & 0xff); + } + + printf("\n"); +} + +static const char* get_bc_name(int bc) +{ + switch(bc) { + default: + case PPC_BC_INVALID: + return ("invalid"); + case PPC_BC_LT: + return ("lt"); + case PPC_BC_LE: + return ("le"); + case PPC_BC_EQ: + return ("eq"); + case PPC_BC_GE: + return ("ge"); + case PPC_BC_GT: + return ("gt"); + case PPC_BC_NE: + return ("ne"); + case PPC_BC_UN: + return ("un"); + case PPC_BC_NU: + return ("nu"); + case PPC_BC_SO: + return ("so"); + case PPC_BC_NS: + return ("ns"); + } +} + +void print_insn_detail_ppc(csh handle, cs_insn *ins) +{ + cs_ppc *ppc; + int i; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + ppc = &(ins->detail->ppc); + if (ppc->op_count) + printf("\top_count: %u\n", ppc->op_count); + + for (i = 0; i < ppc->op_count; i++) { + cs_ppc_op *op = &(ppc->operands[i]); + switch((int)op->type) { + default: + break; + case PPC_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case PPC_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); + break; + case PPC_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != PPC_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base)); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); + + break; + case PPC_OP_CRX: + printf("\t\toperands[%u].type: CRX\n", i); + printf("\t\t\toperands[%u].crx.scale: %d\n", i, op->crx.scale); + printf("\t\t\toperands[%u].crx.reg: %s\n", i, cs_reg_name(handle, op->crx.reg)); + printf("\t\t\toperands[%u].crx.cond: %s\n", i, get_bc_name(op->crx.cond)); + break; + } + } + + if (ppc->bc != 0) + printf("\tBranch code: %u\n", ppc->bc); + + if (ppc->bh != 0) + printf("\tBranch hint: %u\n", ppc->bh); + + if (ppc->update_cr0) + printf("\tUpdate-CR0: True\n"); + + printf("\n"); +} diff --git a/cstool/cstool_sparc.c b/cstool/cstool_sparc.c new file mode 100644 index 00000000..9ee37ce2 --- /dev/null +++ b/cstool/cstool_sparc.c @@ -0,0 +1,68 @@ +/* Capstone Disassembler Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#include + +#include +#include + + +static void print_string_hex(char *comment, unsigned char *str, size_t len) +{ + unsigned char *c; + + printf("%s", comment); + for (c = str; c < str + len; c++) { + printf("0x%02x ", *c & 0xff); + } + + printf("\n"); +} + +void print_insn_detail_sparc(csh handle, cs_insn *ins) +{ + cs_sparc *sparc; + int i; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + sparc = &(ins->detail->sparc); + if (sparc->op_count) + printf("\top_count: %u\n", sparc->op_count); + + for (i = 0; i < sparc->op_count; i++) { + cs_sparc_op *op = &(sparc->operands[i]); + switch((int)op->type) { + default: + break; + case SPARC_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case SPARC_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); + break; + case SPARC_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != X86_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base)); + if (op->mem.index != X86_REG_INVALID) + printf("\t\t\toperands[%u].mem.index: REG = %s\n", + i, cs_reg_name(handle, op->mem.index)); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); + + break; + } + } + + if (sparc->cc != 0) + printf("\tCode condition: %u\n", sparc->cc); + + if (sparc->hint != 0) + printf("\tHint code: %u\n", sparc->hint); + + printf("\n"); +} diff --git a/cstool/cstool_systemz.c b/cstool/cstool_systemz.c new file mode 100644 index 00000000..c5c5f562 --- /dev/null +++ b/cstool/cstool_systemz.c @@ -0,0 +1,70 @@ +/* Capstone Disassembler Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#include + +#include +#include + + +static void print_string_hex(char *comment, unsigned char *str, size_t len) +{ + unsigned char *c; + + printf("%s", comment); + for (c = str; c < str + len; c++) { + printf("0x%02x ", *c & 0xff); + } + + printf("\n"); +} + +void print_insn_detail_sysz(csh handle, cs_insn *ins) +{ + cs_sysz *sysz; + int i; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + sysz = &(ins->detail->sysz); + if (sysz->op_count) + printf("\top_count: %u\n", sysz->op_count); + + for (i = 0; i < sysz->op_count; i++) { + cs_sysz_op *op = &(sysz->operands[i]); + switch((int)op->type) { + default: + break; + case SYSZ_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case SYSZ_OP_ACREG: + printf("\t\toperands[%u].type: ACREG = %u\n", i, op->reg); + break; + case SYSZ_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm); + break; + case SYSZ_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != SYSZ_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base)); + if (op->mem.index != SYSZ_REG_INVALID) + printf("\t\t\toperands[%u].mem.index: REG = %s\n", + i, cs_reg_name(handle, op->mem.index)); + if (op->mem.length != 0) + printf("\t\t\toperands[%u].mem.length: 0x%" PRIx64 "\n", i, op->mem.length); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp); + + break; + } + } + + if (sysz->cc != 0) + printf("\tCode condition: %u\n", sysz->cc); + + printf("\n"); +} diff --git a/cstool/cstool_xcore.c b/cstool/cstool_xcore.c new file mode 100644 index 00000000..80621379 --- /dev/null +++ b/cstool/cstool_xcore.c @@ -0,0 +1,65 @@ +/* Capstone Disassembler Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#include + +#include +#include + + +static void print_string_hex(char *comment, unsigned char *str, size_t len) +{ + unsigned char *c; + + printf("%s", comment); + for (c = str; c < str + len; c++) { + printf("0x%02x ", *c & 0xff); + } + + printf("\n"); +} + +void print_insn_detail_xcore(csh handle, cs_insn *ins) +{ + cs_xcore *xcore; + int i; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + xcore = &(ins->detail->xcore); + if (xcore->op_count) + printf("\top_count: %u\n", xcore->op_count); + + for (i = 0; i < xcore->op_count; i++) { + cs_xcore_op *op = &(xcore->operands[i]); + switch((int)op->type) { + default: + break; + case XCORE_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case XCORE_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); + break; + case XCORE_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != XCORE_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base)); + if (op->mem.index != XCORE_REG_INVALID) + printf("\t\t\toperands[%u].mem.index: REG = %s\n", + i, cs_reg_name(handle, op->mem.index)); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); + if (op->mem.direct != 1) + printf("\t\t\toperands[%u].mem.direct: -1\n", i); + + + break; + } + } + + printf("\n"); +}