[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);