记一次 .NET 某企业采购平台 崩溃分析

网站建设1年前发布
33 00

前段时间有个朋友找到我,说他们的程序有偶发崩溃的情况,让我帮忙看下怎么回事,针对这种 crash 的程序,用 AEDebug 的方式抓取一个便知,有了 dump 之后接下来就可以分析了。,既然是程序的崩溃,我们可以像看蓝屏一下看dump文件,使用 !analyze -v 命令即可。,从上面的信息看,这个程序是一个经典的 访问违例 异常,违例是因为 rax=0 导致读取了不该读取的地方,接下来我们切到异常上下文看下为什么会是 0 ?,要想切到异常上下文,先使用 .ecxr 命令,再使用 ub 反汇编。,从汇编代码看,rax 是 clr!MethodTable::GetComCallWrapperTemplate 方法的返回值,从方法名字看是一个经典的 COM 和 .NET 互操作,接下来继续用 uf 反汇编看下这个方法,精简后的代码如下:,再结合 coreclr 源码:,到这里大概能推测到是因为 EEClass.m_pccwTemplate 字段为 null 所致,从注释看,他是 CLR 用来暴露给 COM 使用的数据结构,那为什么暴露给 COM 使用的数据结构为 NULL 呢? 这个分析起来就复杂了。,但有一点可以确定,像这种逻辑必然是 坚如磐石,受过日月精华,经历过500年的风吹雨打,不可能无缘无故的出篓子。,要寻找突破口还得从调用栈入手,我们用 k 命令洞察一下。,仔细观察线程栈信息,不难发现用户是在用 DoDragDrop 方法实现控件的拖拽,不过在执行流中有一个陌生的动态链接库 wwkrn64,它到底是何方神圣呢?我们用 lmvm 观察下。,从输出信息看,果然是一个外来物种,经过网上一顿搜索,发现是一款 信息安全软件,哪家公司就模糊了哈,截图如下:,记一次 .NET 某企业采购平台 崩溃分析,到这里就真相大白了,让朋友把这款软件卸载掉再试试看,问题就解决了。,我这里只能简单推测一下,ComCallPreStub 和 ComPreStubWorker 方法是 JIT 在编译某一个方法时的前缀路径,也是很多 加壳软件 以及 永恒之蓝 这样的蠕虫病毒重点关注的方法,所以这些高危方法自然也是 安全软件 重点监视的,如果 安全软件 没处理好,自然就会误杀。。。,当然真正的原因只能问 系铃人 。,可能有些朋友要说了,怎么验证这两个方法就是 JIT 编译的前缀,这里我们用 普通方法+windbg 的方法简单验证下吧,参考代码如下:,接下来我们重点观察下 Test 方法的编译过程,看过程之前先上一张架构图:,记一次 .NET 某企业采购平台 崩溃分析,从架构图看 Test() 方法的编译最终是由 clrjit!jitNativeCode 来处理的,要想验证很简单用 bp clrjit!jitNativeCode 下一个断点即可。,如果想在 jitNativeCode 方法中把 md 提取出来的话,可以取 r9 参数。,这次崩溃事故的直接原因是由于第三方安全软件的介入导致的,因 ComPreStubWorker 是加壳程序和蠕虫病毒注入的突破口,不管怎样还是希望安全软件对高危函数 ComPreStubWorker 的照护逻辑再优化下吧,减少误杀的发生。

© 版权声明

相关文章