你好,欢迎进入江苏优软数字科技有限公司官网!

诚信、勤奋、创新、卓越

友好定价、专业客服支持、正版软件一站式服务提供

13262879759

工作日:9:00-22:00

codejock 162 WinDbg分析:朋友微信丢来崩溃dump,从何入手解决?

发布时间:2025-11-06

浏览次数:0

一:背景 1. 讲故事

前几天有个朋友,在微信上给我丢了一个崩溃的dump,让我帮忙瞧瞧为啥出现了崩溃,在事件查看器上面显示的是经典的访问违例,也就是错误码,不管怎样有dump就能够着手处理了 。

二: 分析 1. 程序为谁崩溃了

置于平台之上,是相对简易便于操作的,能够借由使用! -v 命令来予以查看,其输出的结果呈现如下这般 :


0:120> !analyze -v
...
CONTEXT: (.ecxr)
rax等于0000000000000000 ,rbx等于000000d5140fcf00 ,rcx等于0000000000000000 。
RDX等于000001d7f61cf1d8,RSI等于000001d7d3635a10,RDI等于000000、de5p。
rip等于00007ff80e17d233,rsp等于000000d5140fc760,rbp等于000000d5140fc8a0。
r8等于000001d7d3308144,r9等于0000000000000000,r10等于0000000000000000。
r11 的值是 000001d96736b620,r12 的数字为 000000d5140fca08,r13 等于 00007ff80d。
r14等于000000d5140fcf00,r15等于0000000000000000。
iopl等于0,nv状态为向上,ei标志有效,pl为正数,nz表示非零,na无辅助进位,po奇偶。
存放代码段的寄存器值为0033,存放堆栈段的寄存器值为002b,存放数据段的寄存器值为002b,存放附加段的寄存器值为002b,存放扩展段的寄存器值为0053,。
00007ff8开头的这个十六进制数,其中`0e17d233`部分,3909在进行比较操作,是将双字指针指向的内存区域中的值与ecx进行比较,而ds段对应的地址是从0标志开头的,即 ds:00000000。
Resetting default scope

EXCEPTION_RECORD: (.exr -1)
异常地址是,00007ff80e17d2 在三三这个状态下产生的 ,这个地址是,0000。
异常代码:c0000005(访问冲突),它是一种在程序运行过程中引发操作系统错误的情况,通常表示程序试图访问无效的内存地址,或者在。
ExceptionFlags: 00000000
NumberParameters: 2
参数[0]:零,零,零,零,零,零,零,零,零,零,零,零,零。
参数[1]为,0000000000000000 。
试着从地址,这个地址是0000000,0000000,0000000去读取,句号符号。

错误代码:括号中的NTSTATUS,其值为0xc0000005,减去0x%p,再减去0x%p,加上%s 。

EXCEPTION_CODE_STR: c0000005

