记一次 .NET 某医疗器械 程序崩溃分析( 三 )

mscorlib_ni+0x63c78f 中的 Child-SP 值 。
0:120> k # Child-SPRetAddrCall Site ...0e 00000000`3103ca80 00007ffb`aa3882bfntdll!RtlFreeHeap+0x966e00f 00000000`3103cb20 00007ffb`66fac78fKERNELBASE!LocalFree+0x2f10 00000000`3103cb60 00007ffb`66f273a4mscorlib_ni+0x63c78f...因为这个 Child-SP 是 call 之前的 sp, 汇编中的 sp 是 call 之后的,所以相差一个 retaddr 指针单元,所以计算方法是: ChildSp- 0x8 + 0x8 就是 堆块句柄 。
0:120> dp 00000000`3103cb60-0x8+0x8 L100000000`3103cb6000000000`2c873720上面的 000000002c873720 就是堆块句柄,接下来用命令 !heap -x 000000002c873720 观察堆块情况 。
0:120> !heap -x 000000002c873720EntryUserHeapSegmentSizePrevSizeUnusedFlags-------------------------------------------------------------------------------------------------------------000000002c873710000000002c8737200000000000c40000000000002c8703c030-0LFH;free 果不其然,这个堆块已经是 Free 状态了,再 Free 必然会报错,经典的 Double Free 哈 。
4. 回首再看源码仔细阅读源码,发现有两个问题 。

  1. 没有对 localResource 加锁处理,在并发的时候容易出现问题 。
  2. localResource 是一个类级别变量,在多个方法中被使用,建议减低作用域 。
将信息反馈给朋友之后,建议朋友加锁并降低 localResource 作用域 。
三: 总结这次偶发的生产崩溃事故,主要原因是朋友的代码在逻辑上出了点问题,没有合理的保护好 localResource 句柄资源,反复释放导致的 ntheap 破坏 。
这个 dump 虽然问题比较小白,但逆向分析找出原因,还是挺考验基本功的 。
记一次 .NET 某医疗器械 程序崩溃分析

文章插图
【记一次 .NET 某医疗器械 程序崩溃分析】

经验总结扩展阅读