学习心得--------关于seh(2)

原创 2004年07月08日 17:02:00

                          关于seh(2)
     by sssa2000

马家爵被捕了,心中极度的痛苦呀。
Aaah说我中了毒,mydoom,我下了专杀工具,没发现,现在我变得异常警惕,连rundll32这个进程一看就关。
正题。

1、首先,怎么使用seh
    昨天我们说的是c++中封装好的东西,现在我们接触的是赤裸裸的seh哦。

    seh工作原理就是预先设置好处理异常的函数,然后如果有异常
    首先,要使用seh必须先设置处理异常的回调函数。

    怎么设置呢?很简单,3句就可以搞定:

      把回调函数的地址入栈  push offset _handler
      把fs:[0]入栈          push fs:[0]
      把esp存入fs:[0]       mov fs:[0],esp

     为什么要这样呢?这就要说说tib了。
     win32为每个线程定义一个线程信息块tib,这个结构中有一个
     Exceptionlist的指针,它是seh的链入口。

     这个指针指向一个EXCEPTION_REGISTRATION结构,定义如下:
     EXCEPTION_REGISTRATION STRUCT
     prev dd ?       ;前一个EXCEPTION_REGISTRATION的地址
     handler dd ?    ;回调函数的地址
     EXCEPTION_REGISTRATION ENDS

     有了这个结构才能把很多seh联结成链状,注意,这里讲的是基本节构,很多其他资料上还有其他的什么附加数据,那都是自己加上去的,最基本的就这两个。

     现在在来讲解前面的那三句
     由于tib永远载fs:[0] 所以,fs[0]指向的就是Exceptionlist指向的东西,也就是EXCEPTION_REGISTRATION。

     push fs:[0]  把fs:[0]入栈,这时候esp会指向压入的东西,为什么?先去复习一下汇编。 [esp]就是这个EXCEPTION_REGISTRATION的地址。
     这个时候,[esp+0]就是prev字段 [esp+4]是回调函数的地址

     mov fs:[0],esp
     esp放入fs:[0]。我们知道 现在的fs:[0]就是prev,他还没有被附值。现在的esp里面放的就是prev需要的地址,我们要做的就是把prev=esp


     好了,是不是觉得有点不好理解?
     如果第一次接触,那就不妨死记下来
              push offset _handler
              push fs:[0]
              mov fs:[0],esp
       这3句话,只需要把回调函数的名字变一下就可以了,随着以后的学习,你就会熟悉的,别急别急。

看看罗云彬这段代码:


  .386
  .model flat,stdcall
  option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include  windows.inc
include  user32.inc
includelib user32.lib
include  kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  .const
szMsg  db '异常发生位置:%08X,异常代码:%08X,标志:%08X',0
szSafe  db '回到了安全的地方!',0
szCaption db 'SEH例子',0

  .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 错误 Handler
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Handler proc _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext
  local @szBuffer[256]:byte

  pushad
  mov esi,_lpExceptionRecord
  mov edi,_lpContext
  assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
  invoke wsprintf,addr @szBuffer,addr szMsg,/
   [edi].regEip,[esi].ExceptionCode,[esi].ExceptionFlags
  invoke MessageBox,NULL,addr @szBuffer,NULL,MB_OK
;********************************************************************
; 将 EIP 指向安全的位置并恢复堆栈
;********************************************************************
  mov eax,_lpSEH
  push [eax + 8]
  pop [edi].regEip
  push [eax + 0ch]
  pop [edi].regEbp
  push eax
  pop [edi].regEsp
  assume esi:nothing,edi:nothing
  popad
  mov eax,ExceptionContinueExecution
  ret

_Handler endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Test  proc

;********************************************************************
; 在堆栈中构造一个 EXCEPTION_REGISTRATION 结构
;********************************************************************
  assume fs:nothing
  push ebp
  push offset _SafePlace
  push offset _Handler
  push fs:[0]
  mov fs:[0],esp
;********************************************************************
; 会引发异常的指令
;********************************************************************
  pushad
  xor ebp,ebp
  xor eax,eax
  mov dword ptr [eax],0
  popad  ;这一句将无法被执行
