问Delphi7 NtQueryObject和NtQuerySystemInformation

问题描述 投票:-2回答:1

你能解释为什么Handle类型“Process”在Process Hacker中有一个PID /进程名称:

example from Process Hacker

我尝试过NtQueryObject()NtQuerySystemInformation(),但所有这些都不起作用。 Handle Type“Process”上没有PID /进程名称。

delphi delphi-7 pascal rad-studio
1个回答
1
投票

您可以使用NtQuerySystemInformationSystemHandleInformation信息类枚举句柄。这将返回一组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;
© www.soinside.com 2019 - 2024. All rights reserved.