moonYut
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2006-12-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望138点
  • 贡献值17点
  • 好评度117点
  • 原创分0分
  • 专家分0分
阅读:1677回复:0

看wowocock的技术文章

楼主#
更多 发布于:2005-04-29 10:51
               SYSENTER简介及相关例子
                  by wowocock1/CVC.GB

;众所周知微软自XP后引进了FASTCALL SYSENTER,SYSEXIT来代替WIN2K下INT2E系统服务调用
;其优点是快速而且没有保留堆栈的开销,为了便于大家理解我写下面一个在WIN98下的例子
;来说明一下这2条指令的用法。ITNEL的手册上关于他们介绍的很详细,我简要说明一下
;SYSENTER是INTEL自P2后引进的快速从RING3~RING0的FASTCALL,从FAMILY 6,MODEL 3,
;STEP 3也就是从PII300以后引进的,这也是为什么WINXP需要PII300以上的原因。在使用SYSENTER
;之前必须定义好RING0 CS EIP ESP,通过设置相应MSR寄存器,由WRMSR指令来设定(必须在RING0层执行);
;通过将相应的寄存器地址号放入ECX中,WRMSR可以设置这些MSR寄存器,对应关系如下
;SYSENTER_CS_MSR 174H  SYSENTER_ESP_MSR 175H  SYSENTER_EIP_MSR 176H
;执行SYSENTER指令的系统必须满足 1:转换后的RING0代码段必须是FLAT,4GB的可读可执行
;的非一致代码段.2:转换后的RING0堆栈段必须是FLAT,4GB的可读可写向上扩展的数据段
;由于FASTCALL不保存任何返回的地址,所以在调用前你必须自己设定好,RING0代码段SELECTOR
;RING0堆栈段SELECTOR,RING3代码段SELECTOR,RING3堆栈段SELECTOR,必须在GDT中连续的排列
;所以在XP下相应的SELECTOR,必然是8H,10H,1BH,23H,必须将返回至RING3 EIP,ESP通过寄存器
;传递进RING0以便SYSEXIT返回使用,在SYSEXIT返回之前,EDX为RING3 EIP,ECX为RING3 ESP
;而相应的CS,SS,则由RING0 CS加上10H,18H来返回
;RING3~RING0
;1. 装载SYSENTER_CS_MSR 到CS 寄存器.
;2. 装载SYSENTER_EIP_MSR到 EIP寄存器。
;3. SYSENTER_CS_MSR+8 装载到SS寄存器
;4.装载SYSENTER_ESP_MSR 到ESP寄存器。  
;5. 切换RING0.
;6. 清除 EFLAGS的 VM标志
;7. 执行RING0例程
;RING0~RING3
;1。SYSENTER_CS_MSR+16装载到 CS寄存器
;2. 将EDX的值送入EIP
;3.  SYSENTER_CS_MSR+24 装载到SS寄存器
;4. 将ECX的值送入ESP
;5.切换回RING3
;6. 执行EIP处的RING3指令
;下面的例子在示范的基础上加了个小TRICK,就是在通过CALLGATE进RING0设置MSR寄存器的同时
;关掉了你机器上的缓存,然后你可以看看在没有缓存的情况下你的感觉如何,然后点击一下
;对话框,则经由SYSENTER指令进入RING0设定好的地址处恢复你CPU缓存,所以别担心,还有
;没有缓存的时候你的动作最好慢一点,不然会让你等的发疯的,呵呵。
.686p
.model flat,stdcall
option casemap:none

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

sysenter macro
    db 0fh,34h
    endm

sysexit macro
   db 0fh,35h
   endm

CR0_CD  EQU     040000000h      ; Cache Disable bit of CR0
CR0_NW  EQU     020000000h      ; Not Write-through bit of CR0  
  .data
Ring0Cs dw 0ffffh,0,09b00h,0cfh
Ring0Ss dw 0ffffh,0,09300h,0cfh
Ring3Cs dw 0ffffh,0,0fb00h,0cfh
Ring3Ss dw 0ffffh,0,0f300h,0cfh

