我正在尝试关注 this关于 Win32 结构化异常处理的文章。这篇文章很老了,但仍然被认为是对该主题的一个很好的介绍。
我正在尝试从下面转载的文章中编译代码示例 -
//==================================================
// MYSEH - Matt Pietrek 1997
// Microsoft Systems Journal, January 1997
// FILE: MYSEH.CPP
// To compile: CL MYSEH.CPP
//==================================================
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
DWORD scratch;
EXCEPTION_DISPOSITION
__cdecl
_except_handler(
struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
void * DispatcherContext )
{
unsigned i;
// Indicate that we made it to our exception handler
printf( "Hello from an exception handler\n" );
// Change EAX in the context record so that it points to someplace
// where we can successfully write
ContextRecord->Eax = (DWORD)&scratch;
// Tell the OS to restart the faulting instruction
return ExceptionContinueExecution;
}
int main()
{
DWORD handler = (DWORD)_except_handler;
__asm
{ // Build EXCEPTION_REGISTRATION record:
push handler // Address of handler function
push FS:[0] // Address of previous handler
mov FS:[0],ESP // Install new EXECEPTION_REGISTRATION
}
__asm
{
mov eax,0 // Zero out EAX
mov [eax], 1 // Write to EAX to deliberately cause a fault
}
printf( "After writing!\n" );
__asm
{ // Remove our EXECEPTION_REGISTRATION record
mov eax,[ESP] // Get pointer to previous record.
mov FS:[0], EAX // Install previous record
add esp, 8 // Clean our EXECEPTION_REGISTRATION off stack
}
return 0;
}
在用“cl”编译它时,它似乎生成了一个可执行文件,但也会抛出以下错误:
myseh.cpp(42) : warning C4733: Inline asm assigning to 'FS:0': handler not registered as safe handler
myseh.cpp(56) : warning C4733: Inline asm assigning to 'FS:0': handler not registered as safe handler
可执行文件崩溃了,自定义异常处理程序似乎没有正常工作。 在互联网上搜索似乎表明我需要将我的自定义异常处理程序函数注册为安全异常处理程序。我不是专业的开发人员。但是我还是想关注这篇文章。我需要一些关于如何获得工作可执行文件的指导。
我在 Windows 10 上使用 Visual Studio 2015。
最佳答案
来自 C4733 的描述警告:
Inline asm assigning to 'FS:0' : handler not registered as safe handler
A function modifying the value at FS:0 to add a new exception handler may not work with Safe Exceptions, because the handler may not be registered as a valid exception handler (see /SAFESEH).
To resolve this warning, either remove the FS:0 definition or turn off this warning and use .SAFESEH to specify the safe exception handlers.
这基本上意味着您正在尝试使用不会在生成的可执行镜像中注册为安全 SEH 处理程序的处理程序。
根据您的链接器设置,它可能会执行也可能不会执行。
默认情况下,链接器会生成安全处理程序表,但它不知道您的_except_handler
是异常处理程序,因此它不会将其放入安全 SEH 处理程序。要解决它,您基本上有两种选择:
使用
.safeseh
MASM 指令将您的函数标记为安全处理程序。
您必须将其放入单独的 ASM 文件中,因为内联汇编不支持这些指令。使用
/SAFESEH:NO
开关指示链接器不创建安全处理程序表。
这样,您的可执行文件中的任何 SEH 处理程序都将被操作系统视为安全处理程序。
我建议查看 /SAFESEH链接器开关和 .safeseh MASM 指令文档以获取更多信息。
有关安全 SEH 处理程序的更多信息可以在此 article 中找到:
The general idea is to collect handlers' entry points in a designated read-only table and have each entry point verified against this table for exceptions prior to control being passed to the handler.
关于c++ - 内联 asm 分配给 'FS:0' : handler not registered as safe handler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37298061/