问题标签 [seh]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
5148 浏览

c - 如何将 Win32 异常代码转换为字符串?

我不情愿地再次处理 Win32 结构化异常。我正在尝试生成一个描述异常的字符串。大部分都很简单,但我坚持一些基本的问题:如何将异常代码(的结果GetExceptionCode()ExceptionCodean 的成员EXCEPTION_RECORD)转换为描述异常的字符串?

我正在寻找可以将例如 0xC0000005 转换为“访问冲突”的东西。这只是一个电话FormatMessage()吗?

0 投票
1 回答
166 浏览

winapi - 发出带有异常支持的代码

我需要在运行时生成执行以下操作的代码:

或 C 等价物:

cleanup() 函数保证没有异常,但是 do_some_danger_thing() 可能会抛出异常。此运行时代码必须不使用堆栈,这意味着在调用 do_some_danger_thing() 时,堆栈必须处于与我们进入运行时代码时相同的状态,除了返回地址设置为运行时代码(原始值保存到“jmp " 目标,为了返回给调用者)。

因为我们使用的是动态机器码,目标平台在x86 CPU上固定为WIN32,x64 CPU目前不是重点。

为此,我们必须处理任何异常。在 WIN32 C++ 中,异常是基于 SEH 的,所以我们必须处理它。问题是我们无法找到一种方法来做到这一点并使其与其他代码兼容。我们尝试了几种解决方案,但都不起作用,有时用户安装的异常处理程序从未被调用,有时外部异常处理程序被绕过,我们收到“未处理的异常”错误。

更新:

SEH 异常处理程序链似乎只支持 EXE 映像中的代码。如果异常处理程序指向我生成的代码,它将永远不会被调用。我要做的是创建一个静态异常处理函数存根,然后让它调用生成的处理程序。

0 投票
2 回答
3538 浏览

c++ - 结构化异常处理程序 (SEH) 不会捕获堆损坏

我正在编写使用 3rd 方库执行一项简单任务(光栅化)的小型实用程序(VC 2010,无 clr)。以后的实用程序将被更大的应用程序使用。有时,由于 3rd 方库中的一些堆损坏,实用程序会崩溃。没关系,但 Windows (Vista/2008) 显示众所周知的对话框“程序已停止工作......关闭/调试程序”。这在我的情况下不合适(服务器端)。实用程序应在没有任何可见效果的情况下静默崩溃/终止。

为此,我为未处理的异常 (SetUnhandledExceptionFilter) 安装了 SEH。对于像 AV ( *(PDWORD)0 = 0 ) 这样的异常,处理程序被完美地调用,但由于某种原因,它不会在堆损坏的情况下被调用。在卸载第 3 方库 dll 之一的 dllmain 时发生损坏。

几个问题。谁能解释为什么不调用处理程序?还有其他方法可以防止该对话吗?

0 投票
1 回答
2189 浏览

winapi - 逆向工程 SEH:为什么我的 IDENTICAL 汇编代码不像原来的那样工作?

我正在尝试对名为的 Visual C++ 2008 SEH 处理程序进行逆向工程,以__CxxFrameHandler3提供一个可以将结果委托给.__CxxFrameHandlermsvcrt.dll

这个页面这个页面有关于msvcrt.dll和 SEH 的详细信息。)

注意: msvcrt_winxp.obj(32 位)和msvcrt_win2003.obj(64 位)已经做了同样的事情——它们是Windows Driver Kit 7.1的一部分。但是,它们还与许多其他代码捆绑在一起,这弄乱了我的链接器。

我已经成功地反汇编了 32 位版本 ( msvcrt_winxp.obj)、提取__CxxFrameHandler3并创建了提供适当实现的替代方案。

但是,我遇到了 64 位版本 ( msvcrt_win2003.obj) 的问题:

尽管我的 64 位实现看起来完全一样,但它不起作用——但微软提供的那个确实有效。

这是 32 位版本(可以正常工作):

这是(有问题的)64 位版本:

微软的实现(用DumpBinon提取lib\wnet\amd64\msvcrt_win2003.obj)是:

当我尝试调试这两种格式时,只要我到达那一行,push r12Visual Studio 中的调用堆栈就会在我的版本中变得混乱(指向无效地址的表面条目会在堆栈帧之间弹出),在微软版本中的相同点。

事实上,当我允许继续执行时,我的程序在__CxxFrameHandler我的版本中崩溃,但在微软的版本中完全正常。

我正在测试两个来源的程序是:

使用适当的编译器标志 ( /MD /GS- /Od)。

因此我无法弄清楚:

为什么我的代码(应该与提供的实现完全相同msvcrt)会导致's内部的访问冲突__CxxFrameHandler


程序的 base64 编码在这里,因此您可以看到生成的实际二进制文件。

我的坏版本:

微软版本:


编辑:

对于那些好奇的人,我找到了解决方案,这要归功于 Raymond 的链接。

原来我需要更换

0 投票
3 回答
572 浏览

c - 我应该在 C 中“默认”使用 SEH 吗?

当我为 Windows 编写 C 代码时,我应该“默认”使用 SEH 的__try...__finally块,还是认为不必要地这样做是不好的做法?

换句话说,下面哪一个(例如)被认为是更好的实践,为什么?

相对

澄清

我忘了提:

