SEH是window操作系统默认的异常处理机制,逆向分析中,SEH除了基本的异常处理功能外,还大量用于反调试程序(这里SEH时保存在栈中的,漏洞利用的时候会用到)

1.SEH

SEH是windows操作系统异常处理机制,在程序源代码中使用__try,__except,__finally关键字来具体实现。

2.OS异常处理的办法

2.1正常运行时候的异常处理方法

进程运行过程中若发生异常,OS会委托进程进行处理。若进程代码中存在具体的异常处理(如SEH异常处理器)代码,则能够顺利处理相关异常,程序继续运行,但如果进程内部没有具体实现SEH,那么相关异常就无法处理,OS就会启动默认的异常处理机制,终止进程运行

2.2 调试运行时的异常处理方法

被调试的进程内部发生异常,OS会首先把异常抛给调试进程处理。调器拥有被调试者的所有权限。被调试者内部发生的异常都由调试器处理。调试过程中的所有异常都先由调试器管理。被调试者发生异常时,调试器会停止运行,必须采取相应的措施来处理异常,完成后续的调试。遇到异常的时候的处理方法如下。

1)直接修改异常:代码、寄存器、内存

2)将异常泡杯被调试程序,使用od的shift+f7/f8/f9直接将异常抛还给被调试者

3)OS默认异常处理机制

3.异常

操作系统中常见的异常

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

EXCEPTION_ACCESS_VIOLATION     0xC0000005     程序企图读写一个不可访问的地址时引发的异常。例如企图读取0地址处的内存。

EXCEPTION_ARRAY_BOUNDS_EXCEEDED    0xC000008C     数组访问越界时引发的异常。

EXCEPTION_BREAKPOINT                           0x80000003     触发断点时引发的异常。

EXCEPTION_DATATYPE_MISALIGNMENT    0x80000002     程序读取一个未经对齐的数据时引发的异常。

EXCEPTION_FLT_DENORMAL_OPERAND     0xC000008D     如果浮点数操作的操作数是非正常的,则引发该异常。所谓非正常,即它的值太小以至于不能用标准格式表示出来。

EXCEPTION_FLT_DIVIDE_BY_ZERO                   0xC000008E     浮点数除法的除数是0时引发该异常。

EXCEPTION_FLT_INEXACT_RESULT           0xC000008F     浮点数操作的结果不能精确表示成小数时引发该异常。

EXCEPTION_FLT_INVALID_OPERATION            0xC0000090     该异常表示不包括在这个表内的其它浮点数异常。

EXCEPTION_FLT_OVERFLOW                             0xC0000091     浮点数的指数超过所能表示的最大值时引发该异常。

EXCEPTION_FLT_STACK_CHECK                  0xC0000092     进行浮点数运算时栈发生溢出或下溢时引发该异常。

EXCEPTION_FLT_UNDERFLOW                    0xC0000093     浮点数的指数小于所能表示的最小值时引发该异常。

EXCEPTION_ILLEGAL_INSTRUCTION          0xC000001D     程序企图执行一个无效的指令时引发该异常。

EXCEPTION_IN_PAGE_ERROR                        0xC0000006     程序要访问的内存页不在物理内存中时引发的异常。

EXCEPTION_INT_DIVIDE_BY_ZERO                   0xC0000094     整数除法的除数是0时引发该异常。

EXCEPTION_INT_OVERFLOW                             0xC0000095     整数操作的结果溢出时引发该异常。

EXCEPTION_INVALID_DISPOSITION                  0xC0000026     异常处理器返回一个无效的处理的时引发该异常。

EXCEPTION_NONCONTINUABLE_EXCEPTION     0xC0000025     发生一个不可继续执行的异常时,如果程序继续执行,则会引发该异常。

EXCEPTION_PRIV_INSTRUCTION                     0xC0000096     程序企图执行一条当前CPU模式不允许的指令时引发该异常。

EXCEPTION_SINGLE_STEP                          0x80000004     标志寄存器的TF位为1时,每执行一条指令就会引发该异常。主要用于单步调试。

EXCEPTION_STACK_OVERFLOW                   0xC00000FD     栈溢出时引发该异常。

调试的时候经常触发5中最具代表性的异常

3.1  EXCEPTION_ACCESS_VIOLATION     0xC0000005

程序企图读写一个不可访问的地址时引发的异常(不存在,或者不具有访问权限)。例如企图读取0地址处的内存。

3.2EXCEPTION_BREAKPOINT  0x80000003

触发断点时引发的异常。在运行的代码中设置断点以后,cpu尝试执行该处的指令时将触发队形的EXCEPTION_BREAKPOINT异常

