欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

SEH in ASM 研究(二) (6千字)

SEH in ASM 研究(二) (6千字)

PART II 继续深入
三、传递给异常处理句柄的参数
      要想明白seh处理例程如何得到感兴趣的信息,首先要明白SEH的作用机制.事实上,当异常
发生时,系统给了我们一个处理异常的机会,他首先会调用我们自定义的seh处理例程,当然也包括
了相关信息,在调用之前,系统把包含这些信息结构的指针压入stack,供我们的异常处理例程调用,
传递给例程的参数通常是四个,其中只有三个有明确意义,另一个到现在为止还没有发现有什么作用,
这些参数是:pExcept:DWORD,pErr:DWORD,pContext:DWORD,pDispatch意义如下:
pExcept:  ---  EXCEPTION_RECORD结构的指针
pErr:    ---  前面ERR结构的指针
pContext: --- CONTEXT结构的指针
pDispatch:---没有发现有啥意义
    ERR结构是前面介绍的_EXCEPTION_REGISTRATION结构,往前翻翻,Dispatch省略,下面介绍
EXCEPTION_RECORD和CONTEXT结构的定义:
 
;//================================以下是两个成员的详细结构========================================
        EXCEPTION_RECORD STRUCT
          ExceptionCode        DWORD      ?      ;//异常码
          ExceptionFlags        DWORD      ?      ;//异常标志
          pExceptionRecord      DWORD      ?      ;//指向另外一个EXCEPTION_RECORD的指针
          ExceptionAddress      DWORD      ?      ;//异常发生的地址
          NumberParameters      DWORD      ?      ;//下面ExceptionInformation所含有的dword数目
          ExceptionInformation  DWORD EXCEPTION_MAXIMUM_PARAMETERS dup(?)
        EXCEPTION_RECORD ENDS                      ;//EXCEPTION_MAXIMUM_PARAMETERS ==15
;//================================具体解释========================================
ExceptionCode 异常类型,SDK里面有很多类型,你可以在windows.inc里查找STATUS_来找到更多
的异常类型,下面只给出hex值,具体标识定义请查阅windows.inc,你最可能遇到的几种类型如下:
              C0000005h----读写内存冲突
              C0000094h----非法除0
              C00000FDh----堆栈溢出或者说越界
              80000001h----由Virtual Alloc建立起来的属性页冲突
              C0000025h----不可持续异常,程序无法恢复执行,异常处理例程不应处理这个异常
              C0000026h----在异常处理过程中系统使用的代码,如果系统从某个例程莫名奇妙的返回,则出现此代码,
                          如果RtlUnwind时没有Exception Record参数也同样会填入这个代码
              80000003h----调试时因代码中int3中断
              80000004h----处于被单步调试状态
              注:也可以自己定义异常代码,遵循如下规则:
              _____________________________________________________________________+
              位:      31~30            29~28          27~16          15~0
              _____________________________________________________________________+
              含义:    严重程度          29位            功能代码        异常代码
                        0==成功        0==Mcrosoft    MICROSOFT定义  用户定义
                        1==通知        1==客户
                        2==警告          28位
                        3==错误        被保留必须为0
ExceptionFlags 异常标志
              0----可修复异常
              1----不可修复异常
              2----正在展开,不要试图修复什么,需要的话,释放必要的资源
pExceptionRecord 如果程序本身导致异常,指向那个异常结构
ExceptionAddress 发生异常的eip地址
ExceptionInformation 附加消息,在调用RaiseException可指定或者在异常号为C0000005h即内存异常时含义如下
              第一个dword 0==读冲突 1==写冲突
              第二个dword 读写冲突地址
;//================================解释结束========================================
                                                          off.
        CONTEXT STRUCT                    ; _
          ContextFlags  DWORD      ?      ;  |            +0
          iDr0          DWORD      ?      ;  |            +4
          iDr1          DWORD      ?      ;  |            +8
          iDr2          DWORD      ?      ;  >调试寄存器  +C
          iDr3          DWORD      ?      ;  |            +10
          iDr6          DWORD      ?      ;  |            +14
          iDr7          DWORD      ?      ; _|            +18
          FloatSave    FLOATING_SAVE_AREA <>  ;浮点寄存器区 +1C~~~88h
          regGs        DWORD      ?      ;--|            +8C
          regFs        DWORD      ?      ;  |\段寄存器    +90 
          regEs        DWORD      ?      ;  |/            +94           
          regDs        DWORD      ?      ;--|            +98
          regEdi        DWORD      ?      ;____________    +9C
          regEsi        DWORD      ?      ;      |  通用  +A0
          regEbx        DWORD      ?      ;      |  寄    +A4
          regEdx        DWORD      ?      ;      |  存    +A8
          regEcx        DWORD      ?      ;      |  器    +AC
          regEax        DWORD      ?      ;_______|___组_  +B0     
          regEbp        DWORD      ?      ;++++++++++++++++ +B4
          regEip        DWORD      ?      ;    |控制        +B8
          regCs        DWORD      ?      ;    |寄存        +BC
          regFlag      DWORD      ?      ;    |器组        +C0
          regEsp        DWORD      ?      ;    |            +C4
          regSs        DWORD      ?      ;++++++++++++++++ +C8
          ExtendedRegisters db MAXIMUM_SUPPORTED_EXTENSION dup(?)
        CONTEXT ENDS
;//================================以上是两个成员的详细结构========================================
   
        I、传递给final句柄的参数,只有两个可描述为EXCEPTION_POINTERS结构,定义如下:
            EXCEPTION_POINTERS STRUCT
              pExceptionRecord  DWORD      ?             
              ContextRecord    DWORD      ?
            EXCEPTION_POINTERS ENDS
            在call xHandler之前,堆栈结构如下:
            esp    -> *EXCEPTION_RECORD
            esp+4  -> *CONTEXT record  ;//具体结构见下面
                然后执行call _Final_Handler,这样在程序里要调用什么不轻而易举了吗?

   
    II、 传递给per_thread句柄的参数,如下:
    在call xHandler之前,在堆栈中形成如下结构
            esp    -> *EXCEPTION_RECORD
            esp+4  -> *ERR                    ;//注意这也就是fs:[0]的指向
            esp    -> *CONTEXT record          ;//point to registers
            esp    -> *Param                    ;//呵呵,没有啥意义
          然后执行 call _Per_Thread_Handler
调用handler的原型是这样
        invoke HANDLER,*EXCEPTION_RECORD,*_EXCEPTION_REGISTRATION,*CONTEXT record,*Param
        即编译代码如下:
        PUSH *Param                    ;//通常不重要,没有什么意义
        push *CONTEXT record            ;//上面的结构
        push *ERR                      ;//the struc above
        push *EXCEPTION_RECORD          ;//see above
        CALL HANDLER
        ADD ESP,10h

好现在你明白了应该如何访问具体有关系统信息的细节了吧,下一部分,让我们来看看如何应用...(待续)

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功