спросите Delphi7 NtQueryObject и NtQuerySystemInformation - PullRequest
0 голосов
/ 20 марта 2019

Можете ли вы объяснить, почему у типа дескриптора "Процесс" в Process Hacker есть PID / имя процесса:

example from Process Hacker

Я пробовал NtQueryObject() и NtQuerySystemInformation() но все они не работают.В дескрипторе типа «Процесс» отсутствует PID / имя процесса.

1 Ответ

1 голос
/ 20 марта 2019

Вы можете перечислить маркеры с 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;
...