trR dw ?
tssRing0Esp dd ?
GdtLimit dw ?
GdtAddr dd ?

Callgt dq 0        ;call gate’s sel:off
tmpCs  dw ?
szTitle         db      \"CPU info\",0
msg             db 100 dup (?)
Nightmare  db \"切换到其他窗口,尝尝没CACHE的滋味!\",0

       .code
Start:
        mov ax,ds
 test ax,4
 jz Exit;winnt
 xor eax,eax
 cpuid
        lea edi,msg
 xchg eax,ebx
 stosd
 xchg eax,edx
 stosd
 xchg eax,ecx
 stosd
        invoke MessageBoxA,0,addr msg,addr szTitle,0
 mov eax,1
 cpuid
 test edx,800h
 jz Exit
 mov eax,2
 cpuid
SetSel:
 sgdt GdtLimit
        str     word ptr  trR
        ;-----------------------
        ; get the tr mes
        ;-----------------------        
 movzx  esi,trR
        add    esi,GdtAddr
        mov    eax,[esi+2]
        and    eax,0ffffffh
        mov    ebx,[esi+4]
        and    ebx,0ff000000h
        or    eax,ebx
        push dword ptr[eax+4]
 pop    dword ptr [tssRing0Esp]
 movzx eax,GdtLimit
 test  al,1
 jz @f
 inc eax
 @@:
 sub eax,4*8
 mov tmpCs,ax
 add eax,GdtAddr
 lea esi,Ring0Cs
 mov edi,eax
 mov ecx,4*8
 rep movsb
SetMsr:
        ;-------------------------------------
        ; 在GDT中寻找空白表项来制造调用门
        ;-------------------------------------
        mov    esi,GdtAddr
        movzx  eax,GdtLimit
        call    Search_XDT
                                                ;esi==gdt Base
        mov    esi,dword ptr GdtAddr
        push    offset Ring0_SetMsr
        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 and attribute ->386 call gate!

        and    dword ptr Callgt,0
        
        mov    word  ptr [Callgt+4],ax
 pushad
        call    fword ptr [Callgt]            ;Ring0!
        popad
        mov    dword  ptr [esi+eax+0],0
        mov    dword  ptr [esi+eax+4],0
 
invoke MessageBoxA,0,addr Nightmare,addr Nightmare,0
 lea     edx,Exit
 mov     ecx,esp
 sysenter
Exit:
 push    00000000h                       ; Exit program
        call    ExitProcess
Ring0_SetMsr:
       mov ecx,174h
       movzx eax,tmpCs
       wrmsr
       inc ecx
       mov eax,tssRing0Esp
       wrmsr
       inc ecx
       lea eax,Ring0Ip
       wrmsr

       mov     eax,cr0         ; read CR0
       or      eax,CR0_CD      ; set CD but not NW bit of CR0
       mov     cr0,eax         ; cache is now disabled
       wbinvd                  ; flush and invalidate cache

        ; the cache is effectively disabled at this point, but memory
        ; consistency will be maintained. To completely disable cache,
        ; the following two lines may used as well:

       or      eax,CR0_NW      ; now set the NW bit
       mov     cr0,eax         ; turn off the cache entirely
      
       retf
Ring0Ip:
       pushad
      
       pushf                   ; save the flags
       cli                     ; disable interrupts while we do this
       mov     eax,cr0         ; read CR0
       and      eax,0dfffffffh  ; now set the NW bit
       mov     cr0,eax         ; turn on the cache entirely

       and      eax,0bfffffffh      ; set CD but not NW bit of CR0
       mov     cr0,eax         ; cache is now Ensabled                              
    
       popf                    ; restore the flags
        
       mov eax,cr0
       mov [esp+4*7],eax
       popad
       sysexit
Search_XDT proc near      ;entry esi==Base  of Ldt  or GDT
              ;Eax==Limit
    pushad      
    mov ebx,eax    
    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    
    ret        
Search_XDT endp
end     Start
刚则折,柔恒存,柔羽胜刚强! 万法自然,无根无极!--太极
游客

返回顶部