注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

编程学习

我的网上家园

 
 
 

日志

 
 

14章学习 从高特权级转移到低特权级的方法  

2013-04-06 14:05:07|  分类: 《x86汇编语言: |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
为了实现从高特权级的代码转移到低特权级的代码,需要把低特权级的栈选择子 栈指针 低特权级的段选择子 代码的段内偏移量压栈,然后使用retf指令从栈中返回,这样就可以转移到低特权级的代码段执行.

我们先抛开TSS不谈,单独认识一下,使用retf指令从栈中返回时的情形:
从相同特权级的代码返回,也就是当前CPL=栈中的选择子DPL时,不会切换栈. 
过程就是 POP EIP,POP CS(非程序代码,一种表示法)

从不同特权级,也就是从高特权级的代码返回到低特权级的代码时,需要切换栈.
过程是 POP EIP,POP CS,POP ESP,POP SS

特权级的代码在通过调用门 调用高特权级的代码时,需要TSS.
以下的测试(练习)代码演示了如何从高特权级的代码转移到低特权级的代码执行. 因为低特权级的代码在通过调用门调用高特权的代码时,需要用到TSS,所以以下代码没有用到调用门.

在以下代码示例中,有 hlt 指令,该指令是特权指令,通过BOCHS调试的时候,可以看到执行时会引发异常.(多谢作者的指点)

video_ram_seg_sel equ 0x23 ;显示缓冲区是3特权级的

xor ax,ax
mov ss,ax
mov sp,0x7c00
mov ax,[cs:pgdt+0x7c00+0x2]
mov dx,[cs:pgdt+0x7c00+0x4]
mov bx,16
div bx
mov ds,ax
mov bx,dx
mov dword [bx+0x00],0
mov dword [bx+0x04],0
;#4GB内存段
mov dword [bx+0x08],0x0000ffff 
mov dword [bx+0x0c],0x00cf9200
;#MBR
mov dword [bx+0x10],0x7c0001ff 
mov dword [bx+0x14],0x00409800
;#堆栈
mov dword [bx+0x18],0x7c00fffe 
mov dword [bx+0x1c],0x00cf9600
;#显示缓冲区
mov dword [bx+0x20],0x80007fff
mov dword [bx+0x24],0x0040f20b ;定义成3特权级的!!!

;生成putstring调用门描述符
mov edx,0x0000ec00
mov eax,0x10 ;MBR代码段选择子
shl eax,16
or eax,putstring
;#调用门描述符
mov [bx+0x28],eax
mov [bx+0x2c],edx

;#3特权极代码段
mov dword [bx+0x30],0x7c0001ff
mov dword [bx+0x34],0x0040f800
;#3特权级数据段
mov dword [bx+0x38],0x0000ffff
mov dword [bx+0x3c],0x00cff200
;#3特权级栈段
mov dword [bx+0x40],0x7c00fffe
mov dword [bx+0x44],0x00cff600


mov word [cs:pgdt+0x7c00],71
lgdt [cs:pgdt+0x7c00]

in al,0x92
or al,2
out 0x92,al

cli 

mov eax,cr0
or eax,1
mov cr0,eax

jmp 0x10:flush

[bits 32]
flush:
mov eax,0x18
mov ss,eax
mov esp,0
mov eax,0x3b ;111_011B-> RPL=3 ->0x3b 
mov ds,eax ;ds指向特权级为3的数据段
;0特权级的程序可以访问3特权级的数据段
mov ebx,message+0x7c00
;=======================================================
;call 0x28:0x0 ;通过调用门显示字符串. 此处指令中的偏移地址任意,通过调用门调用程序时,指令中的偏移会被忽略.
call 0x2b:0x0 ; [0x28->101_000B 请求RPL=0] [0x2b->101_011B 请求特权级RPL=3]

;请求特权级RPL可以不等于CPL. 当前CPL=0 请求RPL=3
;=======================================================



push 0x43 ;1000_011B-> RPL=3 ->0x43 特权级为3的栈段
push 0
push 0x33 ;110_011B-> RPL=3 ->0x33 特权级为3的代码段
push rpl3
retf


rpl3:
;mov eax,0x3b ;111_011B-> RPL=3 ->0x3b 
;mov ds,eax ;ds指向特权级为3的数据段
mov ebx,message+0x7c00
push 0x33 ;特权级为3的代码段 因为使用CALL指令进行远调用,为了能正常返回,手动压栈当前CS
call putstring
hlt  ;该指令是特权指令,在3特权级执行时将会引发异常.




;入口参数 DS:EBX 指向字符串所在位置
putstring:
push ecx
.show:
mov cl,[ebx]
or cl,cl
jz .exit
call putchar
inc ebx
jmp .show
.exit:
pop ecx
retf

putchar:
pushad
mov dx,0x3d4
mov al,0xe
out dx,al
inc dx
in al,dx
mov ah,al
dec dx
mov al,0xf
out dx,al
inc dx
in al,dx ;AX=当前光标位置
cmp cl,0xd
jnz .0xa
xor dx,dx
mov bx,80
div bx
mul bx
jmp .setcursor
.0xa:
cmp cl,0xa
jnz .ch
add ax,80
cmp ax,25*80
jb .setcursor
sub ax,80
jmp .rollscreen
.ch:
push es
mov ebx,video_ram_seg_sel
mov es,ebx
movzx ebx,ax
shl ebx,1
mov [es:ebx],cl
pop es
inc ax
cmp ax,25*80
jb .setcursor
mov ax,24*80


.rollscreen:
push ds
push es
mov ebx,video_ram_seg_sel
mov ds,ebx
mov es,ebx
mov esi,1*80*2
xor edi,edi
mov ecx,24*80*2/4
cld
rep movsd
mov esi,80*24*2
mov ecx,80*2/4
.clr:
mov dword [esi],0x07200720
add esi,4
loop .clr
pop es
pop ds

.setcursor:
mov bx,ax
mov dx,0x3d4
mov al,0xe
out dx,al
inc dx
mov al,bh
out dx,al
dec dx
mov al,0xf
out dx,al
inc dx
mov al,bl
out dx,al

popad
ret









message: db 0xd,0xa,' hello,world!',0

pgdt dw 0
dd 0x7e00



times 510-($-$$) db 0
db 0x55,0xaa
  评论这张
 
阅读(37)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017