Windows XP下的向量异常处理

Windows C++程序崩溃自动捕获:Minidump原理与工程实践 Windows C++开发中,程序崩溃是常见的调试难题。其核心在于异常处理机制,当发生未处理的异常时,系统会调用未处理异常过滤器,这是程序崩溃前的最后机会。通过SetUnhandledExceptionFilter API,开发者可以接管这一流程,在进程终止前保存关键状态。Minidump技术在此发挥了关键作用,它通过MiniDumpWriteDump API生成小型转储文件,仅包含异常记录、线程堆栈和加载模块等核心信息,文件体积小且生成速度快。这种自动化的崩溃捕获机制极大提升了远程诊断效率,尤其适用于难 阅读详情
Windows XP下的向量异常处理 

作者:Hume/冷雨飘心·发布日期:2002-8-9·


原作名称: Vectored Exception Handling
原作: Matt Pietrek
翻译改写: hume/冷雨飘心

   首先回顾一下(SEH)结构化异常处理,结构化异常处理用EXCEPTION_RETGISTRATION结构链起来的异常处理系统,那么当异常发生时,系统会遍历这个链,首先是链最前面的,系统会问:这个异常你处理吗?如果回答YES(通过返回EXCEPTION_CONTINUE_EXECUTION)的话,那系统就把控制权交给他,然后由其处理这个异常,返回到异常处理程序想返回的任何地方.如果通过返回EXCEPTION_CONTINUE_SEARCH回答:NO,let others do that! 系统就继续查找这个链,不厌其烦地问同样的问题和采取相同的处理原则.这个链最前面的EXCEPTION_RETGISTRATION是由fs:[0]处的一个dword指针指向的.具体细节还请参阅相关资料或我以前的<>.
   让我们来看一下seh的缺点,就是最后安装的seh处理例程总是优先得到控制权,这有时并不是最好的解决方案,但确实是seh的工作机制,当然Final型的或称top型的(还记得吗,也就是通过SetUnHandledExceptionFilter安装的)例外,因为他是不允许嵌套的.我们提到的是线程相关的也就是per_Thread类型的.为什么不是好的解决方案呢,让我们设想一下,假如你用两周写了一个异常完美的seh处理例程,能够完美处理所有异常,并希望异常全部由你来处理,但很不幸,比如你调用了一个外部模块,而这个模块自己安装了一个ugly的seh处理例程,他的动作是只要有异常发生就简单地终止程序...hmmm...!!!这意味着什么?你的两周工作全部付诸东流!又比如你想在你的加壳程序里面加密目标程序代码段,然后发生无效指令异常的时候用你自己安装的处理句柄来解密代码段继续执行,听起来这的确是一个好主意,但遗憾的是大多数C/C++代码都用_try{}_except{}块来保证其正确运行,而这些异常处理例程是在你壳注册的例程之后安装的,因而也就在链的前面,无效指令一执行,首先是C/C++编译器本身提供的处理例程或者程序其他的异常处理例程来处理,可能简单结束程序或者....天知道!
   在Xp下,Microsoft又提供了又一种异常处理,那就是VEH(Vectored Exception Handling),我译作向量异常处理,这个东东用如下api注册,类似于SEH,也是一个链状结构,让我们来看看他的不同之处,噫,好像差不多啊:

    WINBASEAPI PVOID WINAPI AddVectoredExceptionHandler(
    ULONG FirstHandler,
    PVECTORED_EXCEPTION_HANDLER VectoredHandler );

    FirstHandler:是一个标志,可以指定是否将你的VEH处理例程放在VEH链的最前面!=0,放在最后,其他放在最前
    VectoredHandler:这个东东是异常处理例程入口
    返回注册的VEH句柄,后面卸载的时候要用到.

    LONG NTAPI VectoredExceptionHandler(PEXCEPTION_POINTERS);
    PEXCEPTION_POINTERS是指向EXCEPTION_POINTERS的指针,和SEH中FINAL型的EXCEPTION_POINTERS
    的结构是一致的.

    正像你看到的,好像和Final型SEH处理差不多?不一样!区别如下:
    1)首先是AddVectoredExceptionHandler添加的异常处理句柄可以嵌套,而不是只能指定一个
    2)其次是AddVectoredExceptionHandler可以指定你的异常处理句柄是否在链的最前面,hoho,
    这可是我们期望的!当然如果在你后面有人调用AddVectoredExceptionHandler也作同样指定,那对不起,你只得在他后面了.

    相同之处在于:
    1)他们都是进程而不是线程相关的.
    2)若所有均不处理异常,最后系统要进行展开,不过不会调用VEH例程

    XP仍然支持SEH,那么问题来了SEH和VEH是什么关系,答案很简单,VEH优先权高于SEH,只有所有VEH全不处理某个异常的时候,异常处理权才会到达SEH.只要目标程序中没有利用VEH,你的VEH就是第一个得到控制者.嘿嘿,现在的采用SEH作为异常处理的普通C/C++程序对你不会再有干扰了!你可以用VEH来hook了,god!
    另外一个问题,如果有debuger怎么办?控制权转向又如何呢?不幸的消息来了,异常发生后首先通知的还是debugger,debugger不处理才返回控制权给VEH,[VEH不处理,返回给SEH,seh不处理,又给debugger一个机会,如果还不处理,才由系统处理

    RemoveVectoredExceptionHandler 用来移除VEH处理句柄.是否需要看你的了,不过有一点必须注意,系统不会自动移除注册的VEH例程,如果指向的VEH例程所在exe或dll已经卸载,通常会导致严重错误.
    最后有一点要声明,在VEH回调处理例程中必须保护好寄存器,否则会引起莫名其妙的异常,这可是我化了2个小时的代价阿.

下面是一个例子:
;============================================================
;asm ex,By Hume
;.............
.586
.model flat, stdcall
option casemap :none   ; case sensitive
include c:/hd/hd.h
include c:/hd/mac.h
;~~~~~~~~~~~~~~~~~~~protos
ASSUME  fs:nothing
;~~~~~~~~~~~~~~~~~~~~~~~~~
;;--------------

	.DATA
sztit   db "By Hume,2K2",0

	.DATA?
rd      hK32                    ;Kernel32模块地址
rd      hVec                    ;AddVectoredExceptionHandler函数地址
rd      hRemov                  ;RemoveVectoredExceptionHandler函数地址
rd      hvectorhandler1
rd      hvectorhandler2
;;-----------------------------------------
	.CODE
__Start:
        __msg   begin Testing...

        mov     hK32,$invoke(LoadLibrary,CTEXT("KERNEL32.DLL"))
        JEAXZ   _err_1
        mov     hVec,$invoke(GetProcAddress,eax,CTEXT("AddVectoredExceptionHandler"))
        JEAXZ   _err_2
        mov     hRemov,$invoke(GetProcAddress,hK32,CTEXT("RemoveVectoredExceptionHandler"))
        JEAXZ   _err_2

                ;相当于invoke AddVectoredExceptionHandler,0,offset vEcp1
        sWin32	hVec,0,offset vEcp1     ;First VEH
        mov     hvectorhandler1,eax
        sWin32	hVec,0,offset vEcp2     ;Second....
        mov     hvectorhandler2,eax

        lea     eax,[esp-8]
        xchg    eax,fs:[0]
        push    offset sEh1
        push    eax
                                ;以上是安装VEH回调例程和
                                ;SEh回调例程

        pushfd
        or      dword ptr [esp],100h
        popfd
        nop                     ;Here Exception!->veh1
        nop
     @3:
        mov     esi,CTEXT("Good,Was Solved by VEH No 2")
        JMP     @F

     @1:
        INVOKE	MessageBox,0,CTEXT("Good,Was Solved by VEH No 1"),addr sztit,0
        xor     eax,eax
        mov     eax,[eax]       ;Here!->seh1
        JMP     @1
     @2:
        INVOKE	MessageBox,0,CTEXT("Good,Was Solved by seh No 1"),addr sztit,0
        INT     3               ;VEH2
        JMP     @2


        ;--------------------------------------------
        ; 以下是简单错误处理
        ;--------------------------------------------
_err_1:
        mov     esi,CTEXT("Can't load DLL")
        jmp     @F

_err_2:
        mov     esi,CTEXT("Can't Find function")
        @@:
_xit:
        INVOKE	MessageBox,0,esi,CTEXT("By Hume,2K2"),0

                        ;卸载所有的VEH和SEH处理例程
        pop     fs:[0]
        pop     eax
        sWin32	hRemov,hvectorhandler1
        sWin32	hRemov,hvectorhandler2
	invoke ExitProcess,0

        ;=======================
        Assume  esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT

vEcp1   proc    USES esi edi ebx pExcetionPointers:DWORD
        mov     eax,pExcetionPointers
        mov     esi,[eax]               ;pEXCEPTION_RECORD
        mov     edi,[eax+4]             ;pCONTEXT

        ;call    dP
        xor     eax,eax
        test    [esi].ExceptionFlags,4+2+1    ;Unwind or serious
        JNE     @NO_HANDLE
        cmp     [esi].ExceptionCode,80000004h ;Single step
        JNE     @NO_HANDLE
        m2m     [edi].regEip,offset @1
        dec     eax             ;mov     eax,EXCEPTION_CONTINUE_EXECUTION

@NO_HANDLE:                     ;mov     eax,EXCEPTION_CONTINUE_SEARCH
        ret
vEcp1   Endp

        ;-----------------------------------------
vEcp2   proc    USES esi edi ebx pExcetionPointers:DWORD
        mov     eax,pExcetionPointers
        mov     esi,[eax]               ;pEXCEPTION_RECORD
        mov     edi,[eax+4]

        ;call    dP
        xor     eax,eax
        test    [esi].ExceptionFlags,4+2+1    ;Unwind or serious
        JNE     @NO_HANDLE
        cmp     [esi].ExceptionCode,80000003h ;STATUS_BREAKPOINT
        JNE     @NO_HANDLE

        m2m     [edi].regEip,offset @3
        dec     eax              ;mov     eax,EXCEPTION_CONTINUE_EXECUTION

@NO_HANDLE:                      ;mov     eax,EXCEPTION_CONTINUE_SEARCH
        ret
vEcp2   Endp

        ;-----------------------------------------

sEh1    proc    USES esi edi ebx pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
        mov     esi,pExcept
        mov     edi,pContext

        ;call    dP

        xor     eax,eax
        inc     eax
        test    [esi].ExceptionFlags,6+1         ;Unwind & Serious
        jne     @F
        cmp     [esi].ExceptionCode,0C0000005h  ;STATUS_ACCESS_VIOLATION
        jne     @F

        m2m     [edi].regEip,offset @2
        dec     eax
 @@:
        ret
sEh1    endp

       ;Release assume
       Assume  esi:Nothing,edi:Nothing
;-----------------------------------------

        ;FOR    debug purpose,Rubbish,....you can del it!
.data
fmt     db "The Cur EIP IS: %08X   Cur Excpt NUM is: %08X",0dh,0ah
        db "The Ecpt FLAGS VALUE in HEX: %X",0dh,0ah
        db "Common REG DUMP:",0dh,0ah
        db "EAX: %08X       EBX: %08X",0dh,0ah
        db "ECX: %08X       EDX: %08X",0dh,0ah
        db "ESI: %08X       EDI: %08X",0dh,0ah
.code
                ;DUMP   THREAD CONTEXTS Need esi:pt Excpt_Record
                ;edi: pt Context
dP      proc
local   buf[256]:byte
        pushad
        mov     eax,(EXCEPTION_RECORD ptr [esi]).ExceptionFlags
        INVOKE	wsprintf,addr buf,offset fmt,(CONTEXT PTR [edi]).regEip,(dword ptr [esi]),eax,/
                        (CONTEXT PTR [edi]).regEax,(CONTEXT PTR [edi]).regEbx,/
                        (CONTEXT PTR [edi]).regEcx,(CONTEXT PTR [edi]).regEdx,/
                        (CONTEXT PTR [edi]).regEsi,(CONTEXT PTR [edi]).regEdi
        INVOKE	MessageBox,0,addr buf,CTEXT("VEH Detector...debug purpose...Hume"),0
        popad
        ret
dP      endp

END	__Start


;==============================================================
    下面附例子用到的几个宏:
    CTEXT,相信诸位见过多次了,不多说.
    sWin32:相当于push syntax call label
    rd:    数据定义DWORD
    m2m:   相当于push syn1 pop syn2
    JEAXZ  :eax=0,jmp des
    $incoke():inline coding

    详细请下载在我主页上的最新头文件
    revargs     MACRO args:VARARG
        LOCAL   target
        target     TEXTEQU <>
	IFNB
		FOR     arg,
			IFNB
			target     CATSTR ,,target
			ENDIF
		ENDM
		target     SUBSTR target,1,@SizeStr(%target)-1
	ENDIF
	EXITM   target
        ENDM

        sWin32	Macro	label:REQ,args:VARARG		;Which allow no protos discalaiming
        %	FOR	pxx,		;But you need to guarantee the
                   IFNB 				;the syntax yourself
                     push	pxx
                   ENDIF
                ENDM
                call	label
        ENDM

        m2m MACRO M1, M2                          ;mov is too boring!
              push M2
              pop  M1
        ENDM

        $invoke Macro fun:REQ,args:VARARG
        IFNB
           invoke	fun,&args
        ELSE
	   invoke	fun
        ENDIF
        EXITM
        ENDM

        rd	Macro label:REQ,count
	        IFNB
	                label dd &count dup(?)
	        ELSE
	                label	dd ?
	        ENDIF
        EndM

        JEAXZ	MACRO	Destination			;Like JECXZ,for Convinient
                test	eax,eax
                je	Destination
        ENDM


                                                The way OF Hume,2002.7
                                                humewen@21cn.com
                                                humeasm.yeah.net
Windows 异常处理 windows 上的异常处理 阅读详情

相关推荐

Windows XP中的新型向量异常处理

 到现在为止我已在Win32®平台上工作八年有余,在这期间里我积累了一些我所喜欢使用的Win32功能(从API层面上来说)。它们可以让我的编程生活更轻松,同时也让我更容易写出比较有用的工具。当我安装完Windows XPBeta(以前代号为“Whistler”)时,并没有指望能够看到许多新的API,结果却惊喜地发现我错了!在本月的专栏中,我就要讲述这些新增功能其中之一——向量

8629

VEN异常处理的HOOK方式winds平台(1)

*作者 **| 榴莲**编辑 **| RacelWindows操作系统中存在多种异常处理,我们现在需要的是其中的VEH(VectoredExceptionHandler)异常处理,也就是向量异常处理。我们之所以可以使用VEH异常来进行HOOK的主要原因,在于两点。其一,VEH异常处理的优先级是高于SEH异常处理的,也就是说可以先手拿到异常,确保不会被其他异常处理流程将异常截获而导致HOOK失败。

wangluoanquan111的博客 483

VEH+硬件断点实现无痕HOOK

文章目录hook的分类硬件断点hook原理设置硬件断点注册VEH代码实现VEH无痕Hook说说一路踩过的坑实际效果小结关于veh hook的对抗参考文章参考文章 hook的分类 hook方式有多种,这里做了一个系统性的总结对比,如下: 实际上第二种和第三种属于同一类型的hook,都是利用异常处理函数来处理,只是触发异常的方式不同 硬件断点hook原理 想要实现硬件断点hook,需要实现下面几个步骤 设置硬件断点 注册veh异常处理函数 编写异常处理函数,实现自己的hook代码 设置硬件断点 首先来说一

鬼手的博客 1万+

逆向与破解-windows异常处理机制

以前看到过的很棒的一个讲解SEH的,非常的详细和简单易懂,不需要特别纠结具体的结构和处理的方法,初期对过程有一定的掌握就可以。以下为原文 深入解析结构化异常处理(SEH) - by Matt Pietrek 尽管以前写过一篇SEH相关的文章《关于SEH的简单总结》, 但那真的只是皮毛,一直对Windows异常处理的原理似懂非懂, 看了下面的文章 ,一切都豁然开朗.1997年文章,Window...

iamsongyu的博客 2920

Windows XP中的向量异常处理

作者:Matt Pietrek译者:SmartTech本文是Matt Pietrek在2001年9月的MSDN杂志上发表的关于Windows XP中新增的向量异常处理(Vectored Exception Handling)方面的文章。作者深入剖析了向量异常处理机制以及它的用途,并给出一个非常实用的样例程序。译者将其内容更新至当前最流行的Windows XP SP2。希望它能对大家有所帮助。译

Hackett的专栏 924

windows XP下的向量异常处理

http://www.pediy.com/bbshtml/BBS5/pediy50017.htm windows XP下的向量异常处理(Vectored Exception Handling)                                   原作:    Matt Pietrek                                   翻译改写:  h

理性的幻想 888

windows XP下的向量异常处理(Vectored Exception Handling)

<br />原作:     Matt Pietrek<br />                                翻译改写: by Hume/CVC.GB<br />首先回顾一下(SEH)结构化异常处理,结构化异常处理EXCEPTION_RETGISTRATION结构链起来的异常处理系统,那么当异常发生时,系统会遍历这个链,首先是链最前面的,系统会问:这个异常你处理吗?如果回答YES(通过返回EXCEPTION_CONTINUE_EXECUTION)的话,那系统就把控制权交给他,然后由其

Matrix_Designer的专栏 1504

Windows 异常

这篇文章可以为你揭露在 Windows 异常,以及如何捕获这些异常的神秘面纱。

Henzox的专栏 1743

java pattern堆栈溢出_windows堆栈溢出利用的七种方式

文本由 www.169it.com 搜集整理windows下的堆栈溢出攻击和unix下的,原理基本相同。但是,由于windows用户进程地址空间分配和堆栈处理有其独立的特点,导致了windows环境下堆栈溢出攻击时,使用的堆栈溢出字符串,与unix下的,区别很大。另外,windows的版本也导致了windows下的exploit不具有通用性。windows版本不同,而exploit使用了很多动态链...

weixin_42160645的博客 356

WINDOWS+PE权威指南读书笔记(16)

加载配置信息 何谓加载配置信息: Windows 结构化异常处理: 什么是SEH: Windows 异常分类: 内核模式下的异常处理: 用户模式下的异常处理Windows SEH 机制解析: SEH 编程实例: PE 中的加载配置信息: 加载配置信息定位: 加载配置目录 IMAGE_LOAD_CONFIG_DIRECTORY: 加载配置信息实例分析: 加载配置编程: 程序源代码分析: 为 PE 添加加载配置信息: 运行测试: 注册多个异常处理函数示例: 小

沐一 · 林 的博客 1682

VEH和VCH科普

本文转自梦织未来(www.mengwuji.net) 地址:http://www.mengwuji.net/forum.php?mod=viewthread&tid=1371 作者:mengwuji 很久没发帖子了,痛苦的失眠,就顺便来讲讲VEH这玩意儿。 一般,再好的程序员,也不能说自己写出的代码是没bug的、执行后不会产生异常。所以呢,好的程序员总会在可能认为会出现异常问题的那段代码加

mqzzqian的专栏 5294

通过SEH 非inline hook

SEH(Struct Exception Handler,结构化异常) VEH(Vector Exception Handler,向量异常处理) SEH是OS提供给线程来感知和处理异常的一种回调机制。 在Intel Win32平台上,由于FS寄存器问题指向当前的TIB(线程信息块),因此FS:[0]处能找到最新的一个EXCEPTION_REGISTRATION_RECORD结构。 typed

零点起步 1750

Windows PE权威指南》学习之第10章 加载配置信息

加载配置信息最初只用在Windows NT操作系统中,作为文件头部的延伸部分,后来被用做异常处理。加载配置信息表中存放了基于结构化异常处理(Structured Exception Handling, SEH)技术的各种异常句柄。当程序运行发生异常后,操作系统会根据异常类别对异常进行分发处理,并依据这些句柄实施程序流程的转向,保证系统能从异常中全身而退。本章将详细介绍Windows操作系统结构化异常处理机制,以及PE中与之对应的相关数据结构。

chenyijun的专栏 714

windows堆溢出利用方式总结

标 题: 【原创】windows堆溢出利用方式总结 作 者: riusksk 时 间: 2010-11-27,20:38:25 链 接: http://bbs.pediy.com/showthread.php?t=125591 Title:windows堆溢出利用方式总结 Author:riusksk(泉哥) Blog:http://riusksk.bl...

weixin_33851177的博客 305

windows堆栈溢出利用的七种方式

文本由 www.169it.com 收集 windows下的堆栈溢出攻击和unix下的,原理基本相同。但是,由于windows用户进程地址空间分配和堆栈处理有其独立的特点,导致了windows 环境下堆栈溢出攻击时,使用的堆栈溢出字符串,与unix下的,区别很大。另外,windows的版本也导致了windows下的exploit不具有通用性。windows版本不同,而exploit使用了很多

u011809276的专栏 1456

OllyDbg下载及安装:适配老系统的完整示例

手把手带你完成OllyDbg下载及安装,专为Windows XP等老系统优化配置,解决兼容性报错、插件加载失败等典型问题。全程基于真实环境演示,覆盖注册表调整、依赖库补全等关键步骤,确保调试器稳定运行。

weixin_36304957的博客 278
上一篇: ASM编程环境的构建和MASM32宏
下一篇: 用汇编写系统服务程序
xyblack
博客等级 码龄19年 18粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值