利用SEH进入ring0

gls192246 2011-06-30 06:19:55
seh的一个应用是进入ring0,ring0有着更多的权利,你可以进行一些其他ring3级应用程序不能进行的操作,譬如改自己的代码段(在不修改段属性的前提下),改系统数据(病毒?)等等,在9X下进入ring0的方法很多,在NT下困难的多,SEH只是其中较简单的一种.打开调试器看看系统kernel的工作状态,在9X下cs一般是28h,ds,ss等通常是30h,因此只要我们的cs和ss等在异常处理程序中被赋予上述ring0选择子值,进入ring0就可以实现.可能我们需要执行较复杂的操作,在ring0下一般不能直接调用常用api,当然VxD,WDM等提供的系统服务是另外一种选择. 否则,这在用下述简单方法进入ring0后执行会产生错误,因此,我们在ring0下尽快完成需要完成的任务,然后迅速返回ring3.
在ring0下要完成如下任务:
1.取CR3的值,返回ring3显示.在ring3下不可以读取cr3的值.你可以打开kernel调试器看看例子程序取到的值是否正确.
2.修改代码段后面的jmp ****代码,这在通常情况下只会导致保护错误.而在ring0下是可以的,就像在前面例子中用she实现SMC的效果是一样的,最后显示几个MsgBox,证明我们曾经到达过ring0
这个例子是参考owl的那个nasm写的例子用masm改写,并增加ring0下SMC的代码部分以作演示.另外代码中iretd指令并不是简单实现跳转,而是实现从ring0切回ring3的功能,在变换代码特权级的同时,堆栈的也要变换到ring3.可能原例子ljtt前辈的中文注释容易引起初学者的误解.
别的不说,我发现进入ring0后修改代码段可以使trw的跟踪崩溃...hmmm,好消息?代码如下:
其中用的一些宏在Ex5中已经贴了,就不再重复.
;-----------------------------------------
;Ex6,演示利用seh进入ring0! by Hume,2002
;humewen@21cn.com
;hume.longcity.net
;-----------------------------------------
.586
.model flat, stdcall
option casemap :none ; case sensitive
include hd.h
include mac.h
;;--------------

ring0_xHandler proto C :DWORD,:DWORD,:DWORD,:DWORD
.data
szbuf db 100 dup (0)
count dd 0
;;-----------------------------------------
.CODE
_Start:
assume fs:nothing
push offset ring0_xHandler
push fs:[0]
mov fs:[0],esp
;--------------------
mov ecx,ds
test ecx,100b
jz NT_2K_XP ;NT/2K/XP has no LDT
pushfd
mov eax,esp
int 3

mov ebx,cr3 ;现在,正式宣布,进入ring0!

;呵呵这样简单就进入ring0了,至于进入

push ebx ;ring0有啥用,不要问我!

lea ebx,offset _modi ;SMC

mov byte ptr[ebx],75h ;修改jmp addinfo为jnz addinfo指令

pop ebx



push edx ;ss

push eax ;esp

push dword ptr[eax] ;eflags

push ecx ;cs

push offset ring3back ;eip

iretd ;这里是通过iretd 指令返回特权级3



ring3back:

popfd

invoke wsprintf,addr szbuf,ddd("It's in ring0,please see CR3==%08X",0dh,oah,"following display Modified info..."),ebx

invoke MessageBox,0,addr szbuf,ddd("Ring0! by Hume[AfO]"),40h

xor eax,eax

;add eax,2

.data

Nosmc db "Not modified area!",0

besmc db "haha,I am modified by self in ring0!",0

.code

mov ebx,offset Nosmc

mov eax,0

_modi:

jmp addinfo ;SMC后将这里改为jnz addinfo



mov ebx,offset besmc

mov eax,30h

addinfo:

invoke MessageBox,0,ebx,ddd("Rin0 SMC test"),eax

_exit:

;--------------------

pop fs:[0]
add esp,4
invoke ExitProcess,0
NT_2K_XP:

invoke MessageBox,0,ddd("The example not support NT/2K/Xp,only 9x!"),ddd("By hume"),20h
jmp _exit
;-----------------------------------------
ring0_xHandler PROC C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
pushad
assume edi:ptr CONTEXT
assume esi:ptr EXCEPTION_RECORD
mov esi,pExcept

mov edi,pContext

test dword ptr[esi+4],1 ;Exception flags

jnz @f

test dword ptr[esi+4],6

jnz @f

cmp dword ptr[esi],80000003h ;break ponit flag

jnz @f

m2m [edi].regEcx,[edi].regCs ;保存3级代码段选择子
mov [edi].regCs,28h ;0级代码段选择子
m2m [edi].regEdx,[edi].regSs ;保存3级堆栈段选择子

mov [edi].regSs,30h ;0级堆栈选择子
mov dword ptr[esp+7*4],0
popad
ret
@@:
mov dword ptr[esp+7*4],1
popad
ret

ring0_xHandler ENDP

;-----------------------------------------

END _Start
由于在NT/2K/XP下这种进入ring0的方法不能使用,所以首先区别系统版本,如果是NT/2K/XP则拒绝执行, 原理是在NT/2K/XP下没有LDT,因此测试选择子是否指向LDT,这是一种简单的方法,但不推荐使用, 最好使用GetVersionEx...至于

mov dword ptr[esp+7*4],0

popad

是返回eax=1的实现}
文章来自http://www.cosye.com/
...全文
142 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdupoplar 2011-06-30
  • 打赏
  • 举报
回复
不错,学习了!!
hxp2k6 2011-06-30
  • 打赏
  • 举报
回复
呵呵,挺不错的分享

9,506

社区成员

发帖
与我相关
我的任务
社区描述
Windows专区 安全技术/病毒
社区管理员
  • 安全技术/病毒社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