Files
zer0condition 00a3adf890 initial commit
2026-08-19 01:39:41 +05:30

122 lines
4.0 KiB
C

/* driver.c - entry, device create, dispatch */
#include "inc/gvm.h"
#include "../shared/goodmans_ioctl.h"
DRIVER_INITIALIZE DriverEntry;
static DRIVER_UNLOAD gvm_unload;
static DRIVER_DISPATCH gvm_create_close;
static DRIVER_DISPATCH gvm_device_control;
PDEVICE_OBJECT g_device;
static UNICODE_STRING g_symlink;
NTSTATUS
DriverEntry(_In_ PDRIVER_OBJECT drv, _In_ PUNICODE_STRING regpath)
{
UNREFERENCED_PARAMETER(regpath);
// filter mask so DbgView captures our lines without Verbose
DbgSetDebugFilterState(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, TRUE);
DbgSetDebugFilterState(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL, TRUE);
DbgSetDebugFilterState(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, TRUE);
DbgSetDebugFilterState(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, TRUE);
gvm_log_init();
gvm_trace_init();
gvm_watchdog_start();
gvm_log("driver load");
UNICODE_STRING dev_name;
RtlInitUnicodeString(&dev_name, GVM_DEVICE_NAME_U);
NTSTATUS s = IoCreateDevice(drv, 0, &dev_name, GVM_DEVICE_TYPE,
FILE_DEVICE_SECURE_OPEN, FALSE, &g_device);
if (!NT_SUCCESS(s)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[goodmans] IoCreateDevice=%08x\n", s);
return s;
}
RtlInitUnicodeString(&g_symlink, GVM_SYMLINK_NAME_U);
s = IoCreateSymbolicLink(&g_symlink, &dev_name);
if (!NT_SUCCESS(s)) {
IoDeleteDevice(g_device);
g_device = NULL;
return s;
}
s = gvm_modtab_init();
if (!NT_SUCCESS(s)) {
IoDeleteSymbolicLink(&g_symlink);
IoDeleteDevice(g_device);
g_device = NULL;
return s;
}
drv->MajorFunction[IRP_MJ_CREATE] = gvm_create_close;
drv->MajorFunction[IRP_MJ_CLOSE] = gvm_create_close;
drv->MajorFunction[IRP_MJ_DEVICE_CONTROL] = gvm_device_control;
drv->DriverUnload = gvm_unload;
g_device->Flags |= DO_BUFFERED_IO;
g_device->Flags &= ~DO_DEVICE_INITIALIZING;
gvm_log("driver ready, device \\\\.\\Goodmans");
return STATUS_SUCCESS;
}
static VOID
gvm_unload(_In_ PDRIVER_OBJECT drv)
{
UNREFERENCED_PARAMETER(drv);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[goodmans] unload\n");
gvm_ih_teardown();
gvm_watchdog_stop();
gvm_notify_teardown();
gvm_modtab_teardown();
if (g_symlink.Buffer)
IoDeleteSymbolicLink(&g_symlink);
if (g_device)
IoDeleteDevice(g_device);
}
static NTSTATUS
gvm_create_close(_In_ PDEVICE_OBJECT dev, _Inout_ PIRP irp)
{
UNREFERENCED_PARAMETER(dev);
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
static NTSTATUS
gvm_device_control(_In_ PDEVICE_OBJECT dev, _Inout_ PIRP irp)
{
UNREFERENCED_PARAMETER(dev);
PIO_STACK_LOCATION sp = IoGetCurrentIrpStackLocation(irp);
NTSTATUS s = STATUS_INVALID_DEVICE_REQUEST;
switch (sp->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_GVM_LOAD_MODULE: s = gvm_ioctl_load(irp, sp); break;
case IOCTL_GVM_CALL_EXPORT: s = gvm_ioctl_call(irp, sp); break;
case IOCTL_GVM_UNLOAD_MODULE: s = gvm_ioctl_unload(irp, sp); break;
case IOCTL_GVM_LIST_MODULES: s = gvm_ioctl_list(irp, sp); break;
case IOCTL_GVM_MODULE_INFO: s = gvm_ioctl_info(irp, sp); break;
case IOCTL_GVM_UNLOAD_ALL: s = gvm_ioctl_unload_all(irp, sp); break;
case IOCTL_GVM_TAIL_LOG: s = gvm_ioctl_tail_log(irp, sp); break;
case IOCTL_GVM_READ_GUEST: s = gvm_ioctl_read_guest(irp, sp); break;
case IOCTL_GVM_TAIL_TRACE: s = gvm_ioctl_tail_trace(irp, sp); break;
case IOCTL_GVM_TRACE_CTL: s = gvm_ioctl_trace_ctl(irp, sp); break;
case IOCTL_GVM_FORCE_UNLOAD: s = gvm_ioctl_force_unload(irp, sp); break;
case IOCTL_GVM_NOTIFY_STOP: s = gvm_ioctl_notify_stop(irp, sp); break;
default: break;
}
irp->IoStatus.Status = s;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return s;
}