[Windows] 获取指定进程句柄数

有两种方法。

第一种:(此方法需要提升权限)

type
  TGetProcessHandleCount = function (hProcess: THandle; var pdwHandleCount: DWORD): LongBool; stdcall;
var
  _GetProcessHandleCount: TGetProcessHandleCount;

// 获取API地址, 建议放在 initialization 段中
_GetProcessHandleCount := GetProcAddress(GetModuleHandle(kernel32), 'GetProcessHandleCount');

// 使用API获取句柄数
function GetProcessHandleCount(PID: Cardinal): Cardinal;
var
  hProcess: THandle;
begin
  Result := 0;
  if Assigned(_GetProcessHandleCount) then begin
    hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
    if hProcess <> 0 then begin
      _GetProcessHandleCount(hProcess, Result);
      CloseHandle(hProcess);
    end;
  end;
end;

 提升权限的代码:

function EnablePrivilege(PrivName: string; bEnable: Boolean): Boolean;
var
  TP: PTokenPrivileges;
  Dummy: Cardinal;
  hToken: THandle;
begin
  Result := False;
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
  begin
    GetMem(TP, SizeOf(DWORD) + SizeOf(TLUIDAndAttributes));
    try
      TP.PrivilegeCount := 1;
      if LookupPrivilegeValue(nil, PChar(PrivName), TP.Privileges[0].Luid) then begin
        if bEnable then
          TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
        else
          TP.Privileges[0].Attributes := 0;
        Result := AdjustTokenPrivileges(hToken, False, TP^, SizeOf(TP), nil, Dummy);
      end else
        Result := False;
    finally
      FreeMem(TP);
      CloseHandle(hToken);
    end;
  end;
end;
EnablePrivilege('SeDebugPrivilege', True);  // 提升权限

 

Minimum supported client

Windows Vista, Windows XP with SP1 [desktop apps only]

Minimum supported server

Windows Server 2003 [desktop apps only]

 

 第二种: (直接查询信息,不需要提升权限)

type
  TSystemHandleInformationsBuffer = packed record
    NumberOfHandles: LongWord;
    SystemHandleInformations: array[0..MAX_LENGTH-1] of TSystemHandleInformation;
  end;

var
  FLocker: TCriticalSection;
  HandleInfoBuffer: Pointer;
  
function GetProcessHandleCount(PID: Cardinal): Cardinal;
var
  returnSize: Cardinal;
  p, p1: PAnsiChar;
begin
  P := HandleInfoBuffer;
  FLocker.Enter;
  Result := NtQuerySystemInformation(Cardinal(SystemHandleInformation),
    P, SizeOf(TSystemHandleInformationsBuffer), returnSize);
  if Result = 0 then begin
    returnSize := PLongWord(P)^;
    Inc(P, 4);
    p1 := p + returnSize * SizeOf(TSystemHandleInformation);
    while(p < p1) do begin
      if (PSystemHandleInformation(P)^.ProcessId = PID) then
        Inc(Result);
      Inc(P, SizeOf(TSystemHandleInformation));
    end;
  end else
    Result := 0;   
  FLocker.Leave;
end;

相关声明

type
  TNtQuerySystemInformation = function(infoClass: DWORD; buffer: Pointer; bufSize: DWORD;
    var returnSize: Dword): DWORD; stdcall;
  TNtQueryInformationProcess = function (ProcessHandle: Cardinal;
    ProcessInformationClass: PROCESSINFOCLASS; ProcessInformation: Pointer;
    ProcessInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;

var
  _NtQuerySystemInformation: TNtQuerySystemInformation;
  _NtQueryInformationProcess: TNtQueryInformationProcess;

function NtQuerySystemInformation(infoClass: DWORD; buffer: Pointer; bufSize: DWORD;
  var returnSize: Dword): DWORD;
begin
  if not Assigned(_NtQuerySystemInformation) then
    Result := 0
  else
    Result := _NtQuerySystemInformation(infoClass, buffer, bufSize, returnSize);
end;

function NtQueryInformationProcess(ProcessHandle: Cardinal;
    ProcessInformationClass: PROCESSINFOCLASS; ProcessInformation: Pointer;
    ProcessInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS;
begin
  if not Assigned(_NtQueryInformationProcess) then
    Result := 0
  else
    Result := _NtQueryInformationProcess(ProcessHandle, ProcessInformationClass,
      ProcessInformation, ProcessInformationLength, ReturnLength);
end;

initialization
  FLocker := TCriticalSection.Create;
  HandleInfoBuffer := GetMemory(SizeOf(TSystemHandleInformationsBuffer));
  _NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'), 'NtQuerySystemInformation');
  _NtQueryInformationProcess := GetProcAddress(GetModuleHandle('ntdll.dll'), 'NtQueryInformationProcess');

finalization
  FLocker.Free;
  FreeMemory(HandleInfoBuffer);

 

posted @ 2018-04-20 11:17  我爱我家喵喵  阅读(1179)  评论(0编辑  收藏  举报