Client_Reg_Struc STRUCVous pouvez voir qu'il y a deux groupes dans cette structure : Client_xxx et Client_Alt_xxx. Ceci exige une petite explication. Dans une VM (Machine Virtuelle) donnée, il peut y avoir deux liens d'exécution : le mode V86 et le mode-protégé. Si une interruption se produit pendant qu'un programme V86 est actif, le Client_xxx contiendra les images des registres du programme V86, le Client_Alt_xxx contiendra ceux du programme PM (en Mode-Protégé). Alternativement, si une interruption arrive quand le programme PM est actif, le Client_xxx contiendra les valeurs des registres du programme PM alors que le Client_Alt_xxx contiendra les valeurs des registres du programme V86. Le Client_resX est réservé et n'est pas employé.Client_EDI DD ?Client_Reg_Struc ENDS
Client_ESI DD ?
Client_EBP DD ?
Client_res0 DD ?
Client_EBX DD ?
Client_EDX DD ?
Client_ECX DD ?
Client_EAX DD ?
Client_Error DD ?
Client_EIP DD ?
Client_CS DW ?
Client_res1 DW ?
Client_EFlags DD ?
Client_ESP DD ?
Client_SS DW ?
Client_res2 DW ?
Client_ES DW ?
Client_res3 DW ?
Client_DS DW ?
Client_res4 DW ?
Client_FS DW ?
Client_res5 DW ?
Client_GS DW ?
Client_res6 DW ?
Client_Alt_EIP DD ?
Client_Alt_CS DW ?
Client_res7 DW ?
Client_Alt_EFlags DD ?
Client_Alt_ESP DD ?
Client_Alt_SS DW ?
Client_res8 DW ?
Client_Alt_ES DW ?
Client_res9 DW ?
Client_Alt_DS DW ?
Client_res10 DW ?
Client_Alt_FS DW ?
Client_res11 DW ?
Client_Alt_GS DW ?
Client_res12 DW ?
cb_s STRUCCB_Client_Pointer contient le Pointer sur la structure Client Register de Cette VM. Par exemple, vous pouvez obtenir le Pointer de la structure 'Client Register' de la Machine Virtuelle courante par le code suivant :
CB_VM_Status DD ?
CB_High_Linear DD ?
CB_Client_Pointer DD ?
CB_VMID DD ?
CB_Signature DD ?
cb_s ENDS
VMMCall Get_Cur_VM_Handle ; retourne le handle de la VM actuelle dans ebxMaintenant que nous comprenons le fonctionnement de la structure 'Client Register', nous pouvons passer à son utilisation. Nous emploierons la structure Client Register' pour passer les valeurs des registers à une interruption MS-DOS, à savoir, int 21h service 2h, qui est le service : Affichage des Caractères. Ce service MS-DOS prend comme paramètre le caractère qui doit être affiché dans dl. Si nous passons le caractère de sonnerie (07h) à ce service, il fera jouer un petit buzzer par le haut-parleur du PC.
assume ebx:ptr cb_s
mov ebp,[ebx+CB_Client_Pointer] ; pointe sur la structure Client Register
.386p
include \masm\include\vmm.inc
include \masm\include\vwin32.inc
include \masm\include\v86mmgr.incVxDName TEXTEQU <VXDINT>
ControlName TEXTEQU <VXDINT_Control>
VxDMajorVersion TEXTEQU <1>
VxDMinorVersion TEXTEQU <0>VxD_STATIC_DATA_SEG
VxD_STATIC_DATA_ENDSVXD_LOCKED_CODE_SEG
;----------------------------------------------------------------------------
; Souvenez-vous : le nom du VxD DOIT ÊTRE majuscule sinon il ne se Chargera/Déchargera pas
;----------------------------------------------------------------------------
DECLARE_VIRTUAL_DEVICE %VxDName,%VxDMajorVersion,%VxDMinorVersion,
\%ControlName,UNDEFINED_DEVICE_ID,UNDEFINED_INIT_ORDERBegin_control_dispatch %VxDName
Control_Dispatch W32_DEVICEIOCONTROL, OnDeviceIoControl
End_control_dispatch %VxDNameVXD_LOCKED_CODE_ENDS
VXD_PAGEABLE_CODE_SEG
BeginProc OnDeviceIoControl
assume esi:ptr DIOCParams
.if [esi].dwIoControlCode==1
Push_Client_State
VMMCall Begin_Nest_V86_Exec
assume ebp:ptr Client_Byte_Reg_Struc
mov [ebp].Client_dl,7
mov [ebp].Client_ah,2
mov eax,21h
VMMCall Exec_Int
VMMCall End_Nest_Exec
Pop_Client_State
EndI:
.endif
xor eax,eax
ret
EndProc OnDeviceIoControl
VXD_PAGEABLE_CODE_ENDSend
Push_Client_StateIl n'y a pas grand chose à analyser. Quand le VxD reçoit le message DeviceIoControl, ebp controle déjà la structure Client Register de la VM actuelle. Nous appelons la macro Push_Client_State pour sauvegarder l'état actuel du Client Registers (la totalité des registres) sur la pile. Nous rétablissons par la suite le Client Register grâce à Pop_Client_State.
VMMCall Begin_Nest_V86_Execmarque le début du bloc d'exécution emboîté en appelant Begin_Nest_V86_Exec.
assume ebp:ptr Client_Byte_Reg_Strucmodifie les images des registres dl et ah dans la structure Client Register. Ces valeurs une fois changées seront employées par l'interruption.
mov [ebp].Client_dl,7
mov [ebp].Client_ah,2
mov eax,21hExec_Int attend le numéro de l'interruption dans eax. Nous voulons nous servir de l'int 21h. Alors nous appelons Exec_Int pour Simuler l'interruption.
VMMCall Exec_Int
VMMCall End_Nest_ExecUne fois que Exec_Int retourne, nous terminons l'exécution du bloque emboîté et rétablissons les valeurs sauvegardées sur la pile du Client Register.
Pop_Client_State