Can you explain why the Handle type "Process" has a PID / process name in Process Hacker:
I've tried NtQueryObject()
and NtQuerySystemInformation()
but all of them don't work. There is no PID / process name on Handle Type "Process".
Can you explain why the Handle type "Process" has a PID / process name in Process Hacker:
I've tried NtQueryObject()
and NtQuerySystemInformation()
but all of them don't work. There is no PID / process name on Handle Type "Process".
You can enumerate the handles with NtQuerySystemInformation
and the SystemHandleInformation
Information Class. This will return an array of SYSTEM_HANDLE_INFORMATION
records.
SYSTEM_HANDLE_INFORMATION = record // Information Class 16
ProcessId: ULONG;
ObjectTypeNumber: UCHAR;
Flags: UCHAR; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
Handle: USHORT;
Object_: PVOID;
GrantedAccess: ACCESS_MASK;
end;
As this contains the PID of the process you now have a 1:1 relation between a process and the handles it has open.
Example code (full example here):
// uses JwaNative;
procedure EnumHandles;
var
shi: PSYSTEM_HANDLE_INFORMATION;
cbSize: DWORD;
cbRet: DWORD;
nts: NTSTATUS;
i: Integer;
hDupHandle: THandle;
dwErr: DWORD;
ObjectName: string;
begin
WriteLn('Enumerating Handles');
cbSize := $5000;
GetMem(shi, cbSize);
repeat
cbSize := cbSize * 2;
ReallocMem(shi, cbSize);
nts := NtQuerySystemInformation(SystemHandleInformation, shi, cbSize, @cbRet);
until nts <> STATUS_INFO_LENGTH_MISMATCH;
if nts = STATUS_SUCCESS then
begin
for i := 0 to shi^.HandleCount - 1 do
begin
if shi^.Handles[i].GrantedAccess <> $0012019f then
begin
if shi^.Handles[i].ProcessId = dwPid then
begin
nts := NtDuplicateObject(hProcess, shi^.Handles[i].Handle,
GetCurrentProcess, @hDupHandle, 0, 0, 0);
if nts = STATUS_SUCCESS then
begin
ObjectName := GetObjectName(hDupHandle);
if (ObjectName <> '') and SameText(RightStr(ObjectName, Length(EventName)), EventName) then
begin
WriteLn(Format('Handle=%d Name=%s', [shi^.Handles[i].Handle, ObjectName]));
CloseHandle(hDupHandle);
nts := NtDuplicateObject(hProcess, shi^.Handles[i].Handle,
GetCurrentProcess, @hDupHandle, 0, 0, DUPLICATE_CLOSE_SOURCE);
if nts = STATUS_SUCCESS then
begin
WriteLn(Format('Duplicated Handle with DUPLICATE_CLOSE_SOURCE, new Handle=%d', [hDupHandle]));
end;
end;
if hDupHandle > 0 then
CloseHandle(hDupHandle);
end;
end;
end;
end;
end
else begin
dwErr := RtlNtStatusToDosError(nts);
WriteLn(Format('Failed to read handles, NtQuerySystemInformation failed with %.8x => %d (%s)', [nts, SysErrorMessage(dwErr)]));
end;
FreeMem(shi);
end;