-2

Can you explain why the Handle type "Process" has a PID / process name in Process Hacker:

example from Process Hacker

I've tried NtQueryObject() and NtQuerySystemInformation() but all of them don't work. There is no PID / process name on Handle Type "Process".

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Hoho
  • 11
  • 1
    Given a process handle, its filename can be queried using [`GetModuleFileNameEx()`](https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getmodulefilenameexw), [`GetProcessImageFileName()`](https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getprocessimagefilenamew), or [`QueryFullProcessImageName()`](https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-queryfullprocessimagenamew), and its PID can be queried using [`GetProcessId()`](https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getprocessid). – Remy Lebeau Mar 20 '19 at 01:37
  • but, how i get a pid or process name? using hObject ,not hProcess :( – Hoho Mar 20 '19 at 02:11
  • the point is, I want to know if there are other programs that access my program using openprocess – Hoho Mar 20 '19 at 02:22
  • 1
    that doesn't change what I said. `NtQuerySystemInformation()` to get open handles, search them for process handles, duplicate them into your process space, and query them for their info. There are plenty of examples of doing this if you look around. – Remy Lebeau Mar 20 '19 at 02:35
  • Add your point to your question – Nasreddine Galfout Mar 20 '19 at 08:04
  • ProcessHacker is open source you know.. – Sertac Akyuz Mar 20 '19 at 12:34

1 Answers1

1

You can enumerate the handles with NtQuerySystemInformation and the SystemHandleInformation Information Class. This will return an array of SYSTEM_HANDLE_INFORMATION records.

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;

As this contains the PID of the process you now have a 1:1 relation between a process and the handles it has open.

Example code (full example 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;
Remko
  • 7,214
  • 2
  • 32
  • 52