INT3,设置断点对应的汇编指令为INT3,对应的机器指令为0xCC.灵活运用这个原理可以为程序运行带来很大的便利。比如使用hex editor打开PE文件,修改EP地址对应的文件偏移处的第一个字节为0xCC,然后运行该PE文件就会发生EXCEPTION_BREAKPOINT异常,经过OS的默认异常处理后会终止程序运行,若在操作系统的注册表中将默认调试器设置为OllyDbg,那么发生以上异常时OS会自动运行ollydbg调试器,附加发生异常的进程。

3.3EXCEPTION_ILLEGAL_INSTRUCTION  0xC000001D

程序企图执行一个无效的指令时引发该异常。

3.4EXCEPTION_INT_DIVIDE_BY_ZERO   0xC0000094

整数除法的除数是0时引发该异常。

3.5EXCEPTION_SINGLE_STEP   0x80000004

标志寄存器的TF位为1时,每执行一条指令就会引发该异常。主要用于单步调试。

4.SEH详细说明

4.1SEH链

SEH以链的形式存在。第一个异常处理中未处理相关异常,它就会被传递到下一个异常处理器,直到得到处理。SEH是由_EXCEPTION_REGISTRATION_RECORD结构体组成的链表

1

2

3

4

ntdll!_EXCEPTION_REGISTRATION_RECORD

   +0x000 Next             : Ptr32 _EXCEPTION_REGISTRATION_RECORD

   +0x004 Handler          : Ptr32 _EXCEPTION_DISPOSITION 

}

Next成员指向下一个_EXCEPTION_REGISTRATION_RECORD结构体指针,handler成员是异常处理函数(异常处理器)。若Next成员的值为FFFFFFFF,则表示它是链表最后一个结点

发生异常的时候会按照(A)->(B)->(C)的顺序依次传递,直到由异常处理器处理

4.2异常处理函数定义

1

2

3

4

5

6

EXCEPTION_DISPOSITION __cdecl _except_handler (

  EXCEPTION_RECORD      *pRecord,

  EXCEPTION_REGISTRATION_RECORD *pFrame,

  CONTEXT        *pContext,

  PVOID          pValue

);

由系统调用,是一个回调函数,第一个参数是一个指向EXCEPTION_RECORD结构体的指针

1

2

3

4

5

6

7

8

typedef struct _EXCEPTION_RECORD {

    DWORD ExceptionCode;   //异常代码

    DWORD ExceptionFlags;

    struct _EXCEPTION_RECORD *ExceptionRecord;

    PVOID ExceptionAddress;   //异常发生地址

    DWORD NumberParameters;

    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];

} EXCEPTION_RECORD;

异常处理函数的第三个参数是指向CONTEXT结构体的指针,CONTEXT结构体的定义如下,   CONTEXT结构体用来备份CPU的值。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

