Skip to content

Commit

Permalink
port Windows driver support
Browse files Browse the repository at this point in the history
  • Loading branch information
tandasat committed May 12, 2016
1 parent cea4cb0 commit 45e5eab
Show file tree
Hide file tree
Showing 89 changed files with 1,392 additions and 263 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ ipch/
*.opensdf
*.suo
*.user
*.VC.db
*.VC.opendb

# Xcode
xcode/Capstone.xcodeproj/xcuserdata
Expand Down
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ set(HEADERS_ENGINE
MCInst.h
MCInstrDesc.h
MCRegisterInfo.h
myinttypes.h
SStream.h
utils.h
)
Expand Down
47 changes: 44 additions & 3 deletions COMPILE_MSVC.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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= <full path to test_winkernel.sys>
[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
2 changes: 2 additions & 0 deletions CREDITS.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -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.
1 change: 1 addition & 0 deletions HACK.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions LEB128.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#ifndef CS_LLVM_SUPPORT_LEB128_H
#define CS_LLVM_SUPPORT_LEB128_H

#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#endif

/// Utility function to decode a ULEB128 value.
static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n)
Expand Down
2 changes: 2 additions & 0 deletions MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#ifndef CS_MCINST_H
#define CS_MCINST_H

#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#endif

#include "include/capstone/capstone.h"

Expand Down
3 changes: 3 additions & 0 deletions MCInstrDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
#ifndef CS_LLVM_MC_MCINSTRDESC_H
#define CS_LLVM_MC_MCINSTRDESC_H

#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#endif

#include "capstone/platform.h"

//===----------------------------------------------------------------------===//
Expand Down
3 changes: 3 additions & 0 deletions MCRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
#ifndef CS_LLVM_MC_MCREGISTERINFO_H
#define CS_LLVM_MC_MCREGISTERINFO_H

#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#endif

#include "capstone/platform.h"

/// An unsigned integer type large enough to represent all physical registers,
Expand Down
2 changes: 2 additions & 0 deletions MathExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#ifndef CS_LLVM_SUPPORT_MATHEXTRAS_H
#define CS_LLVM_SUPPORT_MATHEXTRAS_H

#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#endif

#ifdef _MSC_VER
# include <intrin.h>
Expand Down
5 changes: 4 additions & 1 deletion SStream.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <[email protected]>, 2013-2015 */

#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#endif
#include <stdarg.h>
#if defined(CAPSTONE_HAS_OSXKERNEL)
#include <libkern/libkern.h>
Expand All @@ -10,9 +12,10 @@
#endif
#include <string.h>

#include <capstone/platform.h>

#include "SStream.h"
#include "cs_priv.h"
#include "myinttypes.h"
#include "utils.h"

#ifdef _MSC_VER
Expand Down
2 changes: 1 addition & 1 deletion arch/AArch64/AArch64BaseInfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions arch/AArch64/AArch64BaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
#define CS_LLVM_AARCH64_BASEINFO_H

#include <ctype.h>
#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#endif
#include <string.h>

#ifndef __cplusplus
Expand Down
6 changes: 3 additions & 3 deletions arch/AArch64/AArch64Disassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions arch/AArch64/AArch64Disassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#ifndef CS_AARCH64_DISASSEMBLER_H
#define CS_AARCH64_DISASSEMBLER_H

#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#endif

#include "capstone/capstone.h"
#include "../../MCRegisterInfo.h"
Expand Down
4 changes: 2 additions & 2 deletions arch/AArch64/AArch64InstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#ifdef CAPSTONE_HAS_ARM64

#include "../../myinttypes.h"
#include <capstone/platform.h>
#include <stdio.h>
#include <stdlib.h>

Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 5 additions & 5 deletions arch/AArch64/AArch64Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion arch/ARM/ARMDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../../myinttypes.h"
#include <capstone/platform.h>

#include "ARMAddressingModes.h"
#include "ARMBaseInfo.h"
Expand Down
4 changes: 2 additions & 2 deletions arch/ARM/ARMInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <stdio.h> // DEBUG
#include <stdlib.h>
#include <string.h>
#include "../../myinttypes.h"
#include <capstone/platform.h>

#include "ARMInstPrinter.h"
#include "ARMAddressingModes.h"
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 5 additions & 5 deletions arch/ARM/ARMMapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
18 changes: 11 additions & 7 deletions arch/M68K/M68KDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 =========================== */
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}
Expand Down
Loading

0 comments on commit 45e5eab

Please sign in to comment.