![]() |
#2
zklhp2011-01-20 14:21
|
1. 示例地址:KmdKit\examples\simple\VirtToPhys 使用的是KmdKit的示例
2. 用RADASM 对VirtToPhys进行项目化 R3 为VirtToPhys.rap R0 为sys文件夹下VirtToPhys1.rap
3. 对程序进行编译,完成并且不报错
4.运行程序加载驱动并且通讯
问题如下:
程序未报错,无法获得实际物理地址.Physical全显示是0 按照书上示例应该会显示 80000H段的地址
希望得到的帮助:
希望论坛高手指导下,错误的步骤是在哪里
PS:附件已经上传,希望尽快得到解答.
只有本站会员才能查看附件,请 登录
VirtToPhys.Asm

.386
.model flat, stdcall
option casemap:none
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; I N C L U D E F I L E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
include windows.inc
include kernel32.inc
include user32.inc
include advapi32.inc
includelib kernel32.lib
includelib user32.lib
includelib advapi32.lib
include winioctl.inc
include D:\RadASM\masm32\Macros\Strings.mac
include VirtToPhys.Inc
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; BigNumToString
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
BigNumToString proc uNum:UINT, pacBuf:LPSTR
; This function accepts a number and converts it to a
; string, inserting separators where appropriate.
local acNum[32]:CHAR
local nf:NUMBERFMT
invoke wsprintf, addr acNum, $CTA0("%u"), uNum
and nf.NumDigits, 0
and nf.LeadingZero, FALSE
mov nf.Grouping, 3
mov nf.lpDecimalSep, $CTA0(".")
mov nf.lpThousandSep, $CTA0(" ")
and nf.NegativeOrder, 0
invoke GetNumberFormat, LOCALE_USER_DEFAULT, 0, addr acNum, addr nf, pacBuf, 32
ret
BigNumToString endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; start
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
start proc uses esi edi
local hSCManager:HANDLE
local hService:HANDLE
local acModulePath[MAX_PATH]:CHAR
local _ss:SERVICE_STATUS
local hDevice:HANDLE
local adwInBuffer[NUM_DATA_ENTRY]:DWORD
local adwOutBuffer[NUM_DATA_ENTRY]:DWORD
local dwBytesReturned:DWORD
local acBuffer[256+64]:CHAR
local acThis[64]:CHAR
local acKernel[64]:CHAR
local acUser[64]:CHAR
local acAdvapi[64]:CHAR
local acNumber[32]:CHAR
; Open a handle to the SC Manager database
invoke OpenSCManager, NULL, NULL, SC_MANAGER_ALL_ACCESS
.if eax != NULL
mov hSCManager, eax
push eax
invoke GetFullPathName, $CTA0("VirtToPhys.sys"), sizeof acModulePath, addr acModulePath, esp
pop eax
; Install service
invoke CreateService, hSCManager, $CTA0("VirtToPhys"), $CTA0("Virtual To Physical Address Converter"), \
SERVICE_START + SERVICE_STOP + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr acModulePath, NULL, NULL, NULL, NULL, NULL
.if eax != NULL
mov hService, eax
; Driver's DriverEntry procedure will be called
invoke StartService, hService, 0, NULL
.if eax != 0
; Driver will receive I/O request packet (IRP) of type IRP_MJ_CREATE
invoke CreateFile, $CTA0("\\\\.\\slVirtToPhys"), GENERIC_READ + GENERIC_WRITE, \
0, NULL, OPEN_EXISTING, 0, NULL
.if eax != INVALID_HANDLE_VALUE
mov hDevice, eax
lea esi, adwInBuffer
assume esi:ptr DWORD
invoke GetModuleHandle, NULL
mov [esi][0*(sizeof DWORD)], eax
invoke GetModuleHandle, $CTA0("kernel32.dll", szKernel32)
mov [esi][1*(sizeof DWORD)], eax
invoke GetModuleHandle, $CTA0("user32.dll", szUser32)
mov [esi][2*(sizeof DWORD)], eax
invoke GetModuleHandle, $CTA0("advapi32.dll", szAdvapi32)
mov [esi][3*(sizeof DWORD)], eax
lea edi, adwOutBuffer
assume edi:ptr DWORD
; Driver will receive IRP of type IRP_MJ_DEVICE_CONTROL
invoke DeviceIoControl, hDevice, IOCTL_GET_PHYS_ADDRESS, esi, sizeof adwInBuffer, edi, sizeof adwOutBuffer, addr dwBytesReturned, NULL
.if ( eax != 0 ) && ( dwBytesReturned != 0 )
invoke GetModuleFileName, [esi][0*(sizeof DWORD)], addr acModulePath, sizeof acModulePath
lea ecx, acModulePath[eax-5]
.repeat
dec ecx
mov al, [ecx]
.until al == '\'
inc ecx
push ecx
CTA0 "%s \t%08Xh\t%08Xh ( %s )\n", szFmtMod
invoke BigNumToString, [edi][0*(sizeof DWORD)], addr acNumber
pop ecx
invoke wsprintf, addr acThis, addr szFmtMod, ecx, [esi][0*(sizeof DWORD)], [edi][0*(sizeof DWORD)], addr acNumber
invoke BigNumToString, [edi][1*(sizeof DWORD)], addr acNumber
invoke wsprintf, addr acKernel, addr szFmtMod, addr szKernel32, [esi][1*(sizeof DWORD)], [edi][1*(sizeof DWORD)], addr acNumber
invoke BigNumToString, [edi][2*(sizeof DWORD)], addr acNumber
invoke wsprintf, addr acUser, addr szFmtMod, addr szUser32, [esi][2*(sizeof DWORD)], [edi][2*(sizeof DWORD)], addr acNumber
invoke BigNumToString, [edi][3*(sizeof DWORD)], addr acNumber
invoke wsprintf, addr acAdvapi, addr szFmtMod, addr szAdvapi32, [esi][3*(sizeof DWORD)], [edi][3*(sizeof DWORD)], addr acNumber
invoke wsprintf, addr acBuffer, $CTA0("Module:\t\tVirtual:\t\tPhysical:\n\n%s\n%s%s%s"), \
addr acThis, addr acKernel, addr acUser, addr acAdvapi
assume esi:nothing
assume edi:nothing
invoke MessageBox, NULL, addr acBuffer, $CTA0("Modules Base Address"), MB_OK + MB_ICONINFORMATION
.else
invoke MessageBox, NULL, $CTA0("Can't send control code to device."), NULL, MB_OK + MB_ICONSTOP
.endif
; Driver will receive IRP of type IRP_MJ_CLOSE
invoke CloseHandle, hDevice
.else
invoke MessageBox, NULL, $CTA0("Device is not present."), NULL, MB_ICONSTOP
.endif
; DriverUnload proc in our driver will be called
invoke ControlService, hService, SERVICE_CONTROL_STOP, addr _ss
.else
invoke MessageBox, NULL, $CTA0("Can't start driver."), NULL, MB_OK + MB_ICONSTOP
.endif
invoke DeleteService, hService
invoke CloseServiceHandle, hService
.else
invoke MessageBox, NULL, $CTA0("Can't register driver."), NULL, MB_OK + MB_ICONSTOP
.endif
invoke CloseServiceHandle, hSCManager
.else
invoke MessageBox, NULL, $CTA0("Can't connect to Service Control Manager."), NULL, MB_OK + MB_ICONSTOP
.endif
invoke ExitProcess, 0
start endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end start
.model flat, stdcall
option casemap:none
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; I N C L U D E F I L E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
include windows.inc
include kernel32.inc
include user32.inc
include advapi32.inc
includelib kernel32.lib
includelib user32.lib
includelib advapi32.lib
include winioctl.inc
include D:\RadASM\masm32\Macros\Strings.mac
include VirtToPhys.Inc
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; BigNumToString
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
BigNumToString proc uNum:UINT, pacBuf:LPSTR
; This function accepts a number and converts it to a
; string, inserting separators where appropriate.
local acNum[32]:CHAR
local nf:NUMBERFMT
invoke wsprintf, addr acNum, $CTA0("%u"), uNum
and nf.NumDigits, 0
and nf.LeadingZero, FALSE
mov nf.Grouping, 3
mov nf.lpDecimalSep, $CTA0(".")
mov nf.lpThousandSep, $CTA0(" ")
and nf.NegativeOrder, 0
invoke GetNumberFormat, LOCALE_USER_DEFAULT, 0, addr acNum, addr nf, pacBuf, 32
ret
BigNumToString endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; start
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
start proc uses esi edi
local hSCManager:HANDLE
local hService:HANDLE
local acModulePath[MAX_PATH]:CHAR
local _ss:SERVICE_STATUS
local hDevice:HANDLE
local adwInBuffer[NUM_DATA_ENTRY]:DWORD
local adwOutBuffer[NUM_DATA_ENTRY]:DWORD
local dwBytesReturned:DWORD
local acBuffer[256+64]:CHAR
local acThis[64]:CHAR
local acKernel[64]:CHAR
local acUser[64]:CHAR
local acAdvapi[64]:CHAR
local acNumber[32]:CHAR
; Open a handle to the SC Manager database
invoke OpenSCManager, NULL, NULL, SC_MANAGER_ALL_ACCESS
.if eax != NULL
mov hSCManager, eax
push eax
invoke GetFullPathName, $CTA0("VirtToPhys.sys"), sizeof acModulePath, addr acModulePath, esp
pop eax
; Install service
invoke CreateService, hSCManager, $CTA0("VirtToPhys"), $CTA0("Virtual To Physical Address Converter"), \
SERVICE_START + SERVICE_STOP + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr acModulePath, NULL, NULL, NULL, NULL, NULL
.if eax != NULL
mov hService, eax
; Driver's DriverEntry procedure will be called
invoke StartService, hService, 0, NULL
.if eax != 0
; Driver will receive I/O request packet (IRP) of type IRP_MJ_CREATE
invoke CreateFile, $CTA0("\\\\.\\slVirtToPhys"), GENERIC_READ + GENERIC_WRITE, \
0, NULL, OPEN_EXISTING, 0, NULL
.if eax != INVALID_HANDLE_VALUE
mov hDevice, eax
lea esi, adwInBuffer
assume esi:ptr DWORD
invoke GetModuleHandle, NULL
mov [esi][0*(sizeof DWORD)], eax
invoke GetModuleHandle, $CTA0("kernel32.dll", szKernel32)
mov [esi][1*(sizeof DWORD)], eax
invoke GetModuleHandle, $CTA0("user32.dll", szUser32)
mov [esi][2*(sizeof DWORD)], eax
invoke GetModuleHandle, $CTA0("advapi32.dll", szAdvapi32)
mov [esi][3*(sizeof DWORD)], eax
lea edi, adwOutBuffer
assume edi:ptr DWORD
; Driver will receive IRP of type IRP_MJ_DEVICE_CONTROL
invoke DeviceIoControl, hDevice, IOCTL_GET_PHYS_ADDRESS, esi, sizeof adwInBuffer, edi, sizeof adwOutBuffer, addr dwBytesReturned, NULL
.if ( eax != 0 ) && ( dwBytesReturned != 0 )
invoke GetModuleFileName, [esi][0*(sizeof DWORD)], addr acModulePath, sizeof acModulePath
lea ecx, acModulePath[eax-5]
.repeat
dec ecx
mov al, [ecx]
.until al == '\'
inc ecx
push ecx
CTA0 "%s \t%08Xh\t%08Xh ( %s )\n", szFmtMod
invoke BigNumToString, [edi][0*(sizeof DWORD)], addr acNumber
pop ecx
invoke wsprintf, addr acThis, addr szFmtMod, ecx, [esi][0*(sizeof DWORD)], [edi][0*(sizeof DWORD)], addr acNumber
invoke BigNumToString, [edi][1*(sizeof DWORD)], addr acNumber
invoke wsprintf, addr acKernel, addr szFmtMod, addr szKernel32, [esi][1*(sizeof DWORD)], [edi][1*(sizeof DWORD)], addr acNumber
invoke BigNumToString, [edi][2*(sizeof DWORD)], addr acNumber
invoke wsprintf, addr acUser, addr szFmtMod, addr szUser32, [esi][2*(sizeof DWORD)], [edi][2*(sizeof DWORD)], addr acNumber
invoke BigNumToString, [edi][3*(sizeof DWORD)], addr acNumber
invoke wsprintf, addr acAdvapi, addr szFmtMod, addr szAdvapi32, [esi][3*(sizeof DWORD)], [edi][3*(sizeof DWORD)], addr acNumber
invoke wsprintf, addr acBuffer, $CTA0("Module:\t\tVirtual:\t\tPhysical:\n\n%s\n%s%s%s"), \
addr acThis, addr acKernel, addr acUser, addr acAdvapi
assume esi:nothing
assume edi:nothing
invoke MessageBox, NULL, addr acBuffer, $CTA0("Modules Base Address"), MB_OK + MB_ICONINFORMATION
.else
invoke MessageBox, NULL, $CTA0("Can't send control code to device."), NULL, MB_OK + MB_ICONSTOP
.endif
; Driver will receive IRP of type IRP_MJ_CLOSE
invoke CloseHandle, hDevice
.else
invoke MessageBox, NULL, $CTA0("Device is not present."), NULL, MB_ICONSTOP
.endif
; DriverUnload proc in our driver will be called
invoke ControlService, hService, SERVICE_CONTROL_STOP, addr _ss
.else
invoke MessageBox, NULL, $CTA0("Can't start driver."), NULL, MB_OK + MB_ICONSTOP
.endif
invoke DeleteService, hService
invoke CloseServiceHandle, hService
.else
invoke MessageBox, NULL, $CTA0("Can't register driver."), NULL, MB_OK + MB_ICONSTOP
.endif
invoke CloseServiceHandle, hSCManager
.else
invoke MessageBox, NULL, $CTA0("Can't connect to Service Control Manager."), NULL, MB_OK + MB_ICONSTOP
.endif
invoke ExitProcess, 0
start endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end start
VirtToPhys.Inc
NUM_DATA_ENTRY equ 4
DATA_SIZE equ (sizeof DWORD) * NUM_DATA_ENTRY
IOCTL_GET_PHYS_ADDRESS equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)
DATA_SIZE equ (sizeof DWORD) * NUM_DATA_ENTRY
IOCTL_GET_PHYS_ADDRESS equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)
驱动部分:VirtToPhys.asm源码

