Hi Michael,
First of all, you should not trust data in the PEB – the user-mode application can modify this. You can get the parent PID from the EPROCESS structure – if you’re in kernel you can use PsGetProcessInheritedFromUniqueProcessId(), or if you’re in user-mode then NtQueryInformationProcess can help you for native code, or the toolhelp API from Win32.
Same for the process image name – the API you’re using queries the image file name from the PEB, which is not trustworthy. If you’re in kernel, use SeLocateProcessImageName. If you’re in user-mode, there’s a different info class from that one, and the documented Win32API is QueryProcessFullImageName.
To answer your question however, PIDs in Windows are re-used, that’s why you can never trust that the parent PID is still around. What Process Explorer does is check the CreateTime of the child and parent. If the create time of the parent is later than the create time of the child, Mark assumes the Parent PID was re-used.
This technique works only if the user never sets the clock back (which Windows can do as well as part of time synchronization).
What you really need is a sequence number. CSRSS maintains one in the CSR_PROCESS structure, but that’s undocumented. In Windows 10, the kernel *finally* stores a per-process sequence number which can solve this issue. But I doubt you want your code to work on Windows 10 only ![]()
The other option is to implement a filter driver by using PsSetProcessCreateNotifyRoutineEx. This way, you’ll get a notification for every PID Created/Terminated, and you can maintain your own state.
–
Best regards,
Alex Ionescu