Current Process Name in Kernel Driver!

Hello Everyone,

I am using the function attached below for retrieving the Current Process Name in a Kernel Driver.

The function seems to work fine on Windows XP, Vista and Windows 7 (32 & 64).
But randomly may be once after trying for several hours, the driver give a blue screen on a Windows XP 64 machine. The minidump created in windows folder does not have any useful stack information. I am not able to figure out what is causing this blue screen.

I have attached a copy of the full function which does the job for me.
Please let me know if this is the right way to retrieve the current process name or if there is any other better way of doing the same.

If required I can also post the stack information in the next message.

Will really appreciate and help on this.

Thank you!

BOOLEAN GetCurrentProcessName(PUNICODE_STRING pusImageFileName)
{
HANDLE lProcID = PsGetCurrentProcessId();

if(lProcID == NULL)
{
return FALSE;
}

return RetrieveNameByID(lProcID, pusImageFileName);
}

BOOLEAN RetrieveNameByID(HANDLE ProcessId, PUNICODE_STRING pusImageFileName)
{
UNICODE_STRING ProcImgName = {0};
HANDLE hProcessHandle = NULL;
NTSTATUS status = STATUS_ACCESS_DENIED;
PEPROCESS eProcess = NULL;
int iEntryIndex = -1;

//get process handle for given PID
status = PsLookupProcessByProcessId(ProcessId, &eProcess);
if((!NT_SUCCESS(status)) || (!eProcess))
{
return FALSE;
}

status = ObOpenObjectByPointer(eProcess, 0, NULL, 0, 0, KernelMode, &hProcessHandle);
if((!NT_SUCCESS(status)) || (!hProcessHandle))
{
ObDereferenceObject(eProcess);
eProcess = NULL;
return FALSE;
}

//Find out name of process
ProcImgName.Length = 0;
ProcImgName.MaximumLength = 1024;
ProcImgName.Buffer = ExAllocatePoolWithTag(NonPagedPool, ProcImgName.MaximumLength, ‘2leN’);

if(ProcImgName.Buffer == NULL)
{
ZwClose(hProcessHandle);
ObDereferenceObject(eProcess);
eProcess = NULL;
return FALSE;
}
RtlZeroMemory( ProcImgName.Buffer, ProcImgName.MaximumLength ) ;

status = GetProcessImageName(hProcessHandle, &ProcImgName);

if(!NT_SUCCESS(status))
{
ExFreePoolWithTag(ProcImgName.Buffer, ‘2leN’);
ZwClose(hProcessHandle);
ObDereferenceObject(eProcess);
eProcess = NULL;
return FALSE;
}

if(pusImageFileName)
{
RtlCopyUnicodeString(pusImageFileName, &ProcImgName);
}

ExFreePoolWithTag(ProcImgName.Buffer, ‘2leN’);
ZwClose(hProcessHandle);
ObDereferenceObject(eProcess);
eProcess = NULL;
return TRUE;
}

NTSTATUS GetProcessImageName(HANDLE ProcessHandle, PUNICODE_STRING ProcessImageName)
{
NTSTATUS status = STATUS_ACCESS_DENIED;
PUNICODE_STRING imageName = NULL;
ULONG returnedLength = 0;
ULONG bufferLength = 0;
PVOID buffer = NULL;

if(ZwQueryInformationProcess == NULL)
{
UNICODE_STRING routineName;
RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");
ZwQueryInformationProcess = (QUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName);
if (NULL == ZwQueryInformationProcess)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
}
// get the size we need
status = ZwQueryInformationProcess(ProcessHandle, ProcessImageFileName, NULL,
0, &returnedLength);

if(STATUS_INFO_LENGTH_MISMATCH != status)
{
return status;
}

//check the buffer size
bufferLength = returnedLength - sizeof(UNICODE_STRING);
if(ProcessImageName->MaximumLength < bufferLength)
{
ProcessImageName->Length = (USHORT) bufferLength;
return STATUS_BUFFER_OVERFLOW;
}

buffer = ExAllocatePoolWithTag(PagedPool, returnedLength, ‘ipgD’);
if(NULL == buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

status = ZwQueryInformationProcess(ProcessHandle, ProcessImageFileName, buffer,
returnedLength, &returnedLength);

if(NT_SUCCESS(status))
{
imageName = (PUNICODE_STRING) buffer;
RtlCopyUnicodeString(ProcessImageName, imageName);
}

ExFreePool(buffer);
return status;
}

Hmmmm… this code looks familiar (http://www.osronline.com/article.cfm?article=472). You’re welcome.

The dump doesn’t have any useful information… BUT you’re able to tell us that the listed function is the problem?

Please post the complete output from !analyze -v, with correct symbols, and we’ll see if we can help.

Peter
OSR

Hi Peter,

Thank you for your reply!
The article (http://www.osronline.com/article.cfm?article=472) solved my problem!

Well the above code was written earlier by one of my colleague, who now is not working with our company anymore.

As you can see the function RetrieveNameByID was written just to get the Process handle, which was not required as NtCurrentProcess() does the job. This I was able to figure this out from the link you provided.

Like I had mentioned in my post earlier that this blue screen occurs very rarely, the last time I had see the crash was at the following line:

//get process handle for given PID
status = PsLookupProcessByProcessId(ProcessId, &eProcess);
if((!NT_SUCCESS(status)) || (!eProcess))
{
return FALSE;
}

> status = ObOpenObjectByPointer(eProcess, 0, NULL, 0, 0, KernelMode, &hProcessHandle);

But that time the following check was missing:
if((!NT_SUCCESS(status)) || (!eProcess))

It was only:
if(!NT_SUCCESS(status))

I thought may be the check for eProcess was required and hence I added the same. As I said its very difficult to reproduce this issue hence not able to collect the dump and provide the analysis for the same. I have already spent 12 hours trying to reproduce the same with the old code.

Will continue to reproduce over the weekend. As of now I hope that replacing the NtCurrentProcess function has solved the problem.

I provided the full function only to get a feedback if there was any other way to retrieve the process name and your article did that for me :slight_smile:

Thank You once again!