;@echo off
;goto make
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; VirtToPhys - Kernel Mode Driver
;
; Translates virtual addres to physical address
;
; Written by Four-F (four-f@mail.ru)
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.386
.model flat, stdcall
option casemap:none
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; I N C L U D E F I L E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc
include \masm32\include\w2k\ntoskrnl.inc
include \masm32\include\w2k\w2kundoc.inc
includelib \masm32\lib\w2k\ntoskrnl.lib
include \masm32\Macros\Strings.mac
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; C O N S T A N T S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.const
NUM_DATA_ENTRY equ 4
DATA_SIZE equ (sizeof DWORD) * NUM_DATA_ENTRY
IOCTL_GET_PHYS_ADDRESS equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)
CCOUNTED_UNICODE_STRING "\\Device\\devVirtToPhys", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING "\\??\\slVirtToPhys", g_usSymbolicLinkName, 4
; May be you have to use this line instead of above one
; if your Windows NT version is <= 4.0
; It will work also under 2K & XP
;CCOUNTED_UNICODE_STRING "\\DosDevices\\slVirtToPhys", g_usSymbolicLinkName, 4
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; N O N D I S C A R D A B L E C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GetPhysicalAddress
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GetPhysicalAddress proc dwAddress:DWORD
; Converts virtual address in dwAddress to corresponding physical address
mov eax, dwAddress
mov ecx, eax
shr eax, 22 ; (Address >> 22) => Page Directory Index, PDI
shl eax, 2 ; * sizeof PDE = PDE offset
mov eax, [0C0300000h][eax] ; [Page Directory Base + PDE offset]
.if ( eax & (mask pde4kValid) ) ; .if ( eax & 01y )
; PDE is valid
.if !( eax & (mask pde4kLargePage) ) ; .if ( eax & 010000000y )
; small page (4kB)
mov eax, ecx
; (Address >> 12) * sizeof PTE => PTE offset
shr eax, 10
and eax, 1111111111111111111100y
add eax, 0C0000000h ; add Page Table Array Base
mov eax, [eax] ; fetch PTE
.if eax & (mask pteValid) ; .if ( eax & 01y )
; PTE is valid
and eax, mask ptePageFrameNumber ; mask PFN (and eax, 11111111111111111111000000000000y)
; We actually don't need these two lines
; because of module base is always page aligned
and ecx, 00000000000000000000111111111111y ; Byte Index
add eax, ecx ; add byte offset to physical address
.else
xor eax, eax ; error
.endif
.else
; large page (4mB)
and eax, mask pde4mPageFrameNumber ; mask PFN (and eax, 11111111110000000000000000000000y)
and ecx, 00000000001111111111111111111111y ; Byte Index
add eax, ecx ; add byte offset to physical address
.endif
.else
xor eax, eax ; error
.endif
ret
GetPhysicalAddress endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DispatchCreateClose
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DispatchCreateClose proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
; CreateFile was called, to get device handle
; CloseHandle was called, to close device handle
; In both cases we are in user process context here
mov eax, pIrp
assume eax:ptr _IRP
mov [eax].IoStatus.Status, STATUS_SUCCESS
and [eax].IoStatus.Information, 0
assume eax:nothing
fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
mov eax, STATUS_SUCCESS
ret
DispatchCreateClose endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DispatchControl
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DispatchControl proc uses esi edi ebx pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
; DeviceIoControl was called
; We are in user process context here
local status:NTSTATUS
local dwBytesReturned:DWORD
and dwBytesReturned, 0
mov esi, pIrp
assume esi:ptr _IRP
IoGetCurrentIrpStackLocation esi
mov edi, eax
assume edi:ptr IO_STACK_LOCATION
.if [edi].Parameters. == IOCTL_GET_PHYS_ADDRESS
mov status, STATUS_BUFFER_TOO_SMALL
.if ( [edi].Parameters.DeviceIoControl.OutputBufferLength >= DATA_SIZE )
.if ( [edi].Parameters.DeviceIoControl.InputBufferLength >= DATA_SIZE )
mov edi, [esi].AssociatedIrp.SystemBuffer
assume edi:ptr DWORD
xor ebx, ebx
.while ebx < NUM_DATA_ENTRY
; Change proc name to MmGetPhysicalAddress
; if you want to ask kernel to do all job for you
invoke GetPhysicalAddress, [edi][ebx*(sizeof DWORD)]
mov [edi][ebx*(sizeof DWORD)], eax
inc ebx
.endw
mov dwBytesReturned, DATA_SIZE
mov status, STATUS_SUCCESS
.endif
.endif
.else
mov status, STATUS_INVALID_DEVICE_REQUEST
.endif
assume edi:nothing
push status
pop [esi].IoStatus.Status
push dwBytesReturned
pop [esi].IoStatus.Information
assume esi:nothing
fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
mov eax, status
ret
DispatchControl endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DriverUnload
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DriverUnload proc pDriverObject:PDRIVER_OBJECT
; ControlService,,SERVICE_CONTROL_STOP was called
; We are in System process (pid = 8) context here
invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
mov eax, pDriverObject
invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject
ret
DriverUnload endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; D I S C A R D A B L E C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code INIT
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DriverEntry
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
; StartService was called
; We are in System process (pid = 8) context here
local status:NTSTATUS
local pDeviceObject:PDEVICE_OBJECT
mov status, STATUS_DEVICE_CONFIGURATION_ERROR
invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
.if eax == STATUS_SUCCESS
invoke IoCreateSymbolicLink, addr g_usSymbolicLinkName, addr g_usDeviceName
.if eax == STATUS_SUCCESS
mov eax, pDriverObject
assume eax:ptr DRIVER_OBJECT
mov [eax].DriverUnload, offset DriverUnload
mov [eax].MajorFunction[IRP_MJ_CREATE*(sizeof PVOID)], offset DispatchCreateClose
mov [eax].MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)], offset DispatchCreateClose
mov [eax].MajorFunction[IRP_MJ_DEVICE_CONTROL*(sizeof PVOID)], offset DispatchControl
assume eax:nothing
mov status, STATUS_SUCCESS
.else
invoke IoDeleteDevice, pDeviceObject
.endif
.endif
mov eax, status
ret
DriverEntry endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end DriverEntry
:make
set drv=VirtToPhys
:makerc
if exist rsrc.obj goto final
\masm32\bin\rc /v rsrc.rc
\masm32\bin\cvtres /machine:ix86 rsrc.res
if errorlevel 0 goto final
echo.
pause
exit
:final
if exist rsrc.res del rsrc.res
\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native /ignore:4078 %drv%.obj rsrc.obj
del %drv%.obj
move %drv%.sys ..
echo.
pause
;goto make
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; VirtToPhys - Kernel Mode Driver
;
; Translates virtual addres to physical address
;
; Written by Four-F (four-f@mail.ru)
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.386
.model flat, stdcall
option casemap:none
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; I N C L U D E F I L E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc
include \masm32\include\w2k\ntoskrnl.inc
include \masm32\include\w2k\w2kundoc.inc
includelib \masm32\lib\w2k\ntoskrnl.lib
include \masm32\Macros\Strings.mac
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; C O N S T A N T S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.const
NUM_DATA_ENTRY equ 4
DATA_SIZE equ (sizeof DWORD) * NUM_DATA_ENTRY
IOCTL_GET_PHYS_ADDRESS equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)
CCOUNTED_UNICODE_STRING "\\Device\\devVirtToPhys", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING "\\??\\slVirtToPhys", g_usSymbolicLinkName, 4
; May be you have to use this line instead of above one
; if your Windows NT version is <= 4.0
; It will work also under 2K & XP
;CCOUNTED_UNICODE_STRING "\\DosDevices\\slVirtToPhys", g_usSymbolicLinkName, 4
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; N O N D I S C A R D A B L E C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GetPhysicalAddress
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GetPhysicalAddress proc dwAddress:DWORD
; Converts virtual address in dwAddress to corresponding physical address
mov eax, dwAddress
mov ecx, eax
shr eax, 22 ; (Address >> 22) => Page Directory Index, PDI
shl eax, 2 ; * sizeof PDE = PDE offset
mov eax, [0C0300000h][eax] ; [Page Directory Base + PDE offset]
.if ( eax & (mask pde4kValid) ) ; .if ( eax & 01y )
; PDE is valid
.if !( eax & (mask pde4kLargePage) ) ; .if ( eax & 010000000y )
; small page (4kB)
mov eax, ecx
; (Address >> 12) * sizeof PTE => PTE offset
shr eax, 10
and eax, 1111111111111111111100y
add eax, 0C0000000h ; add Page Table Array Base
mov eax, [eax] ; fetch PTE
.if eax & (mask pteValid) ; .if ( eax & 01y )
; PTE is valid
and eax, mask ptePageFrameNumber ; mask PFN (and eax, 11111111111111111111000000000000y)
; We actually don't need these two lines
; because of module base is always page aligned
and ecx, 00000000000000000000111111111111y ; Byte Index
add eax, ecx ; add byte offset to physical address
.else
xor eax, eax ; error
.endif
.else
; large page (4mB)
and eax, mask pde4mPageFrameNumber ; mask PFN (and eax, 11111111110000000000000000000000y)
and ecx, 00000000001111111111111111111111y ; Byte Index
add eax, ecx ; add byte offset to physical address
.endif
.else
xor eax, eax ; error
.endif
ret
GetPhysicalAddress endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DispatchCreateClose
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DispatchCreateClose proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
; CreateFile was called, to get device handle
; CloseHandle was called, to close device handle
; In both cases we are in user process context here
mov eax, pIrp
assume eax:ptr _IRP
mov [eax].IoStatus.Status, STATUS_SUCCESS
and [eax].IoStatus.Information, 0
assume eax:nothing
fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
mov eax, STATUS_SUCCESS
ret
DispatchCreateClose endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DispatchControl
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DispatchControl proc uses esi edi ebx pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
; DeviceIoControl was called
; We are in user process context here
local status:NTSTATUS
local dwBytesReturned:DWORD
and dwBytesReturned, 0
mov esi, pIrp
assume esi:ptr _IRP
IoGetCurrentIrpStackLocation esi
mov edi, eax
assume edi:ptr IO_STACK_LOCATION
.if [edi].Parameters. == IOCTL_GET_PHYS_ADDRESS
mov status, STATUS_BUFFER_TOO_SMALL
.if ( [edi].Parameters.DeviceIoControl.OutputBufferLength >= DATA_SIZE )
.if ( [edi].Parameters.DeviceIoControl.InputBufferLength >= DATA_SIZE )
mov edi, [esi].AssociatedIrp.SystemBuffer
assume edi:ptr DWORD
xor ebx, ebx
.while ebx < NUM_DATA_ENTRY
; Change proc name to MmGetPhysicalAddress
; if you want to ask kernel to do all job for you
invoke GetPhysicalAddress, [edi][ebx*(sizeof DWORD)]
mov [edi][ebx*(sizeof DWORD)], eax
inc ebx
.endw
mov dwBytesReturned, DATA_SIZE
mov status, STATUS_SUCCESS
.endif
.endif
.else
mov status, STATUS_INVALID_DEVICE_REQUEST
.endif
assume edi:nothing
push status
pop [esi].IoStatus.Status
push dwBytesReturned
pop [esi].IoStatus.Information
assume esi:nothing
fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
mov eax, status
ret
DispatchControl endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DriverUnload
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DriverUnload proc pDriverObject:PDRIVER_OBJECT
; ControlService,,SERVICE_CONTROL_STOP was called
; We are in System process (pid = 8) context here
invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
mov eax, pDriverObject
invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject
ret
DriverUnload endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; D I S C A R D A B L E C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code INIT
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DriverEntry
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
; StartService was called
; We are in System process (pid = 8) context here
local status:NTSTATUS
local pDeviceObject:PDEVICE_OBJECT
mov status, STATUS_DEVICE_CONFIGURATION_ERROR
invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
.if eax == STATUS_SUCCESS
invoke IoCreateSymbolicLink, addr g_usSymbolicLinkName, addr g_usDeviceName
.if eax == STATUS_SUCCESS
mov eax, pDriverObject
assume eax:ptr DRIVER_OBJECT
mov [eax].DriverUnload, offset DriverUnload
mov [eax].MajorFunction[IRP_MJ_CREATE*(sizeof PVOID)], offset DispatchCreateClose
mov [eax].MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)], offset DispatchCreateClose
mov [eax].MajorFunction[IRP_MJ_DEVICE_CONTROL*(sizeof PVOID)], offset DispatchControl
assume eax:nothing
mov status, STATUS_SUCCESS
.else
invoke IoDeleteDevice, pDeviceObject
.endif
.endif
mov eax, status
ret
DriverEntry endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end DriverEntry
:make
set drv=VirtToPhys
:makerc
if exist rsrc.obj goto final
\masm32\bin\rc /v rsrc.rc
\masm32\bin\cvtres /machine:ix86 rsrc.res
if errorlevel 0 goto final
echo.
pause
exit
:final
if exist rsrc.res del rsrc.res
\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native /ignore:4078 %drv%.obj rsrc.obj
del %drv%.obj
move %drv%.sys ..
echo.
pause