I am creating a kernel mode driver that monitors process creation and sends information about it to the C# application. The information that should be passed is ProcessID and ProcessPath. At this point, the driver only sends ProcessID to the C# application, while I don't know how to send ProcessPath. I tried the GetProcessPathFromDriver() moetode given below in my code, but the returned string is Chinese characters. I am not advanced in kernel mode driver programming, so please help.
What I have tried:
Driver code:
ULONG ProcID;
PUNICODE_STRING ProcPath;
void sCreateProcessNotifyRoutineEx(PEPROCESS process, HANDLE pid, PPS_CREATE_NOTIFY_INFO createInfo)
{
UNREFERENCED_PARAMETER(process);
UNREFERENCED_PARAMETER(pid);
if (createInfo != NULL)
{
ProcID = HandleToUlong(pid);
ProcPath = createInfo->ImageFileName;
}
}
NTSTATUS HandleCustomIOCTL(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION stackLocation = NULL;
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
PVOID* buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG outLength = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
ULONG returnLength = 0;
stackLocation = IoGetCurrentIrpStackLocation(Irp);
if (stackLocation->Parameters.DeviceIoControl.IoControlCode == GET_PROCESS_PID)
{
Irp->AssociatedIrp.SystemBuffer = ProcID;
Irp->IoStatus.Information = sizeof(Irp->AssociatedIrp.SystemBuffer);
}
if (stackLocation->Parameters.DeviceIoControl.IoControlCode == GET_PROCESS_PATH)
{
RtlFillMemory(buffer, outLength, 0);
RtlCopyBytes(buffer, ProcPath->Buffer, ProcPath->Length * 2);
Irp->IoStatus.Status = STATUS_SUCCESS;
returnLength = ProcPath->Length * 2;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
C# app code:
public void GetProcessPathFromDriver()
{
const int MAX_STRING_SIZE = 64;
int numStringBytes = (MAX_STRING_SIZE + 1) * 2;
IntPtr p = Marshal.AllocHGlobal(numStringBytes);
DeviceIoControl(driverHandle, DriverOperations.GET_PROCESS_PATH, IntPtr.Zero, 0, p, numStringBytes, IntPtr.Zero, IntPtr.Zero);
String final = Marshal.PtrToStringUni(p);
if (System.IO.File.Exists(final))
{
MessageBox.Show("Recieved Path from kernel: " + final);
}
Marshal.FreeHGlobal(p);
}