1 /* Capstone Driver */ 2 /* By Satoshi Tanda <tanda.sat (at) 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 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! 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() 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