VxD例程:消息框(Vxd教程5)

原创 2000年09月05日 15:01:00
VxD例程:消息框

VxD例程:消息框

在上一节教程里,我们讲了编写一个VxD程序的方法。现在我们要学以致用。 在这一节里,我们要编写一个静态VxD,这个静态VxD在一个虚拟机创建或销毁时就会弹出一个消息框。
这里下载例子。

捕获虚拟机创建和结束事件

当一个虚拟机创建时,VMM发送Create_VM控制消息给所有的VxD程序。当一个虚拟机退出时,它也发送VM_TerminateVM_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
     
  • CB_VM_Status  包含了反映虚拟机状态的一些标志位。
  • CB_High_Linear 是一个指向在系统共享区(约3GB)的虚拟机镜像的一个线性地址。这个概念需要解释一下。在Window95下,一个VxD不能直接访问到V86区域,代替地,VMM把每个虚拟机的V86区域都映射到系统共享区。当一个VxD程序要访问或修改虚拟机中的V86区时,它就在虚拟机的高线性区域进行操作。例如,如果显存的地址是0B8000H,而你的VxD程序要访问这个区域。它就要把CB_High_Linear中的值上0B8000H,然后访问那个区域。你在高线性镜像区域所作的修改都会被保存到虚拟机中去,因为这两个区域共享一个页面目录入口。使用高线性镜像在它多数情况下非常有效,因为你甚至可以修改一个不是当前虚拟机的虚拟机。
  • CB_Client_Pointer 包含了客户寄存器结构的地址。一个客户寄存器结构包含了在一个虚拟机中被中断的V86或保护模式程序的所有寄存器的值。如果你的VxD程序要读取/改动V86或PM程序的状态,它可以改动客户寄存器结构里的值,当VMM返回执行该程序时,这些改动会被保存到程序里去。
  • CB_VMID  虚拟机的身份验证数字。当VMM创建一个虚拟机时,就给该虚拟机分配一个数字。系统虚拟机的VMID是1。
  • CB_Signature 包含字串“VMcb”。这个元素是用来检测虚拟机句柄是否有效的。

显示一个对话框

一个VxD程序可以通过Virtual Shell Device服务来同用户通讯。在这个例子里我们要用到其中的一个:SHELL_Message.
SHEll_Message是一个寄存器法的服务函数,通过寄存器来传送参数:
  • ebx  显示这个消息的虚拟机的句柄。
  • eax  消息框的标志位。你可以在shell.inc中查查它们的详细信息,它们都是以MB_开头的。
  • ecx  要显示的消息的32位线性地址。
  • edi  消息框的标题的32位线性地址。
  • esi  如果你要知道用户对你的消息框作的反应操作,就在这里填写返回函数的32位线性地址。如果你不想知道,就用NULL。
  • edx  用来传送你的返回函数所需要的参数(如果你在esi中填了这个函数的地址)。
返回后,如果调用成功,返回标志被清零,否则,返回标志被置位。

例子:

.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_VMVM_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
我们用BeginProcEndProc宏来创建OnVMCreate。OnVMCreate函数把调用SHELL_Message服务所需要的参数放到寄存器里面去。因为我们要在系统虚拟机上显示消息框,所以不能使用ebx中的值(ebx包含了在创建的虚拟机的句柄,而我们要的是系统虚拟机的句柄)。于是,我们用另一个VMM服务,Get_Sys_VM_Handle来得到系统虚拟机的虚拟机句柄。我们分别把消息的地址和消息框标题的地址放在ecx和edi里面。我们不需要知道客户的反应,所以我们把esi和edx置零。当每个参数都在相应的寄存器内后,我们就调用 SHELL_Message 来显示消息框。
BeginProc OnVMClose
    mov ecx,OFFSET32 VMDestroyed
    jmp CommonCode
EndProc OnVMClose
OnVMCloseOnVMClose函数本身是很简单的。因为它要使用的代码和OnVMCreate相同,所以它在用另一个消息的地址初始化ecx后,就转到OnVMCreate中的代码去了。

改变定义文件(.def)

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.obj

VxD 的安装:
  • 把message.VxD放到/system目录下。
  • 在system.ini文件里的[386enh]部分里加上如下的一行:
      device=message.VxD
  • 重启你的计算机。
  • 测试这个VxD:

    打开一dos窗口,你会看到弹出的消息框,显示“A VM is created."。当你关闭一个dos窗口,又会弹出一个消息框显示“A VM is destroyed"。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

    win32应用程序如何与vxd直接通讯

       一般而言,VXD与WIN32 应用程序通讯是使用DEVICEIOCONTROL,并且在NT中也是如此. 但WIN95与98提供了另外一种通讯方式.而且介绍VXD的书都或多或少提及,可是没有 具体...
    • pazo_100
    • pazo_100
    • 2007年11月06日 09:06
    • 223

    VxD编程入门教程

    一、Windows 95 DDK的安装        安装Windows 95 DDK一般需要先安装Win32 SDK,原因是Windows 95 DDK 需要Win32 SDK的16位资源编译器,但...
    • tianfeng
    • tianfeng
    • 2001年05月05日 15:36
    • 789

    iczelion Vxd tut9

    Virtual 8086 Memory Manager In the previous tutorial, you learn how to simulate V86 interrupt. Howev...
    • jimgreen
    • jimgreen
    • 2001年08月30日 12:06
    • 515

    VxD编程入门教程

    VxD编程入门教程作者:TBsoft--------------------------------------------------------------------------------一、...
    • lithe
    • lithe
    • 2005年01月13日 08:32
    • 1105

    winio全,包括资源,说明文档,帮助等等

    • 2012年04月13日 10:17
    • 195KB
    • 下载

    CIH V1.5 Source Code

    ; ****************************************************************************; *             The Vi...
    • TruthTracer
    • TruthTracer
    • 2006年06月21日 10:21
    • 1149

    Iczelion 的 Win32Asm VxD 汇编教程 (六)

    DeviceIoControl接口在这一节中我们将要关于学习动态VXD,特别是如何创建,加载和使用。点击这里下载例子VxD接口VxD总共提供了4种接口。l         VxD services  ...
    • kingzeus
    • kingzeus
    • 2002年02月14日 10:44
    • 500

    VxD编程入门教程

    一、Windows 95 DDK的安装 安装Windows 95 DDK一般需要先安装Win32 SDK,原因是Windows 95 DDK需要Win32 SDK的16位资源编译器,但是Win3...
    • playboy1
    • playboy1
    • 2011年10月18日 16:11
    • 200

    用 Delphi 编写 VxD 设备驱动程序(转)

    用 Delphi 编写 VxD 设备驱动程序(转)关键词:Delphi控件杂项作者:Emil Biserov(dinfo@mail.primorye.ru)(Russion) 英语翻译:Vitaly ...
    • ghj1976
    • ghj1976
    • 2000年12月21日 09:02
    • 1448

    (转载)反病毒引擎设计 --- 实时监控篇

    反病毒引擎设计之实时监控篇作者:NJUE    文章来源:安全焦点  2004年01月15日        编者按:绪论《反病毒引擎设计之虚拟机查毒篇》我们重点对虚拟机查毒进行了阐述。下面看看如何对病...
    • Kendiv
    • Kendiv
    • 2005年01月17日 19:15
    • 6807
    内容举报
    返回顶部
    收藏助手
    不良信息举报
    您举报文章:VxD例程:消息框(Vxd教程5)
    举报原因:
    原因补充:

    (最多只允许输入30个字)