SEH IN ASM 研究(二)
2007-01-14 20:14:51 来源:WEB开发网核心提示: 最后一点要注意在嵌套异常处理程序的时候要注意保存寄存器,否则你经常会得到系统异常代码为C00000027h 的异常调用,然后就是被终结.一下给出一点垃圾代码演示可能有助于理解,注意link的时候要加入 /section:.text,RWE 否则例子里面的代码段不能写,SMC功能会产生异常以
最后一点要注意在嵌套异常处理程序的时候要注意保存寄存器,否则你经常会得到系统异常代码为C00000027h 的异常调用,然后就是被终结.
一下给出一点垃圾代码演示可能有助于理解,注意link的时候要加入 /section:.text,RWE 否则例子里面的代码段不能写,SMC功能会产生异常以致整个程序不能进行.
注意:2K/XP下非法指令异常的代码不一致,另外用下面的方法SMC代码段也不可以!不知如何解决?
只用于9X,为了在2k/Xp下也能运行我加了点代码,有兴趣看看,另外帮我解决一下2K/Xp下SMC的问题?thx!
下面例子很烂,不过MASM格式写起来容易一点,也便于理解.
;-----------------------------------------
;Ex4,演示堆栈展开和异常嵌套处理 by Hume,2002
;humewen@21cn.com
;hume.longcity.net
;-----------------------------------------
.586
.model flat, stdcall
option casemap :none ; case sensitive
include hd.h
include mac.h
;;--------------
per_xHandler1 proto C :DWORD,:DWORD,:DWORD,:DWORD
per_xHandler2 proto C :DWORD,:DWORD,:DWORD,:DWORD
per_xHandler3 proto C :DWORD,:DWORD,:DWORD,:DWORD
;-----------------------------------------
.data
sztit db "except Mess,by hume[AfO]",0
count dd 0,0
Expt1_frm dd 0 ;ERR结构指针,用于堆栈展开手动代码
Expt2_frm dd 0
Expt3_frm dd 0
;;-----------------------------------------
.CODE
_Start:
assume fs:nothing
push offset per_xHandler3
push fs:[0]
mov fs:[0],esp
mov Expt3_frm,esp
push offset per_xHandler2
push fs:[0]
mov fs:[0],esp
mov Expt2_frm,esp
push offset per_xHandler1
push fs:[0]
mov fs:[0],esp
mov Expt1_frm,esp
;--------------------------
;install xhnadler
;-----------------------------------------
xor ebx,ebx
mov eax,200
cdq
div ebx ;除法错误
invoke MessageBox,0,ddd("Good,divide overflow was solved!"),addr sztit,40h
sub eax,eax
mov [eax],ebx ;内存写错误
succ:
invoke MessageBox,0,ddd("Good,memory write violation solved!"),addr sztit,40h
db 0F0h,0Fh,0C7h,0C8h ;什么cmpchg8b指令的非法形式?我从来没有成功过!!
;演示程序中使用seh实现SMC技术,加密??...
invoke MessageBox,0,ddd("illeagal instruction was solved!"),addr sztit,20h
;--------------------------
;uninstall xhnadler
;-----------------------------------------
pop fs:[0]
add esp,4
pop fs:[0]
add esp,4
;或者add esp,10h
pop fs:[0]
add esp,4
invoke ExitProcess,0
;-----------------------------------------
;异常处理句柄1,处理除法异常错误
per_xHandler1 PROC C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
pushad
MOV ESI,pExcept
ASSUME ESI:PTR EXCEPTION_RECORD
TEST [ESI].ExceptionFlags,1
JNZ @cantdo1
TEST [ESI].ExceptionFlags,6
JNZ @unwind1
CMP [ESI].ExceptionCode,0C0000094h
JNZ @cantdo1
MOV EDI,pContext
ASSUME EDI:PTR CONTEXT
m2m [edi].regEbx,20 ;将ebx置20,修复除法错误,继续执行
popad
MOV EAX, ExceptionContinueExecution
RET
@unwind1:
invoke MessageBox,0,CTEXT("state: unwinding in xhandler1..."),addr sztit,0
@cantdo1:
popad
MOV EAX,ExceptionContinueSearch
RET
per_xHandler1 ENDP
;-----------------------------------------
;异常处理句柄2,处理内存写错误,扩展可以有其他的例子如自动扩充堆栈
per_xHandler2 PROC C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
pushad
MOV ESI,pExcept
ASSUME ESI:PTR EXCEPTION_RECORD
MOV EDI,pContext
ASSUME EDI:PTR CONTEXT
call Dispcont ;显示一点lame的消息,自己调试用
TEST [ESI].ExceptionFlags,1
JNZ @cantdo2
TEST [ESI].ExceptionFlags,6
JNZ @unwind2
CMP [ESI].ExceptionCode,0C0000005h
JNZ @cantdo2
.data ;ASM的数据定义灵活性,如果需要这是可以的
validAddress dd 0
.code
m2m [EDI].regEax,<offset validAddress> ;置eax为有效地址
popad
MOV EAX, ExceptionContinueExecution
RET
@unwind2:
invoke MessageBox,0,CTEXT("hmmm... unwinding in xhandler2..."),addr sztit,40h
@cantdo2:
popad
MOV EAX,ExceptionContinueSearch
RET
per_xHandler2 ENDP
;-----------------------------------------
per_xHandler3 PROC C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
pushad
MOV ESI,pExcept
ASSUME ESI:PTR EXCEPTION_RECORD
MOV EDI,pContext
ASSUME EDI:PTR CONTEXT
TEST [ESI].ExceptionFlags,1
JNZ @cantdo3
TEST [ESI].ExceptionFlags,6
JNZ @unwind3
;-----------------------------------------
push ecx
mov ecx,cs
xor cl,cl
jecxz win2k_Xp
win9X:
pop ecx
CMP [ESI].ExceptionCode,0C000001DH ;非法指令异常,与2K/XP下的不一致
JNZ @cantdo3
jmp ok_here
win2k_Xp:
pop ecx ;注意,只有在9X下才可以
CMP [ESI].ExceptionCode,0C000001EH ;非法指令异常->2K/XP
JNZ @cantdo3 ;sMc不成
mov [edi].regEip,offset safereturn
popad
mov eax,0
ret
push ebx
push esi
push edi
comment $ 调用RtlUnwind展开堆栈
lea ebx,unwindback
invoke RtlUnwind,Expt3_frm,ebx,esi,0
$
mov dword ptr [esi+4],2 ;置展开标志,准备展开,这里是
;手动代码
mov ebx,fs:[0]
selfun:
;mov eax,Expt2_frm ;这里显示了ASM手动展开的灵活性
mov eax,Expt3_frm
cmp ebx,eax ;按照Jeremy Gordon的好像不大对头
;cmp dword ptr [ebx],-1 ;这样好像有问题,只好如上,请教答案
jz unwindback
push ebx
push esi ; 压入Err和Exeption_registration结构
call dword ptr[ebx+4]
add esp,8
mov ebx,[ebx]
jmp selfun
unwindback:
invoke MessageBox,0,CTEXT("I am Back!"),addr sztit,40h
pop edi
pop esi
pop ebx ;一定要保存这三个寄存器!
MOV EAX,[EDI].regEip
MOV DWORD PTR[EAX],90909090H ;改为nop指令...SMC呵呵这次不神秘了吧
;SMC注意连接选项
popad
MOV EAX, ExceptionContinueExecution
RET
@unwind3:
invoke MessageBox,0,CTEXT("Note... unwinding in xhandler3..."),addr sztit,40h
@cantdo3:
popad
MOV EAX,ExceptionContinueSearch
RET
per_xHandler3 ENDP
;-----------------------------------------
;lame routine for debug
Dispcont proc
inc count
call dispMsg
ret
Dispcont endp
dispMsg proc
local szbuf[200]:byte
pushad
mov eax,dword ptr[esi]
mov ebx,dword ptr[esi+4]
mov ecx,dword ptr[edi+0b8h]
mov edx,dword ptr[edi+0a4h]
.data
fmt db "Context eip--> %8X ebx--> %8X ",0dh,0ah
db "Flags Ex.c-> %8x flg--> %8X",0dh,0ah
db "it's the %d times xhandler was called!",0
.code
invoke wsprintf,addr szbuf,addr fmt,ecx,edx,eax,ebx,count
invoke MessageBox,0,addr szbuf,CTEXT("related Mess of context"),0
popad
ret
dispMsg endp
;;------------------------------------------------
END _Start
;---------------------------------下面是上面用到的宏,我的mac.h比较长,就不贴了-----
ddd MACRO Text ;define data in .data section
local name ;This and other can be used as: ddd("My god!")
.data ;isn't cool?
name db Text,0
.code
EXITM <addr name>
ENDM
CTEXT MACRO y:VARARG ;This is a good macro
LOCAL sym
CONST segment
IFIDNI <y>,<>
sym db 0
ELSE
sym db y,0
ENDIF
CONST ends
EXITM <OFFSET sym>
ENDM
m2m MACRO M1, M2 ;mov is too boring sometimes!
push M2
pop M1
ENDM
;-----------------------------------------
最后更正一点前面介绍的传送给final型的参数是指向EXCEPTION_POINTERS 的指针,压栈前的堆栈是如下的,不好意思,原来写的时候我也没深入研究,可能模糊了一点,如有错误,请大家指正
- ››include指令与<jsp:include>动作的区别
- ››Intent和IntentFilter详解
- ››Interface继承至System.Object?
- ››input按钮在IE浏览器的兼容
- ››Intent调用大全
- ››IntentService实现原理及内部代码
- ››Internet Explorer 无法打开
- ››Intel和Nokia宣称MeeGo将比Android更加开放且方便...
- ››innerText、outerText、innerHTML、outerHTML的区...
- ››Intent Android 详解
- ››InfoSphere Guardium:IBM 新的数据库安全和监视软...
- ››Incorrect string value错误的解决方法
更多精彩
赞助商链接