_SafePlace:
  invoke MessageBox,NULL,addr szSafe,addr szCaption,MB_OK
;********************************************************************
; 恢复原来的 SEH 链
;********************************************************************
  pop fs:[0]
  add esp,0ch
  ret

_Test  endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
  invoke _Test
  invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  end start

 

这段代码我不解释,有一些我还要再下一讲说的,不懂得先记下,好好想一下,下一讲主要就讲一下关于seh的回调函数的问题


好了,现在离我们的目标进入ring0又进了一步,呵呵,虽说技术有点过时,对我们这些小菜还是很有用的,我也是在边学边写哦,cih进入ring0的代码我这几天随身携带,一有空就看,呵呵。  其实我一次写这么一点,是怕到时候我写不出来,延缓以下,呵呵呵。

学习心得---关于seh(1)

                    关于seh(1)  好久就想写点东西了,无赖自己太懒了。好不容易写了篇进程插入得投了,还被退回来了,郁闷。    天天打游戏,玩奇迹,其实每天我都知道要好好学习...
  • sssa2000
  • sssa2000
  • 2004年07月08日 17:01
  • 947

SEH学习心得【2】- 关于FS段寄存器

—————— 关于PEB结构在http://blog.csdn.net/betabin/article/details/7481949中列出。 —————— 看SEH少不了FS段寄存器,关于其大...
  • BetaBin
  • BetaBin
  • 2012年03月13日 19:44
  • 1617

[引用]SEH原理

原文引用自:http://hi.baidu.com/slaff/blog/item/c6d96d4c0ba180fad72afcb7.htmlSEH研究 不少菜菜在编写ASM程序时往往会不太稳定。然而...
  • cranium
  • cranium
  • 2008年01月17日 23:42
  • 2096

结构化异常(SEH)简述

结构化异常处理程序? SEH:structured Exception Handling,结构化异常处理。 结构化异常处理,是Windows操作系统上,Microsoft对C/C++程序语言做的语法...
  • yygydjkthh
  • yygydjkthh
  • 2014年08月04日 00:59
  • 2666

学习心得----seh(4)

解读cih进入ring0的秘密   看了大家对前面几篇的评论,觉得有点怪异,看来大家对技术的追求还不是那么强烈,声明以下,我写的这些东西或许永远也不会对你的实际应用有帮助,这只是黑客们对技术的研究,如...
  • sssa2000
  • sssa2000
  • 2004年07月08日 17:05
  • 912

重构的5W1H(实践总结)

 重构的5W1H(实践总结)  为什么需要重构(Why):提高软件内部质量,了解系统。1.      减少复杂度是唯一的判断标准。2.      内部质量:程序员能够感受到的,比如:可维护、可读性、灵...
  • ThinkInChaos
  • ThinkInChaos
  • 2006年10月02日 15:01
  • 2047

学习心得-------seh(3)

seh(3)   明天去郊外去春游,心里很兴奋哦。    上次贴了一段代码,里面的回调函数有一长串参数,现在解释一下:    _Handler  proc   _lpExceptionRecord,_...
  • sssa2000
  • sssa2000
  • 2004年07月08日 17:03
  • 946

SEH学习心得【1】

(近日遇到大量SEH问题,所以觉得有必要好好研究研究。) 一、SEH的汇编实现 从实践入手,汇编实现SEH其实不难。简单点如下指令: push offset_exception_functi...
  • BetaBin
  • BetaBin
  • 2012年03月12日 21:32
  • 1412

谈SEH( structured exception handling )异常处理

////////////////////////////////////////////////////// 这个跟C++的try-catch异常捕获的两种模式有关。同步模式和异步模式。其中前者不能...
  • ztsinghua
  • ztsinghua
  • 2015年06月05日 16:40
  • 1178

掀起你的盖头来——Windows SEH

将浏览器宽度调窄些有利于阅读本文 掀起你的盖头来——Windows SEH SEH(Structured Exception Handling)亦即结构化异常处理,是Windows操作系统提供处理...
  • nlqlove
  • nlqlove
  • 2012年02月23日 20:26
  • 2665
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章: 学习心得--------关于seh(2)
举报原因:
原因补充:

(最多只允许输入30个字)