总结进入RING0的方法_Nada_Red的博客-程序员秘密

技术标签: div  制造  include  search  VC++  byte  descriptor  

关于进入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,如陷阱门,与中断门基本一致,只不过是让硬件自己产生中断
; *我们则自己置TF=1引发之,注意在中断处理中关闭TF,否则会造成死循环,不断单步,还有故,
; *障门产生故障之后注意cs:eip已经压入堆栈,如果不改指令的话,就得自己修改eip指向安全
; *地址故障门的好处在于不必自己置sel为28h,也不必担心DPL=0,操作系统为我们准备好了一
; *切我们只要替换int处理地址就行了,以下是简单例子
; *__________________________________________
     invoke  MessageBoxA,0,addr CTEXTTrap,addr sztit,MB_YESNO
     cmp  eax,IDNO
     jz   @xit001           ;继续演示?
     ;---------------------------------
     ; int1 单步陷阱或者int4 除法溢出陷阱
     ; 这里演示int 1,int 4类似
     ; 这个和上面的有不同吗,有!就是int 1
     ; 是由CPU而不是我们显式用int 1指令引发
     ;---------------------------------
     push dword ptr [esi+(8*1)+0]   ; 保存原int 1
     push dword ptr [esi+(8*1)+4] 

    push offset myring0_prc_Trapgt
     pop word ptr [esi+(8*1)+0]
     pop word ptr [esi+(8*1)+6]

    pushfd
     pop eax 
     or ah,1 
     push eax
     popfd     ; set TF=1

    nop      ; ring0!

    pop dword ptr [esi+(8*1)+4]; restore IDT entry 
     pop dword ptr [esi+(8*1)+0]
     ;--------------------------------------------
     ; 这里演示故障门,除法错误
     ;--------------------------------------------
     @xit001:invoke  MessageBoxA,0,addr CTEXTFault,addr sztit,MB_YESNO
     cmp  eax,IDNO
     jz   @xit000           ;继续演示?

    push dword ptr [esi+(8*0)+0] ;              
     push dword ptr [esi+(8*0)+4]                       
                                           
     push offset Ring0Code_div                         
     pop word ptr [esi+(8*0)+0]                        
     pop word ptr [esi+(8*0)+6]       
                                           
     xor eax,eax                                
     div eax            ; 除法错误,进入故障门ring0!
     ;-----------------------------------------
     invoke  MessageBoxA,0,addr CTEXTTask,addr sztit,MB_YESNO
     cmp  eax,IDNO
     jz   @xit000
     ;-------------------------------------
     ; 这里演示在GDT中寻找空白表项来制造TSS
     ;-------------------------------------
     mov  esi,dword ptr [gdtR+2]
     movzx eax,word ptr [gdtR]
     call  Search_XDT
     and  ax,0fff8h
     mov  Tss1Sel,ax   ;save Tss1 selector ,esi==gdt Base
     mov  esi,dword ptr [gdtR+2]
     mov  ebx,offset TSS1
     mov  word ptr [esi+eax+0],Tss1Limit    
     mov  dword ptr [esi+eax+2],ebx    ;offset

    mov  word ptr [esi+eax+5],89h
     shr  ebx,24
     mov  byte ptr [esi+eax+7],bl ;set mytss

    ;--------------------------------------------
     ; 这里演示在Ldt中制造任务门
     ;--------------------------------------------
     mov  esi,dword ptr [ldtDes+4]
     mov  eax,dword ptr [ldtDes]

    call  Search_XDT          ;eax返回找到的空白选择子
     push  eax
     or   ax,7h
     mov  Tss1Gate,ax
     pop  eax
     mov  esi,dword ptr [ldtDes+4]

    mov  word ptr [esi+eax+0],0    
     mov  word ptr [esi+eax+6],0    ;offset
     push  word ptr Tss1Sel
     pop  word ptr [esi+eax+2]
     mov  word ptr [esi+eax+4],0E500h ;Tss Gate

    mov esi,dword ptr [TrDes+4]
     assume esi:ptr TSS
     push word ptr ldtR
     pop word ptr[esi].TRLDTR ;设置LDT SELECTOR(WINDOWS98的TSS中LDT 为0???)

    lea edi,TSS1
     assume edi:ptr TSS
     push word ptr trR
     pop word ptr [edi].TRLink  ;返回TSS选择子,设置联接字

    push dword ptr[esi].TRESP0  ;设置SP0
     pop dword ptr[edi].TRESP0
  
     push word ptr[esi].TRSS0   ;设置SS0
     pop word ptr[edi].TRSS0

    push dword ptr[esi].TRCR3  
        ;设置CR3寄存器,即设置好转换以后所有的段及页转换相关寄存器
     pop dword ptr[edi].TRCR3

    push offset Ring0
     pop dword ptr[edi].TREIP

    mov word ptr[edi].TRCS,28h  ;CS=28
     mov word ptr[edi].TRSS,30h  ;ss=30

    push word ptr ldtR      ;设置LDTR
     pop word ptr[edi].TRLDTR

    push ds
     pop dword ptr[edi].TRDS
     mov word ptr[edi+54h+2],0

    call fword ptr Call32
     mov ebx,dword ptr [TestCR3]
    @xit000:
     invoke wsprintf,addr temp2,addr temp1,TestCR3
     invoke MessageBoxA,0,addr temp2,addr sztit,0
     mov eax,dword ptr [ldtDes+4];恢复GDT,LDT中的空选择子。
     movzx esi,Tss1Gate
     and  esi,0fffffff8h
     add eax,esi
     mov dword ptr [eax],0
     mov dword ptr [eax+4],0
     mov eax,dword ptr [gdtR+2]
     movzx esi,Tss1Sel
     add eax,esi
     mov dword ptr [eax],0
     mov dword ptr [eax+4],0
     invoke  ExitProcess,0
     ;-----------------------------------------
Ring0Code_div proc far                            
                                       
     pushad                                  
     mov  ecx,10     ;EIP
    ambalance002:         ;cs
     push  ecx      ;EFLAGS
     call  Beeps
     pop  ecx
     loop  ambalance002                                
     popad                                   
                                       
     add dword ptr [esp],2 ; 修改Eip,略过除错指令(div eax)2个字节长,继续执行             
                                       
     iretd                                   
                                       
Ring0Code_div endp                              

myring0_prc_Trapgt  proc  far
     pushad         ;注意压栈结构为
     mov  ecx,10      ;esp->EIP
    ambalance002:       ;   cs
     push  ecx       ;   EFLAGS
     call  Beeps
     pop  ecx
     loop  ambalance002
     popad
     and  byte ptr [esp+9],0FEh ;一定要置TF=0,终止
     iretd         ;注意iretd,不是iret(w)
myring0_prc_Trapgt  endp

myring0_prc_Intgt  proc   far
     pushad
     mov  ecx,10
    ambalance001:
     push  ecx
     call  Beeps
     pop  ecx
     loop  ambalance001
     popad
     iretd        
myring0_prc_Intgt  endp

myring0_prc_callgt  proc far
     pushad
     pushfd
     pop eax 
     or eax,3000h 
     push eax
     popfd
     mov  ecx,10
    ambalance:
     push  ecx
     call  Beeps
     pop  ecx
     loop  ambalance
     popad
     retf
myring0_prc_callgt  endp
;-----------------------------------------
Search_XDT proc near   ;entry esi==Base of Ldt or GDT
              ;eax==Limit
     pushad   
     mov ebx,eax    ;ebx=limit
     mov eax,8     ; skipping null selector
    @@1:    
     cmp dword ptr [esi+eax+0],0  
     jnz @@2 
     cmp dword ptr [esi+eax+4],0  
     jz @@3 
    @@2:    
     add eax,8    
     cmp eax,ebx    
     jb @@1   ;if we haven't found any free GDT entry,
           ;lets use the last two entries    
     mov eax,ebx   
     sub eax,7     
    @@3:   
     mov [esp+4*7],eax   ; return off in eax
     popad         ; eax=free GDT entry selector
     ret    
Search_XDT endp
;-----------------------------------------
Beeps proc near        ;经典的发声子程序,学dos的时候应该
   pushad         ;没少用吧...
   mov al,0B6h      
   out 43h,al 
   mov al,Freq     ;接口要求,不要多问

  out 42h,al 
   out 42h,al 

  xor byte ptr Freq,0Ch   ; 换频率
                ; 以便下次发出不同的音高
   in al,61h
   or al,3 
   out 61h,al 
   mov ecx,1000000h    ;延时
   loop $

  and al,0FCh       ;关声音
   out 61h,al 
   popad
   ret
Beeps endp

  Ring0:
   mov ebx,cr3
   mov TestCR3,ebx
   iretd
END  __Start
;______________________________Over...___________

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Nada_Red/article/details/265732

智能推荐

Mysql-Proxy 读写分离的各种坑,特别是复制延迟时_proxysql 读写分离延迟_菠萝-琪琪的博客-程序员秘密

延迟问题读写分离不能回避的问题之一就是延迟,可以考虑Google提供的SemiSyncReplicationDesign补丁。端口问题MySQL-Proxy缺省使用的是4040端口,如果你想透明的把3306端口的请求转发给4040的话,那么可以:iptables -t nat -I PREROUTING -s ! 127.0.0.1 -p tcp --dport 3306 -j REDIRECT ...

VC-基础:关于一些符号的意义_avgp36575的博客-程序员秘密

GUI应用程序:Graphic User Interface图形 用户 接口SDI:单文档程序(典型的记事本就是SDI)MID:多文档程序(比如VS2008默认就是多文档的)转载于:https://www.cnblogs.com/CPYER/p/3370644.html...

SVG&nbsp;Dom绘制线段_svg dom 连线_普通网友的博客-程序员秘密

Dom绘制线段" TITLE="SVG Dom绘制线段" />新建html5文件<!DOCTYPEhtml>   <metacharset="utf-8">   SVGDOM绘制矩形         #myline{           border: 1pxsolid red;           width:200px;      

ModelForm表单验证_baijie9529的博客-程序员秘密

form与model的终极结合,具有以下功能:验证、数据库操作。# 写一个和Model类一一对应的formfrom django import formsclass BookModelForm(forms.ModelForm): class Meta: model = models.Book #对应的model中的类 ...

动态规划(DP)问题状态方程合集_weixin_30378623的博客-程序员秘密

主要记录常见动态规划的状态方程设计 ps:忘记之前在哪儿统计的了了,目前只有份文档; 资源问题1 —–机器分配问题 F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2. 资源问题2 ------01背包问题 F[I,j]:=max(f[i-1,j-v[...

iOS 开发 之 - UIScrollView文档_baidun2022的博客-程序员秘密

额。这篇文档主银:http://blog.sina.com.cn/u/2141630575#import &lt;Foundation/Foundation.h&gt;#import &lt;CoreGraphics/CoreGraphics.h&gt;#import &lt;UIKit/UIView.h&gt;#import &lt;UIKit/UIG...

随便推点

数据仓库与数据挖掘 6 (下)_林晚慕的博客-程序员秘密

关联规则挖掘在上两篇文章中提到了关联规则基本原理理解(6(上))以及Apriori 算法挖掘原理介绍(6(中))。我们继续介绍另外一个算法。FP-growth 算法基本定义:定义1 FP-tree频繁模式树FP-tree是一个树形结构。包括一个频繁项组成的头表,一个标记为“null”的根节点,它的子节点为一个项前缀子树的集合。定义2 频繁项单个项目的支持度超过最小支持度则称其为频繁项(Frequent Item)。定义3 频繁项头表频繁项头表(Head Table)的每个表项由两

一步步搭建 VuePress 及优化【插件系列】_H_MZ的博客-程序员秘密

介绍在之前为了搭建 VuePress 的文档,顺带制作了视频教程,如今准备再次搭建一个 VuePress 的项目,一看自己的视频竟然有五个小时,天呐,我只是需要过一遍而已,所以重新整理成文档吧,万一将来又要用呢……当然,如果您觉得文字版不够直观,可以前往观看视频版: 【☛ 视频地址 ☚】 ,当时录制完本地测试后觉得声音大小还可以,结果一套录完了才发现声音很小,所以推荐带上耳机。VuePres...

KiKi's K-Number HDU - 2852 (树状数组求第K大,O(N)算法)_for the k-th number, we all should be very familia_Flyppy_White的博客-程序员秘密

KiKi's K-Number HDU - 2852 For the k-th number, we all should be very familiar with it. Of course,to kiki it is also simple. Now Kiki meets a very similar problem, kiki wants to design a container...

邢台计算机编程培训学校,邢台有几家计算机培训中心_weixin_39692830的博客-程序员秘密

一、招生专业(一)初级班速成班从零起步、指法练习、五笔字型、电脑基础知识。熟练打字指法基础班从零起步、指法练习、五笔字型输入、电脑基本原理、windows98/2000/xp/2003的基本操作、word简单介绍以及计算机故障排除。熟练五笔指法,电脑基础知识。(二)中级班外企文秘班电脑基本原理,wi...一、招生专业招生专业名额学制学费标准(元)毕业颁证就业待遇(元/年)就业去向备注1.计算机及应...

环和有向无环图_有环图和无环图_EmilyGnn的博客-程序员秘密

文章目录定义有向环检测基于DFS的顶点排序拓扑排序在和有向图相关的实际应用中,有向环特别的重要。优先级限制下的调度问题:给定一组需要完成的任务,以及一组关于任务完成先后次序的优先级限制。在满足限制条件的前提下应该如何安排并完成所有任务?对于任意一个这样的问题,我们都可以画出一张有向图,其中顶点对应任务,有向边对应优先级顺序。优先级限制下的调度问题等价于计算有向无环图中所有顶点的拓扑排序。...

STM8S(105K4)使用笔记——活跃停机模式的配置与AWU唤醒_stm8s awu简介_虎川洛鸣的博客-程序员秘密

STM8S提供的可编程的电源管理等待(Wait)模式:通过WFI指令进入。该模式下CPU将停止运行,但外设与中断控制器仍保持运行。该模式下可以通过外设时钟门控、降低CPU时钟频率、选择低功耗时钟源(LSI,HSI)进一步降低功耗。在等待模式下,所有寄存器与RAM的内容不变,进入等待模式前所定义的时钟配置也不会在进入等待模式后改变。每当一个内部或外部中断产生时,CPU从等待模式唤醒并恢复工作。停机(Halt)模式:通过HALT指令进入。该模式下主时钟停止,即由fMASTER提供时钟的CP

推荐文章

热门文章

相关标签