- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
定义:
Seh异常就是数结构化异常处理,Win32 结构化异常处理是操作系统提供的一种服务。
在编译器的 SEH 层减少了直接使用纯操作系统的 SEH 所带来的危害的同时,也将纯
操作系统的 SEH 从大家的面前隐藏了起来。
但程序遇到Seh异常时,异常交给系统处理(这将是一个非常负责的过程,很容易跟飞),所以利用Seh异常可以一定程度的防止程序被调试。(seh异常在壳里是很常见的)
原理:
异常的基本过程(个人理解是这样):
我们来看两个实例
实例文件下载
push 00401051 //地址00401051压入堆栈
push dword ptr fs:[0] //fs[0]压入堆栈,执行完成后,fs[0]指向栈顶
mov dword ptr fs:[0],esp //构造1个err结构
mov esi,0 //简单的赋值语句
mov eax,dword ptr ds:[esi] //产生异常
(OD中异常后,按shift+F8继续运行)
------系统处理(非常复杂,可以自己跟跟看)-----------
若要跟踪,先在A地址下断点
执行后,windows检查到异常,执行线程马上被中段,从用户模式转到内核模式
控制权交到操作系统的异常调试程序(exception dispatcher),由它负责找到
处理这个异常的方法,即所有应用程序的异常最终都是由windwos来处理的,
同一个版本的windows有固定的异常处理代码.
------跳到地址A--------------------------------------
lea eax,dword ptr ss:[esp-8] //开辟8字节的空间,并把栈顶指针保存到eax
xchg dword ptr fs:[0],eax //执行完成后,fs[0]指向栈顶,eax等于原fs[0]
mov ebx,0040102B //地址ebx=0040102B
push ebx //ebx压入堆栈,即地址0040102b
push eax //fs[0]压入堆栈
mov esi,0 //简单的赋值语句
mov eax,dword ptr ds:[esi] //读取线性地址0,产生异常
(OD中异常后,按shift+F8继续运行)
------系统处理(非常复杂,可以自己跟跟看)-----------
若要跟踪,先在A地址下断点
执行后,windows检查到异常,执行线程马上被中段,从用户模式转到内核模式
控制权交到操作系统的异常调试程序(exception dispatcher),由它负责找到
处理这个异常的方法,即所有应用程序的异常最终都是由windwos来处理的,
同一个版本的windows有固定的异常处理代码.
------跳到地址A--------------------------------------
利用:
看了以上这些,我们知道,通过这一下段Seh异常代码,我们可以防止
他人跟踪,并跳到地址A(这点最重要)继续执行。我们可以把它当作jmp来使用,
具体的应用就看你们自己自由发挥了。
其他几个Seh异常代码(异常后跳到地址:********)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push ********
mov eax,dword ptr fs:[0]
push eax
mov dword ptr fs:[0],esp
mov esi,0
mov eax,dword ptr ds:[esi]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push ********
mov eax,dword ptr fs:[0]
push eax
mov dword ptr fs:[0],esp
mov ebx,0
div ebx
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nop
push ********
mov eax,dword ptr fs:[0]
push eax
mov dword ptr fs:[0],esp
int 3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push ********
mov eax,dword ptr fs:[0]
push eax
mov dword ptr fs:[0],esp
nop
int 68
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push ********
mov eax,dword ptr fs:[0]
push eax
mov dword ptr fs:[0],esp
nop
vxdcall 134543
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push ********
mov eax,dword ptr fs:[0]
push eax
mov dword ptr fs:[0],esp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push xxx
push dword ptr fs:[0]
mov fs:[0], esp
stc
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push xxx
push dword ptr fs:[0]
mov fs:[0], esp
JMP 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push xxx
push dword ptr fs:[0]
mov fs:[0], esp
ret
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
push xxx
push dword ptr fs:[0]
mov fs:[0], esp
pop ss
SEH异常在汇编中实现,据我的理解是这样的
push ******** //将需要返回的地址压入堆栈
mov eax,dword ptr fs:[0] //fs:[0]是指向堆栈里面的SEH 那么这句的意思就是将堆栈SEH地址传送到寄存器EAX.
push eax //fs[0]压入堆栈,
其实上面两句的意思就是push dword ptr fs:[0]
mov dword ptr fs:[0],esp //构造一个ERR结构,这句完成后,堆栈里面最上方就有一个SEH记录了
上面的就是SEH结构,下面的就是让程序产生异常.
产生异常最白的理解方法就是让程序出错,不是跳到其他垃圾地方,而是让语句出错 |
|