1 /* Capstone Driver */
2 /* By Satoshi Tanda <tanda.sat@gmail.com>, 2016 */
3
4 // Firstly, compile capstone_static_winkernel and
5 // generate capstone_static_winkernel.lib. It can be done by adding the
6 // capstone_static_winkernel project to your solution and compiling it first.
7 //
8 // Then, configure your driver project (cs_driver in this example) to locate to
9 // capstone.h and capstone_static_winkernel.lib. To do it, open project
10 // properties of the project and set Configuration to "All Configurations" and
11 // Platform to "All Platforms". Then, add the following entries:
12 // - C/C++ > General > Additional Include Directories
13 // - $(SolutionDir)capstone\include
14 // - Linker > Input > Additional Dependencies
15 // - $(OutDir)capstone_static_winkernel.lib
16 // - ntstrsafe.lib
17 //
18 // Note that ntstrsafe.lib is required to resolve __fltused indirectly used in
19 // Capstone.
20
21 #include <ntddk.h>
22 #include <capstone.h>
23
24 // 'conversion' : from function pointer 'type1' to data pointer 'type2'
25 #pragma warning(disable : 4054)
26
27
28 DRIVER_INITIALIZE DriverEntry;
29 static NTSTATUS cs_driver_hello();
30
31
32 // Driver entry point
DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)33 EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,
34 PUNICODE_STRING RegistryPath) {
35 printf("Entering DriverEntry()\n");
36
37 cs_driver_hello();
38
39 printf("Leaving DriverEntry()\n");
40 return STATUS_CANCELLED;
41 }
42
43 // Hello, Capstone!
cs_driver_hello()44 static NTSTATUS cs_driver_hello() {
45 csh handle;
46 cs_insn *insn;
47 size_t count;
48 KFLOATING_SAVE float_save;
49 NTSTATUS status = STATUS_UNSUCCESSFUL;
50
51 // Any of Capstone APIs cannot be called at IRQL higher than DISPATCH_LEVEL
52 // since our malloc implementation based on ExAllocatePoolWithTag() is not able
53 // to allocate memory at higher IRQL than the DISPATCH_LEVEL level.
54 NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
55
56 // On a 32bit driver, KeSaveFloatingPointState() is required before using any
57 // Capstone function because Capstone can access to the MMX/x87 registers and
58 // 32bit Windows requires drivers to use KeSaveFloatingPointState() before and
59 // KeRestoreFloatingPointState() after accessing them. See "Using Floating
60 // Point or MMX in a WDM Driver" on MSDN for more details.
61 status = KeSaveFloatingPointState(&float_save);
62 if (!NT_SUCCESS(status)) {
63 return status;
64 }
65
66 // Do stuff just like user-mode. All functionalities are supported.
67 if (cs_open(CS_ARCH_X86, (sizeof(void *) == 4) ? CS_MODE_32 : CS_MODE_64,
68 &handle) != CS_ERR_OK) {
69 goto exit;
70 }
71
72 count = cs_disasm(handle, (uint8_t *)&cs_driver_hello, 0x80,
73 (uint64_t)&cs_driver_hello, 0, &insn);
74 if (count > 0) {
75 printf("cs_driver!cs_driver_hello:\n");
76 for (size_t j = 0; j < count; j++) {
77 printf("0x%p\t%s\t\t%s\n", (void *)(uintptr_t)insn[j].address,
78 insn[j].mnemonic, insn[j].op_str);
79 }
80 cs_free(insn, count);
81 }
82 cs_close(&handle);
83
84 exit:;
85 // Restores the nonvolatile floating-point context.
86 KeRestoreFloatingPointState(&float_save);
87 return status;
88 }
89
90 // printf()
printf(const char * _Format,...)91 _Use_decl_annotations_ int __cdecl printf(const char *_Format, ...) {
92 NTSTATUS status;
93 va_list args;
94
95 va_start(args, _Format);
96 status = vDbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, _Format, args);
97 va_end(args);
98 return NT_SUCCESS(status);
99 }
100