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;
}
我正在编写一个非常简单的内核 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;
}