你能解释为什么Handle类型“Process”在Process Hacker中有一个PID /进程名称:
我尝试过NtQueryObject()
和NtQuerySystemInformation()
,但所有这些都不起作用。 Handle Type“Process”上没有PID /进程名称。
您可以使用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的关系。
示例代码(完整示例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;