Get process ID from process HANDLE

Hi guys,

I hooked ZwCreateProcess and now would like to print the process ID and the process path for any new process. Obtaining the process path was easy using, but now I have problems obtaining the process ID.

Would you please have a look at the following code?

NTSTATUS my_ZwCreateProcessEx(PARAMS_ZWCREATEPROCEX) {
NTSTATUS origstatus;

BOOLEAN known_proc;
NTSTATUS status;

// process name
UNICODE_STRING us_proc;
PROCESS_BASIC_INFORMATION ProcessBasicInfo;
DWORD pid = 0L;

// perform original call
origstatus = Real_ZwCreateProcessEx(PARAM_NAMES_ZWCREATEPROCEX);

DbgPrint(“HandleProcessInformation called\r\n”);

// get PID
status = NtQueryInformationProcess(
Process,
ProcessBasicInformation,
&ProcessBasicInfo,
sizeof(PROCESS_BASIC_INFORMATION),
NULL
);

DbgPrint(“NtQueryInformationProcess status 0x%x.\r\n”, status);
if (NT_SUCCESS(status)) {
pid = ProcessBasicInfo.UniqueProcessId;
} else {
DbgPrint(“NtQueryInformationProcess failed: 0x%x\r\n”, status);
pid = 0L;
}

return origstatus;
}

Too bad, this code is running into memory_corruption issues at the call to NtQueryInformationProcess(). Any ideas what’s wrong?

Thanks a lot in advance!

Chrischi

PS: Would it be possible to use GetProcessId within Windows API? http://msdn.microsoft.com/en-us/library/ms683215(VS.85).aspx
I tried using it, but loading the driver failed due to the call of GetProcessId with “the specified procedure was not found”.

Why are you resorting to hooking when there is a supported way to do this? If you insist on using the hook I doubt anyone will help you.

Look at PsCreateProcessNotifyRoutine, pre-Vista you need to do some extra work to get the program’s path but there exists an Ex version of the above function in Vista and later that gives you more information.

You can’t use usermode functions from the API in kernelmode.

Hey Chris,

Thanks for the reference to PsCreateProcessNotifyRoutine, it’s working great for my purpose!

Still I’m curious why my above mentioned procedure does not work, even using the kernel-based ZwQueryInformationProcess. Maybe also for other guys sticking to the same issue.

Anyway, thanks for your help!
Chris

Chris, list,

Although my PsCreateProcessNotifyRoutine callback function is ideal to get a handle to the ProcessId, now I’m stuck getting the process name (and path). When hooking ZwCreateProcess, I had a handle to the process and could use ZwQueryInformationProcess to obtain its ProcessImageFileName. However, now only given the ProcessId, I’m lacking the process handle to call this function.

Chris mentioned extra work for Win XP development (as I do), which I guess is an extra call to PsLookupProcessByProcessId to obtain an EPROCESS object of the new process. Still, I don’t understand the way how to obtain the process name given the EPROCESS object. It contains an ImageFileName element, but I think that relying on the EPROCESS structure is a bad idea, since it may change after Windows updates, which is bad for writing a reliable driver.

But maybe I’m still going the wrong way for my simple goal: “For any new process, print PID and process name.”

Thanks again for your help!

After carefully re-reading http://www.osronline.com/article.cfm?article=472 and searching this forum I found that exactly my issue was discussed over and over on OSR, thus sorry for my post. Thanks for this very useful post!

To solve my issue, I am now using PsCreateProcessNotifyRoutine() and PsSetLoadImageNotifyRoutine() in combination. Whichever Image a new process loads first I assume this image is the process name and path itself and I just ignore subsequent image load events for this ProcessId.