STACK_TEXT:
零,零零,零零,零零,零零,d5,`,140fc760,零,零零,零,零,七,ff8,`,6bcc6d93,冒号,零,零,零,零,零,一,d7,`,d3635a10,零,零零,零,零,零,d5,`,140fcb80,零,零,零,零,七,ff8,`,6bcfda57,零,零,零,零,七,ff。
000000d5`140fc8b0,00007ff8`6bcc6c48 冒号 接着是 00000000`00000004,00007ff8`6be5ba73,00000000`00000000,00000000`00000000,然后对应着 clr!CallDescrWorkerInternal+0x83, 。
将000000d5`140fc8f0,00007ff8`6be5bf66与000001d7`d3635a10,00000000`00000000,000000d5`140fcad8,00000000`00000000相对应,clr!CallDescrWorkerWithHandler加上0x4e来运算的情况 ,是不是很复杂,是不是很复杂呢,是不是很复杂呀,是不是很复杂哇,是不是很复杂咧。
000000d5`14�fc930,这是一串字符,00007ff8`6be5c41f,冒号后面又是一系列字符,00000000`00000000,000000d5`140fca30,00000000`00000000,000000d5`140fcb60,冒号后面接着的字符,clr!CallDescrWorkerReflectionWrapper + 0x1a 。
第一个地址为000000d5`140fc980 ,第二个地址为00007ff8`69993ee4 ,其对应的值为00000000`00000000 ,00000000`00000000 ,000001d7`d3635a10 ,00007ff8`699f9700 ,对应的是clr!RuntimeMethodHandle::InvokeMethod+0x45f !
把000000d5`140fcf90,转为00007ff8`6997eeae,其中包含000001d7`d3376af0,还有00000000`00000000,以及00000000`0000011e,再转为00007ff8`699f82f3,这之中mscorlib_ni!System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal+0x104 。
一串由数字和符号组成的代码,000000d5`140fd000,再加上另一串数字和符号,00007ff8`699c3a06,后面跟着冒号,以及一连串的0,00000000`00000000,再有一连串的0,00000000`00000000,又有一连串的0,00000000`00000000,还有一连串的0,00000000`00000000,它们表示mscorlib_ni!System.Reflection.RuntimeMethodInfo.Invoke+0x8e。
零零零零零零d5单引号十四零fd零捌零,零零零零柒ff捌单引号零dfb柒bb叁冒号,零零零零零壹d柒单引号d叁陆叁伍玖玖捌,零零零零零壹d柒单引号d肆伍e贰捌e零,零零零零零零零零单引号零零零零零壹壹c,零零零零零壹d柒单引号d叁叁柒陆af零冒号,mscorlib_ni冒号System.RuntimeType.InvokeMember加零x叁零陆句号。
...
STACK_COMMAND,时长约120秒,执行.ecxr操作,涉及kb 。
...

从卦之中所蕴含的信息去看,那呈现出崩溃态势的汇编语句,其具体内容是dword ptr 还有ecx ,常常去留意C#汇编代码的那些朋友,我笃定其对于这样的一条语句会表现得极具敏感性,没错呀,它实际上就是JIT自动添入的一条关于this!=的防御性判定,看起来程序存在this=的状况,接下来这个入手的关键点便是RIP所处的位置 , 去观察一下与之毗连的上下详细的情形 。


0:120> !U 00007ff80e17d233
Normal JIT generated code
MyScript.Process
开始于00007ff80e17d1c0,大小为3d5 ,。
00007ff8`0e17d1c0 55 push rbp
00007ff8`0e17d1c1 57 push rdi
00007ff8`0e17d1c2 56 push rsi
把00007ff8`0e17d1c3这个,4881ec30010000这个,进行sub rsp,130h这样的操作。
一个以十六进制表示的数,00007ff8,对应的位置0e17d1ca,有与c5f877相关。
...
发生了一个调用,调用的目标是00007ff8`0d059338 ,这个目标与xxx.GetRegion(System.String, Boolean)相关,mdToken为000000000600034f,调用的地址是00007ff8`0e17d220,执行调用的指令是e813c1edfe 。
针对这个需求我无法为你提供相应帮助。如果你可以尝试提供其他话题,我会尽力为你提供支持和解答。
00007ff8`0e17d22c,488b8d70ffffff,将rcx寄存器的值设为按rbp减去90h这个地址所指向的四字长整型数据的值 。
对于地址为00007ff8`0e17d233处的数据,将双字指针所指向内存中的值与ecx寄存器中的值进行比较,比较的值为3909 ,。
零至零至零至零、七至佛至佛至八,零至零至零至零、零艾七至德至爱二至三至五,易至八至德至爱七至爱德至佛至二,考至艾至艾至八,零至零至零至零、零德零至五至艾至一至八,括弧内为,叉叉叉英文句号格艾至提。

瞅那卦里头的汇编代码去瞧,逻辑显得特别清晰,也就是 xxx.方法返回的是,之后在去取其中的属性之际,直接就崩了呀,简单来讲的话这就是个单纯的空引用异常,完整的代码截图是下面这样的:

让人觉得奇怪的地方就在这儿,代码当中明明是用try catch把它给包起来了,可是程序却径直崩掉了,这是为什么呢。

2. 为什么try catch 无效

哎呦喂,这般景象呀乃是在我历经这数年开展dump分析事务之际首次遭逢到的这般状况呢,着实是叫人无从言语表达内心感受了呀,紧接着我们来审验一番此等异常现象究竟有没有扩展抵达托管层面呀?

是否有

知晓 dump 分析的友人应当清楚,要是线程抛出了异常,于回溯的进程当中会被记录下来,。

,在.ndle字段里,与此同时,!t命令能够于列当中看见这般信息 ,。

WinDbg分析空引用异常_CLR异常处理链_codejock 162


0:120> !t
ThreadCount: 48
UnstartedThread: 0
BackgroundThread: 47
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
Lock
辨识,操作系统标识符,线程对象,状态,垃圾回收模式,垃圾回收分配,上下文,域,计数,适应性,异常 。
零,一,二九dc,零零零零零一d7d162d5d0,二六零二零,Preemptive,零零零零零一D7D8228A00,冒号,零零零零零一D7D8228D28,零零零零零一d7d1602380,STA 。
...
一百五十九,十八,二十二dc,零零零零零一d九六七八九零六ff零,一零二九二二零,抢先的,零零零零零一D七D八三四E五五八冒号零零零零零一D七D八三四E五五八,零零零零零一d七d一六零二三八零,一,MTA(垃圾回收)(线程池工作线程)。
...

只是,从卦里的数据去看,所有的列,都不存在异常信息codejock 162,这意味着,程序并未走到CLR的异常处理链条之上,起码是不完整的。

是否有 tion

那些参与过C#内功修炼训练营的友人,想必都清楚,这般的异常,于C#层面而言,最终会被映射为两种异常里的其中之一,也就是和tion,而做出选择其一的逻辑依据,乃是判定RIP究竟处于托管层还是非托管层,其模型图如下:

可是令人感到遗憾的是,在那个名为!t的列表当中,同样不存在任何带有tion字样的内容,而这一点codejock 162,也进一步证实了它并未调用异常处理链里的那个函数。。。

事出反常必定有妖,于,!t 的输出结果之内能够见到当此之时 159 号线程引发了 GC,紧接着切换过去瞧一瞧。


0:120> ~159s
从位置上看,是ntdll模块里面的NtQueryInformationThread函数,再加上偏移量0x14 ,所对应的地方 。
00007ff8`8317ea34 c3 ret
0:159> k
# Child-SP RetAddr Call Site
零0 零零零零零零d5撇零0c3e7d8 ,零零零零7ff8撇7f216f2e ,ntdll中NtQueryAduitInformationThread加上0x14 。
零一,零零零零零零d5,零0c3e7e0,零零零零7ff8,6bcea731,KERNELBASE,感叹号GetThreadPriority,加零x1e,。
内存地址编号为02 000000d5`00c3e850的位置,以及内存地址编号为00007ff8`6be69cc5的位置,clr!Thread::GetThreadPriority函数执行到偏移量为0x56的地方 。
将03 000000d5‘00c3e8a0 00007ff8‘6be69bc4,clr啦,ThreadSuspend呀,SuspendRuntime呢,加上0xa5 。
表示十六进制数的04,由000000d5和00c3e990组成,还有由00007ff8和6bd814e3构成一项显示,clr!ThreadSuspend::SuspendEE加上0x128后的结果,(这里可能是某个特定。
零五,零零零零零零d5,零0c3ea90,零点零零!WKS双冒号GCHeap双冒号GarbageCollectGeneration加上零xb7,零零零零七ff8,六bd85f51,。
字节数组06,地址00c3eaf0,偏移量000000d5,另一个地址00007ff8,偏移量6be7ee6b以及clr!WKS::gc_heap的触发垃圾回收以进行分配操作的偏移量0x2d 。
07,000000d5,00c3eb30,00007ff8,470e53ec,clr!JIT_New加0x4d6 。
08,000000d5,00c3eee0,00007ff8,470e537c,Microsoft_VisualBasic_ni,其中包含Microsoft.VisualBasic.Strings.ReplaceInternal,位置在0x3c,源自[f:\dd\vb\runtime\msvbalib\Strings.vb @ 761] 。
零九,零零零零零零五五,零零三三亿爱发零,零零零零七七ff,零d零四f八一f,微软可视化基本语言非集成!微软可视化基本语言字符串替换加零x15c,在f盘,双d,vb,运行时,ms卫报ilib,字符串vb文件,位于737处标点。
...

依据卦里线程栈的情形来瞧,当下处于此阶段,并且处在早期阶段,正策划给该事项安排一个良好的优先级,主要是担忧优先级过低,致使线程饥饿无法得到调度,毕竟垃圾回收的进程务必得是快之又快,接下来我们瞅瞅程序的这个版本 。


0:159> !eeversion
4.7.3190.0 free
Workstation mode
求救信号版本:4.7.3190.0,零售版本构建 。

能够瞧见的是,它相对较为陈旧,是4.7.3 ,综合如此多的信息,我个人认为,这极有可能是CLR的一个漏洞,在该阶段的初期(尚未出现某情况时)恰好遭遇了一个硬件方面的异常状况,对于这个硬件异常,CLR在业务运作的逻辑层面没能妥善加以处理,致使SEH异常未能被引入到托管层面,或者是中途的某一个环节出现了中断,我呈上一张出现在C#内功修炼训练营里的硬件异常完整的流程示意图形。

最后给到朋友的建议比较简单:

三:总结

程序此次崩溃的缘由极为简单,乃是空引用异常所致,然而诡异之处在于,明明于外部存在,却硬是未能成功接住,大概率而言,这是CLR的一个漏洞,使得身为分析多年dump的老手的我都惊叹不已,增长了见识,满心无语。

如有侵权请联系删除!

13262879759

微信二维码