📄 ring0.txt
字号:
关于进入RING0层的方法,大家一定听说过不少,我在复习保护模式编程中将一些进RING0
的方法;总结了一下,包括调用门,任务门,中断门,陷阱门等,这些方法都是直接利用
IA32的方法,所以和操作系统应该没有多大关系,当然由于NT内核对GDT,IDT,的保护所
以我们不能用这些方法,不过如果一旦突破了NT的保护,那么所有的方法就都可以使用了,
其他的还有SEH等方法,我在前面的文章中也有介绍。
-----------------Code---
;========================================
; WOWOCOCK 编写 ;
;========================================
.586p
.model flat, stdcall
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
;;--------------
TSS STRUC
TRLink dw 0 ;链接字段
dw 0 ;不使用,置为0
TRESP0 dd 0 ;0级堆栈指针
TRSS0 dw 0 ;0级堆栈段寄存器
dw 0 ;不使用,置为0
TRESP1 dd 0 ;1级堆栈指针
TRSS1 dw 0 ;1级堆栈段寄存器
dw 0 ;不使用,置为0
TRESP2 dd 0 ;2级堆栈指针
TRSS2 dw 0 ;2级堆栈段寄存器
dw 0 ;不使用,置为0
TRCR3 dd 0 ;CR3
TREIP dd 0 ;EIP
TREFlag dd 0 ;EFLAGS
TREAX dd 0 ;eax
TRECX dd 0 ;ecx
TREDX dd 0 ;edx
TREBX dd 0 ;ebx
TRESP dd 0 ;esp
TREBP dd 0 ;ebp
TRESI dd 0 ;esi
TREDI dd 0 ;edi
TRES dw 0 ;ES
dw 0 ;不使用,置为0
TRCS dw 0 ;CS
dw 0 ;不使用,置为0
TRSS dw 0 ;ss
dw 0 ;不使用,置为0
TRDS dw 0 ;DS
dw 0 ;不使用,置为0
TRFS dw 0 ;FS
dw 0 ;不使用,置为0
TRGS dw 0 ;GS
dw 0 ;不使用,置为0
TRLDTR dw 0 ;LDTR
dw 0 ;不使用,置为0
TRTrip dw 0 ;调试陷阱标志(只用位0)
TRIOMap dw $+2 ;指向I/O许可位图区的段内偏移
TSS ENDS
.data
sztit db "Gate Test",0
CTEXTCall db "call gate to Ring0!继续?",0
CTEXTInt db "int gate to Ring0 By int 5 !继续?",0
CTEXTIntx db "int gate to Ring0 By int X !继续?",0
CTEXTTrap db "Trap gate to Ring0 By int 1!继续?",0
CTEXTFault db "Fault gate to Ring0!继续?",0
CTEXTTask db "Task gate to Ring0!继续?",0
temp1 db "Cr3的内容是:%8X",0
temp2 db 100 dup(?)
Freq db 08h ;发声频率
gdtR df 0
idtR df 0
ldtR dw 0
trR dw 0 ;the contents of GDTR,IDTR,LDTR,TR
ldtDes dw 0
dw 0 ;LDT Limit
dd 0 ;LDT Base
Callgt dq 0 ;call gate's sel:off
TrDes dw 0
dw 0 ;TR Limit
dd 0 ;TR Base
Tss1Sel dw ? ;TSS
Call32 dd 0
Tss1Gate dw ? ;任务门
TSS1 TSS <>
Tss1Limit equ $-TSS1
TSS2 TSS <>
TestCR3 dd 4
MyCall MACRO Selector,Offsetv
db 09ah
dd Offsetv
dw Selector
ENDM
;;-----------------------------------------
.code
__Start:
sgdt fword ptr gdtR
sidt fword ptr idtR
sldt word ptr ldtR
str word ptr trR ;save them for later use
;-----------------------
; get the ldt mes
;-----------------------
movzx esi,ldtR
add esi,dword ptr [gdtR+2] ;esi->ldt descriptor
mov ax,word ptr [esi]
mov word ptr [ldtDes],ax
mov ax,word ptr [esi+6]
and ax,0fh
mov word ptr [ldtDes+2],ax ;get ldt Limit
mov eax,[esi+2]
and eax,0ffffffh
mov ebx,[esi+4]
and ebx,0ff000000h
or eax,ebx
mov dword ptr [ldtDes+4],eax ;get ldt Base
;-----------------------
; get the tr mes
;-----------------------
movzx esi,trR
add esi,dword ptr [gdtR+2]
mov ax,word ptr [esi]
mov word ptr [TrDes],ax
mov ax,word ptr [esi+6]
and ax,0fh
mov word ptr [TrDes+2],ax ;get tr Limit
mov eax,[esi+2]
and eax,0ffffffh
mov ebx,[esi+4]
and ebx,0ff000000h
or eax,ebx
mov dword ptr [TrDes+4],eax;get tr Base
;-------------------------------------
; 这里演示在GDT中寻找空白表项来制造调用门
;-------------------------------------
mov esi,dword ptr [gdtR+2] ;esi->gdt base
movzx eax,word ptr [gdtR] ;eax=gdt limit
call Search_XDT
;esi==gdt Base
mov esi,dword ptr [gdtR+2]
push offset myring0_prc_callgt ;set callgate in gdt
pop word ptr [esi+eax+0]
pop word ptr [esi+eax+6] ;offset
mov word ptr [esi+eax+2],28h
mov word ptr [esi+eax+4],0EC00h
;sel=28h,dpl=3,and attribute ->386 call gate!
and dword ptr Callgt,0
or al,3h
mov word ptr [Callgt+4],ax
call fword ptr [Callgt] ;use callgate to Ring0!
;--------------------------------------------
; 这里演示在Ldt中制造调用门
;--------------------------------------------
invoke MessageBoxA,0, addr CTEXTCall,addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?
mov esi,dword ptr [ldtDes+4] ;esi->ldt base
mov eax,dword ptr [ldtDes] ;eax=ldt limit
call Search_XDT ;eax返回找到的空白选择子
mov esi,dword ptr [ldtDes+4]
push offset myring0_prc_callgt ;set callgate in ldt
pop word ptr [esi+eax+0]
pop word ptr [esi+eax+6] ;offset
mov word ptr [esi+eax+2],28h
mov word ptr [esi+eax+4],0EC00h
;sel=28h,dpl=3,and attribute ->386 call gate!
and dword ptr Callgt,0
or al,7h ;所以选择子一定要指向LDT
mov word ptr [Callgt+4],ax
call fword ptr [Callgt] ;use callgate to Ring0!
; *通过中断门进入ring0,像在Dos下一样,我们只要替换中断向量表的地址以指向我们
; *自己的程序就可以了,不过在win下中断向量表变为IDT(中断描述符表),其第0~1保存
; *中断处理程序偏移的低16位,6~7字节保存偏移的高16位,我们必须使用描述符具有DPL=3
; *的中断门以便在ring3下转入中断程序,而int 03h,04h,05h,10h,13h,30h等本来就是
; *DPL=3,我们可以方便地利用之,注意中断处理程序返回用iretd
;---------------------------
; 下面利用int 5进入ring0
;---------------------------
invoke MessageBoxA,0,addr CTEXTInt,addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?
mov esi,dword ptr [idtR+2] ;esi->idt base
push dword ptr [esi+8*5+0]
push dword ptr [esi+8*5+4] ;保存INT 5,中断描述符
push offset myring0_prc_Intgt ;替换原来INT5的入口地址
pop word ptr [esi+8*5]
pop word ptr [esi+8*5+6]
int 5 ;进入ring0!
;int 3 ;//可选择利用int 3
;db 0CCh ;//则保存和恢复就改为8*3
;为了增强反跟踪效果
;当然也可以利用int 1,方法一致不过可能在某些处理器上冲突
pop dword ptr [esi+8*5+4] ;恢复,int 5,中断描述符
pop dword ptr [esi+8*5+0]
; *当然,上面使用的全部是DPL=3的int如1,3,5等,如果我们准备使用任意int 来达到
; *目的该怎么办?这就需要自己改int descriptor 的属性值,使DPL=3,sel=28h
; *如下面使用int 255
; *__________________________________________
invoke MessageBoxA,0,addr CTEXTIntx,addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?
movzx ebx,word ptr [idtR] ;ebx=idt limit
sub ebx,7
push dword ptr [esi+ebx+0] ; save IDT entry
push dword ptr [esi+ebx+4]
push offset myring0_prc_Intgt
pop word ptr [esi+ebx+0]
mov word ptr [esi+ebx+2],28h ;ring0 Sel
mov word ptr [esi+ebx+4],0EE00h ;P=1,386中断门,DPL=3
pop word ptr [esi+ebx+6]
;mov eax,ebx
;shl eax,5
;add eax,90C300CDh
;push eax
;call ss:esp ; 在堆栈中形成指令 int 5Fh ret直接转入执行!
int 5fh
;pop eax ; int调用,酷吧!
pop dword ptr [esi+ebx+4]; 恢复
pop dword ptr [esi+ebx+0]
; *
; *还有其他的方法进入ring0,如陷阱门,与中断门基本一致,只不过是让硬件自己产生中断
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -