nhchmg
驱动牛犊
驱动牛犊
  • 注册日期2004-10-27
  • 最后登录2013-08-02
  • 粉丝2
  • 关注0
  • 积分39分
  • 威望220点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
阅读:1235回复:7

怎样读出页表?

楼主#
更多 发布于:2004-11-22 21:38
我现在有CR3的值,我想读出页表,是否需要先构造一个段描述符,另外需要将PG位置0吗,当我读出来后再将PG位还原,要是系统在PG位是0,还没有被还原时将我的程序切换掉,就会重启,要如何才能防止切换?
xcdyjx
驱动牛犊
驱动牛犊
  • 注册日期2004-11-14
  • 最后登录2011-11-14
  • 粉丝0
  • 关注0
  • 积分135分
  • 威望37点
  • 贡献值0点
  • 好评度14点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-11-23 12:13
我现在有CR3的值,我想读出页表,是否需要先构造一个段描述符,另外需要将PG位置0吗,当我读出来后再将PG位还原,要是系统在PG位是0,还没有被还原时将我的程序切换掉,就会重启,要如何才能防止切换?
 



一般NT/XP下页表存储于虚拟地址0xC0000000处,既然你有CR3的值,你可以把虚拟地址转换为物理地址,然后用\DEVICE\PhysicalMemory把相应内容映射到你的进程空间中.

你是怎样读到CR3值的?我一直想知道怎么做
nhchmg
驱动牛犊
驱动牛犊
  • 注册日期2004-10-27
  • 最后登录2013-08-02
  • 粉丝2
  • 关注0
  • 积分39分
  • 威望220点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-11-23 12:30
我用的98,读CR3很容易
nhchmg
驱动牛犊
驱动牛犊
  • 注册日期2004-10-27
  • 最后登录2013-08-02
  • 粉丝2
  • 关注0
  • 积分39分
  • 威望220点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-11-23 12:31
NT我还不熟,另外我想到了,切换PG位是不行的,后面的代码就会错位了,不知道会执行到什么地方,似乎如果系统不把分页表映射到一个固定的地方,我们就没有办法读出分页表

[编辑 -  11/23/04 by  nhchmg]
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2004-11-23 15:53
;******************************************************
;文件:l2p.asm                                        *
;功能:由线性地址得到相应的物理地址,并显示其页属性   *
;******************************************************
.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
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
nhchmg
驱动牛犊
驱动牛犊
  • 注册日期2004-10-27
  • 最后登录2013-08-02
  • 粉丝2
  • 关注0
  • 积分39分
  • 威望220点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-11-23 20:31
谢谢上面的回复

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


这个int 20H 内部是不是也要访问页表?我的意思是从理论上,如果页表并不映射到一个固定的地址,我们是不是不可能访问到页表?
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
6楼#
发布于:2004-11-26 04:57
也是可以的啊...不然os怎么去修改page table呢..
内存的访问总是以线性地址为方式的啊...
os也是通过线性地址访问page table的...

而且如果page table不映射到固定的地址..
那么这个地址保存到哪里呢?某个变量里面?
那这个变量的地址又是什么呢?固定还是不固定?
如果不固定的话?又怎么去获取呢?难道又用一个变量保存?
那就无穷尽了....
所以os总是把page table映射到一个固定的地址
nhchmg
驱动牛犊
驱动牛犊
  • 注册日期2004-10-27
  • 最后登录2013-08-02
  • 粉丝2
  • 关注0
  • 积分39分
  • 威望220点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-11-26 12:59


[编辑 -  11/26/04 by  nhchmg]
游客

返回顶部