unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; // , PsAPI, TLHelp32;
type
T对象句柄 = class(TForm)
Button2: TButton;
Label1: TLabel;
txtPid: TEdit;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
SYSTEM_HANDLE = packed record
ProcessID: DWORD;
HandleType: WORD;
HandleNumber: WORD;
KernelAddress: DWORD;
Flags: DWORD;
end;
TOBJECT_INFORMATION_CLASS = (ObjectBasicInformation, ObjectNameInformation, ObjectTypeInformation, ObjectAllTypesInformation, ObjectHandleInformation);
SYSTEM_HANDLE_INFORMATION = packed record
Count: DWORD;
Handles: SYSTEM_HANDLE;
end;
PNtQuerySystemInformation = function(SystemInformationClass: DWORD; SystemInformation: Pointer; SystemInformationLength: ULONG; ReturnLength: PULONG): DWORD; stdcall;
PNtQueryObject = function(ObjectHandle: THANDLE; ObjectInformationClass: TOBJECT_INFORMATION_CLASS; ObjectInformation: Pointer; ObjectInformationLength: DWORD;
ReturnLength: PDWORD): DWORD; stdcall;
var
对象句柄: T对象句柄;
implementation
{$R *.dfm}
function GetProcessHandleCount(const PID: DWORD): Integer;
const
CIDefaultSize = $2000;
var
Ret: Cardinal;
i: Integer;
pdata: ^SYSTEM_HANDLE_INFORMATION;
pi: ^SYSTEM_HANDLE;
ModuleHandle: DWORD;
NtQueryObject: PNtQueryObject;
NtQuerySystemInformation: PNtQuerySystemInformation;
begin
pdata := nil;
Result := 0;
Ret := 0;
// 提升程序权限,提升Debug权限的代码很多,从网络照抄即可
// EnablePrivilege('SeDebugPrivilege', True);
ModuleHandle := GetModuleHandle('ntdll.dll');
NtQueryObject := GetProcAddress(ModuleHandle, 'NtQueryObject');
NtQuerySystemInformation := GetProcAddress(LoadLibrary('ntdll.dll'), 'NtQuerySystemInformation');
pdata := AllocMem(CIDefaultSize);
try
NtQuerySystemInformation(16, pdata, CIDefaultSize, @Ret); // 16,表明SystemInformationClass是Handle,获取系统所有句柄信息
if Ret > CIDefaultSize then
begin
ReallocMem(pdata, Ret);
if pdata = nil then
Exit;
if NtQuerySystemInformation(16, pdata, Ret, @Ret) <> 0 then
Exit;
end;
pi := @pdata.Handles;
for i := 0 to pdata.Count - 1 do
begin
if pi.ProcessID = PID then
begin
Inc(Result);
end;
Inc(pi);
end;
finally
if pdata <> nil then
FreeMem(pdata);
end;
end;
procedure T对象句柄.Button2Click(Sender: TObject);
var
PID, Count: Integer;
begin
if txtPid.text = '' then
begin
showmessage('PID不能为空!');
Exit;
end
else
begin
PID := StrToInt(txtPid.text);
Count := GetProcessHandleCount(PID);
Label1.caption := '句柄总数:' + IntToStr(Count);
end;
end;
end.
--------------------------------------------------------
以上代码在WinXPSP3,DelphiXE2通过