Click here to Skip to main content
15,867,704 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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)
	{
		// Send process PID to user
		Irp->AssociatedIrp.SystemBuffer = ProcID;
		Irp->IoStatus.Information = sizeof(Irp->AssociatedIrp.SystemBuffer);
	}
	if (stackLocation->Parameters.DeviceIoControl.IoControlCode == GET_PROCESS_PATH)
	{
		// Send process Path to user
		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);
        }
Posted
Updated 12-Mar-23 3:51am
v2
Comments
0x01AA 12-Mar-23 10:27am    
Ṉobody 12-Mar-23 11:22am    
I read it, but did not find a solution there
Rick York 12-Mar-23 12:02pm    
You should read it again because there are a few things mentioned there that you are not doing. One is allocating the buffer for the string.
0x01AA 12-Mar-23 12:03pm    
Sorry, that it did not helped.
Maybe you can add a hex representation, what your c# receives as filename. This, because I think to remember, that I fighted with a similar issue for USB driveres, where the W32 API should deliver WideChar but always delivered Ansi (and this even I used the xyz_W api)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900