l2p.asm
来自「windows下汇编语言 学习汇编语言好助手」· 汇编 代码 · 共 137 行
ASM
137 行
;******************************************************
;文件: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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?