In Windows, the OpenProcess function is a wrapper to the NtOpenProcess routine. NtOpenProcess is implemented in the kernel by NTOSKRNL.EXE. The function prototype for NtOpenProcess is:
NTSTATUS NtOpenProcess (OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL)
The ClientId parameter is the actual PID that is passed by OpenProcess. This parameter is optional, but during our observation the OpenProcess function always specified a ClientId when calling NtOpenProcess.
NtOpenProcess performs three primary functions:
PsLookupProcessByProcessId was the next obvious place for research. One of the outstanding questions was how does PsLookupProcessByProcessId know that a given PID is part of a valid process? The answer becomes clear in the first few lines of the disassembly:
- It verifies the process exists by calling PsLookupProcessByProcessId.
- It attempts to open a handle to the process by calling ObOpenObjectByPointer.
- If it was successful opening a handle to the process, it passes the handle back to the caller.
mov edi, edi
mov ebp, esp
mov eax, large fs:124h
mov esi, eax
dec dword ptr [esi+0D4h]
From the above disassembly, it is clear that ExMapHandleToPointer queries the PspCidTable for the process ID.
Now we have a complete picture of how Blacklight detects hidden processes:
- Blacklight starts looping through the range of valid process IDs, 0 through 0x41DC.
- Blacklight calls OpenProcess on every possible PID.
- OpenProcess calls NtOpenProcess.
- NtOpenProcess calls PsLookupProcessByProcessId to verify the process exists.
- PsLookupProcessByProcessId uses the PspCidTable to verify the processes exists.
- NtOpenProcess calls ObOpenObjectByPointer to get the handle to the process.
- If OpenProcess was successful, Blacklight stores the information about the process and continues to loop.
- Once the process list has been created by exhausting all possible PIDs. Blacklight compares the PIDB list with the list it creates by calling CreateToolhelp32Snapshot. CreateToolhelp32Snapshot is a Win32 API that takes a snapshot of all running processes on the system. A discrepancy between the two lists implies that there is a hidden process. This case is reported by Blacklight.