Driver UNICODE_STRING 有垃圾????在字符串前面,第一个 4 或 8?字节被覆盖

Driver UNICODE_STRING has garbage ???? in front of string, first 4 or 8? bytes overwritten

我正在编写一个非常简单的内核 driver,它将一个 unicode 字符串存储为全局变量,然后只显示您传递给它的字符串。

这是 DebugView 的屏幕截图

运行 2

这是我的代码

UNICODE_STRING  ProcessName;
//...
    PIO_STACK_LOCATION  irpSp;// Pointer to current stack location
    irpSp = IoGetCurrentIrpStackLocation(Irp);
    ULONG inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; // Input buffer length
    ULONG outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; // Output buffer length

    DbgPrintEx(0, 0, "Size:  %lu  %lu \n", inBufLength, outBufLength);

    if (inBufLength == 0) {
        Status = STATUS_INVALID_PARAMETER;
        BytesIO = 0;
        goto finish;
    }

    PWSTR processBuffer;

    // Allocate the buffer that will contain the string
    processBuffer =ExAllocatePoolWithTag(NonPagedPool, irpSp->Parameters.DeviceIoControl.InputBufferLength+2, '5PWA');
    if(processBuffer == NULL){
        DbgPrint("Unable to allocate the dump filename: not enough memory.\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        BytesIO = 0;
        goto finish;
    }

    DbgPrint("Before New Process to %ws, len=%d\n", Irp->AssociatedIrp.SystemBuffer, irpSp->Parameters.DeviceIoControl.InputBufferLength);

    // Copy the buffer
    RtlCopyBytes((PVOID)processBuffer, Irp->AssociatedIrp.SystemBuffer, irpSp->Parameters.DeviceIoControl.InputBufferLength);

    DbgPrint("Set New Process to 1=%d\n", processBuffer[0]);
    DbgPrint("Set New Process to 2=%d\n", processBuffer[1]);
    DbgPrint("Set New Process to 3=%d\n", processBuffer[2]);
    DbgPrint("Set New Process to 4=%d\n", processBuffer[3]);
    DbgPrint("Set New Process to 5=%d\n", processBuffer[4]);
    DbgPrint("Set New Process to 6=%d\n", processBuffer[5]);

    // Force a [=12=] at the end of the filename to avoid that malformed strings cause RtlInitUnicodeString to crash the system
    ((PSHORT)processBuffer)[(irpSp->Parameters.DeviceIoControl.InputBufferLength+2)/2-1]=0;


    DbgPrint("After NULL New Process to %ws, len=%d\n", processBuffer, irpSp->Parameters.DeviceIoControl.InputBufferLength);


    // Create the unicode string
    RtlInitUnicodeString(&ProcessName, processBuffer);

    ExFreePool(processBuffer);

    UNICODE_STRING test;
    RtlInitUnicodeString(&test, L"test123");
    DbgPrint("test is %ws\n", test.Buffer);
    RtlInitUnicodeString(&test, L"test123");
    DbgPrint("test2 is %ws\n", test.Buffer);

    DbgPrint("Set New Process to 1=%d\n", ProcessName.Buffer[0]);
    DbgPrint("Set New Process to 2=%d\n", ProcessName.Buffer[1]);
    DbgPrint("Set New Process to 3=%d\n", ProcessName.Buffer[2]);
    DbgPrint("Set New Process to 4=%d\n", ProcessName.Buffer[3]);
    DbgPrint("Set New Process to 5=%d\n", ProcessName.Buffer[4]);
    DbgPrint("Set New Process to 6=%d\n", ProcessName.Buffer[5]);

    DbgPrint("Set New Process to %ws, len=%d\n", ProcessName.Buffer, irpSp->Parameters.DeviceIoControl.InputBufferLength);
    Status = STATUS_SUCCESS;
    BytesIO = 0;

另外 RtlCopyBytes 可以替换为 RtlMoveMemory

解决了...

我换了

RtlInitUnicodeString(&ProcessName, processBuffer);

RtlCreateUnicodeString(&ProcessName, processBuffer);

这就是源代码不起作用的原因

/**************************************************************************
 *      RtlInitUnicodeString   (NTDLL.@)
 *
 * Initializes a buffered unicode string.
 *
 * RETURNS
 *  Nothing.
 *
 * NOTES
 *  Assigns source to target->Buffer. The length of source is assigned to
 *  target->Length and target->MaximumLength. If source is NULL the length
 *  of source is assumed to be 0.
 */
void WINAPI RtlInitUnicodeString(
    PUNICODE_STRING target, /* [I/O] Buffered unicode string to be initialized */
    PCWSTR source)          /* [I]   '[=12=]' terminated unicode string used to initialize target */
{
    if ((target->Buffer = (PWSTR) source))
    {
        unsigned int length = strlenW(source) * sizeof(WCHAR);
        if (length > 0xfffc)
            length = 0xfffc;
        target->Length = length;
        target->MaximumLength = target->Length + sizeof(WCHAR);
    }
    else target->Length = target->MaximumLength = 0;
}

/**************************************************************************
 *  RtlCreateUnicodeString   (NTDLL.@)
 *
 * Creates a UNICODE_STRING from a null-terminated Unicode string.
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOLEAN WINAPI RtlCreateUnicodeString( PUNICODE_STRING target, LPCWSTR src )
{
    int len = (strlenW(src) + 1) * sizeof(WCHAR);
    if (!(target->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return FALSE;
    memcpy( target->Buffer, src, len );
    target->MaximumLength = len;
    target->Length = len - sizeof(WCHAR);
    return TRUE;
}