diff --git a/.gitignore b/.gitignore index c69f5b2a4a..0ad6684654 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,8 @@ ipch/ *.opensdf *.suo *.user +*.VC.db +*.VC.opendb # Xcode xcode/Capstone.xcodeproj/xcuserdata diff --git a/CMakeLists.txt b/CMakeLists.txt index a0e8eea5c6..36e70616cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,6 @@ set(HEADERS_ENGINE MCInst.h MCInstrDesc.h MCRegisterInfo.h - myinttypes.h SStream.h utils.h ) diff --git a/COMPILE_MSVC.TXT b/COMPILE_MSVC.TXT index e9de12a277..31748be7f5 100644 --- a/COMPILE_MSVC.TXT +++ b/COMPILE_MSVC.TXT @@ -7,12 +7,15 @@ To compile Capstone with CMake, see COMPILE_CMAKE.TXT *-*-*-*-*-* -Capstone requires no prerequisite packages, so it is easy to compile & install. -Open the Visual Studio solution "msvc/capstone.sln" and follow the instructions -below. +Capstone requires no prerequisite packages with default configurations, so it is +easy to compile & install. Open the Visual Studio solution "msvc/capstone.sln" +and follow the instructions below. NOTE: This requires Visual Studio 2010 or newer versions. +If you wish to embed Capstone in a kernel driver, Visual Studio 2013 or newer +versions, and Windows Driver Kit 8.1 Update 1 or newer versions are required. + (0) Tailor Capstone to your need. @@ -60,8 +63,46 @@ NOTE: This requires Visual Studio 2010 or newer versions. - Choose the configuration and the platform you want: Release/Debug & Win32/Win64. - Build only the libraries, or the libraries along with all the tests. + - "capstone_static_winkernel" is for compiling Capstone for a driver and + "test_winkernel" is a test for a driver, and those are excluded from build by + default. To compile them, open the Configuration Manager through the [Build] + menu and check "Build" check boxes for those project. (2) You can make sure the prior steps successfully worked by launching one of the testing binary (test*.exe). + + The testing binary for a driver "test_winkernel.sys" is made up of all tests for + supported architectures configured with the step (0) along side its own tests. + Below explains a procedure to run the test driver and check test results. + + On the x64 platform, the test signing mode has to be enabled to install the test + driver. To do it, open the command prompt with the administrator privileges and + type the following command, and then restart the system to activate the change: + + >bcdedit /set testsigning on + + Test results from the test driver is sent to kernel debug buffer. In order to + see those results, download DebugView and run it with the administrator + privileges, then check [Capture Kernel] through the [Capture] menu. + + DebugView: https://technet.microsoft.com/en-us/sysinternals/debugview.aspx + + To install and uninstall the driver, use the 'sc' command. For installing and + executing test_winkernel.sys, execute the following commands with the + administrator privileges: + + >sc create test_winkernel type= kernel binPath= + [SC] CreateService SUCCESS + + >sc start test_winkernel + [SC] StartService FAILED 995: + + The I/O operation has been aborted because of either a thread exit or an application request. + + To uninstall the driver, execute the following commands with the administrator + privileges: + + >sc delete test_winkernel + >bcdedit /deletevalue testsigning diff --git a/CREDITS.TXT b/CREDITS.TXT index 3ef516535c..bf0d25dd20 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -61,3 +61,5 @@ Adel Gadllah, Francisco Alonso & Stefan Cornelius: RPM package. Felix Gröbert (Google): fuzz testing harness. Daniel Collin & Nicolas Planel: M68K architecture. Pranith Kumar: Explicit registers accessed for Arm64. +Xipiter LLC: Capstone logo redesigned. +Satoshi Tanda: Support Windows kernel driver. diff --git a/HACK.TXT b/HACK.TXT index db373e271b..19099bbceb 100644 --- a/HACK.TXT +++ b/HACK.TXT @@ -21,6 +21,7 @@ Capstone source is organized as followings. ├── include <- API headers in C language (*.h) ├── msvc <- Microsoft Visual Studio support (for Windows compile) ├── packages <- Packages for Linux/OSX/BSD. +├── windows <- Windows support (for Windows kernel driver compile) ├── suite <- Development test tools - for Capstone developers only ├── tests <- Test code (in C language) └── xcode <- Xcode support (for MacOSX compile) diff --git a/LEB128.h b/LEB128.h index 2bd56960cf..a5fd9a3fdc 100644 --- a/LEB128.h +++ b/LEB128.h @@ -18,7 +18,9 @@ #ifndef CS_LLVM_SUPPORT_LEB128_H #define CS_LLVM_SUPPORT_LEB128_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif /// Utility function to decode a ULEB128 value. static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n) diff --git a/MCInst.h b/MCInst.h index 2aae7cda80..bd2a52f8ce 100644 --- a/MCInst.h +++ b/MCInst.h @@ -19,7 +19,9 @@ #ifndef CS_MCINST_H #define CS_MCINST_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "include/capstone/capstone.h" diff --git a/MCInstrDesc.h b/MCInstrDesc.h index 8971ae487f..9e265d1d02 100644 --- a/MCInstrDesc.h +++ b/MCInstrDesc.h @@ -18,7 +18,10 @@ #ifndef CS_LLVM_MC_MCINSTRDESC_H #define CS_LLVM_MC_MCINSTRDESC_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "capstone/platform.h" //===----------------------------------------------------------------------===// diff --git a/MCRegisterInfo.h b/MCRegisterInfo.h index 3bf6178fca..01bc6a75ca 100644 --- a/MCRegisterInfo.h +++ b/MCRegisterInfo.h @@ -19,7 +19,10 @@ #ifndef CS_LLVM_MC_MCREGISTERINFO_H #define CS_LLVM_MC_MCREGISTERINFO_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "capstone/platform.h" /// An unsigned integer type large enough to represent all physical registers, diff --git a/MathExtras.h b/MathExtras.h index 19cbb26329..0d98616e90 100644 --- a/MathExtras.h +++ b/MathExtras.h @@ -17,7 +17,9 @@ #ifndef CS_LLVM_SUPPORT_MATHEXTRAS_H #define CS_LLVM_SUPPORT_MATHEXTRAS_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #ifdef _MSC_VER # include diff --git a/SStream.c b/SStream.c index 96fd85cb01..d12da5e2ab 100644 --- a/SStream.c +++ b/SStream.c @@ -1,7 +1,9 @@ /* Capstone Disassembly Engine */ /* By Nguyen Anh Quynh , 2013-2015 */ +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include #if defined(CAPSTONE_HAS_OSXKERNEL) #include @@ -10,9 +12,10 @@ #endif #include +#include + #include "SStream.h" #include "cs_priv.h" -#include "myinttypes.h" #include "utils.h" #ifdef _MSC_VER diff --git a/arch/AArch64/AArch64BaseInfo.c b/arch/AArch64/AArch64BaseInfo.c index e2b3436928..26eb786aa8 100644 --- a/arch/AArch64/AArch64BaseInfo.c +++ b/arch/AArch64/AArch64BaseInfo.c @@ -629,7 +629,7 @@ void A64SysRegMapper_toString(A64SysRegMapper *S, uint32_t Bits, char *result) Op2S = utostr(Op2, false); //printf("Op1S: %s, CRnS: %s, CRmS: %s, Op2S: %s\n", Op1S, CRnS, CRmS, Op2S); - dummy = sprintf(result, "s%s_%s_c%s_c%s_%s", Op0S, Op1S, CRnS, CRmS, Op2S); + dummy = cs_snprintf(result, 128, "s3_%s_c%s_c%s_%s", Op1S, CRnS, CRmS, Op2S); (void)dummy; cs_mem_free(Op0S); diff --git a/arch/AArch64/AArch64BaseInfo.h b/arch/AArch64/AArch64BaseInfo.h index 2d6e046976..73859c12ea 100644 --- a/arch/AArch64/AArch64BaseInfo.h +++ b/arch/AArch64/AArch64BaseInfo.h @@ -21,7 +21,9 @@ #define CS_LLVM_AARCH64_BASEINFO_H #include +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include #ifndef __cplusplus diff --git a/arch/AArch64/AArch64Disassembler.c b/arch/AArch64/AArch64Disassembler.c index 87859a530c..e1654e2e9f 100644 --- a/arch/AArch64/AArch64Disassembler.c +++ b/arch/AArch64/AArch64Disassembler.c @@ -1165,9 +1165,9 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst, DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); MCOperand_CreateImm0(Inst, offset); - IsLoad = fieldFromInstruction(insn, 22, 1); + IsLoad = fieldFromInstruction(insn, 22, 1) != 0; IsIndexed = fieldFromInstruction(insn, 10, 2) != 0; - IsFP = fieldFromInstruction(insn, 26, 1); + IsFP = fieldFromInstruction(insn, 26, 1) != 0; // Cannot write back to a transfer register (but xzr != sp). if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn) @@ -1260,7 +1260,7 @@ static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn, unsigned Rn = fieldFromInstruction(insn, 5, 5); unsigned Rt2 = fieldFromInstruction(insn, 10, 5); int32_t offset = fieldFromInstruction(insn, 15, 7); - bool IsLoad = fieldFromInstruction(insn, 22, 1); + bool IsLoad = fieldFromInstruction(insn, 22, 1) != 0; unsigned Opcode = MCInst_getOpcode(Inst); bool NeedsDisjointWritebackTransfer = false; diff --git a/arch/AArch64/AArch64Disassembler.h b/arch/AArch64/AArch64Disassembler.h index a115140cb1..c669f4ef84 100644 --- a/arch/AArch64/AArch64Disassembler.h +++ b/arch/AArch64/AArch64Disassembler.h @@ -4,7 +4,9 @@ #ifndef CS_AARCH64_DISASSEMBLER_H #define CS_AARCH64_DISASSEMBLER_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "capstone/capstone.h" #include "../../MCRegisterInfo.h" diff --git a/arch/AArch64/AArch64InstPrinter.c b/arch/AArch64/AArch64InstPrinter.c index 1bb7ad0ba2..7c5a26d98a 100644 --- a/arch/AArch64/AArch64InstPrinter.c +++ b/arch/AArch64/AArch64InstPrinter.c @@ -16,7 +16,7 @@ #ifdef CAPSTONE_HAS_ARM64 -#include "../../myinttypes.h" +#include #include #include @@ -1656,7 +1656,7 @@ static void printSystemPStateField(MCInst *MI, unsigned OpNo, SStream *O) static void printSIMDType10Operand(MCInst *MI, unsigned OpNo, SStream *O) { - unsigned RawVal = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNo)); + uint8_t RawVal = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNo)); uint64_t Val = AArch64_AM_decodeAdvSIMDModImmType10(RawVal); SStream_concat(O, "#%#016llx", Val); if (MI->csh->detail) { diff --git a/arch/AArch64/AArch64Mapping.c b/arch/AArch64/AArch64Mapping.c index 5b9746c2ba..03d9eb4cf8 100644 --- a/arch/AArch64/AArch64Mapping.c +++ b/arch/AArch64/AArch64Mapping.c @@ -1049,26 +1049,26 @@ void AArch64_reg_access(const cs_insn *insn, switch((int)op->type) { case ARM64_OP_REG: if ((op->access & CS_AC_READ) && !arr_exist(regs_read, read_count, op->reg)) { - regs_read[read_count] = op->reg; + regs_read[read_count] = (uint16_t)op->reg; read_count++; } if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) { - regs_write[write_count] = op->reg; + regs_write[write_count] = (uint16_t)op->reg; write_count++; } break; case ARM_OP_MEM: // registers appeared in memory references always being read if ((op->mem.base != ARM64_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) { - regs_read[read_count] = op->mem.base; + regs_read[read_count] = (uint16_t)op->mem.base; read_count++; } if ((op->mem.index != ARM64_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) { - regs_read[read_count] = op->mem.index; + regs_read[read_count] = (uint16_t)op->mem.index; read_count++; } if ((arm64->writeback) && (op->mem.base != ARM64_REG_INVALID) && !arr_exist(regs_write, write_count, op->mem.base)) { - regs_write[write_count] = op->mem.base; + regs_write[write_count] = (uint16_t)op->mem.base; write_count++; } default: diff --git a/arch/ARM/ARMDisassembler.c b/arch/ARM/ARMDisassembler.c index 8e700b1e97..0390112c9a 100644 --- a/arch/ARM/ARMDisassembler.c +++ b/arch/ARM/ARMDisassembler.c @@ -15,7 +15,7 @@ #include #include #include -#include "../../myinttypes.h" +#include #include "ARMAddressingModes.h" #include "ARMBaseInfo.h" diff --git a/arch/ARM/ARMInstPrinter.c b/arch/ARM/ARMInstPrinter.c index 4f10cefb80..95ed9fbd1c 100644 --- a/arch/ARM/ARMInstPrinter.c +++ b/arch/ARM/ARMInstPrinter.c @@ -19,7 +19,7 @@ #include // DEBUG #include #include -#include "../../myinttypes.h" +#include #include "ARMInstPrinter.h" #include "ARMAddressingModes.h" @@ -1792,7 +1792,7 @@ static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O) if (MI->csh->detail) { if (MI->csh->doing_mem) { MI->flat_insn->detail->arm.op_count--; - MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].neon_lane = tmp; + MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].neon_lane = (int8_t)tmp; MI->ac_idx--; // consecutive operands share the same access right } else { MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM; diff --git a/arch/ARM/ARMMapping.c b/arch/ARM/ARMMapping.c index 642330e724..e6b27f267e 100644 --- a/arch/ARM/ARMMapping.c +++ b/arch/ARM/ARMMapping.c @@ -915,26 +915,26 @@ void ARM_reg_access(const cs_insn *insn, switch((int)op->type) { case ARM_OP_REG: if ((op->access & CS_AC_READ) && !arr_exist(regs_read, read_count, op->reg)) { - regs_read[read_count] = op->reg; + regs_read[read_count] = (uint16_t)op->reg; read_count++; } if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) { - regs_write[write_count] = op->reg; + regs_write[write_count] = (uint16_t)op->reg; write_count++; } break; case ARM_OP_MEM: // registers appeared in memory references always being read if ((op->mem.base != ARM_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) { - regs_read[read_count] = op->mem.base; + regs_read[read_count] = (uint16_t)op->mem.base; read_count++; } if ((op->mem.index != ARM_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) { - regs_read[read_count] = op->mem.index; + regs_read[read_count] = (uint16_t)op->mem.index; read_count++; } if ((arm->writeback) && (op->mem.base != ARM_REG_INVALID) && !arr_exist(regs_write, write_count, op->mem.base)) { - regs_write[write_count] = op->mem.base; + regs_write[write_count] = (uint16_t)op->mem.base; write_count++; } default: diff --git a/arch/M68K/M68KDisassembler.c b/arch/M68K/M68KDisassembler.c index a73a65b8b3..faaabc0aae 100644 --- a/arch/M68K/M68KDisassembler.c +++ b/arch/M68K/M68KDisassembler.c @@ -48,8 +48,12 @@ #include "M68KDisassembler.h" #ifndef DECL_SPEC +#ifdef _MSC_VER +#define DECL_SPEC __cdecl +#else #define DECL_SPEC -#endif +#endif // _MSC_VER +#endif // DECL_SPEC /* ======================================================================== */ /* ============================ GENERAL DEFINES =========================== */ @@ -458,7 +462,7 @@ void get_ea_mode_op(m68k_info *info, cs_m68k_op* op, uint instruction, uint size /* address register indirect with displacement*/ op->address_mode = M68K_AM_REGI_ADDR_DISP; op->mem.base_reg = M68K_REG_A0 + (instruction & 7); - op->mem.disp = read_imm_16(info); + op->mem.disp = (uint16_t)read_imm_16(info); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: @@ -481,7 +485,7 @@ void get_ea_mode_op(m68k_info *info, cs_m68k_op* op, uint instruction, uint size case 0x3a: /* program counter with displacement */ op->address_mode = M68K_AM_PCI_DISP; - op->mem.disp = read_imm_16(info); + op->mem.disp = (uint16_t)read_imm_16(info); break; case 0x3b: @@ -517,7 +521,7 @@ static cs_m68k* build_init_op(m68k_info *info, int opcode, int count, int size) ext = &info->extension; - ext->op_count = count; + ext->op_count = (uint8_t)count; ext->op_size.type = M68K_SIZE_TYPE_CPU; ext->op_size.cpu_size = size; @@ -836,7 +840,7 @@ static void build_bitfield_ins(m68k_info *info, int opcode, int has_d_arg) if (BIT_5(extension)) width = extension & 7; else - width = g_5bit_data_table[extension & 31]; + width = (uint8_t)g_5bit_data_table[extension & 31]; if (has_d_arg) { ext->op_count = 2; @@ -1100,7 +1104,7 @@ static void build_movep_re(m68k_info *info, int size) op1->address_mode = M68K_AM_REGI_ADDR_DISP; op1->type = M68K_OP_MEM; op1->mem.base_reg = M68K_REG_A0 + (info->ir & 7); - op1->mem.disp = read_imm_16(info); + op1->mem.disp = (uint16_t)read_imm_16(info); } static void build_movep_er(m68k_info *info, int size) @@ -1115,7 +1119,7 @@ static void build_movep_er(m68k_info *info, int size) op0->address_mode = M68K_AM_REGI_ADDR_DISP; op0->type = M68K_OP_MEM; op0->mem.base_reg = M68K_REG_A0 + (info->ir & 7); - op0->mem.disp = read_imm_16(info); + op0->mem.disp = (uint16_t)read_imm_16(info); op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7); } diff --git a/arch/M68K/M68KDisassembler.h b/arch/M68K/M68KDisassembler.h index a1cbc03ffc..62f4c014a8 100644 --- a/arch/M68K/M68KDisassembler.h +++ b/arch/M68K/M68KDisassembler.h @@ -5,7 +5,10 @@ #define CS_M68KDISASSEMBLER_H #include "../../MCInst.h" + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif /* Private, For internal use only */ typedef struct m68k_info { diff --git a/arch/M68K/M68KInstPrinter.h b/arch/M68K/M68KInstPrinter.h index 9cc4373034..ac96afda07 100644 --- a/arch/M68K/M68KInstPrinter.h +++ b/arch/M68K/M68KInstPrinter.h @@ -4,7 +4,9 @@ #ifndef CS_M68KINSTPRINTER_H #define CS_M68KINSTPRINTER_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "capstone/capstone.h" #include "../../MCRegisterInfo.h" diff --git a/arch/Mips/MipsDisassembler.c b/arch/Mips/MipsDisassembler.c index 4f809340ef..846115f727 100644 --- a/arch/Mips/MipsDisassembler.c +++ b/arch/Mips/MipsDisassembler.c @@ -19,7 +19,7 @@ #include #include -#include "../../myinttypes.h" +#include "capstone/platform.h" #include "../../utils.h" diff --git a/arch/Mips/MipsInstPrinter.c b/arch/Mips/MipsInstPrinter.c index 844437a944..e97bf4d97b 100644 --- a/arch/Mips/MipsInstPrinter.c +++ b/arch/Mips/MipsInstPrinter.c @@ -16,7 +16,7 @@ #ifdef CAPSTONE_HAS_MIPS -#include "../../myinttypes.h" +#include #include #include // debug #include diff --git a/arch/PowerPC/PPCDisassembler.h b/arch/PowerPC/PPCDisassembler.h index f71eb1f170..946f3f701e 100644 --- a/arch/PowerPC/PPCDisassembler.h +++ b/arch/PowerPC/PPCDisassembler.h @@ -4,7 +4,9 @@ #ifndef CS_PPCDISASSEMBLER_H #define CS_PPCDISASSEMBLER_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "capstone/capstone.h" #include "../../MCRegisterInfo.h" diff --git a/arch/PowerPC/PPCGenAsmWriter.inc b/arch/PowerPC/PPCGenAsmWriter.inc index 16f5fd152d..447bd04e3c 100644 --- a/arch/PowerPC/PPCGenAsmWriter.inc +++ b/arch/PowerPC/PPCGenAsmWriter.inc @@ -10,7 +10,7 @@ /* By Nguyen Anh Quynh , 2013-2015 */ #include // debug -#include "../../myinttypes.h" +#include /// printInstruction - This method is automatically generated by tablegen /// from the instruction set description. diff --git a/arch/PowerPC/PPCInstPrinter.c b/arch/PowerPC/PPCInstPrinter.c index a9fd936e24..45680ec0b3 100644 --- a/arch/PowerPC/PPCInstPrinter.c +++ b/arch/PowerPC/PPCInstPrinter.c @@ -19,7 +19,6 @@ #include #include #include -#include "../../myinttypes.h" #include "PPCInstPrinter.h" #include "PPCPredicates.h" diff --git a/arch/Sparc/SparcDisassembler.c b/arch/Sparc/SparcDisassembler.c index aa23fe84b7..78d9333499 100644 --- a/arch/Sparc/SparcDisassembler.c +++ b/arch/Sparc/SparcDisassembler.c @@ -251,7 +251,7 @@ static DecodeStatus DecodeMem(MCInst *MI, unsigned insn, uint64_t Address, DecodeStatus status; unsigned rd = fieldFromInstruction_4(insn, 25, 5); unsigned rs1 = fieldFromInstruction_4(insn, 14, 5); - bool isImm = fieldFromInstruction_4(insn, 13, 1); + bool isImm = fieldFromInstruction_4(insn, 13, 1) != 0; unsigned rs2 = 0; unsigned simm13 = 0; diff --git a/arch/Sparc/SparcDisassembler.h b/arch/Sparc/SparcDisassembler.h index 353bd8d1fd..49ac375477 100644 --- a/arch/Sparc/SparcDisassembler.h +++ b/arch/Sparc/SparcDisassembler.h @@ -4,7 +4,9 @@ #ifndef CS_SPARCDISASSEMBLER_H #define CS_SPARCDISASSEMBLER_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "capstone/capstone.h" #include "../../MCRegisterInfo.h" diff --git a/arch/Sparc/SparcGenAsmWriter.inc b/arch/Sparc/SparcGenAsmWriter.inc index 1b8562c9b3..9ed97609bc 100644 --- a/arch/Sparc/SparcGenAsmWriter.inc +++ b/arch/Sparc/SparcGenAsmWriter.inc @@ -10,7 +10,7 @@ /* By Nguyen Anh Quynh , 2013-2015 */ #include // debug -#include "../../myinttypes.h" +#include /// printInstruction - This method is automatically generated by tablegen diff --git a/arch/Sparc/SparcInstPrinter.c b/arch/Sparc/SparcInstPrinter.c index 68826cf466..ba2a315582 100644 --- a/arch/Sparc/SparcInstPrinter.c +++ b/arch/Sparc/SparcInstPrinter.c @@ -81,7 +81,7 @@ void Sparc_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci) if (insn->id == SPARC_INS_CASX) { // first op is actually a memop, not regop insn->detail->sparc.operands[0].type = SPARC_OP_MEM; - insn->detail->sparc.operands[0].mem.base = insn->detail->sparc.operands[0].reg; + insn->detail->sparc.operands[0].mem.base = (uint8_t)insn->detail->sparc.operands[0].reg; insn->detail->sparc.operands[0].mem.disp = 0; } } @@ -172,9 +172,9 @@ static void printOperand(MCInst *MI, int opNum, SStream *O) if (MI->csh->detail) { if (MI->csh->doing_mem) { if (MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base) - MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.index = reg; + MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.index = (uint8_t)reg; else - MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = reg; + MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = (uint8_t)reg; } else { MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG; MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg; diff --git a/arch/SystemZ/SystemZDisassembler.h b/arch/SystemZ/SystemZDisassembler.h index 1f29929d20..6785d7ca5a 100644 --- a/arch/SystemZ/SystemZDisassembler.h +++ b/arch/SystemZ/SystemZDisassembler.h @@ -4,7 +4,9 @@ #ifndef CS_SYSZDISASSEMBLER_H #define CS_SYSZDISASSEMBLER_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "capstone/capstone.h" #include "../../MCRegisterInfo.h" diff --git a/arch/SystemZ/SystemZGenAsmWriter.inc b/arch/SystemZ/SystemZGenAsmWriter.inc index 0cec420d88..73baaaa93c 100644 --- a/arch/SystemZ/SystemZGenAsmWriter.inc +++ b/arch/SystemZ/SystemZGenAsmWriter.inc @@ -10,7 +10,7 @@ /* By Nguyen Anh Quynh , 2013-2015 */ #include // debug -#include "../../myinttypes.h" +#include /// printInstruction - This method is automatically generated by tablegen diff --git a/arch/SystemZ/SystemZInstPrinter.c b/arch/SystemZ/SystemZInstPrinter.c index 67680f1599..5a8f0196ef 100644 --- a/arch/SystemZ/SystemZInstPrinter.c +++ b/arch/SystemZ/SystemZInstPrinter.c @@ -19,7 +19,7 @@ #include #include #include -#include "../../myinttypes.h" +#include #include "SystemZInstPrinter.h" #include "../../MCInst.h" diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c index 16be0c6c92..0e82273033 100644 --- a/arch/X86/X86ATTInstPrinter.c +++ b/arch/X86/X86ATTInstPrinter.c @@ -21,7 +21,7 @@ #if !defined(CAPSTONE_HAS_OSXKERNEL) #include #endif -#include "../../myinttypes.h" +#include #if defined(CAPSTONE_HAS_OSXKERNEL) #include #else @@ -708,7 +708,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O) MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm; if (opsize > 0) - MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize; + MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = (uint8_t)opsize; else if (MI->op1_size > 0) MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->op1_size; else diff --git a/arch/X86/X86Disassembler.c b/arch/X86/X86Disassembler.c index 7ff165eb30..cd02d94c05 100644 --- a/arch/X86/X86Disassembler.c +++ b/arch/X86/X86Disassembler.c @@ -19,7 +19,7 @@ #ifdef CAPSTONE_HAS_X86 -#include "../../myinttypes.h" // debug +#include #include #include "../../cs_priv.h" diff --git a/arch/X86/X86Disassembler.h b/arch/X86/X86Disassembler.h index eae2fa8e71..10bdeb8791 100644 --- a/arch/X86/X86Disassembler.h +++ b/arch/X86/X86Disassembler.h @@ -77,7 +77,9 @@ #ifndef CS_X86_DISASSEMBLER_H #define CS_X86_DISASSEMBLER_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "capstone/capstone.h" diff --git a/arch/X86/X86DisassemblerDecoder.c b/arch/X86/X86DisassemblerDecoder.c index 4038e2ad4b..a4863f30b1 100644 --- a/arch/X86/X86DisassemblerDecoder.c +++ b/arch/X86/X86DisassemblerDecoder.c @@ -1094,7 +1094,7 @@ static int getIDWithAttrMask(uint16_t *instructionID, hasModRMExtension = modRMRequired(insn->opcodeType, instructionClass, - insn->opcode); + insn->opcode) != 0; if (hasModRMExtension) { if (readModRM(insn)) diff --git a/arch/X86/X86DisassemblerDecoder.h b/arch/X86/X86DisassemblerDecoder.h index 2fccdd129a..777fb90f6b 100644 --- a/arch/X86/X86DisassemblerDecoder.h +++ b/arch/X86/X86DisassemblerDecoder.h @@ -24,7 +24,9 @@ #else #include #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "X86DisassemblerDecoderCommon.h" diff --git a/arch/X86/X86DisassemblerDecoderCommon.h b/arch/X86/X86DisassemblerDecoderCommon.h index 8bd6a5046e..cc1549a0a4 100644 --- a/arch/X86/X86DisassemblerDecoderCommon.h +++ b/arch/X86/X86DisassemblerDecoderCommon.h @@ -25,7 +25,9 @@ #ifndef CS_X86_DISASSEMBLERDECODERCOMMON_H #define CS_X86_DISASSEMBLERDECODERCOMMON_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #define INSTRUCTIONS_SYM x86DisassemblerInstrSpecifiers #define CONTEXTS_SYM x86DisassemblerContexts diff --git a/arch/X86/X86IntelInstPrinter.c b/arch/X86/X86IntelInstPrinter.c index a5a248ff34..247ab3ab2d 100644 --- a/arch/X86/X86IntelInstPrinter.c +++ b/arch/X86/X86IntelInstPrinter.c @@ -20,7 +20,7 @@ #if !defined(CAPSTONE_HAS_OSXKERNEL) #include #endif -#include "../../myinttypes.h" +#include #if defined(CAPSTONE_HAS_OSXKERNEL) #include #else @@ -787,7 +787,7 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O) if (MI->flat_insn->detail->x86.op_count > 0) MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->flat_insn->detail->x86.operands[0].size; else if (opsize > 0) - MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize; + MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = (uint8_t)opsize; else MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm; @@ -904,7 +904,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O) MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM; if (opsize > 0) - MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize; + MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = (uint8_t)opsize; else if (MI->flat_insn->detail->x86.op_count > 0) { if (MI->flat_insn->id != X86_INS_LCALL && MI->flat_insn->id != X86_INS_LJMP) { MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = diff --git a/arch/XCore/XCoreDisassembler.h b/arch/XCore/XCoreDisassembler.h index f72907affe..e50fc551e9 100644 --- a/arch/XCore/XCoreDisassembler.h +++ b/arch/XCore/XCoreDisassembler.h @@ -4,7 +4,9 @@ #ifndef CS_XCOREDISASSEMBLER_H #define CS_XCOREDISASSEMBLER_H +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif #include "capstone/capstone.h" #include "../../MCRegisterInfo.h" diff --git a/arch/XCore/XCoreGenAsmWriter.inc b/arch/XCore/XCoreGenAsmWriter.inc index 85c2feef79..95babb2de2 100644 --- a/arch/XCore/XCoreGenAsmWriter.inc +++ b/arch/XCore/XCoreGenAsmWriter.inc @@ -10,7 +10,7 @@ /* By Nguyen Anh Quynh , 2013-2015 */ #include // debug -#include "../../myinttypes.h" +#include /// printInstruction - This method is automatically generated by tablegen diff --git a/arch/XCore/XCoreInstPrinter.c b/arch/XCore/XCoreInstPrinter.c index c4c741f6be..c050c581ea 100644 --- a/arch/XCore/XCoreInstPrinter.c +++ b/arch/XCore/XCoreInstPrinter.c @@ -19,7 +19,7 @@ #include #include #include -#include "../../myinttypes.h" +#include #include "XCoreInstPrinter.h" #include "../../MCInst.h" @@ -91,7 +91,7 @@ void XCore_insn_extract(MCInst *MI, const char *code) // base register if (MI->csh->detail) { MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM; - MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = id; + MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)id; MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = XCORE_REG_INVALID; MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = 0; MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = 1; @@ -109,7 +109,7 @@ void XCore_insn_extract(MCInst *MI, const char *code) if (id) { // index register if (MI->csh->detail) { - MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = id; + MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)id; } } else { // a number means disp @@ -160,7 +160,7 @@ static void set_mem_access(MCInst *MI, bool status, int reg) if (reg != 0xffff && reg != -0xffff) { MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM; if (reg) { - MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = reg; + MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)reg; } else { MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = XCORE_REG_INVALID; } @@ -171,7 +171,7 @@ static void set_mem_access(MCInst *MI, bool status, int reg) // the last op should be the memory base MI->flat_insn->detail->xcore.op_count--; MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM; - MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg; + MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg; MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = XCORE_REG_INVALID; MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = 0; if (reg > 0) @@ -181,7 +181,7 @@ static void set_mem_access(MCInst *MI, bool status, int reg) } } else { if (reg) { - MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = reg; + MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)reg; // done, create the next operand slot MI->flat_insn->detail->xcore.op_count++; } @@ -199,9 +199,9 @@ static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O) if (MI->csh->detail) { if (MI->csh->doing_mem) { if (MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base == ARM_REG_INVALID) - MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = reg; + MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)reg; else - MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = reg; + MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)reg; } else { MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG; MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = reg; diff --git a/contrib/cs_driver/README b/contrib/cs_driver/README new file mode 100644 index 0000000000..f9a268a20c --- /dev/null +++ b/contrib/cs_driver/README @@ -0,0 +1,5 @@ +This directory contains a sample project for using Capstone from a Windows +driver. Open cs_driver.sln with Visual Studio 2013 or newer and see cs_driver.c +for details. + +For prerequisites to compile Capstone for drivers, see COMPILE_MSVC.TXT. diff --git a/contrib/cs_driver/cs_driver.sln b/contrib/cs_driver/cs_driver.sln new file mode 100644 index 0000000000..f36afa1b49 --- /dev/null +++ b/contrib/cs_driver/cs_driver.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cs_driver", "cs_driver\cs_driver.vcxproj", "{F29A9424-0ECD-4FFE-9CB7-C844756373BB}" + ProjectSection(ProjectDependencies) = postProject + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B} = {FE197816-EF84-4E8D-B29D-E0A6BA2B144B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capstone_static_winkernel", "..\..\msvc\capstone_static_winkernel\capstone_static_winkernel.vcxproj", "{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|Win32.ActiveCfg = Debug|Win32 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|Win32.Build.0 = Debug|Win32 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|Win32.Deploy.0 = Debug|Win32 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|x64.ActiveCfg = Debug|x64 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|x64.Build.0 = Debug|x64 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|x64.Deploy.0 = Debug|x64 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|Win32.ActiveCfg = Release|Win32 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|Win32.Build.0 = Release|Win32 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|Win32.Deploy.0 = Release|Win32 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|x64.ActiveCfg = Release|x64 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|x64.Build.0 = Release|x64 + {F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|x64.Deploy.0 = Release|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.ActiveCfg = Debug|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.Build.0 = Debug|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.Deploy.0 = Debug|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.ActiveCfg = Debug|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.Build.0 = Debug|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.Deploy.0 = Debug|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.ActiveCfg = Release|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.Build.0 = Release|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.Deploy.0 = Release|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.ActiveCfg = Release|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.Build.0 = Release|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.Deploy.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/cs_driver/cs_driver/cs_driver.c b/contrib/cs_driver/cs_driver/cs_driver.c new file mode 100644 index 0000000000..11a129f388 --- /dev/null +++ b/contrib/cs_driver/cs_driver/cs_driver.c @@ -0,0 +1,99 @@ +/* Capstone Driver */ +/* By Satoshi Tanda , 2016 */ + +// Firstly, compile capstone_static_winkernel and +// generate capstone_static_winkernel.lib. It can be done by adding the +// capstone_static_winkernel project to your solution and compiling it first. +// +// Then, configure your driver project (cs_driver in this example) to locate to +// capstone.h and capstone_static_winkernel.lib. To do it, open project +// properties of the project and set Configuration to "All Configurations" and +// Platform to "All Platforms". Then, add the following entries: +// - C/C++ > General > Additional Include Directories +// - $(SolutionDir)capstone\include +// - Linker > Input > Additional Dependencies +// - $(OutDir)capstone_static_winkernel.lib +// - ntstrsafe.lib +// +// Note that ntstrsafe.lib is required to resolve __fltused indirectly used in +// Capstone. + +#include +#include + +// 'conversion' : from function pointer 'type1' to data pointer 'type2' +#pragma warning(disable : 4054) + + +DRIVER_INITIALIZE DriverEntry; +static NTSTATUS cs_driver_hello(); + + +// Driver entry point +EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath) { + printf("Entering DriverEntry()\n"); + + cs_driver_hello(); + + printf("Leaving DriverEntry()\n"); + return STATUS_CANCELLED; +} + +// Hello, Capstone! +static NTSTATUS cs_driver_hello() { + csh handle; + cs_insn *insn; + size_t count; + KFLOATING_SAVE float_save; + NTSTATUS status = STATUS_UNSUCCESSFUL; + + // Any of Capstone APIs cannot be called at IRQL higher than DISPATCH_LEVEL + // since our malloc implementation based on ExAllocatePoolWithTag() is not able + // to allocate memory at higher IRQL than the DISPATCH_LEVEL level. + NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + // On a 32bit driver, KeSaveFloatingPointState() is required before using any + // Capstone function because Capstone can access to the MMX/x87 registers and + // 32bit Windows requires drivers to use KeSaveFloatingPointState() before and + // KeRestoreFloatingPointState() after accesing to them. See "Using Floating + // Point or MMX in a WDM Driver" on MSDN for more details. + status = KeSaveFloatingPointState(&float_save); + if (!NT_SUCCESS(status)) { + return status; + } + + // Do stuff just like user-mode. All functionalites are supported. + if (cs_open(CS_ARCH_X86, (sizeof(void *) == 4) ? CS_MODE_32 : CS_MODE_64, + &handle) != CS_ERR_OK) { + goto exit; + } + + count = cs_disasm(handle, (uint8_t *)&cs_driver_hello, 0x80, + (uint64_t)&cs_driver_hello, 0, &insn); + if (count > 0) { + printf("cs_driver!cs_driver_hello:\n"); + for (size_t j = 0; j < count; j++) { + printf("0x%p\t%s\t\t%s\n", (void *)(uintptr_t)insn[j].address, + insn[j].mnemonic, insn[j].op_str); + } + cs_free(insn, count); + } + cs_close(&handle); + +exit:; + // Restores the nonvolatile floating-point context. + KeRestoreFloatingPointState(&float_save); + return status; +} + +// printf() +_Use_decl_annotations_ int __cdecl printf(const char *_Format, ...) { + NTSTATUS status; + va_list args; + + va_start(args, _Format); + status = vDbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, _Format, args); + va_end(args); + return NT_SUCCESS(status); +} diff --git a/contrib/cs_driver/cs_driver/cs_driver.vcxproj b/contrib/cs_driver/cs_driver/cs_driver.vcxproj new file mode 100644 index 0000000000..623040c23e --- /dev/null +++ b/contrib/cs_driver/cs_driver/cs_driver.vcxproj @@ -0,0 +1,129 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F29A9424-0ECD-4FFE-9CB7-C844756373BB} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 11.0 + Win8.1 Debug + Win32 + cs_driver + + + + Windows7 + true + WindowsKernelModeDriver8.1 + Driver + KMDF + + + Windows7 + false + WindowsKernelModeDriver8.1 + Driver + KMDF + + + Windows7 + true + WindowsKernelModeDriver8.1 + Driver + KMDF + + + Windows7 + false + WindowsKernelModeDriver8.1 + Driver + KMDF + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + trace.h + true + $(SolutionDir)..\..\include;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies) + + + + + trace.h + true + $(SolutionDir)..\..\include;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies) + + + + + trace.h + true + $(SolutionDir)..\..\include;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies) + + + + + trace.h + true + $(SolutionDir)..\..\include;$(IntDir);%(AdditionalIncludeDirectories) + + + $(OutDir)capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies) + + + + + + + + + + + + + \ No newline at end of file diff --git a/contrib/cs_driver/cs_driver/cs_driver.vcxproj.filters b/contrib/cs_driver/cs_driver/cs_driver.vcxproj.filters new file mode 100644 index 0000000000..29491115fc --- /dev/null +++ b/contrib/cs_driver/cs_driver/cs_driver.vcxproj.filters @@ -0,0 +1,26 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Source Files + + + \ No newline at end of file diff --git a/cs.c b/cs.c index ebd810958d..e668932406 100644 --- a/cs.c +++ b/cs.c @@ -17,7 +17,11 @@ #include "utils.h" #include "MCRegisterInfo.h" -#if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(CAPSTONE_DIET) +#if defined(_KERNEL_MODE) +#include "windows\winkernel_mm.h" +#endif + +#if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(CAPSTONE_DIET) && !defined(_KERNEL_MODE) #define INSN_CACHE_SIZE 32 #else // reduce stack variable size for kernel/firmware @@ -82,13 +86,19 @@ static void archs_enable(void) unsigned int all_arch = 0; -#ifdef CAPSTONE_USE_SYS_DYN_MEM -#ifndef CAPSTONE_HAS_OSXKERNEL +#if defined(CAPSTONE_USE_SYS_DYN_MEM) +#if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE) cs_malloc_t cs_mem_malloc = malloc; cs_calloc_t cs_mem_calloc = calloc; cs_realloc_t cs_mem_realloc = realloc; cs_free_t cs_mem_free = free; cs_vsnprintf_t cs_vsnprintf = vsnprintf; +#elif defined(_KERNEL_MODE) +cs_malloc_t cs_mem_malloc = cs_winkernel_malloc; +cs_calloc_t cs_mem_calloc = cs_winkernel_calloc; +cs_realloc_t cs_mem_realloc = cs_winkernel_realloc; +cs_free_t cs_mem_free = cs_winkernel_free; +cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf; #else extern void* kern_os_malloc(size_t size); extern void kern_os_free(void* addr); @@ -114,7 +124,7 @@ cs_vsnprintf_t cs_vsnprintf = NULL; #endif CAPSTONE_EXPORT -unsigned int cs_version(int *major, int *minor) +unsigned int CAPSTONE_API cs_version(int *major, int *minor) { archs_enable(); @@ -127,7 +137,7 @@ unsigned int cs_version(int *major, int *minor) } CAPSTONE_EXPORT -bool cs_support(int query) +bool CAPSTONE_API cs_support(int query) { archs_enable(); @@ -161,7 +171,7 @@ bool cs_support(int query) } CAPSTONE_EXPORT -cs_err cs_errno(csh handle) +cs_err CAPSTONE_API cs_errno(csh handle) { struct cs_struct *ud; if (!handle) @@ -173,7 +183,7 @@ cs_err cs_errno(csh handle) } CAPSTONE_EXPORT -const char *cs_strerror(cs_err code) +const char * CAPSTONE_API cs_strerror(cs_err code) { switch(code) { default: @@ -212,7 +222,7 @@ const char *cs_strerror(cs_err code) } CAPSTONE_EXPORT -cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle) +cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle) { cs_err err; struct cs_struct *ud; @@ -233,7 +243,7 @@ cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle) ud->errnum = CS_ERR_OK; ud->arch = arch; ud->mode = mode; - ud->big_endian = mode & CS_MODE_BIG_ENDIAN; + ud->big_endian = (mode & CS_MODE_BIG_ENDIAN) != 0; // by default, do not break instruction into details ud->detail = CS_OPT_OFF; @@ -257,7 +267,7 @@ cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle) } CAPSTONE_EXPORT -cs_err cs_close(csh *handle) +cs_err CAPSTONE_API cs_close(csh *handle) { struct cs_struct *ud; struct insn_mnem *next, *tmp; @@ -298,7 +308,7 @@ static void fill_insn(struct cs_struct *handle, cs_insn *insn, char *buffer, MCI #ifndef CAPSTONE_DIET char *sp, *mnem; #endif - unsigned int copy_size = MIN(sizeof(insn->bytes), insn->size); + uint16_t copy_size = MIN(sizeof(insn->bytes), insn->size); // fill the instruction bytes. // we might skip some redundant bytes in front in the case of X86 @@ -363,7 +373,7 @@ static uint8_t skipdata_size(cs_struct *handle) switch(handle->arch) { default: // should never reach - return -1; + return (uint8_t)-1; case CS_ARCH_ARM: // skip 2 bytes on Thumb mode. if (handle->mode & CS_MODE_THUMB) @@ -394,7 +404,7 @@ static uint8_t skipdata_size(cs_struct *handle) } CAPSTONE_EXPORT -cs_err cs_option(csh ud, cs_opt_type type, size_t value) +cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value) { struct cs_struct *handle; cs_opt_mnem *opt; @@ -512,25 +522,34 @@ static void skipdata_opstr(char *opstr, const uint8_t *buffer, size_t size) char *p = opstr; int len; size_t i; + size_t available = sizeof(((cs_insn*)NULL)->op_str); if (!size) { opstr[0] = '\0'; return; } - len = sprintf(p, "0x%02x", buffer[0]); + len = cs_snprintf(p, available, "0x%02x", buffer[0]); p+= len; + available -= len; for(i = 1; i < size; i++) { - len = sprintf(p, ", 0x%02x", buffer[i]); + len = cs_snprintf(p, available, ", 0x%02x", buffer[i]); + if (len < 0) { + break; + } + if ((size_t)len > available - 1) { + break; + } p+= len; + available -= len; } } // dynamicly allocate memory to contain disasm insn // NOTE: caller must free() the allocated memory itself to avoid memory leaking CAPSTONE_EXPORT -size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn) +size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn) { struct cs_struct *handle; MCInst mci; @@ -728,13 +747,13 @@ size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, si CAPSTONE_EXPORT CAPSTONE_DEPRECATED -size_t cs_disasm_ex(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn) +size_t CAPSTONE_API cs_disasm_ex(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn) { return cs_disasm(ud, buffer, size, offset, count, insn); } CAPSTONE_EXPORT -void cs_free(cs_insn *insn, size_t count) +void CAPSTONE_API cs_free(cs_insn *insn, size_t count) { size_t i; @@ -747,7 +766,7 @@ void cs_free(cs_insn *insn, size_t count) } CAPSTONE_EXPORT -cs_insn *cs_malloc(csh ud) +cs_insn * CAPSTONE_API cs_malloc(csh ud) { cs_insn *insn; struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; @@ -775,7 +794,7 @@ cs_insn *cs_malloc(csh ud) // iterator for instruction "single-stepping" CAPSTONE_EXPORT -bool cs_disasm_iter(csh ud, const uint8_t **code, size_t *size, +bool CAPSTONE_API cs_disasm_iter(csh ud, const uint8_t **code, size_t *size, uint64_t *address, cs_insn *insn) { struct cs_struct *handle; @@ -862,7 +881,7 @@ bool cs_disasm_iter(csh ud, const uint8_t **code, size_t *size, // return friendly name of regiser in a string CAPSTONE_EXPORT -const char *cs_reg_name(csh ud, unsigned int reg) +const char * CAPSTONE_API cs_reg_name(csh ud, unsigned int reg) { struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; @@ -874,7 +893,7 @@ const char *cs_reg_name(csh ud, unsigned int reg) } CAPSTONE_EXPORT -const char *cs_insn_name(csh ud, unsigned int insn) +const char * CAPSTONE_API cs_insn_name(csh ud, unsigned int insn) { struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; @@ -886,7 +905,7 @@ const char *cs_insn_name(csh ud, unsigned int insn) } CAPSTONE_EXPORT -const char *cs_group_name(csh ud, unsigned int group) +const char * CAPSTONE_API cs_group_name(csh ud, unsigned int group) { struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; @@ -898,7 +917,7 @@ const char *cs_group_name(csh ud, unsigned int group) } CAPSTONE_EXPORT -bool cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id) +bool CAPSTONE_API cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id) { struct cs_struct *handle; if (!ud) @@ -925,7 +944,7 @@ bool cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id) } CAPSTONE_EXPORT -bool cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id) +bool CAPSTONE_API cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id) { struct cs_struct *handle; if (!ud) @@ -952,7 +971,7 @@ bool cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id) } CAPSTONE_EXPORT -bool cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id) +bool CAPSTONE_API cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id) { struct cs_struct *handle; if (!ud) @@ -979,7 +998,7 @@ bool cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id) } CAPSTONE_EXPORT -int cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type) +int CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type) { struct cs_struct *handle; unsigned int count = 0, i; @@ -1055,7 +1074,7 @@ int cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type) } CAPSTONE_EXPORT -int cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type, +int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type, unsigned int post) { struct cs_struct *handle; @@ -1156,7 +1175,7 @@ int cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type, } CAPSTONE_EXPORT -cs_err cs_regs_access(csh ud, const cs_insn *insn, +cs_err CAPSTONE_API cs_regs_access(csh ud, const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count) { diff --git a/include/capstone/arm.h b/include/capstone/arm.h index 9b71471caf..40fa593064 100644 --- a/include/capstone/arm.h +++ b/include/capstone/arm.h @@ -8,7 +8,10 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "platform.h" #ifdef _MSC_VER diff --git a/include/capstone/arm64.h b/include/capstone/arm64.h index 5f91444f65..afd6292c46 100644 --- a/include/capstone/arm64.h +++ b/include/capstone/arm64.h @@ -8,7 +8,10 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "platform.h" #ifdef _MSC_VER diff --git a/include/capstone/capstone.h b/include/capstone/capstone.h index 164db6b46f..61bb35e415 100644 --- a/include/capstone/capstone.h +++ b/include/capstone/capstone.h @@ -8,8 +8,12 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include + #if defined(CAPSTONE_HAS_OSXKERNEL) #include #else @@ -22,12 +26,14 @@ extern "C" { #ifdef _MSC_VER #pragma warning(disable:4201) #pragma warning(disable:4100) +#define CAPSTONE_API __cdecl #ifdef CAPSTONE_SHARED #define CAPSTONE_EXPORT __declspec(dllexport) #else // defined(CAPSTONE_STATIC) #define CAPSTONE_EXPORT #endif #else +#define CAPSTONE_API #ifdef __GNUC__ #define CAPSTONE_EXPORT __attribute__((visibility("default"))) #else @@ -114,11 +120,11 @@ typedef enum cs_mode { CS_MODE_MIPS64 = CS_MODE_64, // Mips64 ISA (Mips) } cs_mode; -typedef void* (*cs_malloc_t)(size_t size); -typedef void* (*cs_calloc_t)(size_t nmemb, size_t size); -typedef void* (*cs_realloc_t)(void *ptr, size_t size); -typedef void (*cs_free_t)(void *ptr); -typedef int (*cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap); +typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size); +typedef void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size); +typedef void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size); +typedef void (CAPSTONE_API *cs_free_t)(void *ptr); +typedef int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap); // User-defined dynamic memory related functions: malloc/calloc/realloc/free/vsnprintf() @@ -144,7 +150,8 @@ typedef struct cs_opt_mnem { // Runtime option for the disassembled engine typedef enum cs_opt_type { - CS_OPT_SYNTAX = 1, // Assembly output syntax + CS_OPT_INVALID = 0, // No option specified + CS_OPT_SYNTAX, // Assembly output syntax CS_OPT_DETAIL, // Break down instruction structure into details CS_OPT_MODE, // Change engine's mode at run-time CS_OPT_MEM, // User-defined dynamic memory related functions @@ -207,7 +214,7 @@ typedef enum cs_group_type { @return: return number of bytes to skip, or 0 to immediately stop disassembling. */ -typedef size_t (*cs_skipdata_cb_t)(const uint8_t *code, size_t code_size, size_t offset, void *user_data); +typedef size_t (CAPSTONE_API *cs_skipdata_cb_t)(const uint8_t *code, size_t code_size, size_t offset, void *user_data); // User-customized setup for SKIPDATA option typedef struct cs_opt_skipdata { @@ -358,7 +365,7 @@ typedef enum cs_err { set both @major & @minor arguments to NULL. */ CAPSTONE_EXPORT -unsigned int cs_version(int *major, int *minor); +unsigned int CAPSTONE_API cs_version(int *major, int *minor); /* @@ -375,7 +382,7 @@ unsigned int cs_version(int *major, int *minor); @return True if this library supports the given arch, or in 'diet' mode. */ CAPSTONE_EXPORT -bool cs_support(int query); +bool CAPSTONE_API cs_support(int query); /* Initialize CS handle: this must be done before any usage of CS. @@ -388,7 +395,7 @@ bool cs_support(int query); for detailed error). */ CAPSTONE_EXPORT -cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle); +cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle); /* Close CS handle: MUST do to release the handle when it is not used anymore. @@ -405,7 +412,7 @@ cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle); for detailed error). */ CAPSTONE_EXPORT -cs_err cs_close(csh *handle); +cs_err CAPSTONE_API cs_close(csh *handle); /* Set option for disassembling engine at runtime @@ -422,7 +429,7 @@ cs_err cs_close(csh *handle); even before cs_open() */ CAPSTONE_EXPORT -cs_err cs_option(csh handle, cs_opt_type type, size_t value); +cs_err CAPSTONE_API cs_option(csh handle, cs_opt_type type, size_t value); /* Report the last error number when some API function fail. @@ -433,7 +440,7 @@ cs_err cs_option(csh handle, cs_opt_type type, size_t value); @return: error code of cs_err enum type (CS_ERR_*, see above) */ CAPSTONE_EXPORT -cs_err cs_errno(csh handle); +cs_err CAPSTONE_API cs_errno(csh handle); /* @@ -445,7 +452,7 @@ cs_err cs_errno(csh handle); passed in the argument @code */ CAPSTONE_EXPORT -const char *cs_strerror(cs_err code); +const char * CAPSTONE_API cs_strerror(cs_err code); /* Disassemble binary code, given the code buffer, size, address and number @@ -481,7 +488,7 @@ const char *cs_strerror(cs_err code); On failure, call cs_errno() for error code. */ CAPSTONE_EXPORT -size_t cs_disasm(csh handle, +size_t CAPSTONE_API cs_disasm(csh handle, const uint8_t *code, size_t code_size, uint64_t address, size_t count, @@ -493,7 +500,7 @@ size_t cs_disasm(csh handle, */ CAPSTONE_EXPORT CAPSTONE_DEPRECATED -size_t cs_disasm_ex(csh handle, +size_t CAPSTONE_API cs_disasm_ex(csh handle, const uint8_t *code, size_t code_size, uint64_t address, size_t count, @@ -507,7 +514,7 @@ size_t cs_disasm_ex(csh handle, to free memory allocated by cs_malloc(). */ CAPSTONE_EXPORT -void cs_free(cs_insn *insn, size_t count); +void CAPSTONE_API cs_free(cs_insn *insn, size_t count); /* @@ -519,7 +526,7 @@ void cs_free(cs_insn *insn, size_t count); this instruction with cs_free(insn, 1) */ CAPSTONE_EXPORT -cs_insn *cs_malloc(csh handle); +cs_insn * CAPSTONE_API cs_malloc(csh handle); /* Fast API to disassemble binary code, given the code buffer, size, address @@ -557,7 +564,7 @@ cs_insn *cs_malloc(csh handle); On failure, call cs_errno() for error code. */ CAPSTONE_EXPORT -bool cs_disasm_iter(csh handle, +bool CAPSTONE_API cs_disasm_iter(csh handle, const uint8_t **code, size_t *size, uint64_t *address, cs_insn *insn); @@ -575,7 +582,7 @@ bool cs_disasm_iter(csh handle, @return: string name of the register, or NULL if @reg_id is invalid. */ CAPSTONE_EXPORT -const char *cs_reg_name(csh handle, unsigned int reg_id); +const char * CAPSTONE_API cs_reg_name(csh handle, unsigned int reg_id); /* Return friendly name of an instruction in a string. @@ -590,7 +597,7 @@ const char *cs_reg_name(csh handle, unsigned int reg_id); @return: string name of the instruction, or NULL if @insn_id is invalid. */ CAPSTONE_EXPORT -const char *cs_insn_name(csh handle, unsigned int insn_id); +const char * CAPSTONE_API cs_insn_name(csh handle, unsigned int insn_id); /* Return friendly name of a group id (that an instruction can belong to) @@ -605,7 +612,7 @@ const char *cs_insn_name(csh handle, unsigned int insn_id); @return: string name of the group, or NULL if @group_id is invalid. */ CAPSTONE_EXPORT -const char *cs_group_name(csh handle, unsigned int group_id); +const char * CAPSTONE_API cs_group_name(csh handle, unsigned int group_id); /* Check if a disassembled instruction belong to a particular group. @@ -624,7 +631,7 @@ const char *cs_group_name(csh handle, unsigned int group_id); @return: true if this instruction indeed belongs to aboved group, or false otherwise. */ CAPSTONE_EXPORT -bool cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id); +bool CAPSTONE_API cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id); /* Check if a disassembled instruction IMPLICITLY used a particular register. @@ -642,7 +649,7 @@ bool cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id); @return: true if this instruction indeed implicitly used aboved register, or false otherwise. */ CAPSTONE_EXPORT -bool cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id); +bool CAPSTONE_API cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id); /* Check if a disassembled instruction IMPLICITLY modified a particular register. @@ -660,7 +667,7 @@ bool cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id); @return: true if this instruction indeed implicitly modified aboved register, or false otherwise. */ CAPSTONE_EXPORT -bool cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id); +bool CAPSTONE_API cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id); /* Count the number of operands of a given type. @@ -676,7 +683,7 @@ bool cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id); or -1 on failure. */ CAPSTONE_EXPORT -int cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type); +int CAPSTONE_API cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type); /* Retrieve the position of operand of given type in .operands[] array. @@ -695,7 +702,7 @@ int cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type); in instruction @insn, or -1 on failure. */ CAPSTONE_EXPORT -int cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type, +int CAPSTONE_API cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type, unsigned int position); // Type of array to keep the list of registers @@ -719,7 +726,7 @@ typedef uint16_t cs_regs[64]; for detailed error). */ CAPSTONE_EXPORT -cs_err cs_regs_access(csh handle, const cs_insn *insn, +cs_err CAPSTONE_API cs_regs_access(csh handle, const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count); diff --git a/include/capstone/m68k.h b/include/capstone/m68k.h index 013edd11db..eb86889204 100644 --- a/include/capstone/m68k.h +++ b/include/capstone/m68k.h @@ -8,7 +8,10 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "platform.h" #ifdef _MSC_VER diff --git a/include/capstone/mips.h b/include/capstone/mips.h index 58b4761953..2e43512889 100644 --- a/include/capstone/mips.h +++ b/include/capstone/mips.h @@ -8,7 +8,10 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "platform.h" // GCC MIPS toolchain has a default macro called "mips" which breaks diff --git a/include/capstone/platform.h b/include/capstone/platform.h index 12132f5c0a..2ff28d3e11 100644 --- a/include/capstone/platform.h +++ b/include/capstone/platform.h @@ -1,15 +1,16 @@ /* Capstone Disassembly Engine */ /* By Axel Souchet & Nguyen Anh Quynh, 2014 */ -// handle C99 issue (for pre-2013 VisualStudio) #ifndef CAPSTONE_PLATFORM_H #define CAPSTONE_PLATFORM_H +// handle C99 issue (for pre-2013 VisualStudio) #if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) // MSVC // stdbool.h -#if (_MSC_VER < 1800) +#if (_MSC_VER < 1800) || defined(_KERNEL_MODE) +// this system does not have stdbool.h #ifndef __cplusplus typedef unsigned char bool; #define false 0 @@ -21,8 +22,84 @@ typedef unsigned char bool; #include #endif -#else // not MSVC -> C99 is supported +#else +// not MSVC -> C99 is supported #include #endif + +// handle C99 issue (for pre-2013 VisualStudio) +#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE))) +// this system does not have inttypes.h + +#if defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)) +// this system does not have stdint.h +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; + +#define INT8_MIN (-127i8 - 1) +#define INT16_MIN (-32767i16 - 1) +#define INT32_MIN (-2147483647i32 - 1) +#define INT64_MIN (-9223372036854775807i64 - 1) +#define INT8_MAX 127i8 +#define INT16_MAX 32767i16 +#define INT32_MAX 2147483647i32 +#define INT64_MAX 9223372036854775807i64 +#define UINT8_MAX 0xffui8 +#define UINT16_MAX 0xffffui16 +#define UINT32_MAX 0xffffffffui32 +#define UINT64_MAX 0xffffffffffffffffui64 +#endif + +#define __PRI_8_LENGTH_MODIFIER__ "hh" +#define __PRI_64_LENGTH_MODIFIER__ "ll" + +#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d" +#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i" +#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o" +#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u" +#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x" +#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" + +#if defined(_MSC_VER) && _MSC_VER <= 1700 +#define PRId32 "ld" +#define PRIi32 "li" +#define PRIo32 "lo" +#define PRIu32 "lu" +#define PRIx32 "lx" +#define PRIX32 "lX" +#else // OSX +#define PRId32 "d" +#define PRIi32 "i" +#define PRIo32 "o" +#define PRIu32 "u" +#define PRIx32 "x" +#define PRIX32 "X" +#endif + +#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d" +#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i" +#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o" +#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u" +#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x" +#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X" + +#else +// this system has inttypes.h by default +#include +#endif + #endif diff --git a/include/capstone/ppc.h b/include/capstone/ppc.h index 1fbdc6393e..c9add21965 100644 --- a/include/capstone/ppc.h +++ b/include/capstone/ppc.h @@ -8,7 +8,10 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "platform.h" #ifdef _MSC_VER diff --git a/include/capstone/sparc.h b/include/capstone/sparc.h index d0dcef2528..343c845090 100644 --- a/include/capstone/sparc.h +++ b/include/capstone/sparc.h @@ -8,7 +8,10 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "platform.h" // GCC SPARC toolchain has a default macro called "sparc" which breaks diff --git a/include/capstone/systemz.h b/include/capstone/systemz.h index 4c8a1e578e..d91706efc4 100644 --- a/include/capstone/systemz.h +++ b/include/capstone/systemz.h @@ -8,7 +8,10 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "platform.h" #ifdef _MSC_VER diff --git a/include/capstone/x86.h b/include/capstone/x86.h index 9cce72d554..17ad3bda39 100644 --- a/include/capstone/x86.h +++ b/include/capstone/x86.h @@ -8,7 +8,9 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif // Calculate relative address for X86-64, given cs_insn structure #define X86_REL_ADDR(insn) (insn.address + insn.size + insn.detail->x86.disp) diff --git a/include/capstone/xcore.h b/include/capstone/xcore.h index 4e455c0d80..6376662b87 100644 --- a/include/capstone/xcore.h +++ b/include/capstone/xcore.h @@ -8,7 +8,10 @@ extern "C" { #endif +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) #include +#endif + #include "platform.h" #ifdef _MSC_VER diff --git a/msvc/README b/msvc/README index 97e5524dcf..c7248fe244 100644 --- a/msvc/README +++ b/msvc/README @@ -6,11 +6,17 @@ NOTE: (1) Visual Studio 2010 or newer versions is required. Open "capstone.sln" to build the libraries & test code with Visual Studio. The resulted binaries - are put under either msvc/Debug or msvc/Release, depending on how you choose - to compile them. + are put under either msvc/Debug, msvc/Release, msvc/x64/Debug, or + msvc/x64/Release, depending on how you choose to compile them. (2) The solution (capstone.sln) & all project files (*.vcxproj) are made in Visual Studio 2010, so if you open them using newer version, an extra step - is needed to convert them to current version. Just accept this when - asked at the initial dialog, and proceed to build the solution normally - afterwards. + is needed to convert them to current version. Just accept this when + asked at the initial dialog, and proceed to build the solution normally + afterwards. + +(3) The capstone_static_winkernel and test_winkernel projects are for Windows + kernel drivers and excluded from build by default. In order to build them, + you need to install Visual Studio 2013 or newer versions, and Windows Driver + Kit 8.1 Update 1 or newer versions, then check "Build" check boxes for those + projects on the Configuration Manager through the [Build] menu. diff --git a/msvc/capstone.sln b/msvc/capstone.sln index 8109bd8e2f..222187d02f 100644 --- a/msvc/capstone.sln +++ b/msvc/capstone.sln @@ -75,6 +75,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_customized_mnem", "tes EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capstone_dll", "capstone_dll\capstone_dll.vcxproj", "{2171C0E8-4915-49B9-AC23-A484FA08C126}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capstone_static_winkernel", "capstone_static_winkernel\capstone_static_winkernel.vcxproj", "{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_winkernel", "test_winkernel\test_winkernel.vcxproj", "{C6E4974C-2CAF-499A-802A-FB906F86B4C8}" + ProjectSection(ProjectDependencies) = postProject + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B} = {FE197816-EF84-4E8D-B29D-E0A6BA2B144B} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -123,6 +130,14 @@ Global {CBE31473-7D0E-41F5-AFCB-8C8422ED8908}.Release|Win32.Build.0 = Release|Win32 {CBE31473-7D0E-41F5-AFCB-8C8422ED8908}.Release|x64.ActiveCfg = Release|x64 {CBE31473-7D0E-41F5-AFCB-8C8422ED8908}.Release|x64.Build.0 = Release|x64 + {5B880AB5-E54F-11E3-8C65-B8E8563B7B00}.Debug|Win32.ActiveCfg = Debug|Win32 + {5B880AB5-E54F-11E3-8C65-B8E8563B7B00}.Debug|Win32.Build.0 = Debug|Win32 + {5B880AB5-E54F-11E3-8C65-B8E8563B7B00}.Debug|x64.ActiveCfg = Debug|x64 + {5B880AB5-E54F-11E3-8C65-B8E8563B7B00}.Debug|x64.Build.0 = Debug|x64 + {5B880AB5-E54F-11E3-8C65-B8E8563B7B00}.Release|Win32.ActiveCfg = Release|Win32 + {5B880AB5-E54F-11E3-8C65-B8E8563B7B00}.Release|Win32.Build.0 = Release|Win32 + {5B880AB5-E54F-11E3-8C65-B8E8563B7B00}.Release|x64.ActiveCfg = Release|x64 + {5B880AB5-E54F-11E3-8C65-B8E8563B7B00}.Release|x64.Build.0 = Release|x64 {28B2D82F-3E95-4ECE-8118-0E891BD453E0}.Debug|Win32.ActiveCfg = Debug|Win32 {28B2D82F-3E95-4ECE-8118-0E891BD453E0}.Debug|Win32.Build.0 = Debug|Win32 {28B2D82F-3E95-4ECE-8118-0E891BD453E0}.Debug|x64.ActiveCfg = Debug|x64 @@ -171,14 +186,6 @@ Global {B09819BB-7EF1-4B04-945D-58117E6940A1}.Release|Win32.Build.0 = Release|Win32 {B09819BB-7EF1-4B04-945D-58117E6940A1}.Release|x64.ActiveCfg = Release|x64 {B09819BB-7EF1-4B04-945D-58117E6940A1}.Release|x64.Build.0 = Release|x64 - {2171C0E8-4915-49B9-AC23-A484FA08C126}.Debug|Win32.ActiveCfg = Debug|Win32 - {2171C0E8-4915-49B9-AC23-A484FA08C126}.Debug|Win32.Build.0 = Debug|Win32 - {2171C0E8-4915-49B9-AC23-A484FA08C126}.Debug|x64.ActiveCfg = Debug|x64 - {2171C0E8-4915-49B9-AC23-A484FA08C126}.Debug|x64.Build.0 = Debug|x64 - {2171C0E8-4915-49B9-AC23-A484FA08C126}.Release|Win32.ActiveCfg = Release|Win32 - {2171C0E8-4915-49B9-AC23-A484FA08C126}.Release|Win32.Build.0 = Release|Win32 - {2171C0E8-4915-49B9-AC23-A484FA08C126}.Release|x64.ActiveCfg = Release|x64 - {2171C0E8-4915-49B9-AC23-A484FA08C126}.Release|x64.Build.0 = Release|x64 {5B880AB5-E54F-11E3-8C65-B8E8563B7BDE}.Debug|Win32.ActiveCfg = Debug|Win32 {5B880AB5-E54F-11E3-8C65-B8E8563B7BDE}.Debug|Win32.Build.0 = Debug|Win32 {5B880AB5-E54F-11E3-8C65-B8E8563B7BDE}.Debug|x64.ActiveCfg = Debug|x64 @@ -203,6 +210,38 @@ Global {D622418C-A872-40D4-8C86-F3D996A4C823}.Release|Win32.Build.0 = Release|Win32 {D622418C-A872-40D4-8C86-F3D996A4C823}.Release|x64.ActiveCfg = Release|x64 {D622418C-A872-40D4-8C86-F3D996A4C823}.Release|x64.Build.0 = Release|x64 + {2171C0E8-4915-49B9-AC23-A484FA08C126}.Debug|Win32.ActiveCfg = Debug|Win32 + {2171C0E8-4915-49B9-AC23-A484FA08C126}.Debug|Win32.Build.0 = Debug|Win32 + {2171C0E8-4915-49B9-AC23-A484FA08C126}.Debug|x64.ActiveCfg = Debug|x64 + {2171C0E8-4915-49B9-AC23-A484FA08C126}.Debug|x64.Build.0 = Debug|x64 + {2171C0E8-4915-49B9-AC23-A484FA08C126}.Release|Win32.ActiveCfg = Release|Win32 + {2171C0E8-4915-49B9-AC23-A484FA08C126}.Release|Win32.Build.0 = Release|Win32 + {2171C0E8-4915-49B9-AC23-A484FA08C126}.Release|x64.ActiveCfg = Release|x64 + {2171C0E8-4915-49B9-AC23-A484FA08C126}.Release|x64.Build.0 = Release|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.ActiveCfg = Debug|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.Build.0 = Debug|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.Deploy.0 = Debug|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.ActiveCfg = Debug|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.Build.0 = Debug|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.Deploy.0 = Debug|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.ActiveCfg = Release|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.Build.0 = Release|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.Deploy.0 = Release|Win32 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.ActiveCfg = Release|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.Build.0 = Release|x64 + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.Deploy.0 = Release|x64 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Debug|Win32.ActiveCfg = Debug|Win32 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Debug|Win32.Build.0 = Debug|Win32 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Debug|Win32.Deploy.0 = Debug|Win32 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Debug|x64.ActiveCfg = Debug|x64 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Debug|x64.Build.0 = Debug|x64 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Debug|x64.Deploy.0 = Debug|x64 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Release|Win32.ActiveCfg = Release|Win32 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Release|Win32.Build.0 = Release|Win32 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Release|Win32.Deploy.0 = Release|Win32 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Release|x64.ActiveCfg = Release|x64 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Release|x64.Build.0 = Release|x64 + {C6E4974C-2CAF-499A-802A-FB906F86B4C8}.Release|x64.Deploy.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/msvc/capstone_static_winkernel/capstone_static_winkernel.vcxproj b/msvc/capstone_static_winkernel/capstone_static_winkernel.vcxproj new file mode 100644 index 0000000000..2420031b2e --- /dev/null +++ b/msvc/capstone_static_winkernel/capstone_static_winkernel.vcxproj @@ -0,0 +1,175 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {FE197816-EF84-4E8D-B29D-E0A6BA2B144B} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 11.0 + Win8.1 Debug + Win32 + capstone_static_winkernel + capstone_static_winkernel + + + + Windows7 + true + WindowsKernelModeDriver8.1 + StaticLibrary + KMDF + + + Windows7 + false + WindowsKernelModeDriver8.1 + StaticLibrary + KMDF + + + Windows7 + true + WindowsKernelModeDriver8.1 + StaticLibrary + KMDF + + + Windows7 + false + WindowsKernelModeDriver8.1 + StaticLibrary + KMDF + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + trace.h + true + ..\..\include;..\headers;$(IntDir);%(AdditionalIncludeDirectories) + CAPSTONE_X86_ATT_DISABLE_NO;CAPSTONE_DIET_NO;CAPSTONE_X86_REDUCE_NO;CAPSTONE_HAS_ARM;CAPSTONE_HAS_ARM64;CAPSTONE_HAS_MIPS;CAPSTONE_HAS_M68K;CAPSTONE_HAS_POWERPC;CAPSTONE_HAS_SPARC;CAPSTONE_HAS_SYSZ;CAPSTONE_HAS_X86;CAPSTONE_HAS_XCORE;CAPSTONE_USE_SYS_DYN_MEM;%(PreprocessorDefinitions) + false + Level3 + + + + + trace.h + true + ..\..\include;..\headers;$(IntDir);%(AdditionalIncludeDirectories) + CAPSTONE_X86_ATT_DISABLE_NO;CAPSTONE_DIET_NO;CAPSTONE_X86_REDUCE_NO;CAPSTONE_HAS_ARM;CAPSTONE_HAS_ARM64;CAPSTONE_HAS_MIPS;CAPSTONE_HAS_M68K;CAPSTONE_HAS_POWERPC;CAPSTONE_HAS_SPARC;CAPSTONE_HAS_SYSZ;CAPSTONE_HAS_X86;CAPSTONE_HAS_XCORE;CAPSTONE_USE_SYS_DYN_MEM;%(PreprocessorDefinitions) + false + Level3 + + + + + trace.h + true + ..\..\include;..\headers;$(IntDir);%(AdditionalIncludeDirectories) + CAPSTONE_X86_ATT_DISABLE_NO;CAPSTONE_DIET_NO;CAPSTONE_X86_REDUCE_NO;CAPSTONE_HAS_ARM;CAPSTONE_HAS_ARM64;CAPSTONE_HAS_MIPS;CAPSTONE_HAS_M68K;CAPSTONE_HAS_POWERPC;CAPSTONE_HAS_SPARC;CAPSTONE_HAS_SYSZ;CAPSTONE_HAS_X86;CAPSTONE_HAS_XCORE;CAPSTONE_USE_SYS_DYN_MEM;%(PreprocessorDefinitions) + false + Level3 + + + + + trace.h + true + ..\..\include;..\headers;$(IntDir);%(AdditionalIncludeDirectories) + CAPSTONE_X86_ATT_DISABLE_NO;CAPSTONE_DIET_NO;CAPSTONE_X86_REDUCE_NO;CAPSTONE_HAS_ARM;CAPSTONE_HAS_ARM64;CAPSTONE_HAS_MIPS;CAPSTONE_HAS_M68K;CAPSTONE_HAS_POWERPC;CAPSTONE_HAS_SPARC;CAPSTONE_HAS_SYSZ;CAPSTONE_HAS_X86;CAPSTONE_HAS_XCORE;CAPSTONE_USE_SYS_DYN_MEM;%(PreprocessorDefinitions) + false + Level3 + + + + + + + + + + \ No newline at end of file diff --git a/msvc/test_winkernel/test_winkernel.vcxproj b/msvc/test_winkernel/test_winkernel.vcxproj new file mode 100644 index 0000000000..ce8427523f --- /dev/null +++ b/msvc/test_winkernel/test_winkernel.vcxproj @@ -0,0 +1,138 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C6E4974C-2CAF-499A-802A-FB906F86B4C8} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 11.0 + Win8.1 Debug + Win32 + test_winkernel + test_winkernel + + + + Windows7 + true + WindowsKernelModeDriver8.1 + Driver + KMDF + + + Windows7 + false + WindowsKernelModeDriver8.1 + Driver + KMDF + + + Windows7 + true + WindowsKernelModeDriver8.1 + Driver + KMDF + + + Windows7 + false + WindowsKernelModeDriver8.1 + Driver + KMDF + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + trace.h + true + ..\..\include;..\headers;$(IntDir);%(AdditionalIncludeDirectories) + CAPSTONE_X86_ATT_DISABLE_NO;CAPSTONE_DIET_NO;CAPSTONE_X86_REDUCE_NO;CAPSTONE_HAS_ARM;CAPSTONE_HAS_ARM64;CAPSTONE_HAS_M68K;CAPSTONE_HAS_MIPS;CAPSTONE_HAS_POWERPC;CAPSTONE_HAS_SPARC;CAPSTONE_HAS_SYSZ;CAPSTONE_HAS_X86;CAPSTONE_HAS_XCORE;CAPSTONE_USE_SYS_DYN_MEM;%(PreprocessorDefinitions) + + + capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies) + ..\Debug + + + + + trace.h + true + ..\..\include;..\headers;$(IntDir);%(AdditionalIncludeDirectories) + CAPSTONE_X86_ATT_DISABLE_NO;CAPSTONE_DIET_NO;CAPSTONE_X86_REDUCE_NO;CAPSTONE_HAS_ARM;CAPSTONE_HAS_ARM64;CAPSTONE_HAS_M68K;CAPSTONE_HAS_MIPS;CAPSTONE_HAS_POWERPC;CAPSTONE_HAS_SPARC;CAPSTONE_HAS_SYSZ;CAPSTONE_HAS_X86;CAPSTONE_HAS_XCORE;CAPSTONE_USE_SYS_DYN_MEM;%(PreprocessorDefinitions) + + + capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies) + ..\Release + + + + + trace.h + true + ..\..\include;..\headers;$(IntDir);%(AdditionalIncludeDirectories) + CAPSTONE_X86_ATT_DISABLE_NO;CAPSTONE_DIET_NO;CAPSTONE_X86_REDUCE_NO;CAPSTONE_HAS_ARM;CAPSTONE_HAS_ARM64;CAPSTONE_HAS_M68K;CAPSTONE_HAS_MIPS;CAPSTONE_HAS_POWERPC;CAPSTONE_HAS_SPARC;CAPSTONE_HAS_SYSZ;CAPSTONE_HAS_X86;CAPSTONE_HAS_XCORE;CAPSTONE_USE_SYS_DYN_MEM;%(PreprocessorDefinitions) + + + capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies) + ..\x64\Debug + + + + + trace.h + true + ..\..\include;..\headers;$(IntDir);%(AdditionalIncludeDirectories) + CAPSTONE_X86_ATT_DISABLE_NO;CAPSTONE_DIET_NO;CAPSTONE_X86_REDUCE_NO;CAPSTONE_HAS_ARM;CAPSTONE_HAS_ARM64;CAPSTONE_HAS_M68K;CAPSTONE_HAS_MIPS;CAPSTONE_HAS_POWERPC;CAPSTONE_HAS_SPARC;CAPSTONE_HAS_SYSZ;CAPSTONE_HAS_X86;CAPSTONE_HAS_XCORE;CAPSTONE_USE_SYS_DYN_MEM;%(PreprocessorDefinitions) + + + capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies) + ..\x64\Release + + + + + + + + + + + + + \ No newline at end of file diff --git a/myinttypes.h b/myinttypes.h deleted file mode 100644 index fe61331d1d..0000000000 --- a/myinttypes.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Capstone Disassembly Engine */ -/* By Axel Souchet, 2014 */ - -#ifndef CS_MYINTTYPES_H -#define CS_MYINTTYPES_H - -#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && _MSC_VER <= 1700) -// this system does not have inttypes.h - -#if defined(_MSC_VER) && _MSC_VER <= 1700 -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#endif - -#define __PRI_8_LENGTH_MODIFIER__ "hh" -#define __PRI_64_LENGTH_MODIFIER__ "ll" - -#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d" -#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i" -#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o" -#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u" -#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x" -#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X" - -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" - -#if defined(_MSC_VER) && _MSC_VER <= 1700 -#define PRId32 "ld" -#define PRIi32 "li" -#define PRIo32 "lo" -#define PRIu32 "lu" -#define PRIx32 "lx" -#define PRIX32 "lX" -#else // OSX -#define PRId32 "d" -#define PRIi32 "i" -#define PRIo32 "o" -#define PRIu32 "u" -#define PRIx32 "x" -#define PRIX32 "X" -#endif - -#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d" -#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i" -#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o" -#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u" -#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x" -#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X" - -#else // this system has inttypes.h by default -#include -#endif - -#endif diff --git a/suite/arm/test_arm_regression.c b/suite/arm/test_arm_regression.c index a6cdc1ce7e..d6bff5cbc2 100644 --- a/suite/arm/test_arm_regression.c +++ b/suite/arm/test_arm_regression.c @@ -9,8 +9,8 @@ #include #include #include -#include "../../myinttypes.h" +#include #include static csh handle; diff --git a/suite/benchmark/test_iter_benchmark.c b/suite/benchmark/test_iter_benchmark.c index 0c04b8f0bc..7aa7c02a2d 100644 --- a/suite/benchmark/test_iter_benchmark.c +++ b/suite/benchmark/test_iter_benchmark.c @@ -4,9 +4,9 @@ #include #include #include -#include "../myinttypes.h" -#include +#include +#include static void test() { diff --git a/tests/README b/tests/README index 02960772aa..e5d3efb48c 100644 --- a/tests/README +++ b/tests/README @@ -26,3 +26,6 @@ This directory contains some test code to show how to use Capstone API. - test_.c These code show how to access architecture-specific information for each architecture. + +- test_winkernel.cpp + This code shows how to use Capstone from a Windows driver. diff --git a/tests/test_arm.c b/tests/test_arm.c index f368a88062..5325f9fe03 100644 --- a/tests/test_arm.c +++ b/tests/test_arm.c @@ -3,8 +3,8 @@ #include #include -#include "../myinttypes.h" +#include #include static csh handle; @@ -30,7 +30,7 @@ static void print_string_hex(char *comment, unsigned char *str, size_t len) printf("\n"); } -static void print_insn_detail(csh handle, cs_insn *ins) +static void print_insn_detail(csh cs_handle, cs_insn *ins) { cs_arm *arm; int i; @@ -52,7 +52,7 @@ static void print_insn_detail(csh handle, cs_insn *ins) default: break; case ARM_OP_REG: - printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(cs_handle, op->reg)); break; case ARM_OP_IMM: printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); @@ -64,10 +64,10 @@ static void print_insn_detail(csh handle, cs_insn *ins) 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)); + i, cs_reg_name(cs_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)); + i, cs_reg_name(cs_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) @@ -115,7 +115,7 @@ static void print_insn_detail(csh handle, cs_insn *ins) else // shift with register printf("\t\t\tShift: %u = %s\n", op->shift.type, - cs_reg_name(handle, op->shift.value)); + cs_reg_name(cs_handle, op->shift.value)); } if (op->vector_index != -1) { @@ -154,13 +154,13 @@ static void print_insn_detail(csh handle, cs_insn *ins) printf("\tMemory-barrier: %u\n", arm->mem_barrier); // Print out all registers accessed by this instruction (either implicit or explicit) - if (!cs_regs_access(handle, ins, + if (!cs_regs_access(cs_handle, ins, regs_read, ®s_read_count, regs_write, ®s_write_count)) { if (regs_read_count) { printf("\tRegisters read:"); for(i = 0; i < regs_read_count; i++) { - printf(" %s", cs_reg_name(handle, regs_read[i])); + printf(" %s", cs_reg_name(cs_handle, regs_read[i])); } printf("\n"); } @@ -168,7 +168,7 @@ static void print_insn_detail(csh handle, cs_insn *ins) if (regs_write_count) { printf("\tRegisters modified:"); for(i = 0; i < regs_write_count; i++) { - printf(" %s", cs_reg_name(handle, regs_write[i])); + printf(" %s", cs_reg_name(cs_handle, regs_write[i])); } printf("\n"); } @@ -319,10 +319,10 @@ static void test() printf("Disasm:\n"); 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%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(handle, &insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_arm64.c b/tests/test_arm64.c index 9170ed4fe6..9795d35beb 100644 --- a/tests/test_arm64.c +++ b/tests/test_arm64.c @@ -3,8 +3,8 @@ #include #include -#include "../myinttypes.h" +#include #include static csh handle; @@ -53,7 +53,7 @@ static void print_insn_detail(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%" PRIx64 "\n", i, op->imm); break; case ARM64_OP_FP: printf("\t\toperands[%u].type: FP = %f\n", i, op->fp); @@ -91,7 +91,7 @@ static void print_insn_detail(cs_insn *ins) break; } - uint8_t access = op->access; + uint32_t access = op->access; switch(access) { default: break; @@ -249,10 +249,10 @@ static void test() printf("Disasm:\n"); 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%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(&insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_basic.c b/tests/test_basic.c index 47c8b005a2..8227e4dd0b 100644 --- a/tests/test_basic.c +++ b/tests/test_basic.c @@ -3,8 +3,8 @@ #include #include -#include "../myinttypes.h" +#include #include struct platform { @@ -272,7 +272,7 @@ static void test() #ifdef CAPSTONE_HAS_M68K { CS_ARCH_M68K, - CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, + (cs_mode)(CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040), (unsigned char*)M68K_CODE, sizeof(M68K_CODE) - 1, "M68K", @@ -307,12 +307,12 @@ static void test() printf("Disasm:\n"); for (j = 0; j < count; j++) { - printf("0x%"PRIx64":\t%s\t\t%s\n", + printf("0x%" PRIx64 ":\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%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_customized_mnem.c b/tests/test_customized_mnem.c index 4a56bf1a91..913586e084 100644 --- a/tests/test_customized_mnem.c +++ b/tests/test_customized_mnem.c @@ -6,8 +6,8 @@ #include #include -#include "../myinttypes.h" +#include #include #define X86_CODE32 "\x75\x01" diff --git a/tests/test_detail.c b/tests/test_detail.c index d0931e8712..fd914a1d54 100644 --- a/tests/test_detail.c +++ b/tests/test_detail.c @@ -3,8 +3,8 @@ #include #include -#include "../myinttypes.h" +#include #include struct platform { @@ -253,7 +253,7 @@ static void test() #ifdef CAPSTONE_HAS_M68K { CS_ARCH_M68K, - CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, + (cs_mode)(CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040), (unsigned char*)M68K_CODE, sizeof(M68K_CODE) - 1, "M68K", @@ -293,7 +293,7 @@ static void test() for (j = 0; j < count; j++) { cs_insn *in = &(all_insn[j]); - printf("0x%"PRIx64":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", + printf("0x%" PRIx64 ":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", in->address, in->mnemonic, in->op_str, in->id, cs_insn_name(handle, in->id)); @@ -328,7 +328,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%" PRIx64 ":\n", all_insn[j-1].address + all_insn[j-1].size); // free memory allocated by cs_disasm() cs_free(all_insn, count); diff --git a/tests/test_iter.c b/tests/test_iter.c index 894f5c98f0..47f2f95a4b 100644 --- a/tests/test_iter.c +++ b/tests/test_iter.c @@ -4,8 +4,8 @@ // This sample code demonstrates the APIs cs_malloc() & cs_disasm_iter(). #include #include -#include "../myinttypes.h" +#include #include struct platform { @@ -245,7 +245,7 @@ static void test() while(cs_disasm_iter(handle, &code, &size, &address, insn)) { int n; - printf("0x%"PRIx64":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", + printf("0x%" PRIx64 ":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", insn->address, insn->mnemonic, insn->op_str, insn->id, cs_insn_name(handle, insn->id)); diff --git a/tests/test_m68k.c b/tests/test_m68k.c index 301acbf49f..557a062b7c 100644 --- a/tests/test_m68k.c +++ b/tests/test_m68k.c @@ -2,8 +2,8 @@ /* By Nguyen Anh Quynh , 2013-2014 */ #include -#include "../myinttypes.h" +#include #include struct platform { @@ -126,7 +126,7 @@ static void test() struct platform platforms[] = { { CS_ARCH_M68K, - CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, + (cs_mode)(CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040), (unsigned char*)M68K_CODE, sizeof(M68K_CODE) - 1, "M68K", @@ -157,10 +157,10 @@ static void test() printf("Disasm:\n"); 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%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(&insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_mips.c b/tests/test_mips.c index 6cb751f697..aef12281b8 100644 --- a/tests/test_mips.c +++ b/tests/test_mips.c @@ -3,8 +3,8 @@ #include #include -#include "../myinttypes.h" +#include #include struct platform { @@ -51,7 +51,7 @@ static void print_insn_detail(cs_insn *ins) 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); + 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); @@ -138,10 +138,10 @@ static void test() printf("Disasm:\n"); 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%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(&insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_ppc.c b/tests/test_ppc.c index a1c8800ba5..42b6a6846e 100644 --- a/tests/test_ppc.c +++ b/tests/test_ppc.c @@ -2,8 +2,8 @@ /* By Nguyen Anh Quynh , 2013> */ #include -#include "../myinttypes.h" +#include #include struct platform { @@ -126,7 +126,7 @@ static void test() }, { CS_ARCH_PPC, - CS_MODE_BIG_ENDIAN + CS_MODE_QPX, + (cs_mode)(CS_MODE_BIG_ENDIAN + CS_MODE_QPX), (unsigned char*)PPC_CODE2, sizeof(PPC_CODE2) - 1, "PPC-64 + QPX", @@ -157,10 +157,10 @@ static void test() printf("Disasm:\n"); 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%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(&insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_skipdata.c b/tests/test_skipdata.c index 8d3f94e92f..a625f41141 100644 --- a/tests/test_skipdata.c +++ b/tests/test_skipdata.c @@ -3,8 +3,8 @@ #include #include -#include "../myinttypes.h" +#include #include struct platform { @@ -31,7 +31,7 @@ static void print_string_hex(unsigned char *str, size_t len) } #ifdef CAPSTONE_HAS_ARM -static size_t mycallback(const uint8_t *buffer, size_t buffer_size, size_t offset, void *p) +static size_t CAPSTONE_API mycallback(const uint8_t *buffer, size_t buffer_size, size_t offset, void *p) { // always skip 2 bytes when encountering data return 2; @@ -74,7 +74,8 @@ static void test() (unsigned char*)X86_CODE32, sizeof(X86_CODE32) - 1, "X86 32 (Intel syntax) - Skip data with custom mnemonic", - 0, 0, + CS_OPT_INVALID, + CS_OPT_OFF, CS_OPT_SKIPDATA_SETUP, (size_t) &skipdata, }, @@ -93,7 +94,8 @@ static void test() (unsigned char*)RANDOM_CODE, sizeof(RANDOM_CODE) - 1, "Arm - Skip data with callback", - 0, 0, + CS_OPT_INVALID, + CS_OPT_OFF, CS_OPT_SKIPDATA_SETUP, (size_t) &skipdata_callback, }, @@ -131,12 +133,12 @@ static void test() printf("Disasm:\n"); for (j = 0; j < count; j++) { - printf("0x%"PRIx64":\t%s\t\t%s\n", + printf("0x%" PRIx64 ":\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%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_sparc.c b/tests/test_sparc.c index 8417cb96df..8444b1f5cd 100644 --- a/tests/test_sparc.c +++ b/tests/test_sparc.c @@ -2,8 +2,8 @@ /* By Nguyen Anh Quynh , 2013-2014 */ #include -#include "../myinttypes.h" +#include #include struct platform { @@ -123,10 +123,10 @@ static void test() printf("Disasm:\n"); 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%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(&insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_systemz.c b/tests/test_systemz.c index 2b8ea3bee3..ec1af9dd35 100644 --- a/tests/test_systemz.c +++ b/tests/test_systemz.c @@ -2,8 +2,8 @@ /* By Nguyen Anh Quynh , 2013-2014 */ #include -#include "../myinttypes.h" +#include #include struct platform { @@ -53,7 +53,7 @@ static void print_insn_detail(cs_insn *ins) 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); + 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); @@ -64,9 +64,9 @@ static void print_insn_detail(cs_insn *ins) 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); + 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); + printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp); break; } @@ -116,10 +116,10 @@ static void test() printf("Disasm:\n"); 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%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(&insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_winkernel.cpp b/tests/test_winkernel.cpp new file mode 100644 index 0000000000..dade77956f --- /dev/null +++ b/tests/test_winkernel.cpp @@ -0,0 +1,171 @@ +/* Capstone Disassembly Engine */ +/* By Satoshi Tanda , 2016 */ +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../utils.h" // for cs_snprintf + +#ifdef __cplusplus +} +#endif + +EXTERN_C DRIVER_INITIALIZE DriverEntry; + +#pragma warning(push) +#pragma warning(disable : 4005) // 'identifier' : macro redefinition +#pragma warning(disable : 4007) // 'main': must be '__cdecl' + +// Drivers must protect floating point hardware state. See use of float simm: +// Use KeSaveFloatingPointState/KeRestoreFloatingPointState around floating +// point operations. Display Drivers should use the corresponding Eng... routines. +#pragma warning(disable : 28110) // Suppress this, as it is false positive. + +// "Import" existing tests into this file. All code is encaptured into unique +// namespace so that the same name does not conflict. Beware that those code +// is going to be compiled as C++ source file and not C files because this file +// is C++. + +namespace basic { +#include "test_basic.c" +} // namespace basic + +namespace detail { +#include "test_detail.c" +} // namespace detail + +namespace skipdata { +#include "test_skipdata.c" +} // namespace skipdata + +namespace iter { +#include "test_iter.c" +} // namespace iter + +namespace customized_mnem_ { +#include "test_customized_mnem.c" +} // namespace customized_mnem_ + +namespace arm { +#include "test_arm.c" +} // namespace arm + +namespace arm64 { +#include "test_arm64.c" +} // namespace arm64 + +namespace mips { +#include "test_mips.c" +} // namespace mips + +namespace m68k { +#include "test_m68k.c" +} // namespace m68k + +namespace ppc { +#include "test_ppc.c" +} // namespace ppc + +namespace sparc { +#include "test_sparc.c" +} // namespace sparc + +namespace systemz { +#include "test_systemz.c" +} // namespace systemz + +namespace x86 { +#include "test_x86.c" +} // namespace x86 + +namespace xcore { +#include "test_xcore.c" +} // namespace xcore + +#pragma warning(pop) + +// Exercises all existing regression tests +static void test() +{ + KFLOATING_SAVE float_save; + NTSTATUS status; + + // Any of Capstone APIs cannot be called at IRQL higher than DISPATCH_LEVEL + // since our malloc implementation using ExAllocatePoolWithTag() is able to + // allocate memory only up to the DISPATCH_LEVEL level. + NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + // On a 32bit driver, KeSaveFloatingPointState() is required before using any + // Capstone function because Capstone can access to the MMX/x87 registers and + // 32bit Windows requires drivers to use KeSaveFloatingPointState() before and + // KeRestoreFloatingPointState() after accesing to them. See "Using Floating + // Point or MMX in a WDM Driver" on MSDN for more details. + status = KeSaveFloatingPointState(&float_save); + if (!NT_SUCCESS(status)) { + printf("ERROR: Failed to save floating point state!\n"); + return; + } + + basic::test(); + detail::test(); + skipdata::test(); + iter::test(); + customized_mnem_::test(); + arm::test(); + arm64::test(); + mips::test(); + m68k::test(); + ppc::test(); + sparc::test(); + systemz::test(); + x86::test(); + xcore::test(); + + // Restores the nonvolatile floating-point context. + KeRestoreFloatingPointState(&float_save); +} + +// Functional test for cs_winkernel_vsnprintf() +static void cs_winkernel_vsnprintf_test() +{ + char buf[10]; + bool ok = true; + ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "") == 0 && strcmp(buf, "") == 0); + ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "0") == 1 && strcmp(buf, "0") == 0); + ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "012345678") == 9 && strcmp(buf, "012345678") == 0); + ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "0123456789") == 10 && strcmp(buf, "012345678") == 0); + ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "01234567890") == 11 && strcmp(buf, "012345678") == 0); + ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "0123456789001234567890") == 22 && strcmp(buf, "012345678") == 0); + if (!ok) { + printf("ERROR: cs_winkernel_vsnprintf_test() did not produce expected results!\n"); + } +} + +// Driver entry point +EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) +{ + UNREFERENCED_PARAMETER(DriverObject); + UNREFERENCED_PARAMETER(RegistryPath); + cs_winkernel_vsnprintf_test(); + test(); + return STATUS_CANCELLED; +} + +// This functions mimics printf() but does not return the same value as printf() +// would do. printf() is required to exercise regression tests. +_Use_decl_annotations_ +int __cdecl printf(const char * format, ...) +{ + NTSTATUS status; + va_list args; + + va_start(args, format); + status = vDbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, format, args); + va_end(args); + return NT_SUCCESS(status); +} diff --git a/tests/test_x86.c b/tests/test_x86.c index a1e1f0235f..13329a3918 100644 --- a/tests/test_x86.c +++ b/tests/test_x86.c @@ -3,8 +3,8 @@ #include #include -#include "../myinttypes.h" +#include #include static csh handle; @@ -196,7 +196,7 @@ static void print_insn_detail(csh ud, cs_mode mode, cs_insn *ins) printf("\timm_count: %u\n", count); for (i = 1; i < count + 1; i++) { int index = cs_op_index(ud, ins, X86_OP_IMM, i); - printf("\t\timms[%u]: 0x%"PRIx64 "\n", i, x86->operands[index].imm); + printf("\t\timms[%u]: 0x%" PRIx64 "\n", i, x86->operands[index].imm); } } @@ -212,7 +212,7 @@ static void print_insn_detail(csh ud, cs_mode mode, cs_insn *ins) printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); break; case X86_OP_IMM: - printf("\t\toperands[%u].type: IMM = 0x%"PRIx64 "\n", i, op->imm); + printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm); break; case X86_OP_FP: printf("\t\toperands[%u].type: FP = %f\n", i, op->fp); @@ -381,10 +381,10 @@ static void test() printf("Disasm:\n"); for (j = 0; j < count; j++) { - printf("0x%"PRIx64":\t%s\t%s\n\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + printf("0x%" PRIx64 ":\t%s\t%s\n\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%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/tests/test_xcore.c b/tests/test_xcore.c index 778e1525c7..b382ef6b47 100644 --- a/tests/test_xcore.c +++ b/tests/test_xcore.c @@ -2,8 +2,8 @@ /* By Nguyen Anh Quynh , 2013-2014 */ #include -#include "../myinttypes.h" +#include #include struct platform { @@ -111,10 +111,10 @@ static void test() printf("Disasm:\n"); 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%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); print_insn_detail(&insn[j]); } - printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size); + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); diff --git a/windows/README b/windows/README new file mode 100644 index 0000000000..8d3ccbec96 --- /dev/null +++ b/windows/README @@ -0,0 +1 @@ +This directory contains code specific to Windows platforms. diff --git a/windows/winkernel_mm.c b/windows/winkernel_mm.c new file mode 100644 index 0000000000..08ca9945fa --- /dev/null +++ b/windows/winkernel_mm.c @@ -0,0 +1,116 @@ +/* Capstone Disassembly Engine */ +/* By Satoshi Tanda , 2016 */ +#include "winkernel_mm.h" +#include + +// A pool tag for memory allocation +static const ULONG CS_WINKERNEL_POOL_TAG = 'kwsC'; + + +// A structure to implement realloc() +typedef struct _CS_WINKERNEL_MEMBLOCK { + size_t size; // A number of bytes allocated + char data[1]; // An address returned to a caller +} CS_WINKERNEL_MEMBLOCK; +C_ASSERT(sizeof(CS_WINKERNEL_MEMBLOCK) == sizeof(void *) * 2); + + +// free() +void CAPSTONE_API cs_winkernel_free(void *ptr) +{ + if (ptr) { + ExFreePoolWithTag(CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data), CS_WINKERNEL_POOL_TAG); + } +} + +// malloc() +void * CAPSTONE_API cs_winkernel_malloc(size_t size) +{ + // Disallow zero length allocation because they waste pool header space and, + // in many cases, indicate a potential validation issue in the calling code. + NT_ASSERT(size); + + CS_WINKERNEL_MEMBLOCK *block = (CS_WINKERNEL_MEMBLOCK *)ExAllocatePoolWithTag( + NonPagedPoolNx, size + sizeof(CS_WINKERNEL_MEMBLOCK), CS_WINKERNEL_POOL_TAG); + if (!block) { + return NULL; + } + block->size = size; + + return block->data; +} + +// calloc() +void * CAPSTONE_API cs_winkernel_calloc(size_t n, size_t size) +{ + size_t total = n * size; + + void *new_ptr = cs_winkernel_malloc(total); + if (!new_ptr) { + return NULL; + } + + return RtlFillMemory(new_ptr, total, 0); +} + +// realloc() +void * CAPSTONE_API cs_winkernel_realloc(void *ptr, size_t size) +{ + void *new_ptr = NULL; + size_t current_size = 0; + size_t smaller_size = 0; + + if (!ptr) { + return cs_winkernel_malloc(size); + } + + new_ptr = cs_winkernel_malloc(size); + if (!new_ptr) { + return NULL; + } + + current_size = CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data)->size; + smaller_size = (current_size < size) ? current_size : size; + RtlCopyMemory(new_ptr, ptr, smaller_size); + cs_winkernel_free(ptr); + + return new_ptr; +} + +// vsnprintf(). _vsnprintf() is avaialable for drivers, but it differs from +// vsnprintf() in a return value and when a null-terminater is set. +// cs_winkernel_vsnprintf() takes care of those differences. +#pragma warning(push) +#pragma warning(disable : 28719) // Banned API Usage : _vsnprintf is a Banned +// API as listed in dontuse.h for security +// purposes. +int CAPSTONE_API cs_winkernel_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) +{ + int result = _vsnprintf(buffer, count, format, argptr); + + // _vsnprintf() returns -1 when a string is truncated, and returns "count" + // when an entire string is stored but without '\0' at the end of "buffer". + // In both cases, null-terminater needs to be added manually. + if (result == -1 || (size_t)result == count) { + buffer[count - 1] = '\0'; + } + + if (result == -1) { + // In case when -1 is returned, the function has to get and return a number + // of characters that would have been written. This attempts so by re-tring + // the same conversion with temp buffer that is most likely big enough to + // complete formatting and get a number of characters that would have been + // written. + char* tmp = cs_winkernel_malloc(0x1000); + if (!tmp) { + return result; + } + + result = _vsnprintf(tmp, 0x1000, format, argptr); + NT_ASSERT(result != -1); + cs_winkernel_free(tmp); + } + + return result; +} +#pragma warning(pop) diff --git a/windows/winkernel_mm.h b/windows/winkernel_mm.h new file mode 100644 index 0000000000..2df3bfd152 --- /dev/null +++ b/windows/winkernel_mm.h @@ -0,0 +1,22 @@ +/* Capstone Disassembly Engine */ +/* By Satoshi Tanda , 2016 */ +#ifndef CS_WINDOWS_WINKERNEL_MM_H +#define CS_WINDOWS_WINKERNEL_MM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void CAPSTONE_API cs_winkernel_free(void *ptr); +void * CAPSTONE_API cs_winkernel_malloc(size_t size); +void * CAPSTONE_API cs_winkernel_calloc(size_t n, size_t size); +void * CAPSTONE_API cs_winkernel_realloc(void *ptr, size_t size); +int CAPSTONE_API cs_winkernel_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr); + +#ifdef __cplusplus +} +#endif + +#endif // CS_WINDOWS_WINKERNEL_MM_H diff --git a/xcode/Capstone.xcodeproj/project.pbxproj b/xcode/Capstone.xcodeproj/project.pbxproj index efe9e711d7..404f459507 100644 --- a/xcode/Capstone.xcodeproj/project.pbxproj +++ b/xcode/Capstone.xcodeproj/project.pbxproj @@ -347,7 +347,6 @@ DC474F6B19DE6F3B00BCA449 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; DC5BFF4019EE544E008CA585 /* test_iter */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_iter; sourceTree = BUILT_PRODUCTS_DIR; }; DC5BFF4819EE54BE008CA585 /* test_iter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = test_iter.c; path = ../tests/test_iter.c; sourceTree = ""; }; - DC696C5E1AD4600200A56306 /* myinttypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = myinttypes.h; path = ../myinttypes.h; sourceTree = ""; }; DCA3577B1BC2C0290094BB3F /* M68KDisassembler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = M68KDisassembler.c; sourceTree = ""; }; DCA3577C1BC2C0290094BB3F /* M68KDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M68KDisassembler.h; sourceTree = ""; }; DCA3577D1BC2C0290094BB3F /* M68KInstPrinter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = M68KInstPrinter.c; sourceTree = ""; }; @@ -704,7 +703,6 @@ DCFE24B719DDCE1E00EF8EA9 /* MCInstrDesc.h */, DCFE24A019DDCDEE00EF8EA9 /* MCRegisterInfo.c */, DCFE24B819DDCE1E00EF8EA9 /* MCRegisterInfo.h */, - DC696C5E1AD4600200A56306 /* myinttypes.h */, DCFE24A119DDCDEE00EF8EA9 /* SStream.c */, DCFE24B919DDCE1E00EF8EA9 /* SStream.h */, DCFE24A219DDCDEE00EF8EA9 /* utils.c */,