.386p;--------------------------------------------------------------------------------------------------------------------------------
include vmm.inc
include vwin32.incDECLARE_VIRTUAL_DEVICE DYNAVXD,1,0, DYNAVXD_Control,\
UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDERBegin_control_dispatch DYNAVXD
Control_Dispatch w32_DeviceIoControl, OnDeviceIoControl
End_control_dispatch DYNAVXDVxD_PAGEABLE_CODE_SEG
BeginProc OnDeviceIoControl
assume esi:ptr DIOCParams
.if [esi].dwIoControlCode==DIOC_Open
xor eax,eax
.endif
ret
EndProc OnDeviceIoControl
VxD_PAGEABLE_CODE_ENDSend
VXD DYNAVXD DYNAMICSEGMENTS
_LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
_TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE
_TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE
_BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LMGTABLE CLASS 'MCODE' PRELOAD NONDISCARDABLE IOPL
_LMSGDATA CLASS 'MCODE' PRELOAD NONDISCARDABLE IOPL
_IMSGTABLE CLASS 'MCODE' PRELOAD DISCARDABLE IOPL
_IMSGDATA CLASS 'MCODE' PRELOAD DISCARDABLE IOPL
_ITEXT CLASS 'ICODE' DISCARDABLE
_IDATA CLASS 'ICODE' DISCARDABLE
_PTEXT CLASS 'PCODE' NONDISCARDABLE
_PMSGTABLE CLASS 'MCODE' NONDISCARDABLE IOPL
_PMSGDATA CLASS 'MCODE' NONDISCARDABLE IOPL
_PDATA CLASS 'PDATA' NONDISCARDABLE SHARED
_STEXT CLASS 'SCODE' RESIDENT
_SDATA CLASS 'SCODE' RESIDENT
_DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
_DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
_DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE
_RCODE CLASS 'RCODE'EXPORTS
DYNAVXD_DDB @1
; VxDLoader.asm
.386Segue il codice sorgente di un VxD dinamico che viene chiamato da vxdloader.asm
.model flat,stdcall
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib.data
AppName db "DeviceIoControl",0
VxDName db "\\.\shellmsg.vxd",0
Success db "Il VxD e' stato caricato con successo!",0
Failure db "Il VxD non e' stato caricato!",0
Unload db "Il VxD viene ora scaricato!",0
MsgTitle db "Esempio di DeviceIoControl",0
MsgText db "Sono stato chiamato da un VxD!",0
InBuffer dd offset MsgTitle
dd offset MsgText
.data?
hVxD dd ?
.code
start:
invoke CreateFile,addr VxDName,0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0
.if eax!=INVALID_HANDLE_VALUE
mov hVxD,eax
invoke MessageBox,NULL,addr Success,addr AppName,MB_OK+MB_ICONINFORMATION
invoke DeviceIoControl,hVxD,1,addr InBuffer,8,NULL,NULL,NULL,NULL
invoke CloseHandle,hVxD
invoke MessageBox,NULL,addr Unload,addr AppName,MB_OK+MB_ICONINFORMATION
.else
invoke MessageBox,NULL,addr Failure,NULL,MB_OK+MB_ICONERROR
.endif
invoke ExitProcess,NULL
end start
.386p
include vmm.inc
include vwin32.inc
include shell.incDECLARE_VIRTUAL_DEVICE SHELLMSG,1,0, SHELLMSG_Control,\
UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDERBegin_control_dispatch SHELLMSG
Control_Dispatch w32_DeviceIoControl, OnDeviceIoControl
End_control_dispatch SHELLMSGVxD_PAGEABLE_DATA_SEG
pTitle dd ?
pMessage dd ?
VxD_PAGEABLE_DATA_ENDSVxD_PAGEABLE_CODE_SEG
BeginProc OnDeviceIoControl
assume esi:ptr DIOCParams
.if [esi].dwIoControlCode==DIOC_Open
xor eax,eax
.elseif [esi].dwIoControlCode==1
mov edi,[esi].lpvInBuffer
;-----------------------------------
; copia il titolo del messaggio in un buffer
;-----------------------------------
VMMCall _lstrlen, <[edi]>
inc eax
push eax
VMMCall _HeapAllocate,<eax,HEAPZEROINIT>
mov pTitle,eax
pop eax
VMMCall _lstrcpyn,<pTitle,[edi],eax>
;-----------------------------------
; copia il testo del messaggio in un buffer
;-----------------------------------
VMMCall _lstrlen, <[edi+4]>
inc eax
push eax
VMMCall _HeapAllocate,<eax,HEAPZEROINIT>
mov pMessage,eax
pop eax
VMMCall _lstrcpyn,<pMessage,[edi+4],eax>
mov edi,pTitle
mov ecx,pMessage
mov eax,MB_OK
VMMCall Get_Sys_VM_Handle
VxDCall SHELL_sysmodal_Message
VMMCall _HeapFree,pTitle,0
VMMCall _HeapFree,pMessage,0
xor eax,eax
.endif
ret
EndProc OnDeviceIoControl
VxD_PAGEABLE_CODE_ENDSend
invoke CreateFile,addr VxDName,0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0Chiamiamo la CreateFile per caricare il VxD dinamico. Notate la flag FILE_FLAG_DELETE_ON_CLOSE . Questa flag indica a Windows di rilasciare il VxD quando l'handle del VxD ritornato dalla CreateFile viene chiuso. Se la CreateFile ha avuto successo, salviamo l'handle del VxD per un uso futuro.
.if eax!=INVALID_HANDLE_VALUE
mov hVxD,eax
....
.else
invoke MessageBox,NULL,addr Failure,NULL,MB_OK+MB_ICONERROR
.endif
invoke MessageBox,NULL,addr Success,addr AppName,MB_OK+MB_ICONINFORMATIONIl programma visualizza una message box quando il VxD viene caricato/scaricato. Esso chiama la DeviceIoControl con il dwIoControlCode impostato su 1 e passa l'indirizzo del InBuffer nel parametro lpInBuffer, e la dimensione del InBuffer (8) nel nInBufferSize. InBuffer e' un vettore dword con due elementi: ogni elemento e' l'indirizzo di una stringa di testo.
invoke DeviceIoControl,hVxD,1,addr InBuffer,8,NULL,NULL,NULL,NULL
invoke CloseHandle,hVxD
invoke MessageBox,NULL,addr Unload,addr AppName,MB_OK+MB_ICONINFORMATION
MsgTitle db "Esempio di DeviceIoControl",0Ora spostiamo la nostra attenzione sul VxD.
MsgText db "Sono stato chiamato da un VxD!",0
InBuffer dd offset MsgTitle
dd offset MsgText
BeginProc OnDeviceIoControlLa OnDeviceIoControl elabora il codice DIOC_Open ritornando 0 in eax.
assume esi:ptr DIOCParams
.if [esi].dwIoControlCode==DIOC_Open
xor eax,eax
.elseif [esi].dwIoControlCode==1Essa elabora inoltre il codice di controllo 1. La prima cosa che fa e' estrarre i dati nel lpvInBuffer che contiene le due dword passate nel lpInBuffer dell'API DeviceIoControl. Esso mette l'indirizzo del vettore di dword in edi per l'estrazione. La prima dword e' l'indirizzo del testo che sara' usato come titolo della message box. La seconda dword e' l'indirizzo del testo che sara' usato come testo della message box.
mov edi,[esi].lpvInBuffer
;-----------------------------------Esso calcola la lunghezza del titolo della message box chiamando il servizio _lstrlen della VMM. Il valore in eax ritornato dalla _lstrlen e' la lunghezza della stringa. Incrementiamo la lunghezza di 1 per tenere in considerazione il NULL conclusivo. Successivamente allochiamo un blocco di memoria largo abbastanza per contenere la stringa terminante con il NULL chiamando _HeapAllocate. La flag HEAPZEROINIT indica alla _HeapAllocate di azzerare il blocco di memoria. La _HeapAllocate ritorna l'indirizzo del blocco di memoria in eax. Quindi copiamo la stringa dall'indirizzo di memoria dell'applicazione win32 nel blocco di memoria che abbiamo allocato. Faremo la stessa operazione sulla stringa di testo che useremo come testo della message box.
; copia il titolo del messaggio in un buffer
;-----------------------------------
VMMCall _lstrlen, <[edi]>
inc eax
push eax
VMMCall _HeapAllocate,<eax,HEAPZEROINIT>
mov pTitle,eax
pop eax
VMMCall _lstrcpyn,<pTitle,[edi],eax>
mov edi,pTitleSalviamo gli indirizzi del titolo e del messaggio rispettivamente in edi e in ecx. Mettiamo la flag desiderata in eax, ottenendo l'handle della VM del sistema chiamando la Get_Sys_VM_handle e quindi la SHELL_Sysmodal_Message. La SHELL_SysModal_Message e' la versione modale di sistema della SHELL_Message. Essa congela il sistema finche' l'utente non risponde alla message box.
mov ecx,pMessage
mov eax,MB_OK
VMMCall Get_Sys_VM_Handle
VxDCall SHELL_sysmodal_Message
VMMCall _HeapFree,pTitle,0Quando la SHELL_Sysmodal_Message ritorna, possiamo liberare i blocchi di memoria chiamando _HeapFree.
VMMCall _HeapFree,pMessage,0
L'interfaccia DeviceIoControl rende ideale l'utilizzo di un VxD dinamico come una estensione di DLL a ring-0 per la vostra applicazione win32.
Traduzione italiana a cura di: fabio@privacy.nu
Torna alla pagina principale |