欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

深入分析Win7的对象引用跟踪机制

深入分析Win7的对象引用跟踪机制

Win7的内核新增了一系列带有Tag参数的对象增加引用(Refrence)/减少引用(Derefrence)函数,更易于找出对象使用中的“泄漏”(即Refrence和Derefrence次数不匹配)。
在Win7中,以下所有不带Tag的函数均使用一个默认的Tag("tlfD")直接调用带Tag参数的函数完成相应功能。相关函数如下:
ObfDereferenceObjectWithTag/ObfReferenceObjectWithTag
ObDereferenceObjectDeferDelete/ObDereferenceObjectDeferDeleteWithTag
ObReferenceObjectByHandle/ObReferenceObjectByHandleWithTag
ObReferenceObjectByPointer/ObReferenceObjectByPointerWithTag
ObfReferenceObject/ObfReferenceObjectWithTag
ObOpenObjectByPointer/ObOpenObjectByPointerWithTag
本文将具体分析该机制的内部实现。由于内容实在太多,有些细节只好略过了。
概述:
对象的引用跟踪机制类似于我们所熟悉的PoolTag内存泄漏跟踪机制,不同的是PoolTag跟踪的是内存的申请/释放操作,通过比对内存的申请/释放计数判断是否存在内存泄漏。而对象引用跟踪则跟踪的是对象的增加引用(Refrence)/减少引用(Derefrence)过程,通过比对两个操作的计数判断是否存在对象引用的“泄漏”。Win7内核提供了这样一种跟踪机制,在对象增加引用(Refrence)/减少引用(Derefrence)时插入一个操作,获取当前调用的上下文及引用的对象、引用计数等信息存入全局变量中,通过Windbg的辅助观察,可以很容易找到问题所在,方便程序员快速排查代码问题。
一、如何进行对象跟踪设置?
对象跟踪的相关参数主要有两个:
第一个是拥有哪些Tag的对象的增加引用(Refrence)/减少引用(Derefrence)操作将会被跟踪
第二个是哪些进程的增加引用(Refrence)/减少引用(Derefrence)操作会被跟踪
进程这个可能好理解一点,而这个Tag参数的理解则稍有点困难(我最初因为那些带Tag的内核函数所影响就理解错了)。这个值实际上应该是对象类型中的Key值,即_OBJECT_TYPE->Key。如果你要跟踪某一类型的对象,那么就把这个Tag参数设置成那个对象类型的Key值就行了,也就是申请/释放那个对象内存时使用的PoolTag。这样的Tag最多可以设置16个,也就是说最多可以跟踪16种不同类型的对象的引用操作。
设置对象跟踪的相关参数有两种方法,一种是通过注册表,可以使用gFlags工具来完成设置。具体地参考以下文章:
Configuring Object Reference Tracing(http://msdn.microsoft.com/en-us/libr...(v=VS.85).aspx)
附张图,一目了然:

通过gFlags设置的内容实际上被保存在HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel,如下:

通过注册表设置的内容需要重新启动才能起作用。
另一种方式则是实时设置,只需调用相关函数正确设置就可以立即开始对象跟踪。不过该方式MS似乎并未公开相关的内容。但是通过对内核中相关函数的逆向,我完整得出了这种设置方法的过程。设置对象跟踪参数是通过ZwSetSystemInformation实现的,InfoClass的值为86。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功