WEB开发网
开发学院网络安全黑客技术 SEH IN ASM 研究(二) 阅读

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 的指针,压栈前的堆栈是如下的,不好意思,原来写的时候我也没深入研究,可能模糊了一点,如有错误,请大家指正

上一页  1 2 3 4  下一页

Tags:SEH IN ASM

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接