当一个虚拟机创建时,VMM发送Create_VM控制消息给所有的VxD程序。当一个虚拟机退出时,它也发送VM_Terminate和VM_Terminate2消息给所有的VxD程序。
我们的工作很简单:在设备控制程序里处理Create_VM and VM_Terminate2消息。
当我们的VxD程序收到这两个控制消息时,它在屏幕上弹出一个消息框。
当VxD程序收到Create_VM或者 VM_Terminate2消息时,该虚拟机的句柄保存在ebx中。一个虚拟记的句柄可以看作它的唯一的ID。
每一个虚拟机都有它自己唯一的ID(虚拟机句柄)。你可以像使用进程ID一样使用虚拟机ID:调用函数时,把它当作参数传送。
更进一步的来看,一个虚拟机句柄实际上是一个指向虚拟机控制块(VMCB)的32位线性地址。
一个虚拟机控制块是一个包括了许多关于该虚拟机的重要属性的结构。它的定义如下:
CB_S STRUC CB_VM_STATUS DD ? CB_HIGH_LINEAR DD ? CB_CLIENT_POINTER DD ? CB_VMID DD ? CB_SIGNATURE DD ? CB_S ENDS
.386P INCLUDE VMM.INC INCLUDE SHELL.INC DECLARE_VIRTUAL_DEVICE MESSAGE,1,0, MESSAGE_CONTROL, UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER Begin_control_dispatch MESSAGE Control_Dispatch Create_VM, OnVMCreate Control_Dispatch VM_Terminate2, OnVMClose End_control_dispatch MESSAGE VxD_PAGEABLE_DATA_SEG MSGTITLE DB "VXD MESSAGEBOX",0 VMCREATED DB "A VM IS CREATED",0 VMDESTROYED DB "A VM IS DESTROYED",0 VxD_PAGEABLE_DATA_ENDS VxD_PAGEABLE_CODE_SEG BeginProc OnVMCreate MOV ECX, OFFSET32 VMCREATED COMMONCODE: VMMCall Get_sys_vm_handle MOV EAX,MB_OK+MB_ICONEXCLAMATION MOV EDI, OFFSET32 MSGTITLE XOR ESI,ESI XOR EDX,EDX VxDCall SHELL_Message RET EndProc OnVMCreate BeginProc OnVMClose MOV ECX,OFFSET32 VMDESTROYED JMP COMMONCODE EndProc OnVMClose VxD_PAGEABLE_CODE_ENDS END 分析: Begin_control_dispatch MESSAGE Control_Dispatch Create_VM, OnVMCreate Control_Dispatch VM_Terminate2, OnVMClose End_control_dispatch MESSAGE 此VxD程序处理两个控制消息,Create_VM和VM_Terminate2当收到Create_VM 控制消息时,它调用OnVMCreate函数。当收到VM_Terminate2 消息时,它调用 OnVMClose 函数。 VxD_PAGEABLE_DATA_SEG MSGTITLE DB "VXD MESSAGEBOX",0 VMCREATED DB "A VM IS CREATED",0 VMDESTROYED DB "A VM IS DESTROYED",0 VxD_PAGEABLE_DATA_ENDS 我们把这些数据放在可调页段里面。 BeginProc OnVMCreate MOV ECX, OFFSET32 VMCREATED COMMONCODE: VMMCall Get_sys_vm_handle MOV EAX,MB_OK+MB_ICONEXCLAMATION MOV EDI, OFFSET32 MSGTITLE XOR ESI,ESI XOR EDX,EDX VxDCall SHELL_Message RET EndProc OnVMCreate我们用BeginProc和 EndProc宏来创建OnVMCreate。OnVMCreate函数把调用SHELL_Message服务所需要的参数放到寄存器里面去。
BeginProc OnVMClose MOV ECX,OFFSET32 VMDESTROYED JMP COMMONCODE EndProc OnVMCloseOnVMCloseOnVMClose函数本身是很简单的。因为它要使用的代码和OnVMCreate相同,所以它在用另一个消息的地址初始化ecx后,就转到OnVMCreate中的代码去了。
VxD MESSAGE SEGMENTS _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 MESSAGE_DDB @1汇编过程:
ml -coff -c -Cx -DMASM6 -DBLD_COFF -DIS_32 message.asm link -VxD -def:message.def message.objVxD 的安装:
device=message.VxD