c++kernelminifilter

using RtlCompareString to compare user data crashes OS


I have the following code which is responsible to receive and send data between my mini-filter driver and user-mode:

NTSTATUS MiniSendRecv(PVOID portcookie, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, PULONG RetLength) {
    PCHAR msg = "Hi User";
    PCHAR userData = (PCHAR)InputBuffer;
    DbgPrintEx(0, 0, "User said: %d:%s\n", strlen(userData), userData);
    DbgPrintEx(0, 0, "Before comparing strings\n");
    if (RtlCompareString(userData, (PCHAR)"status=stop", TRUE) == 0) {
        DbgPrintEx(0, 0, "stop requested\n");
    }
    //if((PCHAR)InputBuffer.contains("status=stopservice"))

    if (strlen(msg) > OutputBufferLength) {

        DbgPrintEx(0, 0, "message length too big\n");
        return STATUS_SUCCESS;
    }
    strncpy((PCHAR)OutputBuffer, msg, 500);
    return STATUS_SUCCESS;
}

WinDBG output:

User said: 11:status=stop
Before comparing strings
KDTARGET: Refreshing KD connection

*** Fatal System Error: 0x0000003b
                       (0x00000000C0000005,0xFFFFF8046D001E82,0xFFFF8580E9924C20,0x0000000000000000)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.

nt!DbgBreakPointWithStatus:
fffff804`6cdffc70 cc              int     3

As you can see the data is received just fine, but as soon as it hit RtlCompareString, the driver crashes causing the OS to crash as well.

Also prior to using PCHAR userData, I was doing if (RtlCompareString((PCHAR)InputBuffer, (PCHAR)"status=stop", TRUE) == 0) but that didn't do any good as well.

Can anyone tell me what is wrong here? when I call RtlCompareString against OutputBuffer, it works just fine.


Solution

  • RtlCompareString compares counted strings. What you have are null terminated strings. Just use the regular strcmp function, or since you seem to be trying to do a case insensitive string comparison you could try the non-standard _stricmp function.