如何知道80000003断点后是否隐藏了其他异常(WER对话框)

我的应用程序,一个可执行文件,正在远程计算机上崩溃。我没有访问那台机器的权限,所以我请求了一个转储,通过任务管理器生成。使用WEBBG,在执行命令!analyze -v时,我可以看到许多其他的文本

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 0000000000000000
ExceptionCode: 80000003 (Break instruction exception)
ExceptionFlags: 00000000
NumberParameters: 0


我怎么知道它是不是对坠机事件负责?如果不是,我如何确定真正的原因?

 int3断点是根本原因吗?

tldr:如果!findstack kernel32!WerpReportFault产生一个结果,那么它可能不是根本原因。
长版本:
当应用程序由于未处理的异常而崩溃时,操作系统将使用名为windows错误报告的功能来获取它。这会导致一些技术问题:
ntdll中的异常分派器启动一个新线程。
在新线程中,会触发断点
异常分派器还调用未处理的异常处理程序
如果应用程序没有这样的处理程序,它将把处理转发到显示对话框的windows错误报告(inkernel32
如果您在那个时候进行崩溃转储,您将看到以下内容:
问题中提到的断点异常

0:002> .exr -1
ExceptionAddress: 775f000c (ntdll!DbgBreakPoint)
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 1
   Parameter[0]: 00000000


一个线程,其内部只有一个断点

0:002> k
ChildEBP RetAddr  
02e2ff58 7767f926 ntdll!DbgBreakPoint
02e2ff88 75b3338a ntdll!DbgUiRemoteBreakin+0x3c
02e2ff94 77619f72 kernel32!BaseThreadInitThunk+0xe
02e2ffd4 77619f45 ntdll!__RtlUserThreadStart+0x70
02e2ffec 00000000 ntdll!_RtlUserThreadStart+0x1b


包含前面提到的相关操作的调用堆栈

0:001> k
ChildEBP RetAddr  
01aff904 770715f7 ntdll!NtWaitForMultipleObjects+0x15
01aff9a0 75b319f8 KERNELBASE!WaitForMultipleObjectsEx+0x100
01aff9e8 75b34200    kernel32!WaitForMultipleObjectsExImplementation+0xe0
01affa04 75b580a4 kernel32!WaitForMultipleObjects+0x18
01affa70 75b57f63 kernel32!WerpReportFaultInternal+0x186
01affa84 75b57858 kernel32!WerpReportFault+0x70
01affa94 75b577d7 kernel32!BasepReportFault+0x20
01affb20 776574ff kernel32!UnhandledExceptionFilter+0x1af
01affb28 776573dc ntdll!__RtlUserThreadStart+0x62
01affb3c 77657281 ntdll!_EH4_CallFilterFunc+0x12
01affb64 7763b499 ntdll!_except_handler4+0x8e
01affb88 7763b46b ntdll!ExecuteHandler2+0x26
01affbac 7763b40e ntdll!ExecuteHandler+0x24
01affc38 775f0133 ntdll!RtlDispatchException+0x127
01affc38 6f8c20ce ntdll!KiUserExceptionDispatcher+0xf


要识别WER断点,可以检查这三个条件。对于后者,可以使用!findstack命令,因为它可能发生在任何线程上。

0:001> !findstack kernel32!WerpReportFault
Thread 001, 2 frame(s) match
        * 04 01affa70 75b57f63 kernel32!WerpReportFaultInternal+0x186
        * 05 01affa84 75b57858 kernel32!WerpReportFault+0x70


我希望方法名不会更改。
如何找出根本原因?
这适用于x86(32位),因为堆栈是如何创建的。它在x64(64位)上不能很好地工作,因为kb命令不可靠。在x64上,参数在寄存器而不是堆栈中传递,但是kb命令只对堆栈有效。
也就是说,异常指针作为第二个参数传递给WerpReportFault()。可以使用该异常指针创建一个新转储,将该异常作为主要异常,如下所示:

.dump /ma /xp <exception pointer> c:\path\to\newdump.dmp


接下来,关闭源转储,打开新转储并再次分析,例如,以以下4个命令作为起点:

.symfix
.reload
.exr -1
!analyze -v

posted on 2020-03-03 14:12  活着的虫子  阅读(1516)  评论(0编辑  收藏  举报

导航