龙马谷

 找回密码
 立即注册

QQ登录

只需一步,快速开始

龙马谷VIP会员办理客服QQ:82926983(如果临时会话没有收到回复,请先加QQ好友再发。)
1 [已完结] GG修改器新手入门与实战教程 31课 2 [已完结] GG修改器美化修改教程 6课 3 [已完结] GG修改器Lua脚本新手入门教程 12课
4 [已完结] 触动精灵脚本新手入门必学教程 22课 5 [已完结] 手游自动化脚本入门实战教程 9课 6 [已完结] C++射击游戏方框骨骼透视与自瞄教程 27课
7 [已完结] C++零基础UE4逆向开发FPS透视自瞄教程 29课 8 [已完结] C++零基础大漠模拟器手游自动化辅助教程 22课
以下是天马阁VIP教程,本站与天马阁合作,赞助VIP可以获得天马阁对应VIP会员,名额有限! 点击进入天马阁论坛
1 [已完结] x64CE与x64dbg入门基础教程 7课 2 [已完结] x64汇编语言基础教程 16课 3 [已完结] x64辅助入门基础教程 9课
4 [已完结] C++x64内存辅助实战技术教程 149课 5 [已完结] C++x64内存检测与过检测技术教程 10课 6 [已完结] C+x64二叉树分析遍历与LUA自动登陆教程 19课
7 [已完结] C++BT功能原理与x64实战教程 29课 8 [已完结] C+FPS框透视与自瞄x64实现原理及防护思路
查看: 2037|回复: 0

VC++ 异常处理 __try __except的用法

[复制链接]

21

主题

0

回帖

26

积分

编程入门

Rank: 1

龙马币
52

__try __except的用法:

__try __except是windows 系统独有的异常处理模型,称为SEH( structured exception handling ),SEH的异常处理模型主要由__try __except语句来完成,与标准的try catch相似。

与C++异常处理模型使用catch关键字来定义异常处理模块,而SEH是采用__except关键字来定义;并且catch关键字后面往往接受一个函数参数,可以是各种类型的异常数据对象;

而 __except关键字则不同,它后面跟的却是一个表达式。

例子:
  1. long WINAPI FilterFunc(DWORD dwExceptionCode)
  2. {
  3.    return (dwExceptionCode ==
  4.    STATUS_STACK_OVERFLOW) ?
  5.    EXCEPTION_EXECUTE_HANDLER :
  6.   EXCEPTION_CONTINUE_SEARCH;
  7. }

  8. UINT WINAPI ThreadFunc(LPVOID param)
  9. {
  10.   __try
  11.  {
  12.        // guarded code
  13.  }
  14.  __except (FilterFunc(GetExceptionCode()))
  15.  {
  16.    // 如果是栈溢出,进行处理。
  17.   }
  18. return 0;
  19. }
复制代码



except参数的值有以下三种:

EXCEPTION_CONTINUE_EXECUTION (–1):          异常被忽略,控制流将在异常出现的点之后,继续恢复运行。
EXCEPTION_CONTINUE_SEARCH (0):                 异常不被识别,也即当前的这个__except模块不是这个异常错误所对应的正确的异常处理模块。
                                                                        系统将继续到上 __try __except域中继续查找一个恰当的__except模块。
EXCEPTION_EXECUTE_HANDLER (1):                异常已经被识别,控制流将进入到__except模块中运行异常处理代码



__try __except的关键是如何在 __except模块中获得异常错误的相关信息?

Windows提供了两个API函数来获取异常信息:
  1. LPEXCEPTION_POINTERS GetExceptionInformation(VOID); //取得异常相关信息
  2. DWORD GetExceptionCode(VOID); // 取得异常编号
复制代码



EXCEPTION_POINTERS结构如下,
  1. typedef struct _EXCEPTION_POINTERS
  2. { // exp
  3. PEXCEPTION_RECORD ExceptionRecord;

  4. PCONTEXT ContextRecord;

  5. } EXCEPTION_POINTERS;
复制代码


EXCEPTION_RECORD类型,它记录了一些与异常相关的信息;

CONTEXT数据结构体中记录了异常发生时,线程当时的上下文环境,主要包括寄存器的值。

有了这些信息,__except模块便可以对异常错误进行很好的分类和恢复处理,通常我们需要一个过滤函数来辅助。一般称为是filterfunction.过滤函数只过滤需要处理的异常。

  1. int exception_access_violation_filter(LPEXCEPTION_POINTERS p_exinfo)
  2. {
  3.     if(p_exinfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
  4.     {
  5.         messagebox("access vialation exceptionn");

  6.        return EXCEPTION_EXECUTE_HANDLER ; //告诉except处理这个异常
  7.     }
  8.     else
  9.     {
  10.      return EXCEPTION_CONTINUE_SEARCH; //不告诉except处理这个异常
  11.     }
  12. }

  13. int exception_int_divide_by_zero_filter(LPEXCEPTION_POINTERS p_exinfo)
  14. {
  15.     if(p_exinfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
  16.     {
  17.         return  EXCEPTION_EXECUTE_HANDLER; //告诉except处理这个异常
  18.     }
  19.    else
  20.    {
  21.     return EXCEPTION_CONTINUE_SEARCH; //不告诉except处理这个异常
  22.    }
  23. }
复制代码



于是,可以这样写这段异常处理代码:
  1. __try
  2. {

  3.   // guarded code

  4. }

  5. __except(exception_access_violation_filter(GetExceptionInformation()))
  6. {

  7. //在此可以调用BugReport程序

  8. }
复制代码




SEH异常处理模型中,也可以抛出一个异常。对应的WindowsAPI函数是RaiseException,
  1. VOID RaiseException(
  2. DWORD dwExceptionCode, // 异常的编号
  3. DWORD dwExceptionFlags, // 异常标记
  4. DWORD nNumberOfArguments, // 参数个数
  5. CONST DWORD *lpArguments //  参数数组首地址
  6. );
复制代码



通常,后三个参数基本不用 SEH异常处理还有__try __finally.类似于java里的try-catch-finally.但是SEH的try只能和except和finally两者之间的一个搭配,不能有try-except-finnaly.

C++异常模型用try-catch语法定义,而SEH异常模型则用try-except语法,与C++异常模型相似,try-except也支持多层的try-except嵌套。

try-except模型中,一个try块只能是有一个except块;而C++异常模型中,一个try块可以有多个catch块。

C++异常模型是按照异常对象的类型来进行匹配查找的;而try-except模型则不同,它通过一个表达式的值来进行判断. __except关键字后面跟的表达式,它可以是各种类型的表达式,

例如,它可以是一个函数调用,或是一个条件表达式,或是一个逗号表达式,或干脆就是一个整 型常量等等。

最常用的是一个函数表达式,并且通过利用GetExceptionCode()或GetExceptionInformation ()函数来获取当前的异常错误信息,便于程序员有效控制异常 错误的分类处理。

SEH异常处理模型中,异常通过RaiseException()函数抛出。RaiseException()函数的作用类似于C++异常模型中的throw。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

龙马谷| C/C++辅助教程| 安卓逆向安全| 论坛导航| 免责申明|Archiver|
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表龙马谷立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2018-2021 All Right Reserved.
在线客服
快速回复 返回顶部 返回列表