汇编网首页登录博客注册
goodboy的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
好友圈
文章收藏
友情链接

[2008-11-21 18:08] 读出页表源程序

.386p 
.model flat,stdcall 
include win32.inc 
extrn ExitProcess:PROC 
extrn MessageBoxA:PROC 
extrn _wsprintfA:PROC 

CALL32 MACRO selector ,offsetv 
DB 09AH 
DD offsetv 
DW selector 
ENDM 

LinearAddr equ offset Start ;要查看的线性地址 

.data 
PhysAddr dd ? ;存放得到的物理地址 
User db 'User',0 
System db 'System',0 
Read db 'Read',0 
Write db 'Write',0 
Caption db '线性地址到物理地址的转换',0 
Text db 150 dup (0) 
ErrParam db '线性地址 %8XH 不在内存中!',0 
SucParam db '线性地址:%8XH',0dh,0ah 
db '物理地址:%8XH',0Dh,0Ah 
db '页属性:%s/%s',0 
.code 
Start: 
call ToRing0Code,offset L2P ;取物理地址及页信息 
call Show ;显示物理地址及页信息 
call ExitProcess,0 ;退出进程 

Show Proc 
test eax,1 ;存在否? 
jnz Present 
call _wsprintfA,offset Text,offset ErrParam,LinearAddr 
add esp,4*3 
call MessageBoxA,0,offset Text,offset Caption,MB_OK 
call ExitProcess,1 
Present: 
mov esi,offset User 
mov edi,offset Read 
test eax,100B ;用户页还是系统页? 
jnz Usr 
mov esi,offset System 
Usr:test eax,10B ;只读还是可写? 
jz RD 
mov edi,offset Write 
RD: call _wsprintfA,offset Text,offset SucParam,LinearAddr,[PhysAddr],esi,edi 
add esp,4*6 
call MessageBoxA,0,offset Text,offset Caption,MB_OK 
ret 
Show endp 

ToRing0Code proc Ring0Proc:DWORD ;生成调用门并调用Ring0子程序Ring0Proc 
LOCAL Temp,Temp1 
call GetLdtAddress ;取出LDT的地址,返回结果在eax中 
mov ecx,[eax] ;保存LDT第一个描述符 
mov [Temp],ecx ; 
mov ecx,[eax+4] ; 
mov [Temp1],ecx ; 
mov edx,Ring0Proc ;把调用门的内容写入LDT 
mov [eax],dx ;偏移量的低16位 
mov word ptr [eax+2],28h ;段选择子 
mov word ptr [eax+4],0ec00h ;属性 
shr edx,16 ;偏移量的高16位 
mov [eax+6],dx ; 
push eax 
CALL32 7,0 ;调用 Ring0 子程序 
pop ebx 
mov edx,[Temp] ;恢复LDT第一个描述符 
mov [ebx],edx ; 
mov edx,[Temp1] ; 
mov [ebx+4],edx ; 
ret 
ToRing0Code endp 
GetLdtAddress proc ;取LDT的地址 
push ebx ;先要取GDT的地址 
sgdt [esp-2] ; 
pop ebx ; 
sldt ax ;取LDT内容 
and eax,0fff8H ;屏蔽掉低3位、eax的高16位清0 
add ebx,eax ;算出LDT描述符的位置 
mov eax,[ebx+2] ;从描述符中取出LDT的地址 
mov dl,[ebx+7] ; 
shl edx,24 ; 
and eax,0ffffffh ; 
or eax,edx ; 
ret 
GetLdtAddress endp 

L2P proc far ;Ring0程序,由线性地址取得物理地址及其页属性 
mov eax,cr3 ;CR3是页表目录寄存器 
push eax ;取页表目录的线性地址 
call P2L ; 
mov edx,LinearAddr ;取出线性地址 
shr edx,22 ;取高10位 
shl edx,2 ;乘4(每项4字节) 
mov eax,[eax+edx] ;取对应页表的(物理)地址 
test eax,1 ;存在否? 
jz Quit 
and eax,0fffff000H ;清除属性位 
push eax ;取对应页表的线性地址 
call P2L ; 
mov edx,LinearAddr ;取线性地址第12-21位 
shl edx,10 ; 
shr edx,22 ; 
shl edx,2 ;乘4 
mov eax,[eax+edx] ;取出物理页地址 
test eax,1 ;存在否? 
jz Quit 
push eax ;保存eax,用作返回值 
and eax,0fffff000H ;填入页内偏移 
mov edx,LinearAddr ; 
and edx,00000FFFH ; 
or eax,edx ; 
mov [PhysAddr],eax ;保存好物理地址 
pop eax ;返回对应的物理页和属性 
Quit: 
ret 
L2P endp 

P2L proc ,Physcial ;由物理地址得到线性地址 
push Physcial 
int 20H ;VxDCall _MapPhysToLinear 
dd 0001006cH 
add esp,4 ;调整堆栈 
ret 
P2L endp 

END Start
评论次数(0)  |  浏览次数(794)  |  类型(保护模式汇编基础) |  收藏此文  | 
 
 请输入验证码  (提示:点击验证码输入框,以获取验证码