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

标签 c# c++ wpf c++-cli buffer-overflow

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

然而,在混合 WPF/C#/CLI/C++ 应用程序的开发过程中,有时会出现应用程序崩溃,而这些崩溃不会进入上述异常处理程序。相反,会弹出一个标准的 Windows 对话框,提示“XXX 已停止工作”。在细节中它显示例如

 Problem Event Name: BEX
 Application Name:   XXX.exe
 Fault Module Name:  clr.dll
 ...

这主要发生在从非托管代码中回调托管函数时,以及该函数更新屏幕时。我没有花很长时间找出问题的根本原因,只是因为我可以在我的机器上重现崩溃并连接调试器:在所有情况下, native 线程仍处于调用函数指针的位置直接调用 C#/WPF 代码的托管委托(delegate)。

真正的问题是当这种情况发生在客户端机器上时:考虑到客户端通常不是最好的错误报告者,当他们能提供给我的只是详细信息时,可能需要非常非常长的时间才能找出问题所在以上。

问题:如何获取此类崩溃的更多信息?无论如何,有没有办法获得像这样调用自定义错误处理程序的异常?或者获取进程转储?加载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  

我能否以某种方式将一些 native C++ 代码 Hook 到 __crt_debugger_hook() 中(例如,用于编写小型转储)?这让我想到了另一个问题:CheckGSCookies 在没有安装调试器的机器上如何运行,它是否仍会调用相同的代码?

更新 对代码的一些说明: native C++ 调用 CLI 委托(delegate)(使用 GetFunctionPointerForDelegate 获取 native 函数指针,后者又调用 C# System.Action . 此操作更新字符串(绑定(bind)到 WPF 标签)并引发 propertychanged 事件。这会以某种方式在我的代码中未直接创建的未命名线程中调用缓冲区溢出(当更新速度非常快时)。

更新 查看 SetUnhandledExceptionFilter,一开始什么也没做,我发现 this nifty article解释如何捕获任何异常。它有效,我能够在使用该过程安装的异常过滤器中编写一个小型转储。转储提供的信息与 Hook 调试器基本相同:真正的问题似乎是 Status 字符串正在被覆盖(通过从 native 线程调用),同时从 ui 线程读取。一切都很好,但它确实需要 dll Hook ,这不是我最喜欢的解决问题的方法。换一种方式还是不错的。

最佳答案

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

当然,您的程序真的受到攻击的可能性很小。更有可能的是,您的 native 代码存在指针错误并将垃圾乱写到 CLR 结构或堆栈框架中。调试并不容易,损坏通常在崩溃前就已完成。一种方法是注释掉代码,直到崩溃消失。

关于c# - 如何在混合应用程序中获取有关缓冲区溢出异常的信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8800611/

相关文章:

c# - 如何在 Windows.Forms 中制作 float (工具提示)控件?

c# - 如何使用 Compact Framework 在 C# 中验证 X.509 证书

c++ - 为 OSX bundle 的 Qt 5.4 应用程序在启动时崩溃

c# - 事件 "While Button is Pressed"

c# - 用纯 C# 代码编写的自定义 DataTemplate 的问题

c# - 动态切换 Microsoft.Speech 配置文件

c# - EF Core 规范模式添加所有列以使用自定义规范对数据进行排序

c++ - SDL2 C++ 未处理异常

c++ - 如何从管道传输到标准输入的文件获取输入

WPF MDI child