Hi There,
After buying all the windows development driver dev books, reading 30 pages of google search results I am completely lost. So posting this is my last option before I just off shore this task to India for a couple of grand. You guys are my last hope.
I am trying (and have been for 3+ weeks) to make a kernel driver capable of intercepting process executions, sending the file details to a windows service, getting a response that says whether they can be executed or not. (Typical Anti-Virus behaviour).
The code I have so far is capable of intercepting processes and printing their details to debug. It is also capable of accepting an IOCTL call “Hello kerneland” message and returning a “hello from kernal land” message to userland.
My next step requires using the Inverted Call model to send the process details to userland so I can get the response. I have read the OSR article 5-6 times now and I understand completely how this works in theory, but the example is using WDF and my code isn’t, so I don’t understand where anything fits (C isn’t my language of choice, im a Python dev that has inherited this project). My Windows userland service is written in VB.net (I am fairly comfortable in VB.net) and I can get information in and out using IOCTL calls from userland, this works fine. Can someone point me in the right direction?
Here is my code currently:
// Known Working - Read + Write - Slight bug with the write printing to much
#include <ntddk.h>
#include <stdio.h>
#define IOCTL_HELLO_WORLD CTL_CODE( FILE_DEVICE_UNKNOWN, 0x900, METHOD_BUFFERED, FILE_READ_DATA|FILE_WRITE_DATA)
PDEVICE_OBJECT pDeviceObject;
UNICODE_STRING dev,dos;
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
VOID UnloadRoutine(
IN PDRIVER_OBJECT DriverObject
);
VOID CreateProcessNotifyEx(
inout PEPROCESS Process,
in HANDLE ProcessId,
__in_opt PPS_CREATE_NOTIFY_INFO CreateInfo
);
VOID CreateProcessNotifyEx(
__inout PEPROCESS Process,
in HANDLE ProcessId,
in_opt PPS_CREATE_NOTIFY_INFO CreateInfo
)
{
if (CreateInfo)
{
if(CreateInfo->FileOpenNameAvailable==TRUE)
{
DbgPrintEx(
DPFLTR_IHVDRIVER_ID,
DPFLTR_INFO_LEVEL,
“PID : 0x%X (%d) ImageName :%wZ CmdLine : %wZ \n”,
ProcessId,ProcessId,
CreateInfo->ImageFileName,
CreateInfo->CommandLine
);
}
//CreateInfo->CreationStatus = STATUS_ACCESS_DENIED;
CreateInfo->CreationStatus = STATUS_SUCCESS;
}
}
// IRP CREATE ROUTINE - Referenced In DriverEntry
NTSTATUS Create(PDEVICE_OBJECT DeviceObject,PIRP irp)
{
DbgPrint(“Create routine called.\n”);
irp->IoStatus.Status=STATUS_SUCCESS;
irp->IoStatus.Information=0;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// IRP CLOSE ROUTINE - Referenced In DriverEntry
NTSTATUS Close(PDEVICE_OBJECT DeviceObject,PIRP irp)
{
DbgPrint(“Close routine called.\n”);
irp->IoStatus.Status=STATUS_SUCCESS;
irp->IoStatus.Information=0;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// IOCTL - Handle I/O - Reference in DriverEntry
NTSTATUS IOCTL(PDEVICE_OBJECT DeviceObject,PIRP irp)
{
char local_buf[200];
int message_length;
PIO_STACK_LOCATION pIoStackLocation;
PVOID pBuf = irp->AssociatedIrp.SystemBuffer;
PCHAR welcome = “Hello from kerneland.”;
pIoStackLocation = IoGetCurrentIrpStackLocation(irp);
switch(pIoStackLocation->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_HELLO_WORLD:
message_length = _snprintf(local_buf,200,“%s”,pBuf);
DbgPrint(“IOCTL HELLOS.”);
DbgPrint(“Message received : %s”, pBuf);
//34
DbgPrint(“Input Message Length: %d”,message_length);
//30
DbgPrint(“Input Buffer Length: %d”,pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength);
RtlZeroMemory(pBuf,pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength);
RtlCopyMemory(pBuf, welcome, strlen(welcome) );
break;
}
// Finish the I/O operation by simply completing the packet and returning
// the same status as in the packet itself.
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = strlen(welcome);
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID UnloadRoutine(IN PDRIVER_OBJECT DriverObject)
{
PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX) CreateProcessNotifyEx, TRUE);
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Driver Was Unloaded\n”);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Driver Entry\n”);
// Define Device
RtlInitUnicodeString(&dev,L"\Device\Driver_Test");
RtlInitUnicodeString(&dos,L"\DosDevices\Driver_Test");
// Create Devce
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Creating Device\n”);
IoCreateDevice(DriverObject,0,&dev,FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_OPEN,FALSE,&pDeviceObject);
// Sym Link Device
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Creating Sym Link\n”);
IoCreateSymbolicLink(&dos,&dev);
// Set Interface State
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Setting Interface State\n”);
IoSetDeviceInterfaceState(RegistryPath, TRUE);
// Set A Create Routine
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Setting Create Callback\n”);
DriverObject->MajorFunction[IRP_MJ_CREATE]=Create;
// Set control routine
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Setting IOCTL Callback\n”);
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=IOCTL;
// Set close routine
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Setting Close Callback\n”);
DriverObject->MajorFunction[IRP_MJ_CLOSE]=Close;
// Set an unload routine for when the driver exits
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Setting Unload Callback\n”);
DriverObject->DriverUnload = UnloadRoutine;
// Set Flags
pDeviceObject->Flags|=DO_DIRECT_IO;
pDeviceObject->Flags&=~DO_DEVICE_INITIALIZING;
// Hook process creation
status = PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)CreateProcessNotifyEx, FALSE);
if(!NT_SUCCESS(status))
{
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,“Failed to PsSetCreateProcessNotifyRoutineEx .status : 0x%X \n”,status);
}
// Print started
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,“Driver Has Started\n”);
return STATUS_SUCCESS;
}
Thanks for your time.</stdio.h></ntddk.h>