记一次 .NET某列控连锁系统 崩溃分析
一:背景
1. 讲故事
过年喝了不少酒,脑子不灵光了,停了将近一个月没写博客,今天就当新年开工写一篇吧。
去年年初有位朋友找到我,说他们的系统会偶发性崩溃,在网上也发了不少帖子求助,没找到自己满意的答案,让我看看有没有什么线索,看样子这是一个牛皮藓的问题,既然对方有了dump,那就分析起来吧。
二:WinDbg分析
1.为什么会崩溃
不管是 windows 还是 linux 上的.net程序崩溃都会存在异常码,前者是ExceptionCode,后者是 SignalCode,所以先用 !analyze -v
观察看看。
0:003> !analyze -v
CONTEXT: (.ecxr)
eax=00000008 ebx=00639498 ecx=00000001 edx=0c75e4c8 esi=0063ec88 edi=083d8f77
eip=71ecaf96 esp=1ad2fa00 ebp=1ad2fa58 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
clr!SVR::gc_heap::mark_object_simple1+0x382:
71ecaf96 f70000000080 test dword ptr [eax],80000000h ds:002b:00000008=????????
Resetting default scope
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 71ecaf96 (clr!SVR::gc_heap::mark_object_simple1+0x00000382)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000001
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 00000008
Attempt to read from address 00000008
从卦中信息看,程序崩在 clr!SVR::gc_heap::mark_object_simple1
方法里,这表示当前gc触发时clr在托管堆标记对象时发现堆损坏了,那到底是不是托管堆损坏呢?可以用 !verifyheap
命令验证下,输出如下:
0:003> !verifyheap
object 083d8f50: bad member 093D8F90 at 083D8F74
Last good object: 083D8F3C.
object 0c75e4c0: bad member 083D8F77 at 0C75E4C8
Last good object: 0C75E454.
从卦中信息看,确实存在着两个坏对象 083d8f50
和 0c75e4c0
,接下来的研究重点就是为什么这两个对象会破坏?
2. 对象为什么损坏了
为了方便解读我们从 083d8f50
入手,先用 !do
观察它的布局。
0:003> !do 083d8f50
Name: System.Windows.DependencyProperty
MethodTable: 727ebe60
EEClass: 72708570
Size: 44(0x2c) bytes
Fields:
MT Field Offset Type VT Attr Value Name
...
727e7f0c 40011fe 24 ....InsertionSortMap 1 instance 083d8f74 _metadataMap
...
0:003> !DumpVC /d 727e7f0c 083d8f74
Name: MS.Utility.InsertionSortMap
MethodTable: 727e7f0c
EEClass: 72721ec8
Size: 12(0xc) bytes
Fields:
MT Field Offset Type VT Attr Value Name
727e7f44 40007e9 0 ...geSortedObjectMap 0 instance 093d8f90 _mapStore
0:003> !DumpObj /d 093d8f90
<Note: this object has an invalid CLASS field>
Invalid object
根据对象的布局知识,093d8f90
存放的是 mt,看样子是mt被损坏了,接下来用 dp 观察下这个地址的附近内存。
0:003> dp 093d8f90-0x20 L10
093d8f70 727e8b50 032e3750 1085da60 04a46fd9
093d8f80 00000000 727e8b50 032e3a48 08157ef0
093d8f90 03217272 00000000 727e8b50 032e353c
093d8fa0 08079f9c 02c028d2 00000000 727e8b50
0:003> !lno 093d8f90
Before: 093d8f84 20 (0x14) MS.Internal.WeakEventTable+EventKey
After: 093d8f98 20 (0x14) MS.Internal.WeakEventTable+EventKey
Heap local consistency confirmed.
0:003> !do 093d8f84
Name: MS.Internal.WeakEventTable+EventKey
MethodTable: 727e8b50
EEClass: 727076c4
Size: 20(0x14) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_MSIL\WindowsBase\v4.0_4.0.0.0__31bf3856ad364e35\WindowsBase.dll
Fields:
MT Field Offset Type VT Attr Value Name
727ec0f4 4001a28 4 ....WeakEventManager 0 instance 032e3a48 _manager
7112dbd4 4001a29 8 System.Object 0 instance 08157ef0 _source
7112f6bc 4001a2a c System.Int32 1 instance 52523634 _hashcode
从卦中信息看 mt=03217272
肯定是不对的,但奇怪的是这附近的内存并没有损坏,它是EventKey._hashcode
的16进制表示,我去,这就奇葩了。。。一下子陷入了迷茫。
3. 内存为什么没坏
说实话分析了这么多的dump,这种情况还是第一次遇见,根据上一节的分析,现在可以怀疑 093d8f90
这个地址本身就是错的,接下来观察它的所属地址 083d8f74
附近的内存。
0:003> dp 083d8f74 -0x40 L20
083d8f34 00000003 00000000 727e72c9 083d8ba4
083d8f44 083d8ec8 775e7de3 00000000 727ebe61
083d8f54 083d8ba4 0ec9e934 083d8ec8 083d8f20
083d8f64 00000000 00000000 00000000 00020368
083d8f74 093d8f90 00000000 727ee329 083d8ec8
083d8f84 0ec9eaf4 000000e0 00000000 727e7f45
083d8f94 083d8fa4 00000001 000000e0 00000000
083d8fa4 727e7fb1 00000002 083d8f04 000000e0
如果你仔细观察卦中的区域内存地址,你会发现一个有意思的现象,它附近的对象都是 083
开头的,凭什么它是 093
开头的?对他产生了怀疑之后,我们观察下托管堆中 mt=727e7f44
下是否存在 093d8f90
的实例,截图如下:
从卦中可以清晰的看到确实不存在 093d8f90
对象,但存在一个将 9 -> 8
之隔的 083d8f90
,有经验的朋友应该知道,这又是一例经典的bit位翻转导致的程序崩溃,可以用 .formats
命令观察下二进制的布局:
4. 另一个坏对象也是如此吗
刚才的 093d8f90
我们搞明白了是由于bit位翻转导致,那 083d8f77
也是如此吗?有了刚才的经验这个就比较好验证了,可以查一下 mt=727ee328
下是否有这个实例。
0:003> !do 0c75e4c0
Name: System.Windows.Media.Pen
MethodTable: 6f38a110
EEClass: 6f1568b4
Size: 40(0x28) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\PresentationCore\v4.0_4.0.0.0__31bf3856ad364e35\PresentationCore.dll
Fields:
MT Field Offset Type VT Attr Value Name
...
727ee328 40011dc 8 ...endencyObjectType 0 instance 083d8f77 _dType
...
0:003> !dumpheap -mt 727ee328
Address MT Size
...
083d8db0 727ee328 20
083d8f7c 727ee328 20
...
又是一个无语的结论,原来 083d8f7c
被错赋成了 083d8f77
,用 .formats 命令观察之后发现有 3个bit的翻转。截图如下:
三:总结
有丰富经验的朋友肯定知道,bit翻转大多是辐射导致计算机数字信号偶发的紊乱,这也是为什么医院要加个铅版来阻隔,而这个程序所处的环境刚好是辐射比较多的高铁系。
所以分析完之后,非我等调试师能为之,远离辐射。。。
记一次 .NET某列控连锁系统 崩溃分析的更多相关文章
- 记一次 .NET 某工控MES程序 崩溃分析
一:背景 1.讲故事 前几天有位朋友找到我,说他的程序出现了偶发性崩溃,已经抓到了dump文件,Windows事件日志显示的崩溃点在 clr.dll 中,让我帮忙看下是怎么回事,那到底怎么回事呢? 上 ...
- 记一次 .NET 某企业 ERP网站系统 崩溃分析
一:背景 1. 讲故事 前段时间收到了一个朋友的求助,说他的ERP网站系统会出现偶发性崩溃,找了好久也没找到是什么原因,让我帮忙看下,其实崩溃好说,用 procdump 自动抓一个就好,拿到 dump ...
- 记一次 .NET 某工控软件 内存泄露分析
一:背景 1.讲故事 上个月 .NET调试训练营 里的一位老朋友给我发了一个 8G 的dump文件,说他的程序内存泄露了,一时也没找出来是哪里的问题,让我帮忙看下到底是怎么回事,毕竟有了一些调试功底也 ...
- 记一次 .NET 某工控自动化控制系统 卡死分析
一:背景 1. 讲故事 前段时间遇到了好几起关于窗体程序的 进程加载锁 引发的 程序卡死 和 线程暴涨 问题,这种 dump 分析难度较大,主要涉及到 Windows操作系统 和 C++ 的基础知识, ...
- 记一次 .NET某医疗器械清洗系统 卡死分析
一:背景 1. 讲故事 前段时间协助训练营里的一位朋友分析了一个程序卡死的问题,回过头来看这个案例比较经典,这篇稍微整理一下供后来者少踩坑吧. 二:WinDbg 分析 1. 为什么会卡死 因为是窗体程 ...
- 记一次 .NET 某自动化集采软件 崩溃分析
一:背景 1.讲故事 前段时间有位朋友找到我,说他的程序在客户的机器上跑着跑着会出现偶发卡死,然后就崩掉了,但在本地怎么也没复现,dump也抓到了,让我帮忙看下到底怎么回事,其实崩溃类的dump也有简 ...
- 记一次 .NET 某医疗住院系统 崩溃分析
一:背景 1. 讲故事 最近收到了两起程序崩溃的dump,查了下都是经典的 double free 造成的,蛮有意思,这里就抽一篇出来分享一下经验供后面的学习者避坑吧. 二:WinDbg 分析 1. ...
- jqGrid选择列控件向右拖拽超出边界处理
jqGrid选择列控件向右拖拽超出边界处理 $("#tb_DeviceInfo").jqGrid('navButtonAdd', '#jqGridPager', { ...
- 记一次 .NET 某纺织工厂 MES系统 API 挂死分析
一:背景 1. 讲故事 这个月中旬,有位朋友加我wx求助他的程序线程占有率很高,寻求如何解决,截图如下: 说实话,和不同行业的程序员聊天还是蛮有意思的,广交朋友,也能扩大自己的圈子,朋友说他因为这个b ...
- 记hive select distinct 多列 误区一则
当select distinct a,b,c时,只会对a.b.c都起作用,无法达到只顾虑多余的a列: 根据hive官方网站说明:当有表 a b 10 1 10 2 10 3 此时select a,b ...
随机推荐
- [转帖]LSM树详解
https://zhuanlan.zhihu.com/p/181498475 LSM树(Log-Structured-Merge-Tree)的名字往往会给初识者一个错误的印象,事实上,LSM树并不像B ...
- [转帖]比快更快的 ELK 8 安装使用指南-Elasticsearch,Kibana,Logstash
https://juejin.cn/post/7133907643386560519 携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情 Elastic 8 ...
- [转帖]云平台部署CNA、VRM手动安装方法
云平台部署CNA.VRM手动安装方法 分享人:郭道川 00443725 日期:2018.11.06 Ⅰ. 项目介绍 该项目主要为XX煤矿智能煤炭项目云平台部署交付,该项目所采用的服务器为RH2 ...
- [转帖]探索惊群 ④ - nginx - accept_mutex
https://wenfh2020.com/2021/10/10/nginx-thundering-herd-accept-mutex/ 由主进程创建的 listen socket,要被 fork ...
- [转帖]台积电3nm成功量产,稳了吗?
https://docs.pingcode.com/info/13836.html?p=13836 2023-01-19 资讯 21 原标题:台积电3纳米成功量产:未来与三星仍将决战鳍式场效晶体管(F ...
- [转帖]Oracle入门精读28-字符集 AL32UTF8与UTF8
字符(Character) 字符是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等. 字符编码(Character Encoding) 是一套法则,使用该法则能够对自然语言的字符的一个 ...
- ESXi6.5+vCenter6.5 CentOS7 虚拟机启动之后控制台黑屏的解决方案
公司最近搬迁服务器, 服务器的地址都发生了变化, 发现部分机器总是黑屏无法使用, 想了一个坚决办法使服务器能够连接设置地址后使用. 1. 控制台开机. 2. 注意在开机五秒之内打开web控制台, 然后 ...
- 麒麟信安V3.4 安装PG15的过程
麒麟信安V3.4 安装PG15的过程 背景 发现基于OpenEuler的几个系统使用CentOS的rpm包 安装PG数据库时有问题. 会提示缺少依赖的so文件. 今天想着解决一下, 就百度了一下并且进 ...
- 【JS 逆向百例】转变思路,少走弯路,X米加密分析
声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:X米账号登 ...
- C/C++ 实现获取硬盘序列号
获取硬盘的序列号.型号和固件版本号,此类功能通常用于做硬盘绑定或硬件验证操作,通过使用Windows API的DeviceIoControl函数与物理硬盘驱动程序进行通信,发送ATA命令来获取硬盘的信 ...