; Программа чтения физического адреса по линейному. ; Этот динамический VxD можно загружать через DeviceIOControl и получать ; по указателю тип адресации, размер страницы, etc. ; Coded by Chingachguk. 2002. ; .586p include vmm.inc include vwin32.inc DECLARE_VIRTUAL_DEVICE PHY,1,0, PHY_Control,\ UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER Begin_control_dispatch PHY Control_Dispatch w32_DeviceIoControl, OnDeviceIoControl End_control_dispatch PHY ; Сегмент данных нашего VxD ; Структура параметров при вызове CallParams struc LinearAddr dd ? PhysAddr dd ? CallParams ends VxD_PAGEABLE_DATA_SEG Result dd ? ; Если будет ошибка, мы будем хранит тут 0FFFFFFFFh (-1). VxD_PAGEABLE_DATA_ENDS ; А вот наш сегмент кода. VxD_PAGEABLE_CODE_SEG BeginProc OnDeviceIoControl ; Сделаем так, чтобы esi был адресом переданной нам структуры - DIOCParams. ; Она состоит из одного поля размером dd - адрес, куда читаем что-то. assume esi:ptr DIOCParams .if [esi].dwIoControlCode==DIOC_Open ; Контрольное сообщение ?! xor eax,eax ; Надо отвечать: eax=0. ; А вот это уже серьезно. Это вызов из вин-приложения с конкретным заданием. ; Что это за задание - знаем только мы и тот, кто нас вызвал. .elseif [esi].dwIoControlCode==1 mov dword ptr Result,0FFFFFFFFh ; Установим флаг ошибки pushad ; На всякий случай сохраним все регистры, кроме сегментных - pushad pushfd ; Сохраним флаг направления. Видимо, это перестраховка. mov edi,[esi].lpvInBuffer mov edi,[edi] ; указатель на буфер, который нам передал win32-код ; Get physical base of Page Directory mov eax,CR3 and eax,1111111111111111111100000000000b mov ecx,[edi].LinearAddr shr ecx,22 shl ecx,2 ; Get Index in Page Directory (bits 22..31) add eax,ecx ; eax=phys addr in Page Directory call GetLinearAddr_Memory ; Get linear address by physical address jz @@PageDirectoryErr mov eax,[eax] ; ...and eax=physical address of Page Table and eax,1111111111111111111100000000000b mov ecx,[edi].LinearAddr shr ecx,12 and ecx,1111111111b shl ecx,2 ; Get Index in Page Table (bits 12..21) add eax,ecx ; Address in Page Table call GetLinearAddr_Memory ; Get linear address by physical address jz @@PageDirectoryErr mov eax,[eax] ; ...and eax=physical address of Page and eax,1111111111111111111100000000000b mov ecx,[edi].LinearAddr and ecx,111111111111b ; Get Index in Page (bits 0..11) add eax,ecx ; Get Physical Address ! mov [edi].PhysAddr,eax mov dword ptr Result,0h ; Сбросим флаг ошибки - все прошло нормально. @@PageDirectoryErr: popfd ; Восстановим флаги направления и т.д. - перестраховка ?! popad mov eax,dword ptr Result ; Вернем в eax флаг ошибки .endif ret EndProc OnDeviceIoControl GetLinearAddr_Memory proc ; Input: eax=phys addr Res: eax=linear or ZF is set ; Get linear address by physical address ; VMMCall _MapPhysToLinear, push 0h ; flags push 4h ; 4 bytes push eax ; PhysAddr int 20h ; Call VxD dw 006Ch ; 006Ch map physical address to linear address dw 0001h ; ID VMM add esp,3*4 ; C-call function cmp eax,0FFFFFFFFh ; 0FFFFFFFFh if not addressable ; eax = address of first byte ; Returns the linear address of the first byte in the specified range of ; physical addresses. Uses EAX, ECX, EDX and Flags. ret GetLinearAddr_Memory endp VxD_PAGEABLE_CODE_ENDS end