C# 如何在混合应用程序中获取有关缓冲区溢出异常的信息?

C# 如何在混合应用程序中获取有关缓冲区溢出异常的信息?,c#,c++,wpf,c++-cli,buffer-overflow,C#,C++,Wpf,C++ Cli,Buffer Overflow,在我开发的所有WPF应用程序中,都有一个订阅了AppDomain.CurrentDomain.UnhandledException的全局异常处理程序,它记录了它能找到的所有内容,然后显示一个对话框,告诉用户联系作者,日志文件所在的位置等。这非常好用,客户和我都非常满意,因为它允许快速修复问题 然而,在开发一个混合的WPF/C、/CLI/C++应用程序时,有时会出现应用崩溃,而不能应用到上述异常处理程序中。相反,会弹出一个标准的windows对话框,上面写着“XXX已停止工作”。在细节上它显示了例

在我开发的所有WPF应用程序中,都有一个订阅了AppDomain.CurrentDomain.UnhandledException的全局异常处理程序,它记录了它能找到的所有内容,然后显示一个对话框,告诉用户联系作者,日志文件所在的位置等。这非常好用,客户和我都非常满意,因为它允许快速修复问题

然而,在开发一个混合的WPF/C、/CLI/C++应用程序时,有时会出现应用崩溃,而不能应用到上述异常处理程序中。相反,会弹出一个标准的windows对话框,上面写着“XXX已停止工作”。在细节上它显示了例如

 Problem Event Name: BEX
 Application Name:   XXX.exe
 Fault Module Name:  clr.dll
 ...
这通常发生在从代码中调用托管函数以及该函数更新屏幕时。我没有花很长时间找出问题的根本原因,只是因为我可以在我的机器上重现崩溃并连接调试器:在所有情况下,本机线程仍然处于调用函数指针的位置,指向直接调用C#/WPF代码的托管委托

真正的问题是当这种情况发生在客户机上时:考虑到客户机通常不是最好的错误报告程序,可能需要非常、非常长的时间才能找出问题所在,而他们所能提供的只是上面的细节

问题是:我能做些什么来获取更多关于此类碰撞的信息?有没有办法通过调用自定义错误处理程序来获取这样的异常?或者得到一个进程转储?加载msvcr100_clr0004.dll和clr.dll的符号(加载到发生中断的线程上)时,调用堆栈如下所示:

msvcr100_clr0400.dll!__crt_debugger_hook()  
clr.dll!___report_gsfailure()  + 0xeb bytes 
clr.dll!_DoJITFailFast@0()  + 0x8 bytes 
clr.dll!CrawlFrame::CheckGSCookies()  + 0x2c3b72 bytes  

我能将一些本地C++代码挂钩到y-CRTJUnjultGrErHooC()中(例如,编写一个MIDIDUMP)?这就引出了另一个问题:

CheckGSCookies
在没有安装调试器的机器上如何运行,它还会调用相同的代码吗

>强>更新< /String >代码:本地C++调用CLI委托(使用一个本地函数指针获取它,使用<代码> GETFrasePotoFruteRealPux< /Cult>),这又调用一个Cy.SytStudio.Actudio。并引发propertychanged事件。这会以某种方式调用未命名线程中的缓冲区溢出(当更新非常快时),该线程不是在我的代码中直接创建的


update查看
SetUnhandledExceptionFilter
,它起初没有做任何事情,我发现解释了如何捕获任何异常。它是有效的,我能够在使用该过程安装的异常过滤器中编写一个小转储。转储提供的信息基本上与挂接调试器相同:真正的p问题似乎是状态字符串正在被覆盖(通过从本机线程调用)同时从ui线程读取。所有的nice都是这样,但它确实需要dll挂接,这不是我最喜欢的解决方法。另一种方法仍然很好。

CLR的.NET 4版本具有防止缓冲区溢出攻击的保护。基本方案是代码编写“cookie”在数组或堆栈帧的末尾,然后稍后检查cookie是否仍然具有原始值。如果cookie已更改,则运行时会假定恶意软件已破坏程序状态并立即中止程序。这种中止不会通过通常未经处理的异常机制进行,这太容易被利用


您的程序确实受到攻击的可能性当然很小。更有可能的是,您的本机代码存在指针错误,并在CLR结构或堆栈帧中乱涂乱画。调试并不容易,损坏通常在崩溃之前就已经完成。一种方法是注释掉代码,直到崩溃消失。

纠正我的错误如果我错了:1.目标平台是Windows。2.您正在安装一个应用程序范围的未处理异常筛选器。3.您创建了一些线程并动态加载了一些DLL。4.您调用了一些DLL函数,这些函数抛出的异常不会进入您的处理程序。是否正确?此外,这些异常发生在您的一个线程中或者在(可能)由DDLs函数创建的线程中?@AzzA 1.是2.是,但使用CurrentDomain.UnhandledException,不确定这是否足够3.是4.请参阅更新尝试:1.尝试使用
SetUnhandledExceptionFilter
WinAPI,而不是
CurrentDomain.UnhandledException
(尽管如此,我严重怀疑它是上述WinAPI的包装器).2.看起来动态加载的DLL可能在启动时将处理程序重置为默认空值。我试图指出的一点是,加载DLL后,您必须安装筛选器,考虑到它们可能会延迟加载-您是在代码中使用链接器还是
LoadLibrary
加载它们d:
SetUnhandledExceptionFilter
为进程的所有当前和未来线程安装筛选器,因此即使DLL也会创建一些线程,这应该不是问题。另外,我假设,在安装文件服务器后会发生异常。否则,这非常简单。@Azza DLL不会重置CurrentDomain。UnhandledException:af加载所有内容后,仍会捕获正常的C#异常。dll的加载方式如下:主C#应用程序使用Load/LoadFrom加载其他程序集。这些程序集依次加载C++/CLI dll(不确定如何执行此操作)它会链接到一组C++ DLL。我会看到什么代码> StunDundLeXPuthPosivs>代码可以做的,听起来很有趣。这很有趣。我看到这些东西是由MS编译器安装的,正好我回答缓冲区溢出。它已经拆卸并显示<代码> SualthyOxCuovie/Cuff>安装。似乎没有。不仅是.NET,还有MS编译器。谢谢bri