定位句柄泄露需提权启用sedebugprivilege,再用ntquerysysteminformation+system_handle_information_ex获取进程句柄快照,结合objaddr差分比对识别未关闭资源,并通过api hook或类型枚举检测典型泄漏模式。

在Windows平台开发C++服务程序时,需要实时捕获进程当前所有打开的句柄(文件、事件、互斥体、线程、注册表键等),并持续比对变化以识别未关闭资源,这是定位句柄泄露的核心手段。
启用SeDebugPrivilege权限
调用OpenProcess或NtQuerySystemInformation获取其他进程句柄前,必须先为当前进程提权。否则OpenProcess会返回ERROR_ACCESS_DENIED,NtQuerySystemInformation对非自身进程句柄枚举将被跳过。
调用OpenProcessToken→LookupPrivilegeValue(L"SeDebugPrivilege")→AdjustTokenPrivileges启用该权限。这一步失败会导致后续所有跨进程句柄采集全部静默失败。
注意:仅管理员组成员可成功启用此权限;普通用户即使调用成功,AdjustTokenPrivileges也会返回FALSE且GetLastError为ERROR_NOT_ALL_ASSIGNED。
获取当前进程完整句柄表快照
方法一:使用NtQuerySystemInformation + SYSTEM_HANDLE_INFORMATION_EX(推荐)
声明SYSTEM_HANDLE_INFORMATION_EX结构体,调用NtQuerySystemInformation(38, buf, size, &retSize)反复重试直至缓冲区足够;过滤出CurrentProcessId匹配的条目,保存HandleValue、ObjectTypeIndex、Object、GrantedAccess字段。
方法二:通过ZwQueryObject逐个探测(低效但稳定)
遍历0x1000~0xFFFF句柄值,对每个句柄调用ZwQueryObject(handle, ObjectBasicInformation, …),若返回STATUS_SUCCESS则说明句柄有效,再调用ZwQueryObject(handle,ObjectNameInformation,…)获取名称。该方式不依赖系统信息类API,但速度极慢且可能触发AV(访问已释放句柄)。
【务必在调用ZwQueryObject前用IsBadReadPtr验证ObjectInfo缓冲区可写】
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
构建句柄生命周期追踪器
第一步:定义快照数据结构
struct HandleRecord { HANDLE h; DWORD pid; USHORT typeIdx; ULONG64 objAddr; std::wstring name; }; 使用std::map
第二步:实现差分比对逻辑
对同一PID的两次快照A和B,遍历B中每个句柄,检查其h+objAddr是否存在于A中;未命中者视为新分配句柄;A中有而B中无者标记为“疑似已关闭”。需特别注意:相同句柄值可能被重复分配(如CloseHandle后又CreateEvent),因此必须联合objAddr判断唯一性。
第三步:注入定时采集点
在主线程创建一个WaitForSingleObject(hTimer, 5000)循环,每次触发时调用快照函数并存入std::deque<:pair snapshot>>历史队列,最多保留最近10次快照。避免高频采集拖垮系统性能。
识别典型资源泄露模式
监控CreateFileW/CreateFileA调用后未配对CloseHandle:在DLL入口或模块初始化处Hook Kernel32!CreateFileW,记录调用栈与返回句柄;再Hook CloseHandle,移除对应记录;运行一段时间后,未被移除的句柄即为泄漏点。
检测重复OpenEvent/OpenMutex未Close:枚举句柄类型索引(通过ObGetObjectTypeIndex或硬编码映射表),筛选出类型为Event/Mutant/Section的句柄,统计同名对象出现次数。若同一名称的Event句柄在快照中持续存在且数量递增,基本可判定未释放。
注意:某些系统服务会复用句柄值(如svchost.exe频繁创建销毁事件),应结合objAddr而非仅凭句柄数值判断是否真实泄漏。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










