问Delphi7 NtQueryObject和NtQuerySystemInformation

时间:2019-03-20 01:20:17

标签: delphi delphi-7 pascal rad-studio

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

example from Process Hacker

我尝试过NtQueryObject()NtQuerySystemInformation(),但它们都不起作用。句柄类型“进程”上没有PID /进程名称。

1 个答案:

答案 0 :(得分: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;