From 68a39e344f2002e115f14f3d62a8a8ba1e1d9159 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 Nov 2013 17:40:07 +0800 Subject: [PATCH 01/10] change cs_disasm() and cs_disasm_dyn() to be portable API. fix related code using these API --- arch/AArch64/AArch64Disassembler.c | 8 ++--- arch/AArch64/AArch64Disassembler.h | 4 +-- arch/ARM/ARMDisassembler.c | 16 +++++----- arch/ARM/ARMDisassembler.h | 4 +-- arch/ARM/ARMGenDisassemblerTables.inc | 2 +- arch/ARM/ARMInstPrinter.c | 6 ++-- arch/Mips/MipsDisassembler.c | 16 +++++----- arch/Mips/MipsDisassembler.h | 8 ++--- arch/X86/X86Disassembler.c | 4 +-- arch/X86/X86Disassembler.h | 4 +-- cs.c | 10 +++---- cs_priv.h | 2 +- include/arm.h | 4 +-- include/capstone.h | 20 ++++++------- tests/test.c | 42 +++++++++++++-------------- tests/test_arm.c | 34 +++++++++++----------- tests/test_arm64.c | 22 +++++++------- tests/test_detail.c | 42 +++++++++++++-------------- tests/test_mips.c | 22 +++++++------- tests/test_x86.c | 32 ++++++++++---------- 20 files changed, 151 insertions(+), 151 deletions(-) diff --git a/arch/AArch64/AArch64Disassembler.c b/arch/AArch64/AArch64Disassembler.c index 97a247948d..e9e883db27 100644 --- a/arch/AArch64/AArch64Disassembler.c +++ b/arch/AArch64/AArch64Disassembler.c @@ -226,9 +226,9 @@ void AArch64_init(MCRegisterInfo *MRI) static DecodeStatus _getInstruction(MCInst *MI, - unsigned char *code, uint64_t code_len, + unsigned char *code, size_t code_len, uint16_t *Size, - uint64_t Address, MCRegisterInfo *MRI) + size_t Address, MCRegisterInfo *MRI) { if (code_len < 4) { // not enough data @@ -254,10 +254,10 @@ static DecodeStatus _getInstruction(MCInst *MI, return MCDisassembler_Fail; } -bool AArch64_getInstruction(csh ud, char *code, uint64_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info) +bool AArch64_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr, uint16_t *size, size_t address, void *info) { DecodeStatus status = _getInstruction(instr, - (unsigned char *)code, code_len, + code, code_len, size, address, (MCRegisterInfo *)info); diff --git a/arch/AArch64/AArch64Disassembler.h b/arch/AArch64/AArch64Disassembler.h index b1e07678f9..5490c6b3e4 100644 --- a/arch/AArch64/AArch64Disassembler.h +++ b/arch/AArch64/AArch64Disassembler.h @@ -12,8 +12,8 @@ void AArch64_init(MCRegisterInfo *MRI); -bool AArch64_getInstruction(csh ud, char *code, uint64_t code_len, - MCInst *instr, uint16_t *size, uint64_t address, void *info); +bool AArch64_getInstruction(csh ud, unsigned char *code, size_t code_len, + MCInst *instr, uint16_t *size, size_t address, void *info); #endif diff --git a/arch/ARM/ARMDisassembler.c b/arch/ARM/ARMDisassembler.c index 5b3900f054..d86a52e61d 100644 --- a/arch/ARM/ARMDisassembler.c +++ b/arch/ARM/ARMDisassembler.c @@ -422,8 +422,8 @@ void ARM_init(MCRegisterInfo *MRI) 0); } -static DecodeStatus _ARM_getInstruction(MCInst *MI, char *code, uint64_t code_len, - uint16_t *Size, uint64_t Address) +static DecodeStatus _ARM_getInstruction(MCInst *MI, unsigned char *code, size_t code_len, + uint16_t *Size, size_t Address) { uint8_t bytes[4]; @@ -644,8 +644,8 @@ static void UpdateThumbVFPPredicate(MCInst *MI) } } -static DecodeStatus _Thumb_getInstruction(MCInst *MI, char *code, uint64_t code_len, - uint16_t *Size, uint64_t Address) +static DecodeStatus _Thumb_getInstruction(MCInst *MI, unsigned char *code, size_t code_len, + uint16_t *Size, size_t Address) { uint8_t bytes[4]; @@ -821,8 +821,8 @@ static DecodeStatus _Thumb_getInstruction(MCInst *MI, char *code, uint64_t code_ return MCDisassembler_Fail; } -bool Thumb_getInstruction(csh ud, char *code, uint64_t code_len, MCInst *instr, - uint16_t *size, uint64_t address, void *info) +bool Thumb_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr, + uint16_t *size, size_t address, void *info) { //cs_struct *handle = (cs_struct *)ud; DecodeStatus status = _Thumb_getInstruction(instr, code, code_len, size, address); @@ -830,8 +830,8 @@ bool Thumb_getInstruction(csh ud, char *code, uint64_t code_len, MCInst *instr, return status == MCDisassembler_Success; } -bool ARM_getInstruction(csh ud, char *code, uint64_t code_len, MCInst *instr, - uint16_t *size, uint64_t address, void *info) +bool ARM_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr, + uint16_t *size, size_t address, void *info) { //cs_struct *handle = (cs_struct *)ud; DecodeStatus status = _ARM_getInstruction(instr, code, code_len, size, address); diff --git a/arch/ARM/ARMDisassembler.h b/arch/ARM/ARMDisassembler.h index ab604bda27..eb466a3f8d 100644 --- a/arch/ARM/ARMDisassembler.h +++ b/arch/ARM/ARMDisassembler.h @@ -9,8 +9,8 @@ void ARM_init(MCRegisterInfo *MRI); -bool ARM_getInstruction(csh handle, char *code, uint64_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info); +bool ARM_getInstruction(csh handle, unsigned char *code, size_t code_len, MCInst *instr, uint16_t *size, size_t address, void *info); -bool Thumb_getInstruction(csh handle, char *code, uint64_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info); +bool Thumb_getInstruction(csh handle, unsigned char *code, size_t code_len, MCInst *instr, uint16_t *size, size_t address, void *info); #endif diff --git a/arch/ARM/ARMGenDisassemblerTables.inc b/arch/ARM/ARMGenDisassemblerTables.inc index 668064a564..d4b1f14d00 100644 --- a/arch/ARM/ARMGenDisassemblerTables.inc +++ b/arch/ARM/ARMGenDisassemblerTables.inc @@ -13448,7 +13448,7 @@ DecodeToMCInst(decodeToMCInst_4, fieldFromInstruction_4, uint32_t) #define DecodeInstruction(fname, fieldname, decoder, InsnType) \ static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI, \ - InsnType insn, uint64_t Address, \ + InsnType insn, size_t Address, \ int feature) \ { \ uint64_t Bits = ARM_getFeatureBits(feature); \ diff --git a/arch/ARM/ARMInstPrinter.c b/arch/ARM/ARMInstPrinter.c index 76f894e975..f08d9f54ff 100644 --- a/arch/ARM/ARMInstPrinter.c +++ b/arch/ARM/ARMInstPrinter.c @@ -163,7 +163,7 @@ static void printRegImmShift(MCInst *MI, SStream *O, ARM_AM_ShiftOpc ShOpc, //assert (!(ShOpc == ARM_AM_ror && !ShImm) && "Cannot have ror #0"); SStream_concat(O, ARM_AM_getShiftOpcStr(ShOpc)); - MI->pub_insn.arm.operands[MI->pub_insn.arm.op_count - 1].shift.type = ShOpc; + MI->pub_insn.arm.operands[MI->pub_insn.arm.op_count - 1].shift.type = (arm_shifter)ShOpc; if (ShOpc != ARM_AM_rrx) { SStream_concat(O, " "); @@ -342,7 +342,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info) SStream_concat(O, ", %s", markup("")); - MI->pub_insn.arm.operands[MI->pub_insn.arm.op_count - 1].shift.type = ARM_AM_getSORegShOp(MCOperand_getImm(MO2)); + MI->pub_insn.arm.operands[MI->pub_insn.arm.op_count - 1].shift.type = (arm_shifter)ARM_AM_getSORegShOp(MCOperand_getImm(MO2)); MI->pub_insn.arm.operands[MI->pub_insn.arm.op_count - 1].shift.value = translateShiftImm(getSORegOffset(MCOperand_getImm(MO2))); return; } @@ -622,7 +622,7 @@ static void printAM2PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O) if (getAM2Offset(MCOperand_getImm(MO3))) { // Don't print +0. SStream_concat(O, ", %s", markup("pub_insn.arm.operands[MI->pub_insn.arm.op_count].shift.type = getAM2Op(MCOperand_getImm(MO3)); + MI->pub_insn.arm.operands[MI->pub_insn.arm.op_count].shift.type = (arm_shifter)getAM2Op(MCOperand_getImm(MO3)); MI->pub_insn.arm.operands[MI->pub_insn.arm.op_count].shift.value = getAM2Offset(MCOperand_getImm(MO3)); SStream_concat(O, markup(">")); } diff --git a/arch/Mips/MipsDisassembler.c b/arch/Mips/MipsDisassembler.c index 7943632746..e6a8cd48da 100644 --- a/arch/Mips/MipsDisassembler.c +++ b/arch/Mips/MipsDisassembler.c @@ -243,9 +243,9 @@ static DecodeStatus readInstruction32(unsigned char *code, uint32_t *insn, bool } static DecodeStatus MipsDisassembler_getInstruction(int mode, MCInst *instr, - char *code, uint64_t code_len, + unsigned char *code, size_t code_len, uint16_t *Size, - uint64_t Address, bool isBigEndian, MCRegisterInfo *MRI, + size_t Address, bool isBigEndian, MCRegisterInfo *MRI, bool isMicroMips) { uint32_t Insn; @@ -279,8 +279,8 @@ static DecodeStatus MipsDisassembler_getInstruction(int mode, MCInst *instr, return MCDisassembler_Fail; } -bool Mips_getInstruction(csh ud, char *code, uint64_t code_len, MCInst *instr, - uint16_t *size, uint64_t address, void *info) +bool Mips_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr, + uint16_t *size, size_t address, void *info) { cs_struct *handle = (cs_struct *)(uintptr_t)ud; @@ -294,9 +294,9 @@ bool Mips_getInstruction(csh ud, char *code, uint64_t code_len, MCInst *instr, } static DecodeStatus Mips64Disassembler_getInstruction(int mode, MCInst *instr, - char *code, uint64_t code_len, + unsigned char *code, size_t code_len, uint16_t *Size, - uint64_t Address, bool isBigEndian, MCRegisterInfo *MRI) + size_t Address, bool isBigEndian, MCRegisterInfo *MRI) { uint32_t Insn; @@ -320,8 +320,8 @@ static DecodeStatus Mips64Disassembler_getInstruction(int mode, MCInst *instr, return MCDisassembler_Fail; } -bool Mips64_getInstruction(csh ud, char *code, uint64_t code_len, MCInst *instr, - uint16_t *size, uint64_t address, void *info) +bool Mips64_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr, + uint16_t *size, size_t address, void *info) { cs_struct *handle = (cs_struct *)(uintptr_t)ud; diff --git a/arch/Mips/MipsDisassembler.h b/arch/Mips/MipsDisassembler.h index 04089202f9..850023cb70 100644 --- a/arch/Mips/MipsDisassembler.h +++ b/arch/Mips/MipsDisassembler.h @@ -11,10 +11,10 @@ void Mips_init(MCRegisterInfo *MRI); -bool Mips_getInstruction(csh handle, char *code, uint64_t code_len, - MCInst *instr, uint16_t *size, uint64_t address, void *info); +bool Mips_getInstruction(csh handle, unsigned char *code, size_t code_len, + MCInst *instr, uint16_t *size, size_t address, void *info); -bool Mips64_getInstruction(csh handle, char *code, uint64_t code_len, - MCInst *instr, uint16_t *size, uint64_t address, void *info); +bool Mips64_getInstruction(csh handle, unsigned char *code, size_t code_len, + MCInst *instr, uint16_t *size, size_t address, void *info); #endif diff --git a/arch/X86/X86Disassembler.c b/arch/X86/X86Disassembler.c index 2ba22a39ae..6663ac48ff 100644 --- a/arch/X86/X86Disassembler.c +++ b/arch/X86/X86Disassembler.c @@ -35,7 +35,7 @@ #include "X86GenInstrInfo.inc" struct reader_info { - char *code; + unsigned char *code; uint64_t size; uint64_t offset; }; @@ -611,7 +611,7 @@ static void update_pub_insn(cs_insn *pub, InternalInstruction *inter) } // Public interface for the disassembler -bool X86_getInstruction(csh ud, char *code, uint64_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *_info) +bool X86_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr, uint16_t *size, size_t address, void *_info) { cs_struct *handle = (cs_struct *)(uintptr_t)ud; InternalInstruction insn; diff --git a/arch/X86/X86Disassembler.h b/arch/X86/X86Disassembler.h index c0cc1ca21b..aadf0d11fd 100644 --- a/arch/X86/X86Disassembler.h +++ b/arch/X86/X86Disassembler.h @@ -95,7 +95,7 @@ #undef INSTRUCTION_SPECIFIER_FIELDS #undef INSTRUCTION_IDS -bool X86_getInstruction(csh handle, char *code, uint64_t code_len, - MCInst *instr, uint16_t *size, uint64_t address, void *info); +bool X86_getInstruction(csh handle, unsigned char *code, size_t code_len, + MCInst *instr, uint16_t *size, size_t address, void *info); #endif diff --git a/cs.c b/cs.c index 31fb548d48..7cc352896c 100644 --- a/cs.c +++ b/cs.c @@ -189,12 +189,12 @@ static void fill_insn(cs_struct *handle, cs_insn *insn, char *buffer, MCInst *mc insn->mnemonic[sizeof(insn->mnemonic) - 1] = '\0'; } -uint64_t cs_disasm(csh ud, char *buffer, uint64_t size, uint64_t offset, uint64_t count, cs_insn *insn) +size_t cs_disasm(csh ud, unsigned char *buffer, size_t size, size_t offset, size_t count, cs_insn *insn) { cs_struct *handle = (cs_struct *)(uintptr_t)ud; MCInst mci; uint16_t insn_size; - uint64_t c = 0; + size_t c = 0; if (!handle) { // FIXME: handle this case? @@ -238,15 +238,15 @@ uint64_t cs_disasm(csh ud, char *buffer, uint64_t size, uint64_t offset, uint64_ // dynamicly allocate memory to contain disasm insn // NOTE: caller must free() the allocated memory itself to avoid memory leaking -uint64_t cs_disasm_dyn(csh ud, char *buffer, uint64_t size, uint64_t offset, uint64_t count, cs_insn **insn) +size_t cs_disasm_dyn(csh ud, unsigned char *buffer, size_t size, size_t offset, size_t count, cs_insn **insn) { cs_struct *handle = (cs_struct *)(uintptr_t)ud; MCInst mci; uint16_t insn_size; - uint64_t c = 0, f = 0; + size_t c = 0, f = 0; cs_insn insn_cache[64]; void *total = NULL; - uint64_t total_size = 0; + size_t total_size = 0; if (!handle) { // FIXME: how to handle this case: diff --git a/cs_priv.h b/cs_priv.h index 441d31724b..32e03f5f78 100644 --- a/cs_priv.h +++ b/cs_priv.h @@ -15,7 +15,7 @@ typedef void (*Printer_t)(MCInst *MI, SStream *OS, void *info); // this is the best time to gather insn's characteristics typedef void (*PostPrinter_t)(unsigned int insn, cs_insn *, char *mnem); -typedef bool (*Disasm_t)(csh handle, char *code, uint64_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info); +typedef bool (*Disasm_t)(csh handle, unsigned char *code, size_t code_len, MCInst *instr, uint16_t *size, size_t address, void *info); typedef char *(*GetName_t)(unsigned int reg); diff --git a/include/arm.h b/include/arm.h index 64ccf5cf2c..27cad9552e 100644 --- a/include/arm.h +++ b/include/arm.h @@ -62,7 +62,7 @@ typedef struct arm_op_mem { unsigned int base; // base register unsigned int index; // index register int scale; // scale for index register (can be 1, or -1) - int64_t disp; // displacement/offset value + int disp; // displacement/offset value } arm_op_mem; // Instruction operand @@ -74,7 +74,7 @@ typedef struct cs_arm_op { arm_op_type type; // operand type union { unsigned int reg; // register value for REG operand - int64_t imm; // immediate value for C-IMM, P-IMM or IMM operand + unsigned int imm; // immediate value for C-IMM, P-IMM or IMM operand double fp; // floating point value for FP operand arm_op_mem mem; // base/index/scale/disp value for MEM operand }; diff --git a/include/capstone.h b/include/capstone.h index a842c1e8e2..f6df708ca5 100644 --- a/include/capstone.h +++ b/include/capstone.h @@ -12,7 +12,7 @@ extern "C" { #include // Handle using with all API -typedef uint64_t csh; +typedef size_t csh; // Architecture type typedef enum cs_arch { @@ -52,7 +52,7 @@ typedef struct cs_insn { unsigned int id; // Offset address of this instruction - uint64_t address; + size_t address; // Size of this instruction uint16_t size; @@ -144,10 +144,10 @@ cs_err cs_errno(csh handle); @return: the number of succesfully disassembled instructions, or 0 if this function failed to disassemble the given code */ -uint64_t cs_disasm(csh handle, - char *code, uint64_t code_size, - uint64_t offset, - uint64_t count, +size_t cs_disasm(csh handle, + unsigned char *code, size_t code_size, + size_t offset, + size_t count, cs_insn *insn); /* @@ -168,10 +168,10 @@ uint64_t cs_disasm(csh handle, @return: the number of succesfully disassembled instructions, or 0 if this function failed to disassemble the given code */ -uint64_t cs_disasm_dyn(csh handle, - char *code, uint64_t code_size, - uint64_t offset, - uint64_t count, +size_t cs_disasm_dyn(csh handle, + unsigned char *code, size_t code_size, + size_t offset, + size_t count, cs_insn **insn); /* diff --git a/tests/test.c b/tests/test.c index 65e55e449a..b52ee22d34 100644 --- a/tests/test.c +++ b/tests/test.c @@ -10,14 +10,14 @@ struct platform { cs_arch arch; cs_mode mode; - char *code; - int size; + unsigned char *code; + size_t size; char *comment; }; -static void print_string_hex(char *str, int len) +static void print_string_hex(unsigned char *str, int len) { - char *c; + unsigned char *c; printf("Code: "); for (c = str; c < str + len; c++) { @@ -48,84 +48,84 @@ static void test() { .arch = CS_ARCH_X86, .mode = CS_MODE_16, - .code = X86_CODE16, + .code = (unsigned char*)X86_CODE16, .size = sizeof(X86_CODE16) - 1, .comment = "X86 16bit (Intel syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_32 + CS_MODE_SYNTAX_ATT, - .code = X86_CODE32, + .code = (unsigned char*)X86_CODE32, .size = sizeof(X86_CODE32) - 1, .comment = "X86 32bit (ATT syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_32, - .code = X86_CODE32, + .code = (unsigned char*)X86_CODE32, .size = sizeof(X86_CODE32) - 1, .comment = "X86 32 (Intel syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_64, - .code = X86_CODE64, + .code = (unsigned char*)X86_CODE64, .size = sizeof(X86_CODE64) - 1, .comment = "X86 64 (Intel syntax)" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_ARM, - .code = ARM_CODE, + .code = (unsigned char*)ARM_CODE, .size = sizeof(ARM_CODE) - 1, .comment = "ARM" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_THUMB, - .code = THUMB_CODE2, + .code = (unsigned char*)THUMB_CODE2, .size = sizeof(THUMB_CODE2) - 1, .comment = "THUMB-2" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_ARM, - .code = ARM_CODE2, + .code = (unsigned char*)ARM_CODE2, .size = sizeof(ARM_CODE2) - 1, .comment = "ARM: Cortex-A15 + NEON" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_THUMB, - .code = THUMB_CODE, + .code = (unsigned char*)THUMB_CODE, .size = sizeof(THUMB_CODE) - 1, .comment = "THUMB" }, { .arch = CS_ARCH_MIPS, .mode = CS_MODE_32 + CS_MODE_BIG_ENDIAN, - .code = MIPS_CODE, + .code = (unsigned char*)MIPS_CODE, .size = sizeof(MIPS_CODE) - 1, .comment = "MIPS-32 (Big-endian)" }, { .arch = CS_ARCH_MIPS, .mode = CS_MODE_64+ CS_MODE_LITTLE_ENDIAN, - .code = MIPS_CODE2, + .code = (unsigned char*)MIPS_CODE2, .size = sizeof(MIPS_CODE2) - 1, .comment = "MIPS-64-EL (Little-endian)" }, { .arch = CS_ARCH_ARM64, .mode = CS_MODE_ARM, - .code = ARM64_CODE, + .code = (unsigned char*)ARM64_CODE, .size = sizeof(ARM64_CODE) - 1, .comment = "ARM-64" }, }; csh handle; - uint64_t address = 0x1000; + size_t address = 0x1000; //cs_insn insn[16]; cs_insn *insn; int i; @@ -137,22 +137,22 @@ static void test() return; } - //uint64_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, insn); - uint64_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); + //size_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, insn); + size_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); if (count) { printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); print_string_hex(platforms[i].code, platforms[i].size); printf("Disasm:\n"); - uint64_t j; + size_t j; for (j = 0; j < count; j++) { - printf("0x%"PRIx64":\t%s\t\t%s\n", + printf("0x%zu:\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); } // print out the next offset, after the last insn - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); diff --git a/tests/test_arm.c b/tests/test_arm.c index 21e1194336..631de17d92 100644 --- a/tests/test_arm.c +++ b/tests/test_arm.c @@ -12,14 +12,14 @@ static csh handle; struct platform { cs_arch arch; cs_mode mode; - char *code; - int size; + unsigned char *code; + size_t size; char *comment; }; -static void print_string_hex(char *comment, char *str, int len) +static void print_string_hex(char *comment, unsigned char *str, int len) { - char *c; + unsigned char *c; printf("%s", comment); for (c = str; c < str + len; c++) { @@ -46,7 +46,7 @@ static void print_insn_detail(cs_arch mode, cs_insn *ins) 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%"PRIx64 "\n", i, op->imm); + printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); break; case ARM_OP_FP: printf("\t\toperands[%u].type: FP = %f\n", i, op->fp); @@ -62,14 +62,14 @@ static void print_insn_detail(cs_arch mode, cs_insn *ins) 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%" PRIx64 "\n", i, op->mem.disp); + 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 = %"PRIu64 "\n", i, op->imm); + printf("\t\toperands[%u].type: P-IMM = %u\n", i, op->imm); break; case ARM_OP_CIMM: - printf("\t\toperands[%u].type: C-IMM = %"PRIu64 "\n", i, op->imm); + printf("\t\toperands[%u].type: C-IMM = %u\n", i, op->imm); break; } @@ -152,34 +152,34 @@ static void test() { .arch = CS_ARCH_ARM, .mode = CS_MODE_ARM, - .code = ARM_CODE, + .code = (unsigned char *)ARM_CODE, .size = sizeof(ARM_CODE) - 1, .comment = "ARM" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_THUMB, - .code = THUMB_CODE, + .code = (unsigned char *)THUMB_CODE, .size = sizeof(THUMB_CODE) - 1, .comment = "Thumb" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_THUMB, - .code = ARM_CODE2, + .code = (unsigned char *)ARM_CODE2, .size = sizeof(ARM_CODE2) - 1, .comment = "Thumb-mixed" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_THUMB, - .code = THUMB_CODE2, + .code = (unsigned char *)THUMB_CODE2, .size = sizeof(THUMB_CODE2) - 1, .comment = "Thumb-2" }, }; - uint64_t address = 0x1000; + size_t address = 0x1000; cs_insn *insn; int i; @@ -187,19 +187,19 @@ static void test() if (cs_open(platforms[i].arch, platforms[i].mode, &handle)) return; - uint64_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); + size_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); if (count) { printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); print_string_hex("Code:", platforms[i].code, platforms[i].size); printf("Disasm:\n"); - uint64_t j; + size_t j; for (j = 0; j < count; j++) { - printf("0x%"PRIx64":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%zu:\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(platforms[i].mode, &insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); diff --git a/tests/test_arm64.c b/tests/test_arm64.c index 80aa552474..310d7c7cc5 100644 --- a/tests/test_arm64.c +++ b/tests/test_arm64.c @@ -12,14 +12,14 @@ static csh handle; struct platform { cs_arch arch; cs_mode mode; - char *code; - int size; + unsigned char *code; + size_t size; char *comment; }; -static void print_string_hex(char *comment, char *str, int len) +static void print_string_hex(char *comment, unsigned char *str, int len) { - char *c; + unsigned char *c; printf("%s", comment); for (c = str; c < str + len; c++) { @@ -137,13 +137,13 @@ static void test() { .arch = CS_ARCH_ARM64, .mode = CS_MODE_ARM, - .code = ARM64_CODE, + .code = (unsigned char *)ARM64_CODE, .size = sizeof(ARM64_CODE) - 1, .comment = "ARM-64" }, }; - uint64_t address = 0x2c; + size_t address = 0x2c; //cs_insn insn[16]; cs_insn *insn; int i; @@ -152,20 +152,20 @@ static void test() if (cs_open(platforms[i].arch, platforms[i].mode, &handle)) return; - //uint64_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, insn); - uint64_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); + //size_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, insn); + size_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); if (count) { printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); print_string_hex("Code:", platforms[i].code, platforms[i].size); printf("Disasm:\n"); - uint64_t j; + size_t j; for (j = 0; j < count; j++) { - printf("0x%"PRIx64":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%zu:\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(platforms[i].mode, &insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); diff --git a/tests/test_detail.c b/tests/test_detail.c index 0254f2ea17..c89425944e 100644 --- a/tests/test_detail.c +++ b/tests/test_detail.c @@ -10,14 +10,14 @@ struct platform { cs_arch arch; cs_mode mode; - char *code; - int size; + unsigned char *code; + size_t size; char *comment; }; -static void print_string_hex(char *str, int len) +static void print_string_hex(unsigned char *str, int len) { - char *c; + unsigned char *c; printf("Code: "); for (c = str; c < str + len; c++) { @@ -50,84 +50,84 @@ static void test() { .arch = CS_ARCH_X86, .mode = CS_MODE_16, - .code = X86_CODE16, + .code = (unsigned char *)X86_CODE16, .size = sizeof(X86_CODE32) - 1, .comment = "X86 16bit (Intel syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_32 + CS_MODE_SYNTAX_ATT, - .code = X86_CODE32, + .code = (unsigned char *)X86_CODE32, .size = sizeof(X86_CODE32) - 1, .comment = "X86 32bit (ATT syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_32, - .code = X86_CODE32, + .code = (unsigned char *)X86_CODE32, .size = sizeof(X86_CODE32) - 1, .comment = "X86 32 (Intel syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_64, - .code = X86_CODE64, + .code = (unsigned char *)X86_CODE64, .size = sizeof(X86_CODE64) - 1, .comment = "X86 64 (Intel syntax)" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_ARM, - .code = ARM_CODE, + .code = (unsigned char *)ARM_CODE, .size = sizeof(ARM_CODE) - 1, .comment = "ARM" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_THUMB, - .code = THUMB_CODE2, + .code = (unsigned char *)THUMB_CODE2, .size = sizeof(THUMB_CODE2) - 1, .comment = "THUMB-2" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_ARM, - .code = ARM_CODE2, + .code = (unsigned char *)ARM_CODE2, .size = sizeof(ARM_CODE2) - 1, .comment = "ARM: Cortex-A15 + NEON" }, { .arch = CS_ARCH_ARM, .mode = CS_MODE_THUMB, - .code = THUMB_CODE, + .code = (unsigned char *)THUMB_CODE, .size = sizeof(THUMB_CODE) - 1, .comment = "THUMB" }, { .arch = CS_ARCH_MIPS, .mode = CS_MODE_32 + CS_MODE_BIG_ENDIAN, - .code = MIPS_CODE, + .code = (unsigned char *)MIPS_CODE, .size = sizeof(MIPS_CODE) - 1, .comment = "MIPS-32 (Big-endian)" }, { .arch = CS_ARCH_MIPS, .mode = CS_MODE_64+ CS_MODE_LITTLE_ENDIAN, - .code = MIPS_CODE2, + .code = (unsigned char *)MIPS_CODE2, .size = sizeof(MIPS_CODE2) - 1, .comment = "MIPS-64-EL (Little-endian)" }, { .arch = CS_ARCH_ARM64, .mode = CS_MODE_ARM, - .code = ARM64_CODE, + .code = (unsigned char *)ARM64_CODE, .size = sizeof(ARM64_CODE) - 1, .comment = "ARM-64" }, }; csh handle; - uint64_t address = 0x1000; + size_t address = 0x1000; //cs_insn all_insn[16]; cs_insn *all_insn; int i; @@ -136,19 +136,19 @@ static void test() if (cs_open(platforms[i].arch, platforms[i].mode, &handle)) return; - //uint64_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, all_insn); - uint64_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &all_insn); + //size_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, all_insn); + size_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &all_insn); if (count) { printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); print_string_hex(platforms[i].code, platforms[i].size); printf("Disasm:\n"); - uint64_t j; + size_t j; int n; for (j = 0; j < count; j++) { cs_insn *i = &(all_insn[j]); - printf("0x%"PRIx64":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", + printf("0x%zu:\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", i->address, i->mnemonic, i->op_str, i->id, cs_insn_name(handle, i->id)); @@ -187,7 +187,7 @@ static void test() } // print out the next offset, after the last insn - printf("0x%"PRIx64":\n", all_insn[j-1].address + all_insn[j-1].size); + printf("0x%zu:\n", all_insn[j-1].address + all_insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(all_insn); diff --git a/tests/test_mips.c b/tests/test_mips.c index fbbd976747..b80d8dbad3 100644 --- a/tests/test_mips.c +++ b/tests/test_mips.c @@ -10,16 +10,16 @@ struct platform { cs_arch arch; cs_mode mode; - char *code; - int size; + unsigned char *code; + size_t size; char *comment; }; static csh handle; -static void print_string_hex(char *comment, char *str, int len) +static void print_string_hex(char *comment, unsigned char *str, int len) { - char *c; + unsigned char *c; printf("%s", comment); for (c = str; c < str + len; c++) { @@ -79,20 +79,20 @@ static void test() { .arch = CS_ARCH_MIPS, .mode = CS_MODE_32 + CS_MODE_BIG_ENDIAN, - .code = MIPS_CODE, + .code = (unsigned char *)MIPS_CODE, .size = sizeof(MIPS_CODE) - 1, .comment = "MIPS-32 (Big-endian)" }, { .arch = CS_ARCH_MIPS, .mode = CS_MODE_64+ CS_MODE_LITTLE_ENDIAN, - .code = MIPS_CODE2, + .code = (unsigned char *)MIPS_CODE2, .size = sizeof(MIPS_CODE2) - 1, .comment = "MIPS-64-EL (Little-endian)" }, }; - uint64_t address = 0x1000; + size_t address = 0x1000; cs_insn *insn; int i; @@ -100,19 +100,19 @@ static void test() if (cs_open(platforms[i].arch, platforms[i].mode, &handle)) return; - uint64_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); + size_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); if (count) { printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); print_string_hex("Code:", platforms[i].code, platforms[i].size); printf("Disasm:\n"); - uint64_t j; + size_t j; for (j = 0; j < count; j++) { - printf("0x%"PRIx64":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%zu:\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(platforms[i].mode, &insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); diff --git a/tests/test_x86.c b/tests/test_x86.c index 64531111ec..7f8c408671 100644 --- a/tests/test_x86.c +++ b/tests/test_x86.c @@ -12,14 +12,14 @@ static csh handle; struct platform { cs_arch arch; cs_mode mode; - char *code; - int size; + unsigned char *code; + size_t size; char *comment; }; -static void print_string_hex(char *comment, char *str, int len) +static void print_string_hex(char *comment, unsigned char *str, int len) { - char *c; + unsigned char *c; printf("%s", comment); for (c = str; c < str + len; c++) { @@ -34,12 +34,12 @@ static void print_insn_detail(csh ud, cs_mode mode, cs_insn *ins) int i; cs_x86 *x86 = &(ins->x86); - print_string_hex("\tPrefix:", (char *)x86->prefix, 5); + print_string_hex("\tPrefix:", x86->prefix, 5); if (x86->segment != X86_REG_INVALID) printf("\tSegment override: %s\n", cs_reg_name(handle, x86->segment)); - print_string_hex("\tOpcode:", (char *)x86->opcode, 3); + print_string_hex("\tOpcode:", x86->opcode, 3); printf("\top_size: %u, addr_size: %u, disp_size: %u, imm_size: %u\n", x86->op_size, x86->addr_size, x86->disp_size, x86->imm_size); printf("\tmodrm: 0x%x\n", x86->modrm); printf("\tdisp: 0x%x\n", x86->disp); @@ -117,34 +117,34 @@ static void test() { .arch = CS_ARCH_X86, .mode = CS_MODE_16, - .code = X86_CODE16, + .code = (unsigned char *)X86_CODE16, .size = sizeof(X86_CODE16) - 1, .comment = "X86 16bit (Intel syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_32 + CS_MODE_SYNTAX_ATT, - .code = X86_CODE32, + .code = (unsigned char *)X86_CODE32, .size = sizeof(X86_CODE32) - 1, .comment = "X86 32 (AT&T syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_32, - .code = X86_CODE32, + .code = (unsigned char *)X86_CODE32, .size = sizeof(X86_CODE32) - 1, .comment = "X86 32 (Intel syntax)" }, { .arch = CS_ARCH_X86, .mode = CS_MODE_64, - .code = X86_CODE64, + .code = (unsigned char *)X86_CODE64, .size = sizeof(X86_CODE64) - 1, .comment = "X86 64 (Intel syntax)" }, }; - uint64_t address = 0x1000; + size_t address = 0x1000; //cs_insn insn[16]; cs_insn *insn; int i; @@ -153,20 +153,20 @@ static void test() if (cs_open(platforms[i].arch, platforms[i].mode, &handle)) return; - //uint64_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, insn); - uint64_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); + //size_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, insn); + size_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn); if (count) { printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); print_string_hex("Code:", platforms[i].code, platforms[i].size); printf("Disasm:\n"); - uint64_t j; + size_t j; for (j = 0; j < count; j++) { - printf("0x%"PRIx64":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%zu:\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(handle, platforms[i].mode, &insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); From 12d0cbd5e871fd47476fe07e6b3212c864ba936d Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 Nov 2013 17:40:49 +0800 Subject: [PATCH 02/10] bump API to 1.3 --- cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cs.c b/cs.c index 7cc352896c..100cf88215 100644 --- a/cs.c +++ b/cs.c @@ -29,7 +29,7 @@ #include "utils.h" #define VERSION_MAJOR 1 -#define VERSION_MINOR 2 +#define VERSION_MINOR 3 cs_err cs_errno(csh handle) { From 03af57a2c9b3a75af198d72242d576cabca2da08 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 Nov 2013 17:54:17 +0800 Subject: [PATCH 03/10] fix arm64_op_mem & arm64_op_type structures: int32_t is enough for imm & disp --- include/arm64.h | 4 ++-- tests/test_arm64.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/arm64.h b/include/arm64.h index 78f1b4b789..c15a3fd0e6 100644 --- a/include/arm64.h +++ b/include/arm64.h @@ -70,7 +70,7 @@ typedef enum arm64_op_type { typedef struct arm64_op_mem { unsigned int base; // base register unsigned int index; // index register - int64_t disp; // displacement/offset value + int32_t disp; // displacement/offset value } arm64_op_mem; // Instruction operand @@ -83,7 +83,7 @@ typedef struct cs_arm64_op { arm64_op_type type; // operand type union { unsigned int reg; // register value for REG operand - int64_t imm; // immediate value for C-IMM or IMM operand + int32_t imm; // immediate value, or index for C-IMM or IMM operand double fp; // floating point value for FP operand arm64_op_mem mem; // base/index/scale/disp value for MEM operand }; diff --git a/tests/test_arm64.c b/tests/test_arm64.c index 310d7c7cc5..4801375b7b 100644 --- a/tests/test_arm64.c +++ b/tests/test_arm64.c @@ -46,7 +46,7 @@ static void print_insn_detail(cs_arch mode, cs_insn *ins) 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); + printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); break; case ARM64_OP_FP: printf("\t\toperands[%u].type: FP = %f\n", i, op->fp); @@ -58,11 +58,11 @@ static void print_insn_detail(cs_arch mode, cs_insn *ins) 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%" PRIx64 "\n", i, op->mem.disp); + 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 = %"PRIu64 "\n", i, op->imm); + printf("\t\toperands[%u].type: C-IMM = %u\n", i, op->imm); break; } From 086f04fe678c24f86c42186430328a19f192b430 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 Nov 2013 18:07:02 +0800 Subject: [PATCH 04/10] python: fix code to reflect last API changes --- bindings/python/capstone/arm.py | 4 ++-- bindings/python/capstone/arm64.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/python/capstone/arm.py b/bindings/python/capstone/arm.py index b83e564b33..8388560f41 100644 --- a/bindings/python/capstone/arm.py +++ b/bindings/python/capstone/arm.py @@ -48,7 +48,7 @@ class arm_op_mem(ctypes.Structure): ('base', ctypes.c_uint), ('index', ctypes.c_uint), ('scale', ctypes.c_int), - ('disp', ctypes.c_int64), + ('disp', ctypes.c_int), ) class arm_op_shift(ctypes.Structure): @@ -60,7 +60,7 @@ class arm_op_shift(ctypes.Structure): class arm_op_value(ctypes.Union): _fields_ = ( ('reg', ctypes.c_uint), - ('imm', ctypes.c_int64), + ('imm', ctypes.c_int), ('fp', ctypes.c_double), ('mem', arm_op_mem), ) diff --git a/bindings/python/capstone/arm64.py b/bindings/python/capstone/arm64.py index a77bbc34ed..ccf92f717b 100644 --- a/bindings/python/capstone/arm64.py +++ b/bindings/python/capstone/arm64.py @@ -54,7 +54,7 @@ class arm64_op_mem(ctypes.Structure): _fields_ = ( ('base', ctypes.c_uint), ('index', ctypes.c_uint), - ('disp', ctypes.c_int64), + ('disp', ctypes.c_int32), ) class arm64_op_shift(ctypes.Structure): @@ -66,7 +66,7 @@ class arm64_op_shift(ctypes.Structure): class arm64_op_value(ctypes.Union): _fields_ = ( ('reg', ctypes.c_uint), - ('imm', ctypes.c_int64), + ('imm', ctypes.c_int32), ('fp', ctypes.c_double), ('mem', arm64_op_mem), ) From dbc6b0c915f0eb235265c1e5993ca8b7dd3bdff3 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 Nov 2013 18:30:37 +0800 Subject: [PATCH 05/10] python: fix capstone.py to reflect new change in cs_disasm_dyn() --- bindings/python/capstone/capstone.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/python/capstone/capstone.py b/bindings/python/capstone/capstone.py index 0241d5238d..bb5baaca61 100644 --- a/bindings/python/capstone/capstone.py +++ b/bindings/python/capstone/capstone.py @@ -118,7 +118,7 @@ class _cs_arch(ctypes.Union): class _cs_insn(ctypes.Structure): _fields_ = ( ('id', ctypes.c_uint), - ('address', ctypes.c_uint64), + ('address', ctypes.c_size_t), ('size', ctypes.c_uint16), ('mnemonic', ctypes.c_char * 32), ('op_str', ctypes.c_char * 96), @@ -134,8 +134,8 @@ def _setup_prototype(lib, fname, restype, *argtypes): getattr(lib, fname).argtypes = argtypes _setup_prototype(_cs, "cs_open", ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_uint64)) -_setup_prototype(_cs, "cs_disasm_dyn", ctypes.c_uint64, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_uint64, \ - ctypes.c_uint64, ctypes.c_uint64, ctypes.POINTER(ctypes.POINTER(_cs_insn))) +_setup_prototype(_cs, "cs_disasm_dyn", ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, \ + ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.POINTER(_cs_insn))) _setup_prototype(_cs, "cs_free", None, ctypes.c_void_p) _setup_prototype(_cs, "cs_close", ctypes.c_int, ctypes.POINTER(ctypes.c_uint64)) _setup_prototype(_cs, "cs_reg_name", ctypes.c_char_p, ctypes.c_uint64, ctypes.c_uint) From e7f8a94c04cec154a9e2b7a3d6a07a970e958665 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 Nov 2013 18:46:03 +0800 Subject: [PATCH 06/10] python: more fixes, so this works on x86 --- bindings/python/capstone/capstone.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/bindings/python/capstone/capstone.py b/bindings/python/capstone/capstone.py index bb5baaca61..4d35bd523f 100644 --- a/bindings/python/capstone/capstone.py +++ b/bindings/python/capstone/capstone.py @@ -133,18 +133,18 @@ def _setup_prototype(lib, fname, restype, *argtypes): getattr(lib, fname).restype = restype getattr(lib, fname).argtypes = argtypes -_setup_prototype(_cs, "cs_open", ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_uint64)) +_setup_prototype(_cs, "cs_open", ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_size_t)) _setup_prototype(_cs, "cs_disasm_dyn", ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, \ ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.POINTER(_cs_insn))) _setup_prototype(_cs, "cs_free", None, ctypes.c_void_p) -_setup_prototype(_cs, "cs_close", ctypes.c_int, ctypes.POINTER(ctypes.c_uint64)) -_setup_prototype(_cs, "cs_reg_name", ctypes.c_char_p, ctypes.c_uint64, ctypes.c_uint) -_setup_prototype(_cs, "cs_insn_name", ctypes.c_char_p, ctypes.c_uint64, ctypes.c_uint) -_setup_prototype(_cs, "cs_insn_group", ctypes.c_bool, ctypes.c_uint64, ctypes.POINTER(_cs_insn), ctypes.c_uint) -_setup_prototype(_cs, "cs_reg_read", ctypes.c_bool, ctypes.c_uint64, ctypes.POINTER(_cs_insn), ctypes.c_uint) -_setup_prototype(_cs, "cs_reg_write", ctypes.c_bool, ctypes.c_uint64, ctypes.POINTER(_cs_insn), ctypes.c_uint) -_setup_prototype(_cs, "cs_op_count", ctypes.c_int, ctypes.c_uint64, ctypes.POINTER(_cs_insn), ctypes.c_uint) -_setup_prototype(_cs, "cs_op_index", ctypes.c_int, ctypes.c_uint64, ctypes.POINTER(_cs_insn), ctypes.c_uint, ctypes.c_uint) +_setup_prototype(_cs, "cs_close", ctypes.c_int, ctypes.POINTER(ctypes.c_size_t)) +_setup_prototype(_cs, "cs_reg_name", ctypes.c_char_p, ctypes.c_size_t, ctypes.c_uint) +_setup_prototype(_cs, "cs_insn_name", ctypes.c_char_p, ctypes.c_size_t, ctypes.c_uint) +_setup_prototype(_cs, "cs_insn_group", ctypes.c_bool, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint) +_setup_prototype(_cs, "cs_reg_read", ctypes.c_bool, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint) +_setup_prototype(_cs, "cs_reg_write", ctypes.c_bool, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint) +_setup_prototype(_cs, "cs_op_count", ctypes.c_int, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint) +_setup_prototype(_cs, "cs_op_index", ctypes.c_int, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint, ctypes.c_uint) _setup_prototype(_cs, "cs_version", None, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)) _setup_prototype(_cs, "cs_errno", ctypes.c_int, ctypes.c_int64) @@ -158,7 +158,7 @@ def cs_version(): # quick & dirty Python function to disasm raw binary code def cs_disasm_quick(arch, mode, code, offset, count = 0): - csh = ctypes.c_uint64() + csh = ctypes.c_size_t() status = _cs.cs_open(arch, mode, ctypes.byref(csh)) if status != CS_ERR_OK: return @@ -254,7 +254,7 @@ def op_index(self, op_type, position): class cs: def __init__(self, arch, mode): self.arch, self.mode = arch, mode - self.csh = ctypes.c_uint64() + self.csh = ctypes.c_size_t() status = _cs.cs_open(arch, mode, ctypes.byref(self.csh)) if status != CS_ERR_OK: raise ValueError("Error: Wrong arch or mode") From 2170e58dfd15c283441e070324e676103eb9352d Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 Nov 2013 20:26:34 +0800 Subject: [PATCH 07/10] reduce the size of @operands for arm & arm64 --- bindings/python/capstone/arm.py | 2 +- bindings/python/capstone/arm64.py | 2 +- include/arm.h | 2 +- include/arm64.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/python/capstone/arm.py b/bindings/python/capstone/arm.py index 8388560f41..30461bae4c 100644 --- a/bindings/python/capstone/arm.py +++ b/bindings/python/capstone/arm.py @@ -78,7 +78,7 @@ class _cs_arm(ctypes.Structure): ('update_flags', ctypes.c_bool), ('writeback', ctypes.c_bool), ('op_count', ctypes.c_uint8), - ('operands', arm_op * 32), + ('operands', arm_op * 20), ) def get_arch_info(arch): diff --git a/bindings/python/capstone/arm64.py b/bindings/python/capstone/arm64.py index ccf92f717b..6702243934 100644 --- a/bindings/python/capstone/arm64.py +++ b/bindings/python/capstone/arm64.py @@ -85,7 +85,7 @@ class _cs_arm64(ctypes.Structure): ('update_flags', ctypes.c_bool), ('writeback', ctypes.c_bool), ('op_count', ctypes.c_uint8), - ('operands', arm64_op * 32), + ('operands', arm64_op * 8), ) def get_arch_info(a): diff --git a/include/arm.h b/include/arm.h index 27cad9552e..ecbdd35013 100644 --- a/include/arm.h +++ b/include/arm.h @@ -90,7 +90,7 @@ typedef struct cs_arm { // or 0 when instruction has no operand. uint8_t op_count; - cs_arm_op operands[32]; // operands for this instruction. + cs_arm_op operands[20]; // operands for this instruction. } cs_arm; // ARM registers diff --git a/include/arm64.h b/include/arm64.h index c15a3fd0e6..9f721173d0 100644 --- a/include/arm64.h +++ b/include/arm64.h @@ -99,7 +99,7 @@ typedef struct cs_arm64 { // or 0 when instruction has no operand. uint8_t op_count; - cs_arm64_op operands[32]; // operands for this instruction. + cs_arm64_op operands[8]; // operands for this instruction. } cs_arm64; // ARM64 registers From 237d7e344d70efafb2b041de5d2e1a1d16533320 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 29 Nov 2013 22:36:45 +0800 Subject: [PATCH 08/10] tests: typecast size_t to uint64_t for printf, since MingW doesnt support zu specifier --- tests/test.c | 8 +++++--- tests/test_arm.c | 4 ++-- tests/test_arm64.c | 4 ++-- tests/test_detail.c | 6 +++--- tests/test_mips.c | 4 ++-- tests/test_x86.c | 4 ++-- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/test.c b/tests/test.c index b52ee22d34..7502c831a7 100644 --- a/tests/test.c +++ b/tests/test.c @@ -146,13 +146,14 @@ static void test() printf("Disasm:\n"); size_t j; + for (j = 0; j < count; j++) { - printf("0x%zu:\t%s\t\t%s\n", - insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%"PRIx64":\t%s\t\t%s\n", + (uint64_t)insn[j].address, insn[j].mnemonic, insn[j].op_str); } // print out the next offset, after the last insn - printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); + printf("0x%"PRIx64":\n", (uint64_t)insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); @@ -175,6 +176,7 @@ int main() #if 0 #define offsetof(type, member) (int)(&((type *)0)->member) + cs_insn insn; printf("size: %lu\n", sizeof(insn)); printf("@id: %u\n", offsetof(cs_insn, id)); diff --git a/tests/test_arm.c b/tests/test_arm.c index 631de17d92..f9acdba25d 100644 --- a/tests/test_arm.c +++ b/tests/test_arm.c @@ -196,10 +196,10 @@ static void test() size_t j; for (j = 0; j < count; j++) { - printf("0x%zu:\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%"PRIx64":\t%s\t%s\n", (uint64_t)insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(platforms[i].mode, &insn[j]); } - printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); + printf("0x%"PRIx64":\n", (uint64_t)insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); diff --git a/tests/test_arm64.c b/tests/test_arm64.c index 4801375b7b..29e4ad752e 100644 --- a/tests/test_arm64.c +++ b/tests/test_arm64.c @@ -162,10 +162,10 @@ static void test() size_t j; for (j = 0; j < count; j++) { - printf("0x%zu:\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%"PRIx64":\t%s\t%s\n", (uint64_t)insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(platforms[i].mode, &insn[j]); } - printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); + printf("0x%"PRIx64":\n", (uint64_t)insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); diff --git a/tests/test_detail.c b/tests/test_detail.c index c89425944e..b3ef2e1627 100644 --- a/tests/test_detail.c +++ b/tests/test_detail.c @@ -148,8 +148,8 @@ static void test() int n; for (j = 0; j < count; j++) { cs_insn *i = &(all_insn[j]); - printf("0x%zu:\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", - i->address, i->mnemonic, i->op_str, + printf("0x%"PRIx64":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", + (uint64_t)i->address, i->mnemonic, i->op_str, i->id, cs_insn_name(handle, i->id)); // print implicit registers used by this instruction @@ -187,7 +187,7 @@ static void test() } // print out the next offset, after the last insn - printf("0x%zu:\n", all_insn[j-1].address + all_insn[j-1].size); + printf("0x%"PRIx64":\n", (uint64_t)all_insn[j-1].address + all_insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(all_insn); diff --git a/tests/test_mips.c b/tests/test_mips.c index b80d8dbad3..6eb1287462 100644 --- a/tests/test_mips.c +++ b/tests/test_mips.c @@ -109,10 +109,10 @@ static void test() size_t j; for (j = 0; j < count; j++) { - printf("0x%zu:\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%"PRIx64":\t%s\t%s\n", (uint64_t)insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(platforms[i].mode, &insn[j]); } - printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); + printf("0x%"PRIx64":\n", (uint64_t)insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); diff --git a/tests/test_x86.c b/tests/test_x86.c index 7f8c408671..a3b949abbe 100644 --- a/tests/test_x86.c +++ b/tests/test_x86.c @@ -163,10 +163,10 @@ static void test() size_t j; for (j = 0; j < count; j++) { - printf("0x%zu:\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%"PRIx64":\t%s\t%s\n", (uint64_t)insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(handle, platforms[i].mode, &insn[j]); } - printf("0x%zu:\n", insn[j-1].address + insn[j-1].size); + printf("0x%"PRIx64":\n", (uint64_t)insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm_dyn() cs_free(insn); From 1252643a3fc3968bede503722cd61281845d101d Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 30 Nov 2013 00:54:24 +0800 Subject: [PATCH 09/10] arm64: handle alias insn in a better way, and add support for MNEG. bug reported by Patroklos Argyroudis --- MCInst.c | 10 ++++++++++ MCInst.h | 5 +++++ arch/AArch64/AArch64InstPrinter.c | 5 +++-- arch/AArch64/mapping.c | 4 ++++ arch/AArch64/mapping.h | 2 +- cs.c | 8 ++++++-- include/arm64.h | 4 ++++ tests/test_arm64.c | 2 ++ 8 files changed, 35 insertions(+), 5 deletions(-) diff --git a/MCInst.c b/MCInst.c index 1ec8f8a9ff..c7d8b1763b 100644 --- a/MCInst.c +++ b/MCInst.c @@ -35,11 +35,21 @@ void MCInst_setOpcode(MCInst *inst, unsigned Op) inst->Opcode = Op; } +void MCInst_setOpcodePub(MCInst *inst, unsigned Op) +{ + inst->OpcodePub = Op; +} + unsigned MCInst_getOpcode(const MCInst *inst) { return inst->Opcode; } +unsigned MCInst_getOpcodePub(const MCInst *inst) +{ + return inst->OpcodePub; +} + MCOperand *MCInst_getOperand(MCInst *inst, unsigned i) { return &inst->Operands[i]; diff --git a/MCInst.h b/MCInst.h index be7c221dc7..2407eff2c8 100644 --- a/MCInst.h +++ b/MCInst.h @@ -89,6 +89,7 @@ struct MCInst { unsigned size; // number of operands cs_insn pub_insn; // insn to be exposed to public cs_mode mode; // to be referenced by internal code + unsigned OpcodePub; }; void MCInst_Init(MCInst *inst); @@ -101,6 +102,10 @@ void MCInst_setOpcode(MCInst *inst, unsigned Op); unsigned MCInst_getOpcode(const MCInst*); +void MCInst_setOpcodePub(MCInst *inst, unsigned Op); + +unsigned MCInst_getOpcodePub(const MCInst*); + MCOperand *MCInst_getOperand(MCInst *inst, unsigned i); unsigned MCInst_getNumOperands(const MCInst *inst); diff --git a/arch/AArch64/AArch64InstPrinter.c b/arch/AArch64/AArch64InstPrinter.c index 1cfddfccef..d4b208b1d4 100644 --- a/arch/AArch64/AArch64InstPrinter.c +++ b/arch/AArch64/AArch64InstPrinter.c @@ -636,10 +636,11 @@ void AArch64_printInst(MCInst *MI, SStream *O, void *Info) if (printAliasInstr(MI, O, Info)) { char *mnem = strdup(O->buffer); char *tab = strchr(mnem, '\t'); - if (tab) + if (tab) { *tab = '\0'; + } // reflect the new insn name (alias) in the opcode - MCInst_setOpcode(MI, AArch64_get_insn_id2(AArch64_map_insn(mnem))); + MCInst_setOpcodePub(MI, AArch64_map_insn(mnem)); free(mnem); } else AArch64InstPrinter_printInstruction(MI, O); diff --git a/arch/AArch64/mapping.c b/arch/AArch64/mapping.c index 735490103c..b8aed36a20 100644 --- a/arch/AArch64/mapping.c +++ b/arch/AArch64/mapping.c @@ -1854,6 +1854,7 @@ void AArch64_get_insn_id(cs_insn *insn, unsigned int id) } } +// given public insn id, return internal instruction ID unsigned int AArch64_get_insn_id2(unsigned int id) { return insn_reverse_id(insns, ARR_SIZE(insns), id); @@ -2224,6 +2225,7 @@ char *AArch64_insn_name(unsigned int id) return insn_name_maps[id].name; } +// map instruction name to public instruction ID arm64_reg AArch64_map_insn(char *name) { // map *S instructions back to original id @@ -2234,6 +2236,8 @@ arm64_reg AArch64_map_insn(char *name) { ARM64_INS_BIC, "BICS" }, { ARM64_INS_SBC, "SBCS" }, { ARM64_INS_SUB, "SUBS" }, + // alias insn + { ARM64_INS_MNEG, "MNEG" }, }; // NOTE: skip first NULL name in insn_name_maps diff --git a/arch/AArch64/mapping.h b/arch/AArch64/mapping.h index 7cd316b9bc..5e0f314136 100644 --- a/arch/AArch64/mapping.h +++ b/arch/AArch64/mapping.h @@ -18,7 +18,7 @@ unsigned int AArch64_get_insn_id2(unsigned int id); char *AArch64_insn_name(unsigned int id); -// map instruction name to instruction ID +// map instruction name to public instruction ID arm64_reg AArch64_map_insn(char *name); #endif diff --git a/cs.c b/cs.c index 100cf88215..0147533be7 100644 --- a/cs.c +++ b/cs.c @@ -170,8 +170,12 @@ static void fill_insn(cs_struct *handle, cs_insn *insn, char *buffer, MCInst *mc memcpy(insn, &mci->pub_insn, sizeof(*insn)); // map internal instruction opcode to public insn ID - if (handle->insn_id) - handle->insn_id(insn, MCInst_getOpcode(mci)); + if (MCInst_getOpcodePub(mci)) + MCInst_setOpcode(mci, MCInst_getOpcodePub(mci)); + else { + if (handle->insn_id) + handle->insn_id(insn, MCInst_getOpcode(mci)); + } if (printer) printer(insn->id, insn, buffer); diff --git a/include/arm64.h b/include/arm64.h index 9f721173d0..b329df0450 100644 --- a/include/arm64.h +++ b/include/arm64.h @@ -691,6 +691,10 @@ typedef enum arm64_insn { ARM64_INS_USUBW, ARM64_INS_UXTB, ARM64_INS_UXTH, + + // alias insn + ARM64_INS_MNEG, + ARM64_INS_MAX, } arm64_insn; diff --git a/tests/test_arm64.c b/tests/test_arm64.c index 29e4ad752e..993df04c13 100644 --- a/tests/test_arm64.c +++ b/tests/test_arm64.c @@ -131,6 +131,8 @@ static void test() //#define ARM64_CODE "\x5f\x3f\x03\xd5" // clrex //#define ARM64_CODE "\x5f\x3e\x03\xd5" // clrex #14 //#define ARM64_CODE "\x20\x00\x02\xab" // adds x0, x1, x2 (alias of adds x0, x1, x2, lsl #0) +//#define ARM64_CODE "\x20\xf4\x18\x9e" // fcvtzs x0, s1, #3 +//#define ARM64_CODE "\x20\xfc\x02\x9b" // mneg x0, x1, x2 #define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b" struct platform platforms[] = { From 3feb0ec24ab61338b274188d7dc1798b934bb79c Mon Sep 17 00:00:00 2001 From: Daniel Godas-Lopez Date: Fri, 29 Nov 2013 15:33:29 +0000 Subject: [PATCH 10/10] try to build all known targets and run the tests --- test.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100755 test.sh diff --git a/test.sh b/test.sh new file mode 100755 index 0000000000..0843f570e6 --- /dev/null +++ b/test.sh @@ -0,0 +1,28 @@ +#! /bin/bash + +export LD_LIBRARY_PATH=. + +for x in nix32 clang cross-win32 cross-win64 cygwin-mingw32 cygwin-mingw64; do + ./compile.sh $x &> /dev/null + + if [ $? == 0 ]; then + echo "$x -> compiled" + else + echo -e "$x -> failed to compile\n" + continue + fi + + for t in test test_arm test_arm64 test_detail test_mips test_x86; do + ./tests/$t &> /dev/null + + if [ $? -eq 0 ]; then + echo " $t -> PASS" + else + echo " $t -> FAIL" + fi + done + + echo +done + +make clean &> /dev/null