首先得感谢XFish的Virus系列教程,让我学到了很多东西。
感谢翻译组riusksk组织的exploit翻译教程。让我领略了Exploit的美妙。
有翻译组提供的exploit教程,在Tutorials Part 8 :Win32 Egg Hunting中看到了一段代码,觉得十分美妙,令我浮想联翩。代码如下:
这段代码在我此种菜鸟看来非常美妙,原因如下:
一、重定位技术
这个是基础知识,经常用在PE病毒的感染上。为了获得某条指令运行时的绝对地址,
采用方式如下:
call GetBase
BaseAddr:
........................ ;一堆变量或者函数定义
GetBase:
pop eax ; eax存储了BaseAddr的绝对地址
在call某个函数时,会将下一条指令地址压栈。这里是将BaseAddr标签运行时的绝对地址压入栈中。调用GetBase后,该地址被放入了eax中。
在上面的代码中,一开始Jmp short 0x23,在0x23处call 0x2。
也就是将0x28处指令运行时的绝对地址压入了栈中。同时在0x2处,执行pop ecx,将0x28处运行时的绝对地址放到了ecx中。
二、SEH
在此段代码中,为了在整个地址空间进行搜索同时保证程序能稳定运行,采用了SEH。如果你搜索的地址还没有分配,就会触发一个异常。没有SEH保护的话,被搜索的进程就死掉了。我想先介绍下SEH(主要是针对跟我一样的菜鸟)以及SEH的几个应用,最后再介绍下上面这段代码的原理。
1. SEH原型说明
注意,这里我不涉及编译器提供的异常处理技术。所以,如果你用__try{}__except(){}和__try{}__finally{}写了一段代码,然后反汇编后让我看,让我说明是怎么做的,怎样进行扩展unwind和tryblock trylevel是怎样对应到每个函数的,我很抱歉。
对Asm Fan来说,SEH简化成了这样一段代码:
seh:
mov eax,seh_handler
push eax
push fs:[0]
mov fs:[0],esp
..........
......... ;中间处理
end_seh:
pop fs:[0]
add esp,4
这里面涉及到几个结构体和一个函数原型。这两个东西弄清楚了,对我们下面的SEH应用会有很大帮助。
结构体:
EXCEPTION_REGISTRATION struc
prev dd ? //前一个EXCEPTION_REGISTRATION的地址
handler dd ? //异常处理函数
EXCEPTION_REGISTRATION ends
这里可以看到,EXCEPTION_REGISTRAION是一个链的形式,就是传说中的SEH链了。这个链结尾的标志是prev=0xFFFFFFFF,也就是-1。链的起始处,也就是当前函数的异常处理结构EXCEPTION_REGISTRATION由fs:[0]指向。
这就意味着,你如果要给当前的函数添加你自己定义的异常处理函数,只要在堆栈上新建一个这样的结构体,接入链中,并由fs:[0]指向就好了。
异常发生时处理顺序如下:
如果该进程正在被调试,系统将处理异常的机会交给了调试器(正好可以探测调试器的存在)
如果调试器不能处理该异常或者进程没有被调试,系统则调用你安装的异常处理函数。
你安装的异常处理函数如果不处理该异常,系统会从你安装的_EXCEPTION_REGISTRATION处向上遍历,直到找到处理该异常的函数
如果没有,则调用系统自带的处理函数,弹出一个很难看的框
下面来看看异常处理函数原型。
EXCEPTION_DISPOSITION (*handler)
(PEXCEPTION_RECORD,
PEXCEPTION_REGISTRATION,
PCONTEXT,
PEXCETION_RECORD) (参见A Crash Course on the depths of Win32 SEH)
这里需要注意,异常处理函数被调用时,栈上esp+0为要返回的eip,esp+4为第一个参数EXCEPTION_RECORD的地址,esp+8为第二个参数EXCETPION_REGISTRATION的地址,esp+0x0c为CONTEXT的地址。CONTEXT结构体中含有异常发生时各个寄存器的值。系统会使用CONTEXT结构体中的值从异常发生处恢复执行。
异常处理函数执行时的堆栈状况要牢牢记住。下面的SEH exploit和使用SEH对抗硬件断点都要用到。
常见的SEH handler的代码如下:
Seh_handler:
mov eax,[esp+0xc] ;获得CONTEXT地址
............... ;一些中间操作 通常是操作CONTEXT中的各个寄存器
mov cl,0xb8
add dword [eax+ecx],xxx ; [eax+ecx]是CONTEXT.EIP,这里修改eip的值
xor eax,eax
ret
- 标 题:SEH之浮想联翩
- 作 者:AntBean
- 时 间:2010-11-12 15:31:55
- 链 接:http://bbs.pediy.com/showthread.php?t=124656