Debugging 怎么会这样?(在调试小型转储文件中)
我正在跟踪dmp文件,它似乎在调用断开对象实例的虚拟函数时崩溃了 似乎坏掉的对象指针的vft指向了错误的地址(Debugging 怎么会这样?(在调试小型转储文件中),debugging,crash,windbg,crash-reports,Debugging,Crash,Windbg,Crash Reports,我正在跟踪dmp文件,它似乎在调用断开对象实例的虚拟函数时崩溃了 似乎坏掉的对象指针的vft指向了错误的地址(0x3822a497),程序在调用edx到0x3822a497(最后一次控制转移:从00ccde67到3822a497)后立即崩溃,指令指针(EIP)甚至无法再进一步。那么,它不应该是edx=0x3822a497吗?但Visual Studio和Windbg都指示edx=0x1E4DC0 有人能解释一下这是怎么发生的吗 编辑:我太信任上一次的控制传输,但仍然存在着神秘。请先看下面更新的假
0x3822a497
),程序在调用edx
到0x3822a497
(最后一次控制转移:从00ccde67到3822a497
)后立即崩溃,指令指针(EIP
)甚至无法再进一步。那么,它不应该是edx=0x3822a497吗?但Visual Studio和Windbg都指示edx=0x1E4DC0
有人能解释一下这是怎么发生的吗
编辑:我太信任上一次的控制传输,但仍然存在着神秘。请先看下面更新的假设1,2,3,并给我一个可能的场景。
windbg的结果!分析-v
windbg r的结果
上次控制转移前的拆卸:从00ccde67到3822a497
编辑
哦,我忘了把堆栈状态
堆栈(esp=0x18cfe4)
eip周围的拆解(0x3822A497)
eip周围的内存转储(0x3822A497)
显然,这不是有效的指令,而是宽字符文本。
我认为被调用方很可能破坏了xwlan所说的edx信息。
(我认为,LAST\u CONTROL\u TRANSFER
是一种可靠的信息。它只是向eip
显示最后一个调用堆栈条目)
但我的假设仍然没有意义。有人能想出一个有意义的方案吗
假设1:指令在0x3822A497
之前跳转并执行popad
我认为这很有道理。(例如,可以通过一些间接跳转/调用指向文本缓冲区的指针来跳转0x3822A490
)
如果是这样,将执行popad
,从堆栈中弹出EDI、ESI、EBP、EBX、EDX、ECX和EAX
。
那么为什么我不能从堆栈中找到这些寄存器的值呢?
例如,如果是这样,我是否应该从0x0018CFE4(esp)
附近的堆栈中看到0x00000002(ebp)
,0x01e4dcc0(edx)
假设2:被调用方不是0x3822A497
,指令正好跳到0x3822A497
我认为这是非常罕见的情况。
如果跳转是通过间接调用/jmp进行的,则不会有任何内容指向奇数0x3822A497
,
如果跳转是通过相对调用/jmp进行的,则调用指令将接近0x3822A497
,
但是当我从0x3822A497
因为它有###,00,##,00,###宽字符文本的模式,
最可能的跳转指令跳转到下一个指令指针,例如:
3822A494 72 00 > jb 3822A496
3822A496 61 popad
3822A497 00 6E 00 add byte ptr [esi],ch
假设3:被调用方是0x3822A497
那么为什么edx不是
0x3822A497
。(第一个问题)您对调用堆栈的信任度太高了,很可能在这里丢失了一个帧(可能是某种与FPO相关的工件)。我怀疑EDX不是坏的EIP,它持有一个有效函数的地址,该函数最终设置了无效的EIP
如果我是你,我会在崩溃时重建EDX,看看它是什么功能。然后,您可以尝试找出该函数可能对垃圾EIP做了什么(可能是堆栈溢出)。如果你感到幸运/懒惰,你可以希望EDX没有受到干扰,看看“uf@EDX”能给你带来什么。看起来像堆栈损坏,“esp=0018cfe4 ebp=00000002”,ebp显然是个坏值。
我建议检查代码“00CCDE65 call edx”,edx看起来像指向一个虚拟函数,这个函数及其被调用方破坏了堆栈。windbg中的dds esp可以帮助转储当前堆栈内存,以检查是否存在任何可疑值,例如任何字符串?谢谢,正如您所说,似乎被调用方已注册,但我仍然无法理解有意义的场景。我添加了转储堆栈,并更新了问题。由于堆栈已损坏,eip不可信任,当陷阱进入调试器时,它是一个垃圾值。但是,00CCDE34和00CCDE67之间的代码是正确的。我想你应该知道这些asm代码映射到什么源文件。00CCDE65发出对函数ptr的调用,我建议您从此函数进行调查。此外,dds是转储堆栈的更好命令,因为windbg将为每个可能的ptr匹配符号。dds esp-100,这可以转储使用的堆栈(较低的地址)。匹配的源代码在反汇编中:current_time=timeGetTime();(*it)->proc();因为它是通用对象的迭代器,所以我知道崩溃的主要原因是迭代器/对象被破坏,并且我可能应该通过日志记录或完全转储来缩小,以便跟踪崩溃的原因。实际上,这个问题的重点不是“如何追踪崩溃的原因”,而是“这个cpu状态(寄存器,eip,…)是怎么发生的?”因为我不明白,并且很好奇,即使它已经损坏了,上次的情况是怎么发生的。对不起,误解了你们的问题。我认为你的假设(2)是基于你发布的数据的唯一可能的情况。有可能存在一个“jmp dword ptr[xxx]”,其中xxx包含0x3822A497。jmp指令包含在曾经执行过损坏的eip的区域中。关于模式0x3822A497的搜索内存如何?一般的建议是很好的——但是,ebp中的小整数很可能表明代码是在启用帧指针消除优化的情况下编译的,这意味着代码将ebp用作通用寄存器。您是对的。我知道我不应该信任调用堆栈,但我从未想过最后一次控制传输只是显示最后一次调用堆栈条目。但我仍然无法做出有意义的假设,(在原始答案中添加了假设)你能指出更多关于这一点吗?
0:000> .ecxr
eax=0018d0c8 ebx=78b3b6a8 ecx=00cddb00 edx=01e4dcc0 esi=0138d2cc edi=0018cfc8
eip=3822a497 esp=0018cfe4 ebp=00000002 iopl=0 nv up ei ng nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210282
3822a497 006e00 add byte ptr [esi],ch ds:002b:0138d2cc=??
Last set context:
eax=0018d0c8 ebx=78b3b6a8 ecx=00cddb00 edx=01e4dcc0 esi=0138d2cc edi=0018cfc8
eip=3822a497 esp=0018cfe4 ebp=00000002 iopl=0 nv up ei ng nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210282
3822a497 006e00 add byte ptr [esi],ch ds:002b:0138d2cc=??
current_time = timeGetTime();
00CCDE34 call dword ptr [__imp__timeGetTime@0 (17EE5FCh)]
(*it)->proc();
00CCDE3A mov eax,dword ptr [ebx]
00CCDE3C test eax,eax
00CCDE3E je 00CCDFFE
00CCDE44 test edi,edi
00CCDE46 je 00CCDFFE
00CCDE4C cmp dword ptr [eax+4],edi
00CCDE4F ja 00CCDFFE
00CCDE55 cmp edi,dword ptr [eax+8]
00CCDE58 jae 00CCDFFE
00CCDE5E mov ecx,dword ptr [edi]
00CCDE60 mov eax,dword ptr [ecx]
00CCDE62 mov edx,dword ptr [eax+0Ch]
00CCDE65 call edx
00CCDE67 push 0
0x0018CFA4 00000000 00000000 00000000 00000000 ................
0x0018CFB4 00000000 00000000 00000000 00000000 ................
0x0018CFC4 00000000 fffffd34 000002e4 fffffd34 ....4?..?...4?..
0x0018CFD4 000002cc 00000019 00000000 0018d0c8 ?...........??..
0x0018CFE4 >00ccde67 1a75cb52 00000000 28e86c00 g??.R?u......l?(
0x0018CFF4 00000011 29b52260 00000000 78b3c718 ....`"?).....??x
0x0018D004 29b522a0 00000000 78b3b6ac 29b522a0 ?"?)....???x?"?)
0x0018D014 00000000 78b3b6a8 1a75cb52 00000140 ....???xR?u.@...
0x0018D024 01e4f688 1a75cb52 0018d050 0170d884 ???.R?u.P?..??p.
0x0018D034 ffffffff 0018d05c 0098ec41 1a75cb36 ....\?..A??.6?u.
3822A490 54 push esp
3822A491 00 db 00h
3822A492 65 db 65h
3822A493 00 72 00 add byte ptr [edx],dh
3822A496 61 popad
3822A497 00 6E 00 add byte ptr [esi],ch
3822A49A 69 00 74 00 65 00 imul eax,dword ptr [eax],650074h
0x3822A480 55da14f5 80000000 00001e08 00000024 ?.?U........$...
0x3822A490 00650054 00610072 0069006e 00650074 T.e.r.a.n.i.t.e.
0x3822A4A0 004e0020 00630065 006c006b 00630061 .N.e.c.k.l.a.c.
0x3822A4B0 00000065 4d747cba 55da14f2 80000000 e...?|tM?.?U....
3822A494 72 00 > jb 3822A496
3822A496 61 popad
3822A497 00 6E 00 add byte ptr [esi],ch