typedef struct _CONTEXT {

    DWORD ContextFlags;

    DWORD   Dr0;

    DWORD   Dr1;

    DWORD   Dr2;

    DWORD   Dr3;

    DWORD   Dr6;

    DWORD   Dr7;

    FLOATING_SAVE_AREA FloatSave;

    DWORD   SegGs;

    DWORD   SegFs;

    DWORD   SegEs;

    DWORD   SegDs;

    DWORD   Edi;

    DWORD   Esi;

    DWORD   Ebx;

    DWORD   Edx;

    DWORD   Ecx;

    DWORD   Eax;

    DWORD   Ebp;

    DWORD   Eip;

    DWORD   SegCs;              // MUST BE SANITIZED

    DWORD   EFlags;             // MUST BE SANITIZED

    DWORD   Esp;

    DWORD   SegSs;

    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;

异常发生的时候,执行异常代码的线程就会发生中断,转而运行SEH,此时OS会把线程 CONTEXT结构体的指针传递给异常处理函数的相应参数。里面有个eip成员,在异常处理函数中将参数传递过来的CONTEXT.eip设置为其他地址,然后返回处理函数。这样之前暂停的线程会执行新的EIP地址处的代码(反调试中经常使用这个技术)

4.3  TEB.NtTib.ExceptionList

通过TEB结构体的NtTib成员可以很容易的访问进程的SEH链,TEB。

NtTib.ExceptionList=FS:[0]

4.4 SEH安装/删除方法

汇编中安装使用

1

2

3

push @MyHandler  ;异常处理程序

push FS:[0]       ;SEH Linked List头

mov dword ptr fs:[0],esp  ;添加链表

汇编中的删除SEH代码

1

2

POP DWORD PRT FS:[0] ;读取栈值并将其放入FS:[0],这里的栈值存放的下一个SEH的起始地址,执行该命令之后,就可以从栈中删除对应的SEH。

ADD ESP,4

od中有查看SEH链的功能

5  od中的SEH

程序在正常运行与调试运行的时候有不同的分支代码,借助SEH实现的反调试及时很多,这为代码的调试带来了很多不便,使调试更加困难。OD提供了很多调试选项,调试中发生异常的时候,调试器不会暂停,会自动将异常派送给被调试者。od中选择options-debugging options-.exception选项卡:灵活使用od的excettion选项,可以在不暂停调试器的前提下自动规避使用SEH的反调试“花招”,从而继续调试。

[原创]windows-SEH详解相关推荐

  1. Windows系统文件详解

    Windows系统文件详解 Windows系统自带了几百个文件,这些文件都是干什么用的?那些文件可以删除,而不影响系统的运行? A ACCESS.CHM Windows帮助文件 ACCSTAT.EXE ...

  2. WINDOWS系统服务详解

    1 WINDOWS系统服务详解    --  WINDOWS系统服务详解 <P>1 Alerter 当系统发生故障时向管理员发送错误警报,除非电脑处于局域网,而且配有网络管理员,一 般不需 ...

  3. 计算机服务设置详解,Windows 虚拟内存详解服务器教程 -电脑资料

    window|详解 简单来讲就是文件数据交叉链接的活动文件, 二.虚拟内存的作用内存在计算机中的作用很大,电脑中所有运行的程序都需要经过内存来执行,如果执行的程序很大或很多,就会导致内存消耗殆尽.为了 ...

  4. 《Win10 下安装Ubuntu 16.04双系统详解》与《 U盘安装windows系统详解》

    <Win10下安装Ubuntu16.04双系统 >与<U盘安装windows系统详解> 本文由博主经过查阅网上资料后亲自操作实验后记录编写,如存在不对之处请留言以便更正,内容仅 ...

  5. 这可能是最详细的 Windows Debug 详解 了

    Debug概览 Debug是什么? debug是Windows 16位或者32位机器上的一款调试工具.也就是说,在WindowsXP及以前的机器上都有debug,直接Win+X debug就可以调出: ...

  6. Windows进程详解!!(精)

    简述以下 以下以Windows XP系统为例介绍 1.最基本的系统进程 此类系统进程是系统运行的必备条件,只有这些进程处于活动状态,系统才能正常运行.因此,它们是不能被结束任务的. winlogon. ...

  7. windows.h 详解

    参考windows.h解构 刚开头的一段注释是对该头文件的描述: /*++ BUILD Version: 0001 Increment this if a change has global effe ...

  8. windows.h详解

    参考 http://blog.csdn.net/fengningning/article/details/2306650?locationNum=1&fps=1 windows.h解构 刚开头 ...

  9. Windows系统文件详解【大全】

    这是网络上转载的一篇文章,找不到原创的出处了-- 详细的介绍了WINDOWS系统文件的用途,我想各位保存一份以后说不定会有用吧,呵呵.. 这里按A到Z为大家分好类了,查询的话可以按键盘的Ctrl+F进 ...

  10. (原创)ics-openvpn编译详解

    一.Windows环境下编译(仅适用于ics-openvpn_v0.7.3及以上版本) 1.下载.配置AndroidStudio: 浏览器访问https://developer.android.goo ...

最新文章

  1. [BZOJ1602] [Usaco2008 Oct] 牧场行走 (LCA)
  2. 三国志幻想大陆服务器维护,三国志幻想大陆8月14日更新维护公告
  3. xml转json和实体类的两种方式
  4. 现在很多技术知识点缺乏来龙去脉的介绍
  5. Mybatis之Oracle增删查改示例--转
  6. cannot be found on object of type xx.CacheExpressionRootObject
  7. Linux系统网卡配置方法
  8. Oracle 以某字段分组,以某字段排序,取前几条
  9. domain gap(域间隙)是什么?==>在一个数据集上训练好的模型无法应用在另一个数据集上
  10. 内存管理(注意事项和重点)
  11. Vue项目部署遇到的问题及解决方案
  12. 如何通过PXE实现一键自动化安装操作系统
  13. C++类的静态成员变量
  14. Win10问题篇:解决电脑插入耳机没声音。
  15. Desktops 虚拟桌面软件(推荐)
  16. 海盗号推荐 | 十分钟读懂币圈必读书籍:《区块链十年》
  17. App Inventor 2制作天气预报
  18. 【原理图专题】OrCAD Capture CIS中元件产生A,B属性解决办法
  19. java公路车为什么会被喷,最全指南
  20. 谷歌浏览器Chrome错误代码:ERR_CONNECTION_ABORTED

热门文章

  1. RC滤波器和LC滤波器的区别
  2. Windows无法安装到GPT分区形式磁盘 - 解决方案
  3. CAN总线系统(一)---基础介绍
  4. Andorid 自定义标题栏
  5. HDU 4352 XHXJ's LIS(*数位DP 记忆化搜索 待整理)
  6. 如何在Python中进行描述性统计分析?
  7. 奶爸日记22 - 2021年元旦随记
  8. 商家后台-商品录入【基本信息】
  9. SU2 在linux操作系统上的安装过程
  10. 【Python代码进阶】