天天学驱动之小菜题一:示例源码编译成功后,失效~~
步骤如下:1. 示例地址:KmdKit\examples\simple\VirtToPhys 使用的是KmdKit的示例
2. 用RADASM 对VirtToPhys进行项目化 R3 为VirtToPhys.rap R0 为sys文件夹下VirtToPhys1.rap
3. 对程序进行编译,完成并且不报错
4.运行程序加载驱动并且通讯
问题如下:
程序未报错,无法获得实际物理地址.Physical全显示是0 按照书上示例应该会显示 80000H段的地址
希望得到的帮助:
希望论坛高手指导下,错误的步骤是在哪里
PS:附件已经上传,希望尽快得到解答.
VirtToPhys.rar
(12.5 KB)
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
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)
驱动部分: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