恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
SystemInformer 开发规范完全指南:读懂 Process Hacker 源码必备的七类编码约定
首页
资讯中心
/
SystemInformer 开发规范完全指南:读懂 Process Hacker 源码必备的七类编码约定
SystemInformer 开发规范完全指南:读懂 Process Hacker 源码必备的七类编码约定
发布时间:2026/10/21 4:38:05
SystemInformer 开发规范完全指南读懂 Process Hacker 源码必备的七类编码约定【免费下载链接】systeminformerA free, powerful, multi-purpose tool that helps you monitor system resources, debug software and detect malware. Brought to you by Winsider Seminars Solutions, Inc. https://windows-internals.com项目地址: https://gitcode.com/GitHub_Trending/sy/systeminformerSystemInformer前身 Process Hacker由 Winsider Seminars Solutions 维护是一款开源的 Windows 系统监控、调试与反恶意软件工具其根目录的 HACKING.md 就是这套开发规范的核心文档。本文把其中的命名、类型、同步与内存管理约定整理成一份入职速查手册读完你能顺畅阅读源码也能写出符合规范的补丁。命名篇一个符号怎么读——风格与前缀体系风格只有三种且严格分工函数、函数参数、全局变量用CamelCase如PhCreateThread局部变量用lowerCamelCase如myString结构体、枚举、联合体用CAPS_WITH_UNDERSCORES如PH_STRING、PH_QUEUED_LOCK。前缀则是符号的“门牌号”Ph函数或PH_结构体公开 API外部可以依赖Php或PHP_模块私有实现派生规则很机械——在公开前缀后追加字母p所以Ph变Php、Pha变Phap没有前缀的函数与全局变量必须声明为static反过来static符号也不允许带公开前缀带私有前缀的名字不必static可以跨文件服务于本模块没有前缀的结构体只允许出现在.c/.cpp源文件内。这套体系的价值看符号首字母就能判断它是对外契约、模块内部实现还是文件级局部——评审代码时立刻知道哪些能碰、哪些不能动。 记住这一点见到Php/PHP_就当它是“别人家的内接线”可以读但不要在你的改动里调用或修改它。数据篇类型、布尔与注解固定宽度类型。除 Win32 API 场景外全库统一使用 NT 风格的定宽类型1 字节布尔用BOOLEAN4 字节布尔用LOGICAL字节用UCHAR2 字节SHORT/USHORT4 字节LONG/ULONG8 字节LONG64/ULONG64字符CHAR1 字节与WCHAR2 字节字符串PSTR/PWSTR。要点是“宽度钉死、跨平台一致”而不是靠类型名表达语义。布尔直接判断。写成if (flag)而不是if (flag TRUE)。原因TRUE宏值是 1而部分接口会返回非 1 的真值相等比较容易误判直接测试既简洁又安全。配套小技巧用!!expr把任意表达式“强转”成规范的 0/1 布尔把非布尔量赋给BOOLEAN时尤其好用。注解纪律。所有函数都要带_In_、_Inout_、_Out_等 SAL 注解。以 phlib/include/phbasesup.h 中的PhAllocate为例它同时挂了DECLSPEC_ALLOCATOR、DECLSPEC_NOALIAS、DECLSPEC_RESTRICT——MSVC 的 /analyze 静态分析靠这些注解自动校验内存与别名问题不是摆设。另有一条禁令定义中不用volatile确有必要时先转成指向 volatile 的指针再访问避免volatile沿变量扩散、过度压制编译器优化。契约篇成功与失败的四种说法全库只有四套“成败话术”返回BOOLEANTRUE即成功返回NTSTATUS用NT_SUCCESS宏判断返回HRESULT用HR_SUCCESS宏判断——明确禁用SUCCEEDED。原因是某些第三方组件用S_FALSE表达错误而SUCCEEDED会把它当成功导致假通过返回结果本身如指针用NULL这类特殊值表示失败。两条附属契约比话术更关键失败不改输出参数除非另有说明函数失败时_Out_/_Out_opt_参数保持调用前原样别假设回调没被调用传入回调的函数即便最终失败回调也可能已执行过所以回调内部必须自带状态防护。并发篇线程、集合与同步原语线程例程与统一入口线程入口函数必须长成这样_Function_class_注解配合NTAPI调用约定_Function_class_(USER_THREAD_START_ROUTINE) NTSTATUS NTAPI NameOfRoutine( _In_ PVOID Parameter );创建一律走四个入口PhCreateThread直接返回句柄、PhCreateThreadExNTSTATUS报告结果、句柄走输出参数、PhCreateThread2丢弃句柄、PhQueueUserWorkItem投递线程池工作项。入口收敛后每个线程的生命周期管理才可追溯。集合怎么选选型分两个阵营非侵入式PH_ARRAY、PH_LIST、PH_POINTER_LIST数组、RTL_AVL_TABLEAVL 树、RTL_GENERIC_TABLEsplay 树、PH_HASHTABLE哈希表、PH_CIRCULAR_BUFFER环形缓冲——容器自己管理元素存储侵入式LIST_ENTRY双链表/栈/队列、SINGLE_LIST_ENTRY单链表/栈、PH_AVL_LINKS、PH_HASH_ENTRY——链接字段直接嵌在元素结构体里省掉每节点一次额外分配。一句话建议元素本身需要独立存活、同时挂到列表里进程项、线程项这类场景优先侵入式要下标随机访问就用PH_ARRAY/PH_POINTER_LIST。同步基石queued lockHACKING.md 的硬规定是所有同步都用 queued lock理由尺寸小、性能好。phlib/include/queuedlock.h 里的PH_QUEUED_LOCK全部家当就是一个指针宽度的ULONG_PTR Value所有者标志、共享读计数、等待队列头都编码在它的位段里可静态初始化为PH_QUEUED_LOCK_INIT { 0 }。发生争用时等待者挂在 16 字节对齐的_PH_QUEUED_WAIT_BLOCK等待块链表上按到达顺序唤醒——像银行叫号排队插队不可能饿死不存在。它本质是读写锁但只拿独占获取/释放这对函数用效果等同互斥量PhAcquireQueuedLockExclusive(lock); // ...临界区... PhReleaseQueuedLockExclusive(lock);事件PH_EVENT 的惰性内核对象PH_EVENT把“状态位 引用计数 内核事件句柄”塞进一个结构体只有线程真正阻塞时才在背后创建内核事件对象平时测状态就是测PH_EVENT_SET这一个标志位开销远低于一次内核调用。高频 set/test、低频阻塞的场景这是最划算的形态。Rundown 保护对象销毁的“浇灭”PH_RUNDOWN_PROTECT解决监控工具的典型难题后台线程还在遍历列表UI 线程却要销毁它。rundown 的语义是允许已进入的读者继续跑完、拦住新读者进入、等全部读者退出后销毁方才能继续——先关闸等店内最后一位顾客出门再拉闸断电。条件变量直接建在 queued lock 上PH_CONDITION就是_PH_QUEUED_LOCK的 typedef——锁即条件变量无需额外同步状态。声明一个 queued lock 变量PhPulseCondition/PhPulseAllCondition负责唤醒PhWaitForCondition负责等待二者都是宏实际落到Phf前缀实现带超时的版本是PhWaitForConditionEx。Wake Event轮询加唤醒的自定义阻塞需要在循环里同时盯多个条件时约定姿势是循环内测试条件 →PhQueueWakeEvent/PhWaitForWakeEvent阻塞 → 条件被别的线程修改时调PhSetWakeEvent唤醒 →如果PhQueueWakeEvent之后发现条件其实已满足、不必阻塞就改调PhSetWakeEvent撤销等待。PH_WAKE_EVENT同样是 queued lock 的 typedef全程不产生内核事件对象。异常篇SEH 只留给三种时刻常规错误处理只有返回值一条路。SEH 异常仅用于“无法轻易恢复”的情形锁获取函数没能阻塞、对象引用计数为负等且只放行三个特例PhAllocate分配失败时抛异常。理由是分配失败罕见得足以让“每次分配都写检查分支”的额外成本不划算确实需要防御的路径改用PhAllocateSafe——它带_Must_inspect_result_注解强制调用方检查返回值两者分工非常清晰PhProbeAddress地址越界时抛异常。用异常表达探针失败能让一个__try块覆盖多次地址范围检查省掉每次检查一条分支程序员错误路径抛STATUS_NOT_IMPLEMENTED异常——那些本不应被走到的代码此处用assert(FALSE)也 acceptable。除此之外别加__try查返回值就够了。生命周期篇从 Allocate 到 Dereference基座是PhAllocate/PhFree复杂对象一律交给引用计数系统PhReferenceObject加一、PhDereferenceObject减一归零即销毁批量版PhReferenceObjects/PhDereferenceObjects对数组整体操作PhDereferenceObjectDeferDelete把删除推迟执行定义见 phlib/include/ref.h。引用计数就是借阅台账每次借出登记一笔计数归零才真正还书。不想手工记账的话半自动机制兜底PhAutoDereferenceObject宏名PH_AUTO把对象塞进当前线程的 auto-dereference 池设计对标 Apple 的NSAutoreleasePool——对象在未来某个不确定的时刻自动解引用但保证当前函数执行期间不被动。便捷宏PH_AUTO_T(PH_STRING, ...)即基于它。两条铁律违反是崩溃重灾区指针一旦存入全局可见位置或传给另一个线程必须先引用其余本地短暂引用多数情况不必传给函数的对象整个调用期间必须至少持有一个引用。经典错误是窗口过程里留着可能已被销毁的引用并隐式使用它——窗口过程执行中仍可能泵消息比如弹出对话框所以窗口过程要第一时间引用对象。动词语义精确分工这张表最容易写出“看着对、语义错”的代码动词含义收尾配对Allocate分配内存不初始化FreeCreate分配并初始化引用计数体系下指经引用系统创建Free/Destroy/PhDereferenceObjectFree释放Allocate或Create产物—Destroy同Free用于Create产物—Initialize用调用方提供的存储初始化DeleteDelete与Initialize配对只清状态、不释放内存—官方例子一一对应PhAllocateFromFreeList/PhFreeToFreeList、PhCreateFileDialog/PhFreeFileDialog、PhInitializeWorkQueue/PhDeleteWorkQueue、PhCreateString/PhDereferenceObject。计数的三种单位Length恒为字节PhCreateString要求字节长度、Count为元素/字符PhSubstring的长度、Index亦为元素PhSubstring的起点。细节向输出写 null 结尾字符串时返回计数必须包含 null 终止符本身。字符串对象PH_STRING头部是一个 union——既可当PH_STRINGREF看也可直接取Length永远字节与Buffer数据区WCHAR Data[1]与头部连续分配尾部另有 null 兼容传统 C 接口。操作面PhCreateString内联内部按字节数转调PhCreateStringEx、PhReferenceEmptyString取共享空串、PhConcatStrings/PhConcatStrings2拼接、PhFormatString格式化格式串带_Printf_format_string_注解分析器会替你核对参数。 记住这一点——不可变性边界字符串只在“PhCreateString/PhCreateStringEx刚创建之后、指针尚未外传之前”允许本地修改指针一旦交给别的函数或存入全局变量立即冻结为只读。PPH_STRING myString PhCreateString(Lhello); PPH_STRING title PH_AUTO_T( PH_STRING, PhConcatStrings2(LProcess: , myString-Buffer) );例子里的title随函数结束自动进池解引用省掉手写PhDereferenceObject的样板。收尾贡献者“下笔前自查清单”提交 PR 前逐项过一遍命名三种风格没有串门公开符号带Ph/PH_前缀文件私有函数是static且无前缀类型用定宽家族ULONG、PWSTR等布尔直接判断、不与TRUE比较参数全部带 SAL 注解HRESULT 用HR_SUCCESS判断全库搜不到SUCCEEDED失败路径保证不碰输出参数回调体做了状态防护线程走PhCreateThread/PhQueueUserWorkItem入口函数是统一签名同步用 queued lock含条件变量、wake event定义里没有volatile指针跨线程或入全局前先引用窗口过程里第一时间引用对象动词配对正确Create对Free/Dereference、Initialize对DeleteLength字节、Count/Index元素清单用熟之后“SystemInformer 式写法”就成肌肉记忆——这正是这套约定的目的让几十万行代码的评审与协作快如“一眼定归属”。【免费下载链接】systeminformerA free, powerful, multi-purpose tool that helps you monitor system resources, debug software and detect malware. Brought to you by Winsider Seminars Solutions, Inc. https://windows-internals.com项目地址: https://gitcode.com/GitHub_Trending/sy/systeminformer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考