欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

总结进入RING0的方法

程序员文章站 2022-06-28 08:28:49
by wowocock1/CVC.GB 关于进入RING0层的方法,大家一定听说过不少,我在复习保护模式编程中将一些进RING0的方法;总结了一下,包括调用门,任务门,中断门,陷阱门等,这些...

by wowocock1/CVC.GB

关于进入RING0层的方法,大家一定听说过不少,我在复习保护模式编程中将一些进RING0
的方法;总结了一下,包括调用门,任务门,中断门,陷阱门等,这些方法都是直接利用
IA32的方法,所以和操作系统应该没有多大关系,当然由于NT内核对GDT,IDT,的保护所
以我们不能用这些方法,不过如果一旦突破了NT的保护,那么所有的方法就都可以使用了,
其他的还有SEH等方法,我在前面的文章中也有介绍。

-----------------Code---

;========================================
;      WOWOCOCK  编写      ;
;======================================== 
   .586p
   .model flat, stdcall
   option casemap :none  ; case sensitive
   include masm32includewindows.inc
   include masm32includekernel32.inc
   include masm32includeuser32.inc
   includelib masm32libkernel32.lib
   includelib masm32libuser32.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 selff

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  e