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 + -
显示快捷键?