2026/5/24 14:55:44
网站建设
项目流程
搜索关键词站长工具,建网站代理,wordpress手机端加载不出来,在线制作头像图片生成器一#xff1a;背景1. 讲故事这段时间都在跑外卖#xff0c;感觉好久都没写文章了#xff0c;今天继续给大家带来一篇崩溃类的生产事故#xff0c;这是微信上有位老朋友找到我的#xff0c;让我帮忙看下为啥崩溃了#xff0c;dump也在手#xff0c;接下来就可以一顿分析。…一背景1. 讲故事这段时间都在跑外卖感觉好久都没写文章了今天继续给大家带来一篇崩溃类的生产事故这是微信上有位老朋友找到我的让我帮忙看下为啥崩溃了dump也在手接下来就可以一顿分析。二崩溃分析1. 为什么会崩溃双击打开dump文件会看到崩溃信息通览参考如下Executable search path is:Windows 10 Version 17763 MP (48 procs) Free x64Product: Server, suite: TerminalServer DataCenter SingleUserTSEdition build lab: 17763.1.amd64fre.rs5_release.180914-1434Debug session time: Fri Oct 31 17:38:42.000 2025 (UTC 8:00)System Uptime: 14 days 2:42:29.643Process Uptime: 0 days 0:00:58.000.......................................................................................................Loading unloaded module list.This dump file has an exception of interest stored in it.The stored exception information can be accessed via .ecxr.(5a74.6250): Unknown exception - code c0000374 (first/second chance not available)For analysis of this file, run !analyze -vntdll!NtWaitForMultipleObjects0x14:00007ffe57baf0e4 c3 ret从卦中看崩溃码是 c0000374即 ntheap 损坏哈哈到这里一下子就把范围给缩小了。2. 为什么ntheap 损坏那为什么ntheap会损坏呢可以使用 .ecxr 切到崩溃时的调用栈观察崩溃行为。0:032 .ecxr0:032 k*** Stack trace for last set context - .thread/.cxr resets it# Child-SP RetAddr Call Site00 000000b48503ede0 00007ffe57c0b313 ntdll!RtlReportFatalFailure0x901 000000b48503ee30 00007ffe57c13b9e ntdll!RtlReportCriticalFailure0x9702 000000b48503ef20 00007ffe57c13eaa ntdll!RtlpHeapHandleError0x1203 000000b48503ef50 00007ffe57bae109 ntdll!RtlpHpHeapHandleError0x7a04 000000b48503ef80 00007ffe57bbbb0e ntdll!RtlpLogHeapFailure0x4505 000000b48503efb0 00007ffe17d17b3f ntdll!RtlFreeHeap0x9d3ce06 000000b48503f050 00007ffe541392af AcLayers!NS_FaultTolerantHeap::APIHook_RtlFreeHeap0x41f07 000000b48503f0b0 00007ffe3773b17e KERNELBASE!LocalFree0x2f08 000000b48503f0f0 00007ffe37661d12 mscorlib_ni0x58b17e09 000000b48503f1a0 00007ffde49fe127 mscorlib_ni!System.Runtime.InteropServices.Marshal.FreeHGlobal0x22 [f:\dd\ndp\clr\src\BCL\system\runtime\interopservices\marshal.cs 1212]...0:032 !clrstackOS Thread Id: 0x6250 (32)Child SP IP Call Site000000b48503f118 00007ffe57baf0e4 [InlinedCallFrame: 000000b48503f118] Microsoft.Win32.Win32Native.LocalFree(IntPtr)000000b48503f118 00007ffe3773b17e [InlinedCallFrame: 000000b48503f118] Microsoft.Win32.Win32Native.LocalFree(IntPtr)000000b48503f0f0 00007ffe3773b17e DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr)000000b48503f1a0 00007ffe37661d12 System.Runtime.InteropServices.Marshal.FreeHGlobal(IntPtr) [f:\dd\ndp\clr\src\BCL\system\runtime\interopservices\marshal.cs 1212]000000b48503f1e0 00007ffde49fe127 b.BA.MoveNext()000000b48503f240 00007ffe376b3423 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs 954]000000b48503f310 00007ffe376b32b4 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs 902]...000000b48503f5c0 00007ffde49fb04e DomainBoundILStubClass.IL_STUB_ReversePInvoke(Int32, Int32, Int64)从卦中可以清晰的看到是 b.BA.MoveNext 方法中调用了 FreeHGlobal 导致的NTHeap崩溃如果你经验比较足的话看到这个 FreeHGlobal 就应该想到 double free 问题这是一个经典的问题。3. 何为 double free双释放即对一个 block 块进行二次释放windows 的 RtlFreeHeap 方法会在业务逻辑中对这种情况直接判为异常接下来你或许想知道这个 block 的地址是什么这个可以用 !heap -s 观察参考代码如下0:032 !heap -s************************************************************************************************************************NT HEAP STATS BELOW************************************************************************************************************************Details:Heap address: 0000028c75bb0000Error address: 0000028c786018a0Error type: HEAP_FAILURE_BLOCK_NOT_BUSYDetails: The caller performed an operation (such as a freeor a size check) that is illegal on a free block.Follow-up: Check the errors stack trace to find the culprit.Stack trace:Stack trace at 0x00007ffe57c7284800007ffe57bae109: ntdll!RtlpLogHeapFailure0x4500007ffe57bbbb0e: ntdll!RtlFreeHeap0x9d3ce00007ffe17d17b3f: AcLayers!NS_FaultTolerantHeap::APIHook_RtlFreeHeap0x41f00007ffe541392af: KERNELBASE!LocalFree0x2f00007ffe3773b17e: mscorlib_ni0x58b17e00007ffe37661d12: mscorlib_ni!System.Runtime.InteropServices.Marshal.FreeHGlobal0x2200007ffde49fe127: 0xe49fe127LFH Key : 0x765363a7204cf973Termination on corruption : ENABLEDHeap Flags Reserv Commit Virt Free List UCR Virt Lock Fast(k) (k) (k) (k) length blocks cont. heap-------------------------------------------------------------------------------------0000028c75bb0000 00000002 17920 9256 16364 2120 214 5 1 a LFHExternal fragmentation 23 % (214 free blocks)0000028c75b40000 00008000 64 4 64 2 1 1 0 00000028c75de0000 00001002 2636 132 1080 20 5 2 0 0 LFH0000028c76190000 00001002 4680 2268 3124 1420 40 3 0 0 LFHExternal fragmentation 62 % (40 free blocks)0000028c76130000 00001002 2636 472 1080 5 27 2 0 0 LFH0000028c767f0000 00041002 60 8 60 5 1 1 0 00000028c77020000 00041002 60 16 60 2 2 1 0 0-------------------------------------------------------------------------------------从卦中可以看到 Heap address: 0000028c75bb0000 即为 block 地址接下来使用 !heap -x 0000028c786018a0 观察这个 block 块的状态可以看到此时确实是 free 的。0:032 !heap -x 0000028c786018a0Entry User Heap Segment Size PrevSize Unused Flags-------------------------------------------------------------------------------------------------------------0000028c786018a0 0000028c786018b0 0000028c75bb0000 0000028c785c80d0 e0 - 0 LFH;free到这里问题的成因我们是完全搞清楚了接下来就是反推问题代码的时候了。4. 问题代码在哪里应该有朋友知道问题是在 b.BA.MoveNext() 方法中从名字上看这个项目应该是混淆的有点搞哈。。。得要费点眼力截图如下从卦中的 IntPtr intPtr Interlocked.Exchange(ref b.A, IntPtr.Zero); 来看这个 intPtr 是一个类级别变量看样子是多个方法在操控类级别变量时没有合理的控制好为了一探究竟再次分析源代码果然是的截图如下到这里就真相大白了让朋友修改源码自己控制好这个变量。