我的想法是,如果有人稍后在块中插入更多代码(例如,从函数中提前返回),我的代码仍然会执行清理,而不是过早退出。所以它应该比其他任何东西都更具预防性。我仍然应该避免使用 SEH 吗?

0 投票
1 回答
751 浏览

winapi - 启用异常链验证 (SEHOP) 的光纤的 SEH 设置

我正在研究原生光纤/协程实现——相当标准,对于每个光纤,分配一个单独的堆栈,并且为了切换上下文,寄存器被推送到源上下文堆栈并从目标堆栈中弹出。它运作良好,但现在我遇到了一个小问题:

我需要 SEH 在纤程内工作(如果程序终止或奇怪的事情开始发生,直到纤程的最后一个堆栈帧之前未处理异常,这没关系,它不会)。只是在上下文切换期间保存/恢复FS:[0](显然与FS:[4]and一起FS:[8])并最初为新分配的纤程设置 FS:[0] 0xFFFFFFFF(以便在上下文切换后设置的异常处理程序将成为链的根)几乎可以工作。

准确地说,它适用于我测试过的所有非服务器 Windows 操作系统——问题是 Windows Server 2008 和 2008 R2 默认启用了异常链验证(SEHOP、SEH 覆盖保护)功能,这使得RaiseException检查原始处理程序是否(在 ntdll.dll 中的某处)仍然是链的根,并立即终止程序,就好像没有安装任何处理程序一样。

因此,我面临着在堆栈上构建适当的根框架以保持验证代码满意的问题。是否有任何(隐藏的?)API 函数我可以调用来做到这一点,还是我必须弄清楚需要什么才能让RtlDispatchException朋友开心并_EXCEPTION_REGISTRATION自己构建适当的条目?我不能只重用创建线程中的 Windows 提供的地址,因为它会位于错误的地址(SEH 实现还检查处理程序地址是否在 and 给出的边界内FS:[4]FS:[8]并且还可能检查地址顺序是否一致)。

哦,我强烈希望诉诸CreateFiberWinAPI 系列函数。

0 投票
2 回答
1585 浏览

c++ - 当 ExceptionCode 为 STATUS_UNWIND_CONSOLIDATE 时,RtlRestoreContext 会做什么?

我试图了解 Visual C++ 运行时如何在 x64 上实现 C++ 异常处理。

在阅读关于在 x64 上实现 SEH 的 Nynaeve 博客http://www.nynaeve.net/?p=110后,似乎 RtlUnwindEx 调用 RtlRestoreContext 并将 ExceptionCode 设置为 STATUS_UNWIND_CONSOLIDATE 以展开框架合并。

我不完全清楚的是 RtlRestoreContext 做了什么?MSDN 在http://msdn.microsoft.com/en-us/site/ms680605声明“RtlRestoreContext 在调用回调函数之前将其框架和上下文记录中指定的框架之间的调用框架合并。这隐藏了任何异常的框架回调函数中可能发生的处理。”

“在其框架和上下文记录中指定的框架之间合并调用框架”是什么意思?这如何“隐藏回调函数中可能发生的任何异常处理的帧”?“框架整合”是什么意思,整合的框架到底在哪里?

假设 RtlRestoreContext 将调用 C++ 捕获处理程序,它会引发另一个异常 - (重新)抛出的异常是否受某种 SEH 块的保护?或者,这个框架整合业务以某种方式处理它?如果是,如何?

0 投票
1 回答
5283 浏览

ollydbg - 无法在 Olly 调试器中传递异常

我正在使用 Olly Debugger 调试程序。它在执行时安装一个异常处理程序,如下所示:

因此,现在安装了位于地址 004010a9 的异常处理程序。

下一条指令触发内存访问冲突,如下所示:

由于代码没有写入代码部分的权限,因此它会触发内存访问冲突并停止。

现在,我可以通过按 Shift + F9 将异常传递给程序。

但是,当我按下时,什么也没有发生,程序仍处于暂停状态。

此时我的 SEH 链如下所示:

我在 Olly Debugger 中的调试选项设置如下:

在异常选项卡下,我只选中了以下选项:

忽略 Kernel32 中的内存访问冲突

我无法理解为什么当我按下 Shift + F9 时程序没有将异常传递给位于 004010a9 的异常处理程序,因为它是当前线程异常处理程序。

谢谢。

0 投票
1 回答
180 浏览

windows - 使用 SEH 保护我的代码免受第三方 COM 对象抛出的异常是否合理

我正在保护我自己的 C++ 代码(Windows x86)免受第三方 COM 对象中的异常影响,并使用以下 SEH 伪代码记录这些异常。

如果 SEH 代码不存在,这种方法是否可能捕获将要处理的异常?

下面的一篇 MSDN 文章提到,默认的未处理异常过滤器将捕获并修复代码在加载的资源中写入内存的情况。在其他情况下,使用 SEH 会干扰理想的默认操作系统行为吗?

Win32™ 结构化异常处理深度速成课程

0 投票
1 回答
7415 浏览

c# - Azure 角色环境未初始化

我的项目突然停止工作。我正在使用本地存储,当我尝试初始化角色环境时,它说:

“Microsoft.WindowsAzure.ServiceRuntime 错误:102:角色环境。初始化失败”

并且发生 SEH 异常,错误代码为“-2147467259”。我启动项目的云部分的新实例,然后尝试在同一解决方案中启动我的 WPF 应用程序的新实例。我认为当 WPF 应用程序运行时,它会停止云实例部署。但我不确定。