100 lines
3.2 KiB
C
100 lines
3.2 KiB
C
/* Capstone Driver */
|
|
/* By Satoshi Tanda <tanda.sat@gmail.com>, 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 <ntddk.h>
|
|
#include <capstone/capstone.h>
|
|
|
|
// '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 accessing 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 functionalities 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);
|
|
}
|