views:

141

answers:

1

I'm writing a simple kernel driver for my application (which is somehow an antimalware application).

I hooked ZwOpenFile() and got the process handle calling this API with PsGetCurrentProcess() which returns a PEPROCESS stucture:

PEPROCESS proc = PsGetCurrentProcess();

then I used ZwQueryInformationProcess to get the PID and ImageFileName in this way:

DbgPrint("ZwOpenFile Called...\n");
DbgPrint("PID: %d\n", PsGetProcessId(proc));
DbgPrint("ImageFileName: %.16s\n", PsGetProcessImageFileName(proc));

And it works as expected.

To get the process FullPath I added the following lines, but It won't work and causes BSOD when I'm trying to open a file (for example when I open Notepad).

WCHAR strBuffer[260];
UNICODE_STRING str;

//initialize
str.Buffer = strBuffer;
str.Length = 0x0;
str.MaximumLength = sizeof(strBuffer);

//note that the seconds arg (27) is ProcessImageFileName
ZwQueryInformationProcess(proc, 27, &str, sizeof(str), NULL);

DbgPrint("FullPath: %wZ\n", str.Buffer);

Here is my DbgView output: DbgView Output

As you see str.Buffer is empty or filled with something irrelevant. maybe a buffer overflow while filling the str with ZwQueryInformationProcess causes the BSOD.

Can you please help me with this?

BSOD: alt text

+1  A: 

The MSDN docs for this API indicate that

When the ProcessInformationClass parameter is ProcessImageFileName, the buffer pointed to by the ProcessInformation parameter should be large enough to hold a UNICODE_STRING structure as well as the string itself. The string stored in the Buffer member is the name of the image file.file.

With this in mind, I suggest you try modifying your buffer structure like this:

WCHAR strBuffer[(sizeof(UNICODE_STRING) / sizeof(WCHAR)) + 260];
UNICODE_STRING str;
str = (UNICODE_STRING*)&strBuffer;

//initialize
str.Buffer = &strBuffer[sizeof(UNICODE_STRING) / sizeof(WCHAR)];
str.Length = 0x0;
str.MaximumLength = 260 * sizeof(WCHAR);

//note that the seconds arg (27) is ProcessImageFileName
ZwQueryInformationProcess(proc, 27, &strBuffer, sizeof(strBuffer), NULL);

Additionally, your code needs to check and handle the error case described in the docs here. This may be why you missed the BSOD trigger case.

If the buffer is too small, the function fails with the STATUS_INFO_LENGTH_MISMATCH error code and the ReturnLength parameter is set to the required buffer size.

Steve Townsend