登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> CLQ工作室开源代码 >> 主题: MinGW 中的 seh 如何使用     [回主站]     [分站链接]
标题
MinGW 中的 seh 如何使用
clq
浏览(9) + 2021-10-06 11:56:08 发表 编辑

关键字:

[2021-10-06 13:32:51 最后更新]
MinGW 中的 seh 如何使用

MinGW 是有多个发行版本的,其中比较常用的 seh 版本是其中一个,那个 MinGW 中的 seh 如何使用呢?

参考 https://blog.csdn.net/aa13058219642/article/details/80263706
http://bytepointer.com/resources/pietrek_crash_course_depths_of_win32_seh.htm

----------------------------------------------------------------
不过 ndk 里目前来说应该是不支持的,还是要用传统的 longjmp 。

clq
2021-10-06 11:56:39 发表 编辑

结构化异常处理(SEH)在MSVC和MinGW上的使用

SEH 即 Structured Exception Handling,结构化异常处理。是 M$ 在 Windows 下实现的一套异常处理机制,用于支持软件和硬件异常处理。SEH 作为 Windows 特有的机制,同时也是 Windows 溢出攻击中常见的利用的途径之一。

关于SEH的详细分析,请看Matt Pietrek的文章(原文是发布在MSDN上的,但似乎已经被删除了,这是别处转载的链接):

英语原文:A Crash Course on the Depths of Win32 Structured Exception Handling
英语转载:A Crash Course on the Depths of Win32 Structured Exception Handling
译文:深入解析结构化异常处理(SEH)
在MSVC上使用

#include <windows.h>
#include <Dbghelp.h>

//崩溃函数
int crashFunc()
{
    printf("crashFunc\n");
    int *p = NULL;
    *p = 1;
    return *p;
}

LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)
{
    printf("UnhandledExceptionFilterEx call\n");

    return EXCEPTION_CONTINUE_SEARCH;
    //return EXCEPTION_EXECUTE_HANDLER;
}

int main(int argc, char** argv)
{

    //方式1 调用winapi,把崩溃处理函数挂载在顶层异常处理中
    SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
    crashFunc();


    //方式2 使用__try/__except拦截异常
    __try
    {
        crashFunc();
    }
    __except(UnhandledExceptionFilterEx(GetExceptionInformation()))
    {
        printf("crash __except\n");
    }
}



在mingw上使用

#include <windows.h>
#include <Dbghelp.h>

//崩溃函数
int crashFunc()
{
    printf("crashFunc\n");
    int *p = NULL;
    *p = 1;
    return *p;
}

LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)
{
    printf("UnhandledExceptionFilterEx call\n");

    return EXCEPTION_CONTINUE_SEARCH;
    //return EXCEPTION_EXECUTE_HANDLER;
}

int exceptEx(_In_ EXCEPTION_POINTERS *lpEP)
{
    return UnhandledExceptionFilterEx(lpEP);
}


int main(int argc, char** argv)
{

    //方式1 和msvc一样,都是调用winapi
    SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
    crashFunc();


    //方式2 __try1/__except1拦截异常
    __try1(exceptEx)
    {
        crashFunc();
    }
    __except1
    {
        printf("crash __except1\n");
    }
}
————————————————

clq
2021-10-06 12:50:15 发表 编辑

//seh 支持
//原文来自 https://blog.csdn.net/aa13058219642/article/details/80263706
//我的 mingw64_seh 不支持这个,实际上现在是不行的,原因不明,要用以下链接处的方法 https://blog.csdn.net/weixin_34014277/article/details/93383173
//主要是修改了 __try1() 中的函数原型,另外有可能要加 excpt.h
//实际运行时还需要 libstdc++-6.dll libgcc_s_seh-1.dll 这些 dll ,实际上我全部复制了 mingw64_seh bin 下面的 dll ,文件大概 2m 还好不算太大

//int exceptEx(_In_ EXCEPTION_POINTERS *lpEP)
extern "C" int exceptEx(_In_ EXCEPTION_POINTERS *lpEP)
{
    return UnhandledExceptionFilterEx(lpEP);
}

//EXCEPTION_DISPOSITION MyHandler (struct _EXCEPTION_RECORD* er, void* buf, struct _CONTEXT* ctx, void* buf2)
extern "C" EXCEPTION_DISPOSITION MyHandler (struct _EXCEPTION_RECORD* er, void* buf, struct _CONTEXT* ctx, void* buf2)
{
//   printf("ExceptionCode  = %08X %s\n"
//     "ExceptionFlags = %08X\n"
//      "ContextFlags   = %08X\n"
//      "SegGs  = %08X\n"
//      "SegFs  = %08X\n"
//      "SegEs  = %08X\n"
//      "SegDs  = %08X\n"
//      "Edi  = %08X\n"
//      "Esi  = %08X\n"
//      "Ebx  = %08X\n"
//      "Edx  = %08X\n"
//      "Ecx  = %08X\n"
//      "Eax  = %08X\n"
//      "Ebp  = %08X\n"
//      "Eip  = %08X\n"
//      "SegCs  = %08X\n"
//      "EFlags = %08X\n"
//      "Esp  = %08X\n"
//      "SegSs  = %08X\n",
//      er->ExceptionCode,
//      GetExceptionDescription(er->ExceptionCode),
//      er->ExceptionFlags,
//      ctx->ContextFlags,
//      ctx->SegGs,
//      ctx->SegFs,
//      ctx->SegEs,
//      ctx->SegDs,
//      ctx->Edi,
//      ctx->Esi,
//      ctx->Ebx,
//      ctx->Edx,
//      ctx->Ecx,
//      ctx->Eax,
//      ctx->Ebp,
//      ctx->Eip,
//      ctx->SegCs,
//      ctx->EFlags,
//      ctx->Esp,
//      ctx->SegSs
//     );
  return ExceptionNestedException;
}

//int main(int argc, char** argv)
void seh_test1_main()
{

    //方式1 和msvc一样,都是调用winapi
    ////SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
    ////crashFunc();


    //方式2 __try1/__except1拦截异常
    //__try1(exceptEx)  //我的 mingw64_seh 不支持这个
    __try1(MyHandler)
    {
        crashFunc();
    }
    __except1
    {
        printf("crash __except1\n");
    }
}

clq
2021-10-06 12:52:01 发表 编辑

这样的代码写在业务逻辑中显然不太合适,目前也不可能通用。不过用来制作 win 下面的功能库是非常好的。
所以也还算是很有用的知识吧。

clq
2021-10-06 13:32:51 发表 编辑

另参考 https://www.cnblogs.com/feiyucq/archive/2010/05/12/1733462.html

总数:4 页次:1/1 首页 尾页  
总数:4 页次:1/1 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1