Вы можете перечислить маркеры с NtQuerySystemInformation
и SystemHandleInformation
Информационным классом.Это вернет массив SYSTEM_HANDLE_INFORMATION
записей.
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;
Поскольку он содержит PID процесса, теперь у вас есть отношение 1: 1 между процессом и дескрипторами, которые у него открыты.
Пример кода (полный пример здесь ):
// 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;