seh(3)
明天去郊外去春游,心里很兴奋哦。
上次贴了一段代码,里面的回调函数有一长串参数,现在解释一下:
_Handler proc _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext
_lpExceptionRecord指向EXCEPTION_RECORD结构。
_lpContext指向一个Context结构。这个结构保存了异常发生的时候所有寄存器的值。这个结构比较常用的字段有regEip。他用来得知异常发生的位置。如果要修正某个寄存器中的错误取值修改这个字段就可以了。
_lpSEH指向注册回调函数时使用到的EXCEPTION_REGISTRATION结构的地址。如果希望异常处理程序能被封装在子程序里面的话,这个参数必不可少,如果不需要,就没用。
谈谈展开操作。
什么叫展开?
展开就是Unwinding。假设出现异常,seh链上有多个回调函数,但是没有一个函数能够处理的话,系统会把每一个回调函数调用一次,这个时候参数中指定的异常代码就是EXCEPTION_UNWIND。
好了,我们现在要应用了,SEH可以干什么?这其实是最先应该想到的,我们不可能什么都学,要有所选择。所以这应该是我们看这篇文章的第一个问题。
除了可以使我们的程序更加健壮,还可以做一些坏事,例如进入RING0,反跟踪,获得Kernel32的地址等等,这就是我学习seh的目的。我也是最近几天学seh的,在学习过程中我也有很多没明白的地方,希望和大家讨论一下
现在我们来预热一下:
CIH将handler指向它自己程序中。在它入口处有如下代码:
MyVirusStart:
; Ring3代码入口点
push ebp
; *************************************
; * Let's Modify Structured Exception *
; * Handing, Prevent Exception Error *
; * Occurrence, Especially in NT. *
; *************************************
lea eax, [esp-04h*2]
;在栈中分配8字节存放_EXCEPTION_REGISTRATION结构,相当于C中基于栈的数据,即局部变量(C编译器中完成)这样EAX即指向_EXCEPTION_REGISTRATION的指针,但此时_EXCEPTION_REGISTRATION结构未初始化;具体实现机制可翻阅编译原理书籍和Matt Pietrek大师文章
xor ebx, ebx
xchg eax, fs:[ebx] ;FS:[0]<->EAX
;此时EAX存放的是原来异常处理代码,FS:[0]指向TEB中ExceptionList(FS指向TEB,ExceptionList偏移为0,即FS:[0])
call @0
@0:
pop ebx
;此三行计算代码入口,此时ebx就是@0的地址,如果不明白请参看有关病毒的教程
lea ecx, StopToRunVirusCode-@0[ebx]
;将ecx指向自己内部代码处
push ecx
;填充_EXCEPTION_REGISTRATION结构的handler
;在发生异常时,操作系统会自动调用,此时为CIH代码
push eax
;EAX为原来异常处理代码
;填充_EXCEPTION_REGISTRATION结构的prev
.
.
.
这其后CIH调用int 3使系统发生异常,仍能进入自已的代码,
int 3 ;
int3在破解中就是breakpoint,呵呵,学了一些时候的破解总算能用一下了。
呵呵,怎么样,是不是觉得也不是很难呢?
在这里,不知道你们有没有一个问题,这个问题从我开始学习cih代码到现在都一直存在,那就是,为什么可以用seh来现进入ring0,seh为实什么可以突破封锁进入ring0呢?我心里模模糊糊有点概念,但是写出来却写不清楚,大家如果谁知道,还请指教哦。
好了,下次我们就要开始令人激动的旅程了。