Home | History | Annotate | Download | only in cs_driver
      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