您的位置:首页 > 其它

PE结构、SEH相关知识学习笔记

2015-02-03 10:49 441 查看
原文:http://www.pediy.com/kssd/index.html -- 病毒技术 -- 病毒知识 -- Anti Virus专题

PE结构的学习

原文中用fasm自己构造了一个pe,这里贴一个用masm的,其实是使用WriteFile API将编写的PE数据写成文件~也没啥好说的,PE结构在这里没有仔细介绍,需要可以另外查询,剩下要说的的基本都在代码注释里了

参考:点击打开链接(PEDIY技术之新思路(二)_用'高级'编译器MASM实现自定义PE文件结构)

Pe.asm:

.386
02.    .model flat, stdcall
03.    option casemap:none
04.
05.include windows.inc
06.include user32.inc
07.include kernel32.inc
08.includelib user32.lib
09.includelib kernel32.lib
10.
11.    .data
12.szCaption   db 'TestSEH', 0
13.szMsgOK     db "It's now in the Per_Thread handler!", 0
14.szMsgERR1   db 'It would never Get here!', 0
15.buff        db 200 dup(0)
16.
17.    .code
18.start:
19.    assume fs:nothing
20.    push offset perThread_Handler
21.    push fs:[0]
22.    mov fs:[0], esp
23.    xor ecx, ecx
24.    mov eax, 200
25.    cdq
26.    div ecx
27.    ; 以下不会运行
28.    invoke MessageBox, NULL, addr szMsgERR1, addr szCaption, \
29.        MB_OK or MB_ICONINFORMATION
30.    pop fs:[0]
31.    add esp, 4
32.    invoke ExitProcess, NULL
33.
34.perThread_Handler:
35.    invoke MessageBox, NULL, addr szMsgOK, addr szCaption, \
36.        MB_OK or MB_ICONINFORMATION
37.    mov eax, 1  ; ExceptionContinueSearch, 不处理,由其他例程或系统处理
38.    ;mov eax, 0 ; ExceptionContinueExecution, 表示修复CONTEXT, 可以从已成发生处继续执行
39.            ; 如果返回0,你会陷入死循环,不断跳出对话框
40.    ret
41.
42.    end start


View Code

当异常发生时,系统给了我们一个处理异常的机会,他首先会调用我们自定义的seh处理例程,当然也包括
了相关信息,在调用之前,系统把包含这些信息结构的指针压入stack,供我们的异常处理例程调用,
传递给例程的参数通常是四个,其中只有三个有明确意义,另一个到现在为止还没有发现有什么作用,
这些参数是:pExcept:DWORD,pErr:DWORD,pContext:DWORD,pDispatch意义如下:
pExcept:  ---  EXCEPTION_RECORD结构的指针
pErr:    ---  前面ERR结构的指针
pContext: --- CONTEXT结构的指针
pDispatch:---没有发现有啥意义

ERR结构是前面介绍的_EXCEPTION_REGISTRATION结构,往前翻翻,Dispatch省略,下面介绍
EXCEPTION_RECORD和CONTEXT结构的定义(Windows核心编程第五版P657, Windows环境下32位汇编程序设计第二版P508):

01.EXCEPTION_RECORD STRUCT
02.  ExceptionCode        DWORD      ?      ;//异常码
03.  ExceptionFlags        DWORD      ?      ;//异常标志
04.  pExceptionRecord      DWORD      ?      ;//指向另外一个EXCEPTION_RECORD的指针
05.  ExceptionAddress      DWORD      ?      ;//异常发生的地址
06.  NumberParameters      DWORD      ?      ;//下面ExceptionInformation所含有的dword数目
07.  ExceptionInformation  DWORD EXCEPTION_MAXIMUM_PARAMETERS dup(?)
08.EXCEPTION_RECORD ENDS                      ;//EXCEPTION_MAXIMUM_PARAMETERS ==1

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 读写冲突地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: