From 861a09822f5ae5475bb90b30e78e436cc1d6002e Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 4 Nov 2016 23:59:34 +0800 Subject: [PATCH 01/10] cstool: remove its version --- cstool/cstool.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cstool/cstool.c b/cstool/cstool.c index 92c55a9414..83abba1d61 100644 --- a/cstool/cstool.c +++ b/cstool/cstool.c @@ -7,7 +7,6 @@ #include -#define VERSION "2.0" void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins); void print_insn_detail_arm(csh handle, cs_insn *ins); @@ -73,7 +72,7 @@ static uint8_t *preprocess(char *code, size_t *size) static void usage(char *prog) { - printf("Cstool v%s for Capstone Disassembler Engine (core v%u.%u.%u)\n\n", VERSION, CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA); + printf("Cstool for Capstone Disassembler Engine v%u.%u.%u\n\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA); printf("Syntax: %s [-d] [start-address-in-hex-format]\n", prog); printf("\nThe following options are supported:\n"); From 41a3980b6dea99bec60b280d4c3fefdb7d1b5d0a Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 5 Nov 2016 00:47:14 +0800 Subject: [PATCH 02/10] cstool: print out insn groups --- cstool/cstool.c | 12 ++++ cstool/cstool_arm.c | 2 - cstool/cstool_arm64.c | 2 - cstool/cstool_m68k.c | 121 ++++++++++++++++++++++++++++++++++++++++ cstool/cstool_mips.c | 2 - cstool/cstool_ppc.c | 2 - cstool/cstool_sparc.c | 2 - cstool/cstool_systemz.c | 2 - cstool/cstool_x86.c | 2 - 9 files changed, 133 insertions(+), 14 deletions(-) create mode 100644 cstool/cstool_m68k.c diff --git a/cstool/cstool.c b/cstool/cstool.c index 83abba1d61..6d7f199654 100644 --- a/cstool/cstool.c +++ b/cstool/cstool.c @@ -371,6 +371,18 @@ int main(int argc, char **argv) if (arch == CS_ARCH_XCORE) { print_insn_detail_xcore(handle, &insn[i]); } + + if (insn[i].detail->groups_count) { + int j; + + printf("\tGroups: "); + for(j = 0; j < insn[i].detail->groups_count; j++) { + printf("%s ", cs_group_name(handle, insn[i].detail->groups[j])); + } + printf("\n"); + } + + printf("\n"); } } cs_free(insn, count); diff --git a/cstool/cstool_arm.c b/cstool/cstool_arm.c index 5453fa6961..987c6d2744 100644 --- a/cstool/cstool_arm.c +++ b/cstool/cstool_arm.c @@ -110,6 +110,4 @@ void print_insn_detail_arm(csh handle, cs_insn *ins) 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 index 25a402f8ad..da456f0c42 100644 --- a/cstool/cstool_arm64.c +++ b/cstool/cstool_arm64.c @@ -99,6 +99,4 @@ void print_insn_detail_arm64(csh handle, cs_insn *ins) if (arm64->cc) printf("\tCode-condition: %u\n", arm64->cc); - - printf("\n"); } diff --git a/cstool/cstool_m68k.c b/cstool/cstool_m68k.c new file mode 100644 index 0000000000..9a0fc7f30b --- /dev/null +++ b/cstool/cstool_m68k.c @@ -0,0 +1,121 @@ +// +// cstool_m68k.c +// +// +// Created by YUHANG TANG on 26/10/16. +// +// + +#include +#include + +void print_string_hex(char *comment, unsigned char *str, size_t len); + +static const char* s_addressing_modes[] = { + "", + + "Register Direct - Data", + "Register Direct - Address", + + "Register Indirect - Address", + "Register Indirect - Address with Postincrement", + "Register Indirect - Address with Predecrement", + "Register Indirect - Address with Displacement", + + "Address Register Indirect With Index - 8-bit displacement", + "Address Register Indirect With Index - Base displacement", + + "Memory indirect - Postindex", + "Memory indirect - Preindex", + + "Program Counter Indirect - with Displacement", + + "Program Counter Indirect with Index - with 8-Bit Displacement", + "Program Counter Indirect with Index - with Base Displacement", + + "Program Counter Memory Indirect - Postindexed", + "Program Counter Memory Indirect - Preindexed", + + "Absolute Data Addressing - Short", + "Absolute Data Addressing - Long", + "Immediate value", +}; + +static void print_read_write_regs(cs_detail* detail, csh handle) +{ + int i; + + for (i = 0; i < detail->regs_read_count; ++i) { + uint16_t reg_id = detail->regs_read[i]; + const char* reg_name = cs_reg_name(handle, reg_id); + printf("\treading from reg: %s\n", reg_name); + } + + for (i = 0; i < detail->regs_write_count; ++i) { + uint16_t reg_id = detail->regs_write[i]; + const char* reg_name = cs_reg_name(handle, reg_id); + printf("\twriting to reg: %s\n", reg_name); + } +} + +void print_insn_detail_m68k(csh handle, cs_insn *ins) +{ + cs_m68k* m68k; + cs_detail* detail; + int i; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + detail = ins->detail; + m68k = &detail->m68k; + if (m68k->op_count) + printf("\top_count: %u\n", m68k->op_count); + + print_read_write_regs(detail, handle); + + printf("\tgroups_count: %u\n", detail->groups_count); + + for (i = 0; i < m68k->op_count; i++) { + cs_m68k_op* op = &(m68k->operands[i]); + + switch((int)op->type) { + default: + break; + case M68K_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case M68K_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%x\n", i, (int)op->imm); + break; + case M68K_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base_reg != M68K_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base_reg)); + if (op->mem.index_reg != M68K_REG_INVALID) { + printf("\t\t\toperands[%u].mem.index: REG = %s\n", + i, cs_reg_name(handle, op->mem.index_reg)); + printf("\t\t\toperands[%u].mem.index: size = %c\n", + i, op->mem.index_size ? 'l' : 'w'); + } + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); + if (op->mem.scale != 0) + printf("\t\t\toperands[%u].mem.scale: %d\n", i, op->mem.scale); + + printf("\t\taddress mode: %s\n", s_addressing_modes[op->address_mode]); + break; + case M68K_OP_FP_SINGLE: + printf("\t\toperands[%u].type: FP_SINGLE\n", i); + printf("\t\t\toperands[%u].simm: %f\n", i, op->simm); + break; + case M68K_OP_FP_DOUBLE: + printf("\t\toperands[%u].type: FP_DOUBLE\n", i); + printf("\t\t\toperands[%u].dimm: %lf\n", i, op->dimm); + break; + } + } +} + diff --git a/cstool/cstool_mips.c b/cstool/cstool_mips.c index 45faba7b83..3beb7b3232 100644 --- a/cstool/cstool_mips.c +++ b/cstool/cstool_mips.c @@ -44,6 +44,4 @@ void print_insn_detail_mips(csh handle, cs_insn *ins) } } - - printf("\n"); } diff --git a/cstool/cstool_ppc.c b/cstool/cstool_ppc.c index 771d88e716..a56fa40e7c 100644 --- a/cstool/cstool_ppc.c +++ b/cstool/cstool_ppc.c @@ -86,6 +86,4 @@ void print_insn_detail_ppc(csh handle, cs_insn *ins) if (ppc->update_cr0) printf("\tUpdate-CR0: True\n"); - - printf("\n"); } diff --git a/cstool/cstool_sparc.c b/cstool/cstool_sparc.c index 34bd9ca7d4..8e53230a2e 100644 --- a/cstool/cstool_sparc.c +++ b/cstool/cstool_sparc.c @@ -51,6 +51,4 @@ void print_insn_detail_sparc(csh handle, cs_insn *ins) 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 index f35d6f836d..eb5e2bc6ce 100644 --- a/cstool/cstool_systemz.c +++ b/cstool/cstool_systemz.c @@ -53,6 +53,4 @@ void print_insn_detail_sysz(csh handle, cs_insn *ins) if (sysz->cc != 0) printf("\tCode condition: %u\n", sysz->cc); - - printf("\n"); } diff --git a/cstool/cstool_x86.c b/cstool/cstool_x86.c index 0b091af043..cc47a8b070 100644 --- a/cstool/cstool_x86.c +++ b/cstool/cstool_x86.c @@ -108,6 +108,4 @@ void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins) printf("\t\toperands[%u].size: %u\n", i, op->size); } - - printf("\n"); } From 8853489ea99b5f47be6b9c8fe7aea4740ab6a987 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 5 Nov 2016 00:52:54 +0800 Subject: [PATCH 03/10] cstool: remove M68K support --- cstool/cstool_m68k.c | 121 ------------------------------------------- 1 file changed, 121 deletions(-) delete mode 100644 cstool/cstool_m68k.c diff --git a/cstool/cstool_m68k.c b/cstool/cstool_m68k.c deleted file mode 100644 index 9a0fc7f30b..0000000000 --- a/cstool/cstool_m68k.c +++ /dev/null @@ -1,121 +0,0 @@ -// -// cstool_m68k.c -// -// -// Created by YUHANG TANG on 26/10/16. -// -// - -#include -#include - -void print_string_hex(char *comment, unsigned char *str, size_t len); - -static const char* s_addressing_modes[] = { - "", - - "Register Direct - Data", - "Register Direct - Address", - - "Register Indirect - Address", - "Register Indirect - Address with Postincrement", - "Register Indirect - Address with Predecrement", - "Register Indirect - Address with Displacement", - - "Address Register Indirect With Index - 8-bit displacement", - "Address Register Indirect With Index - Base displacement", - - "Memory indirect - Postindex", - "Memory indirect - Preindex", - - "Program Counter Indirect - with Displacement", - - "Program Counter Indirect with Index - with 8-Bit Displacement", - "Program Counter Indirect with Index - with Base Displacement", - - "Program Counter Memory Indirect - Postindexed", - "Program Counter Memory Indirect - Preindexed", - - "Absolute Data Addressing - Short", - "Absolute Data Addressing - Long", - "Immediate value", -}; - -static void print_read_write_regs(cs_detail* detail, csh handle) -{ - int i; - - for (i = 0; i < detail->regs_read_count; ++i) { - uint16_t reg_id = detail->regs_read[i]; - const char* reg_name = cs_reg_name(handle, reg_id); - printf("\treading from reg: %s\n", reg_name); - } - - for (i = 0; i < detail->regs_write_count; ++i) { - uint16_t reg_id = detail->regs_write[i]; - const char* reg_name = cs_reg_name(handle, reg_id); - printf("\twriting to reg: %s\n", reg_name); - } -} - -void print_insn_detail_m68k(csh handle, cs_insn *ins) -{ - cs_m68k* m68k; - cs_detail* detail; - int i; - - // detail can be NULL on "data" instruction if SKIPDATA option is turned ON - if (ins->detail == NULL) - return; - - detail = ins->detail; - m68k = &detail->m68k; - if (m68k->op_count) - printf("\top_count: %u\n", m68k->op_count); - - print_read_write_regs(detail, handle); - - printf("\tgroups_count: %u\n", detail->groups_count); - - for (i = 0; i < m68k->op_count; i++) { - cs_m68k_op* op = &(m68k->operands[i]); - - switch((int)op->type) { - default: - break; - case M68K_OP_REG: - printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); - break; - case M68K_OP_IMM: - printf("\t\toperands[%u].type: IMM = 0x%x\n", i, (int)op->imm); - break; - case M68K_OP_MEM: - printf("\t\toperands[%u].type: MEM\n", i); - if (op->mem.base_reg != M68K_REG_INVALID) - printf("\t\t\toperands[%u].mem.base: REG = %s\n", - i, cs_reg_name(handle, op->mem.base_reg)); - if (op->mem.index_reg != M68K_REG_INVALID) { - printf("\t\t\toperands[%u].mem.index: REG = %s\n", - i, cs_reg_name(handle, op->mem.index_reg)); - printf("\t\t\toperands[%u].mem.index: size = %c\n", - i, op->mem.index_size ? 'l' : 'w'); - } - if (op->mem.disp != 0) - printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); - if (op->mem.scale != 0) - printf("\t\t\toperands[%u].mem.scale: %d\n", i, op->mem.scale); - - printf("\t\taddress mode: %s\n", s_addressing_modes[op->address_mode]); - break; - case M68K_OP_FP_SINGLE: - printf("\t\toperands[%u].type: FP_SINGLE\n", i); - printf("\t\t\toperands[%u].simm: %f\n", i, op->simm); - break; - case M68K_OP_FP_DOUBLE: - printf("\t\toperands[%u].type: FP_DOUBLE\n", i); - printf("\t\t\toperands[%u].dimm: %lf\n", i, op->dimm); - break; - } - } -} - From a2d62f92bfc214b4f8788239cb92f2ca8fc67da9 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Tue, 8 Nov 2016 10:28:40 +0800 Subject: [PATCH 04/10] x86: fix sysexit in #806 --- arch/X86/X86ATTInstPrinter.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c index 46d97e9781..86da083cd9 100644 --- a/arch/X86/X86ATTInstPrinter.c +++ b/arch/X86/X86ATTInstPrinter.c @@ -799,6 +799,15 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info) else printInstruction(MI, OS, info); + // HACK TODO: fix this in machine description + switch(MI->flat_insn->id) { + default: break; + case X86_INS_SYSEXIT: + SStream_Init(OS); + SStream_concat0(OS, "sysexit"); + break; + } + if (MI->has_imm) { // if op_count > 1, then this operand's size is taken from the destination op if (MI->flat_insn->detail->x86.op_count > 1) { From c86e78fce7831116f7ee912db1d652e83651a165 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Tue, 8 Nov 2016 10:56:18 +0800 Subject: [PATCH 05/10] x86: fix movw instruction in #789 --- arch/X86/X86ATTInstPrinter.c | 2 +- arch/X86/X86GenAsmWriter.inc | 11 +++++++---- cstool/Makefile | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c index 86da083cd9..5fd8d1c0ad 100644 --- a/arch/X86/X86ATTInstPrinter.c +++ b/arch/X86/X86ATTInstPrinter.c @@ -728,7 +728,7 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O) } } } else { - SStream_concat0(O, "0"); + //SStream_concat0(O, "0"); } } diff --git a/arch/X86/X86GenAsmWriter.inc b/arch/X86/X86GenAsmWriter.inc index 6e6ae6f40b..536d22c85e 100644 --- a/arch/X86/X86GenAsmWriter.inc +++ b/arch/X86/X86GenAsmWriter.inc @@ -14168,12 +14168,15 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI) uint64_t Bits2 = OpInfo2[opcode]; uint64_t Bits = (Bits2 << 32) | Bits1; // assert(Bits != 0 && "Cannot print this instruction."); - if (!X86_lockrep(MI, O)) + if (!X86_lockrep(MI, O)) { #ifndef CAPSTONE_DIET - SStream_concat0(O, AsmStrs+(Bits & 16383)-1); -#else - ; + // HACK TODO + if (opcode == X86_MOV32sm) { + SStream_concat0(O, "movw\t"); + } else + SStream_concat0(O, AsmStrs+(Bits & 16383)-1); #endif + } // Fragment 0 encoded into 7 bits for 79 unique commands. diff --git a/cstool/Makefile b/cstool/Makefile index be2c05cae8..450ac1ba3b 100644 --- a/cstool/Makefile +++ b/cstool/Makefile @@ -24,7 +24,7 @@ else endif clean: - ${RM} -rf *.o cstool + ${RM} -rf *.o $(TARGET) %.o: %.c ifeq ($(V),0) From 08b0e46a4c253d5c3974f205f4576d163b18ac00 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Tue, 8 Nov 2016 11:28:09 +0800 Subject: [PATCH 06/10] x86: fix (AT&T) ROL instruction in issue #804 --- arch/X86/X86GenAsmWriter.inc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/arch/X86/X86GenAsmWriter.inc b/arch/X86/X86GenAsmWriter.inc index 536d22c85e..720c01cc3a 100644 --- a/arch/X86/X86GenAsmWriter.inc +++ b/arch/X86/X86GenAsmWriter.inc @@ -14171,10 +14171,17 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI) if (!X86_lockrep(MI, O)) { #ifndef CAPSTONE_DIET // HACK TODO - if (opcode == X86_MOV32sm) { - SStream_concat0(O, "movw\t"); - } else - SStream_concat0(O, AsmStrs+(Bits & 16383)-1); + switch(opcode) { + default: + SStream_concat0(O, AsmStrs+(Bits & 16383)-1); + break; + case X86_MOV32sm: + SStream_concat0(O, "movw\t"); + break; + case X86_ROL32r1: + SStream_concat0(O, "rol\t$1, "); + break; + } #endif } From c19af63e538d9d18d5029c9d36c11538fe4fa1d0 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Tue, 8 Nov 2016 11:39:10 +0800 Subject: [PATCH 07/10] x86: fix (AT&T) instruction lgs for issue #805 --- arch/X86/X86GenAsmWriter.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/X86/X86GenAsmWriter.inc b/arch/X86/X86GenAsmWriter.inc index 720c01cc3a..b7afa1e8aa 100644 --- a/arch/X86/X86GenAsmWriter.inc +++ b/arch/X86/X86GenAsmWriter.inc @@ -14181,6 +14181,9 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI) case X86_ROL32r1: SStream_concat0(O, "rol\t$1, "); break; + case X86_LGS64rm: + SStream_concat0(O, "lgs\t"); + break; } #endif } From 8308ace3a0393d9742515019d11ba4254b1d3951 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Tue, 8 Nov 2016 11:46:21 +0800 Subject: [PATCH 08/10] x86: fix (AT&T) instruction SLDT for issue #807 --- arch/X86/X86GenAsmWriter.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/X86/X86GenAsmWriter.inc b/arch/X86/X86GenAsmWriter.inc index b7afa1e8aa..6d7bd21f81 100644 --- a/arch/X86/X86GenAsmWriter.inc +++ b/arch/X86/X86GenAsmWriter.inc @@ -14184,6 +14184,9 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI) case X86_LGS64rm: SStream_concat0(O, "lgs\t"); break; + case X86_SLDT64m: + SStream_concat0(O, "sldt\t"); + break; } #endif } From 04ec1815bd896125742a6a2be83092303aa95765 Mon Sep 17 00:00:00 2001 From: b33f Date: Fri, 11 Nov 2016 15:11:00 +0100 Subject: [PATCH 09/10] PowerShell binding (#803) * Binding.README * Binding.README * Binding.README * Binding.README.Ps1 * Binding.PowerShell-Script Added script to generate compressed DLL output & update for README * PowerShell.Binding-Rework A rework of the pull request based on feedback for the same pull request in Keystone * +Get-CapstoneDisassembly Reworked according to the module in Keystone * Revert constant generation + Quality of service change --- bindings/README | 4 + bindings/powershell/Capstone/Capstone.psd1 | 25 + bindings/powershell/Capstone/Capstone.psm1 | 442 ++++++++++++++++++ .../Capstone/Lib/Capstone/.gitignore | 0 bindings/powershell/README.md | 30 ++ 5 files changed, 501 insertions(+) create mode 100755 bindings/powershell/Capstone/Capstone.psd1 create mode 100755 bindings/powershell/Capstone/Capstone.psm1 create mode 100644 bindings/powershell/Capstone/Lib/Capstone/.gitignore create mode 100755 bindings/powershell/README.md diff --git a/bindings/README b/bindings/README index 64bd090cbc..b481d2205c 100644 --- a/bindings/README +++ b/bindings/README @@ -51,3 +51,7 @@ More bindings created & maintained by the community are available as followings. https://github.com/mattifestation/capstone +- PowerShell binding (by Ruben Boonen). + + https://github.com/aquynh/capstone/tree/master/bindings/powershell + diff --git a/bindings/powershell/Capstone/Capstone.psd1 b/bindings/powershell/Capstone/Capstone.psd1 new file mode 100755 index 0000000000..f7b1f4c3fc --- /dev/null +++ b/bindings/powershell/Capstone/Capstone.psd1 @@ -0,0 +1,25 @@ +@{ +# Script module or binary module file associated with this manifest. +ModuleToProcess = 'Capstone.psm1' + +# Version number of this module. +ModuleVersion = '0.0.0.1' + +# ID used to uniquely identify this module +GUID = 'd34db33f-9958-436d-a2d8-a77844a2bda5' + +# Author of this module +Author = 'Ruben Boonen' + +# Copyright statement for this module +Copyright = 'BSD 3-Clause' + +# Description of the functionality provided by this module +Description = 'Capstone Engine Binding Module' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '2.0' + +# Functions to export from this module +FunctionsToExport = '*' +} diff --git a/bindings/powershell/Capstone/Capstone.psm1 b/bindings/powershell/Capstone/Capstone.psm1 new file mode 100755 index 0000000000..035a3bb38a --- /dev/null +++ b/bindings/powershell/Capstone/Capstone.psm1 @@ -0,0 +1,442 @@ +function Get-CapstoneDisassembly { +<# +.SYNOPSIS + Powershell wrapper for Capstone (using inline C#). + +.DESCRIPTION + Author: Ruben Boonen (@FuzzySec) + License: BSD 3-Clause + Required Dependencies: None + Optional Dependencies: None + +.PARAMETER Architecture + Architecture type. + +.PARAMETER Mode + Mode type. + +.PARAMETER Bytes + Byte array to be disassembled. + +.PARAMETER Syntax + Syntax for output assembly. + +.PARAMETER Address + Assign address for the first instruction to be disassembled. + +.PARAMETER Detailed + Return detailed output. + +.PARAMETER Version + Print ASCII version banner. + +.EXAMPLE + + C:\PS> $Bytes = [Byte[]] @( 0x10, 0xf1, 0x10, 0xe7, 0x11, 0xf2, 0x31, 0xe7, 0xdc, 0xa1, 0x2e, 0xf3, 0xe8, 0x4e, 0x62, 0xf3 ) + C:\PS> Get-CapstoneDisassembly -Architecture CS_ARCH_ARM -Mode CS_MODE_ARM -Bytes $Bytes + + sdiv r0, r0, r1 + udiv r1, r1, r2 + vbit q5, q15, q6 + vcgt.f32 q10, q9, q12 + +.EXAMPLE + + # Detailed mode & ATT syntax + C:\PS> $Bytes = [Byte[]] @( 0xB8, 0x0A, 0x00, 0x00, 0x00, 0xF7, 0xF3 ) + C:\PS> Get-CapstoneDisassembly -Architecture CS_ARCH_X86 -Mode CS_MODE_32 -Bytes $Bytes -Syntax ATT -Detailed + + Size : 5 + Address : 0x100000 + Mnemonic : movl + Operands : $0xa, %eax + Bytes : {184, 10, 0, 0...} + RegRead : + RegWrite : + + Size : 2 + Address : 0x100005 + Mnemonic : divl + Operands : %ebx + Bytes : {247, 243, 0, 0...} + RegRead : {eax, edx} + RegWrite : {eax, edx, eflags} + +.EXAMPLE + + # Get-CapstoneDisassembly emits objects + C:\PS> $Bytes = [Byte[]] @( 0xB8, 0x0A, 0x00, 0x00, 0x00, 0xF7, 0xF3 ) + C:\PS> $Object = Get-CapstoneDisassembly -Architecture CS_ARCH_X86 -Mode CS_MODE_32 -Bytes $Bytes -Detailed + C:\PS> $Object |Select-Object Size,Mnemonic,Operands + + Size Mnemonic Operands + ---- -------- -------- + 5 mov eax, 0xa + 2 div ebx + +#> + + param( + [Parameter(ParameterSetName='Capstone', Mandatory = $True)] + [ValidateSet( + 'CS_ARCH_ARM', + 'CS_ARCH_ARM64', + 'CS_ARCH_MIPS', + 'CS_ARCH_X86', + 'CS_ARCH_PPC', + 'CS_ARCH_SPARC', + 'CS_ARCH_SYSZ', + 'CS_ARCH_XCORE', + 'CS_ARCH_MAX', + 'CS_ARCH_ALL') + ] + [String]$Architecture, + + [Parameter(ParameterSetName='Capstone', Mandatory = $True)] + [ValidateSet( + 'CS_MODE_LITTLE_ENDIAN', + 'CS_MODE_ARM', + 'CS_MODE_16', + 'CS_MODE_32', + 'CS_MODE_64', + 'CS_MODE_THUMB', + 'CS_MODE_MCLASS', + 'CS_MODE_V8', + 'CS_MODE_MICRO', + 'CS_MODE_MIPS3', + 'CS_MODE_MIPS32R6', + 'CS_MODE_MIPSGP64', + 'CS_MODE_V9', + 'CS_MODE_BIG_ENDIAN', + 'CS_MODE_MIPS32', + 'CS_MODE_MIPS64') + ] + [String]$Mode, + + [Parameter(ParameterSetName='Capstone', Mandatory = $True)] + [ValidateNotNullOrEmpty()] + [Byte[]]$Bytes, + + [Parameter(ParameterSetName='Capstone', Mandatory = $False)] + [ValidateSet( + 'Intel', + 'ATT') + ] + [String]$Syntax = "Intel", + + [Parameter(ParameterSetName='Capstone', Mandatory = $False)] + [Int]$Address = 0x100000, + + [Parameter(ParameterSetName='Capstone', Mandatory = $False)] + [switch]$Detailed = $null, + + [Parameter(ParameterSetName='Version', Mandatory = $False)] + [switch]$Version = $null + ) + + # Compatibility for PS v2 / PS v3+ + if(!$PSScriptRoot) { + $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent + } + + # Set the capstone DLL path + $DllPath = $($PSScriptRoot + '\Lib\Capstone\capstone.dll').Replace('\','\\') + + # Make sure the user didn't forget the DLL + if (![IO.File]::Exists($DllPath)) { + echo "`n[!] Missing Capstone DLL" + echo "[>] Quitting!`n" + Return + } + + # Inline C# to parse the unmanaged capstone DLL + Add-Type -TypeDefinition @" + using System; + using System.Diagnostics; + using System.Runtime.InteropServices; + using System.Security.Principal; + + [StructLayout(LayoutKind.Sequential)] + public struct cs_insn + { + public uint id; + public ulong address; + public ushort size; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] bytes; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] + public string mnemonic; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 160)] + public string operands; + public IntPtr detail; + } + + /// Partial, only architecture-independent internal data + [StructLayout(LayoutKind.Sequential)] + public struct cs_detail + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] + public byte[] regs_read; + public byte regs_read_count; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] regs_write; + public byte regs_write_count; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] groups; + public byte groups_count; + } + + public enum cs_err : int + { + CS_ERR_OK = 0, /// No error: everything was fine + CS_ERR_MEM, /// Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter() + CS_ERR_ARCH, /// Unsupported architecture: cs_open() + CS_ERR_HANDLE, /// Invalid handle: cs_op_count(), cs_op_index() + CS_ERR_CSH, /// Invalid csh argument: cs_close(), cs_errno(), cs_option() + CS_ERR_MODE, /// Invalid/unsupported mode: cs_open() + CS_ERR_OPTION, /// Invalid/unsupported option: cs_option() + CS_ERR_DETAIL, /// Information is unavailable because detail option is OFF + CS_ERR_MEMSETUP, /// Dynamic memory management uninitialized (see CS_OPT_MEM) + CS_ERR_VERSION, /// Unsupported version (bindings) + CS_ERR_DIET, /// Access irrelevant data in "diet" engine + CS_ERR_SKIPDATA, /// Access irrelevant data for "data" instruction in SKIPDATA mode + CS_ERR_X86_ATT, /// X86 AT&T syntax is unsupported (opt-out at compile time) + CS_ERR_X86_INTEL, /// X86 Intel syntax is unsupported (opt-out at compile time) + } + public enum cs_arch : int + { + CS_ARCH_ARM = 0, /// ARM architecture (including Thumb, Thumb-2) + CS_ARCH_ARM64, /// ARM-64, also called AArch64 + CS_ARCH_MIPS, /// Mips architecture + CS_ARCH_X86, /// X86 architecture (including x86 & x86-64) + CS_ARCH_PPC, /// PowerPC architecture + CS_ARCH_SPARC, /// Sparc architecture + CS_ARCH_SYSZ, /// SystemZ architecture + CS_ARCH_XCORE, /// XCore architecture + CS_ARCH_MAX, + CS_ARCH_ALL = 0xFFFF, /// All architectures - for cs_support() + } + public enum cs_mode : int + { + CS_MODE_LITTLE_ENDIAN = 0, /// little-endian mode (default mode) + CS_MODE_ARM = 0, /// 32-bit ARM + CS_MODE_16 = 1 << 1, /// 16-bit mode (X86) + CS_MODE_32 = 1 << 2, /// 32-bit mode (X86) + CS_MODE_64 = 1 << 3, /// 64-bit mode (X86, PPC) + CS_MODE_THUMB = 1 << 4, /// ARM's Thumb mode, including Thumb-2 + CS_MODE_MCLASS = 1 << 5, /// ARM's Cortex-M series + CS_MODE_V8 = 1 << 6, /// ARMv8 A32 encodings for ARM + CS_MODE_MICRO = 1 << 4, /// MicroMips mode (MIPS) + CS_MODE_MIPS3 = 1 << 5, /// Mips III ISA + CS_MODE_MIPS32R6 = 1 << 6, /// Mips32r6 ISA + CS_MODE_MIPSGP64 = 1 << 7, /// General Purpose Registers are 64-bit wide (MIPS) + CS_MODE_V9 = 1 << 4, /// SparcV9 mode (Sparc) + CS_MODE_BIG_ENDIAN = 1 << 31, /// big-endian mode + CS_MODE_MIPS32 = CS_MODE_32, /// Mips32 ISA (Mips) + CS_MODE_MIPS64 = CS_MODE_64, /// Mips64 ISA (Mips) + } + + public static class Capstone + { + [DllImport("$DllPath")] + public static extern cs_err cs_open( + cs_arch arch, + cs_mode mode, + ref IntPtr handle); + + [DllImport("$DllPath")] + public static extern UInt32 cs_disasm( + IntPtr handle, + byte[] code, + int code_size, + ulong address, + int count, + ref IntPtr insn); + + [DllImport("$DllPath")] + public static extern bool cs_free( + IntPtr insn, + int count); + + [DllImport("$DllPath")] + public static extern cs_err cs_close( + IntPtr handle); + + [DllImport("$DllPath")] + public static extern cs_err cs_option( + IntPtr handle, + int type, + int value); + + [DllImport("$DllPath", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr cs_reg_name( + IntPtr handle, + uint reg_id); + + [DllImport("$DllPath")] + public static extern int cs_version( + uint major, + uint minor); + } +"@ + + if ($Version){ + $VerCount = [System.BitConverter]::GetBytes($([Capstone]::cs_version($null,$null))) + $Banner = @" + + (((; + (; "((((\ + ;((((((; "((((; + ((((""\(((( "(((( + ((((" ((\ "(((( "(((\ + ;(((/ ((((((( "(((( \((( + ((((" (((* "(((( \(((;"(((\ + ((((";((("/(( \(((;"(((\"(((\ + (((( (((( ((((" "(((\ ((() (((\ + ;((("(((( (((* **"" ((()"(((; + (((" ((( (((( ((((((((((((((:*((( + (((( (((*)((( ********"""" ;;(((((; + (((* ((( (((((((((((((((((((((*"" ( + ((("(((( """***********"""" ;;((((( + "" (((((((((((((((((((((((((((*"" + """****(((((****""" + + -=[Capstone Engine v$($VerCount[1]).$($VerCount[0])]=- + +"@ + # Mmm ASCII version banner! + $Banner + Return + } + + # Disasm Handle + $DisAsmHandle = [IntPtr]::Zero + + # Initialize Capstone with cs_open() + $CallResult = [Capstone]::cs_open($Architecture,$Mode,[ref]$DisAsmHandle) + if ($CallResult -ne "CS_ERR_OK") { + if ($CallResult -eq "CS_ERR_MODE"){ + echo "`n[!] Invalid Architecture/Mode combination" + echo "[>] Quitting..`n" + } else { + echo "`n[!] cs_open error: $CallResult" + echo "[>] Quitting..`n" + } + Return + } + + # Set disassembly syntax + #--- + # cs_opt_type -> CS_OPT_SYNTAX = 1 + #--- + # cs_opt_value -> CS_OPT_SYNTAX_INTEL = 1 + # -> CS_OPT_SYNTAX_ATT = 2 + if ($Syntax -eq "Intel") { + $CS_OPT_SYNTAX = 1 + } else { + $CS_OPT_SYNTAX = 2 + } + $CallResult = [Capstone]::cs_option($DisAsmHandle, 1, $CS_OPT_SYNTAX) + if ($CallResult -ne "CS_ERR_OK") { + echo "`n[!] cs_option error: $CallResult" + echo "[>] Quitting..`n" + $CallResult = [Capstone]::cs_close($DisAsmHandle) + Return + } + + # Set disassembly detail + #--- + # cs_opt_type -> CS_OPT_DETAIL = 2 + #--- + # cs_opt_value -> CS_OPT_ON = 3 + # -> CS_OPT_OFF = 0 + if ($Detailed) { + $CS_OPT = 3 + } else { + $CS_OPT = 0 + } + $CallResult = [Capstone]::cs_option($DisAsmHandle, 2, $CS_OPT) + if ($CallResult -ne "CS_ERR_OK") { + echo "`n[!] cs_option error: $CallResult" + echo "[>] Quitting..`n" + $CallResult = [Capstone]::cs_close($DisAsmHandle) + Return + } + + # Out Buffer Handle + $InsnHandle = [IntPtr]::Zero + + # Disassemble bytes + $Count = [Capstone]::cs_disasm($DisAsmHandle, $Bytes, $Bytes.Count, $Address, 0, [ref]$InsnHandle) + + if ($Count -gt 0) { + # Result Array + $Disasm = @() + + # Result struct + $cs_insn = New-Object cs_insn + $cs_insn_size = [System.Runtime.InteropServices.Marshal]::SizeOf($cs_insn) + $cs_insn = $cs_insn.GetType() + + # Result detail struct + $cs_detail = New-Object cs_detail + $cs_detail = $cs_detail.GetType() + + # Result buffer offset + $BuffOffset = $InsnHandle.ToInt64() + + for ($i=0; $i -lt $Count; $i++) { + # Cast Offset to cs_insn + $InsnPointer = New-Object System.Intptr -ArgumentList $BuffOffset + $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($InsnPointer,[type]$cs_insn) + + if ($CS_OPT -eq 0) { + $HashTable = @{ + Address = echo "0x$("{0:X}" -f $Cast.address)" + Instruction = echo "$($Cast.mnemonic) $($Cast.operands)" + } + $Object = New-Object PSObject -Property $HashTable + $Disasm += $Object |Select-Object Address,Instruction + } else { + $DetailCast = [system.runtime.interopservices.marshal]::PtrToStructure($Cast.detail,[type]$cs_detail) + if($DetailCast.regs_read_count -gt 0) { + $RegRead = @() + for ($r=0; $r -lt $DetailCast.regs_read_count; $r++) { + $NamePointer = [Capstone]::cs_reg_name($DisAsmHandle, $DetailCast.regs_read[$r]) + $RegRead += [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($NamePointer) + } + } + if ($DetailCast.regs_write_count -gt 0) { + $RegWrite = @() + for ($r=0; $r -lt $DetailCast.regs_write_count; $r++) { + $NamePointer = [Capstone]::cs_reg_name($DisAsmHandle, $DetailCast.regs_write[$r]) + $RegWrite += [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($NamePointer) + } + } + $HashTable = @{ + Address = echo "0x$("{0:X}" -f $Cast.address)" + Mnemonic = $Cast.mnemonic + Operands = $Cast.operands + Bytes = $Cast.bytes + Size = $Cast.size + RegRead = $RegRead + RegWrite = $RegWrite + } + $Object = New-Object PSObject -Property $HashTable + $Disasm += $Object |Select-Object Size,Address,Mnemonic,Operands,Bytes,RegRead,RegWrite + } + $BuffOffset = $BuffOffset + $cs_insn_size + } + } else { + echo "[!] Disassembly Failed" + echo "[>] Quitting.." + $CallResult = [Capstone]::cs_close($DisAsmHandle) + Return + } + + # Print result + $Disasm + + # Free Buffer Handle + $CallResult = [Capstone]::cs_free($InsnHandle, $Count) +} \ No newline at end of file diff --git a/bindings/powershell/Capstone/Lib/Capstone/.gitignore b/bindings/powershell/Capstone/Lib/Capstone/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/bindings/powershell/README.md b/bindings/powershell/README.md new file mode 100755 index 0000000000..1197a318fd --- /dev/null +++ b/bindings/powershell/README.md @@ -0,0 +1,30 @@ +This documentation explains how to install & use the PowerShell binding for Capstone. + + +Install +------ + +Compile the relevant version (x86/x64) of `capstone.dll` and place it in +`./Capstone/Lib/Capstone/`. + +Alternatively, pre-compiled DLL’s can be obtained from the Capstone homepage +at http://capstone-engine.org/download + + +Usage +----- + +To use the PowerShell binding, the entire Capstone folder should be added to +one of the PowerShell module directories: + + # Global PSModulePath path + %Windir%\System32\WindowsPowerShell\v1.0\Modules + + # User PSModulePath path + %UserProfile%\Documents\WindowsPowerShell\Modules + +Once this is done the module can be initialized by typing “Import-Module Capstone” +in a new PowerShell terminal. Further information on the usage of the binding +can be obtained with the following command: + + Get-Help Get-CapstoneDisassembly -Full \ No newline at end of file From d909de00ca32c0e45ab3e6e905f5b851791d0799 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 11 Nov 2016 23:14:23 +0900 Subject: [PATCH 10/10] update CREDITS.TXT --- CREDITS.TXT | 1 + README | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CREDITS.TXT b/CREDITS.TXT index 3bb69b2010..e13d4512e1 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -61,3 +61,4 @@ Xipiter LLC: Capstone logo redesigned. Satoshi Tanda: Support Windows kernel driver. Tang Yuhang: cstool. Andrew Dutcher: better Python setup. +Ruben Boonen: PowerShell binding. diff --git a/README b/README index 5ceb761ecd..d6234aaee5 100644 --- a/README +++ b/README @@ -14,9 +14,10 @@ Capstone offers some unparalleled features: - Provide semantics of the disassembled instruction, such as list of implicit registers read & written. -- Implemented in pure C language, with lightweight bindings for Emacs, Haskell, Perl, Python, - Ruby, C#, NodeJS, Java, GO, C++, OCaml, Lua, Rust, Delphi, Free Pascal & Vala - ready either in main code, or provided externally by the community). +- Implemented in pure C language, with lightweight bindings for PowerShell, + Emacs, Haskell, Perl, Python, Ruby, C#, NodeJS, Java, GO, C++, OCaml, Lua, + Rust, Delphi, Free Pascal & Vala ready either in main code, or provided + externally by the community). - Native support for all popular platforms: Windows, Mac OSX, iOS, Android, Linux, *BSD, Solaris, etc.