Copying data from kernel to user mode

I have a structure as follows:

typedef struct PROCESS_LIST_ENTRY : LIST_ENTRY{
unsigned int ProcessID;
unsigned int ParentID;
PUNICODE_STRING ProcessPath;
}ProcessNameListEntry;

and in a method I have the following code:

UNICODE_STRING filePath;
//some code to copy data to filePath…
RtlStringCbCopyUnicodeString(pEntry->ProcessPath->Buffer, 1024,
&filePath);//Causes BSOD

The data being copied is a filepath and so can be up to 256 or 1024
even after ProcessPath->Buffer has been initialized with Rtlinit…

What could be causing this error? how to safely copy the data?

Can you post the code which initialises pEntry->ProcessPath?

If you are passing pEntry->ProcessPath->Buffer into RtlInitUnicodeString this is wrong - that function expects a UNICODE_STRING pointer, not a PWSTR and it will have corrupted the UNICODE_STRING structure if you do that. Instead pass pEntry->ProcessPath to RtlInitUnicodeString.

If I’m not mistaken, you mean that you’re trying to copy the data FROM USERMODE and TO KERNEL.
In this case, pEntry->ProcessPath->Buffer is a buffer you’ve allocated in the kernel and filePath is a user-space buffer.

In such a case - your access will cause a structured exception. you can verify it using _try around the RtlStringCbCopyUnicodeString line and see if the crash stops.

In order to copy the buffer from user-space into your kernel buffer, you need to attach to the process’s stack using KeStackAttachProcess which will make the user-space buffer accessible.

Note that KeStackAttachProcess is an expensive operation in regard to performance. Read the remarks section @ MSDN.

Good luck,
Daniel

@ISL: I’m initializing using ExAllocatePoolWithTag

filePath.Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool, IMAGE_FILEPATH_LENGTH + 1, ‘pPr’);

@Daniel
filePath is not user-space but the idea is to eventually pass pEntry->ProcessPath, ProcessId, and ParentId to userspace, using memcpy. I think there’s a reference violation before this line though but I’m having difficulty tracing the exact point.

Sure, but what about the UNICODE_STRING structure itself? You’re allocating memory for its buffer but if that’s all you’re doing then the pEntry->ProcessPath is not a valid pointer so when you dereference it you’ll get a BSOD. You need to allocate memory for pEntry->ProcessPath AND its member buffer as well as initialising ‘Length’ and ‘MaximumLength’.

I suppose you remember that each UNICODE character takes two bytes (if not using those extended ranges)?