Pass .NET Structure per IOCTL to KMDF

xxxxx@freenet.de wrote:

i’ve tried it by concating the string hash-values, convert them to a byte array and pass it down to driver by the following code:

string _HashValues =
*14cf73d771fa977a9f1cbaa5c301f912*7f0e061f5b6f311013968503d4c1d052*

static byte GetBytes(string str)
{
byte bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}

byte inBuffer = GetBytes(_HashValues);
DeviceIoControl(handle, ServiceInstaller.IOCTL_UPDATE_PROG_TABLE, inBuffer, inBuffer.Length, outBuffer, 0, out bytesReturned, IntPtr.Zero);

My last problem (and question, i promise) is that sometimes not the correct string-value appears in the driver:

wchar_t* test = (wchar_t*)Irp->AssociatedIrp.SystemBuffer;
DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, “test-wchar_t: %ls\n”,test);

The output looks like this (at the end of the string additional character are appended):

*14cf73d771fa977a9f1cbaa5c301f912*7f0e061f5b6f311013968503d4c1d052*e2-806e6f6e6963
or
*14cf73d771fa977a9f1cbaa5c301f912*7f0e061f5b6f311013968503d4c1d052*???}}}
(but not always)

I think i make a great mistake somewhere

Your mistake is not stepping back to think about what you are doing.

Say your string is 5 characters long, “ABCDE”. You are allocating 10
bytes. You then copy 10 bytes, so the buffer looks like this:
41 00 42 00 43 00 44 00 45 00

You then pass that to kernel mode, where you try to DbgPrint it with
%ls. What exactly does “%ls” mean? You are telling printf “I am
passing you a zero-terminated Unicode string.” But you are lying to
printf, because your string does not have a zero terminator. Printf
doesn’t know where the end of the string is.

So, the data is being passed correctly. It is your debug print that is
wrong. If you really want to print the string, there are several
options. You could wrap the buffer in a UNICODE_STRING structure and
print it using %Z:

UNICODE_STRING us = {
irpStack->Parameters.DeviceIoControl.InputBufferLength,
irpStack->Parameters.DeviceIoControl.InputBufferLength,
Irp->AssociatedIrp.SystemBuffer
};
DebugPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_ERROR_LEVEL, “test-wchar_t:
%Z\n”, &us );

Or, you can pass the length in:
DebugPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_ERROR_LEVEL, “test-wchar_t:
%.*ls\n”,
irpStack->Parameters.DeviceIoControl.InputBufferLength,
Irp->AssociatedIrp.SystemBuffer
);

Why are you not writing a KMDF driver?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.