一:背景
1. 讲故事
前几天高级调试训练营里的一位学员找到我,说他们的程序句柄爆高,经过自己分析之后发现是几百万的 process 句柄,截图如下:
说实话,第一眼看到有这么多的 process 句柄还是挺震惊的,在我的400+dump分析之旅中还是从未见过,这也给了我很大的好奇心,接下来我们就来分析下到底是何方神圣导致的问题。
二:WinDbg 分析
1. process 句柄真的爆高吗
dump分析的一个重要原则就是相信数据而不是人言,即使是我的学员。。。所以我让学员用 procdump 给我抓一个 minidump,我要亲自用 !handle
洞察 process 句柄个数,参考命令如下:
由于process句柄太多,没法全部刷出来,不过从满篇的Process
来看,确实是这样,接下来的问题是如何知道 process 句柄是谁创建的?
2. Process 句柄是谁创建的
哈哈,学员就是学员,精髓都学到了,知道这种问题应该用什么工具,对,就是 perfview,学员用 perfview 追踪了 3分钟多,有些人可能要问,这个时间是怎么看出来的,可以打开 TraceInfo
选项就知道了,截图如下:
有了 etl 文件之后,打开 Windows Handle Ref Count Stacks
选项卡,可以看到 3分多时间内 追踪到了 5756
个句柄,截图如下:
接下来就是双击 Handle Type Process
行,展开这 5756 个句柄详情,然后多次点击具体的句柄观察特征,结果发现大量的 process 的上游都挂了 halcon 的 ReadImage() 方法,截图如下:
从调用栈来看,ReadImage()
会涉及到文件IO,所以在内核层自然会和文件系统驱动 fltmgr.sys
打交道,但在调用栈的末端被一个 dcfafilter.sys
驱动给拦截了,从名字上来看不像是windows自带的,而且也正是它创建的 process 句柄,类似 OpenProcess 操作。
到这里我的疑心越来越重,让朋友到 C:\Windows\System32\drivers
目录中看下这个驱动是干什么的?是哪个程序引用着这个驱动。可以用类似的命令查看。
经过朋友的一顿猛如虎的操作,终于给找到了,原来是 ManageEngine Unified Endpoint Security - Agent
服务,截图如下;
拿着这个信息到网上一搜,我去,还真是第三方的运维监控软件,截图如下:
到这里就真相大白了,然来是 ManageEngine 捣的鬼。。。无语了。。。朋友关闭了这个服务之后,句柄恢复了正常,截图如下;
三:总结
我见过太多的安全软件导致程序出现各种故障,但那些都是在用户态
层面进行的干扰,而这次生产故障是我第一次见到有安全软件在内核态
干扰应用程序,长见识啦!