iczelion Vxd tut5

    技术2022-05-11  152

     

    VxD Example: MessageBox

    In the previous tutorials, you learn about mechanics of VxD programming. Now is the time to apply what you have learned. In this tutorial, we will create a simple static VxD which will display a message box whenever a VM is created/destroyed.

    Trapping VM creation and termination events

    When a VM is created, the VMM sends Create_VM control message to all VxDs. Also when a VM is terminated normally, it sends VM_Terminate and VM_Terminate2 to all VxDs. Our job is easy: Process Create_VM and VM_Terminate2 messages in our device control procedure. When our VxD receives those two control messages, it displays a message box on the screen. When our VxD receives Create_VM or VM_Terminate2 message, ebx contains the handle of the VM. A VM handle can be considered as the unique ID of the VM. Each VM has its unique ID (VM handle). You can use VM handle in the same manner as you use a process ID, by passing it as a parameter to the services that need it. On closer examination, a VM handle is actually the 32-bit linear address of the VM control block (VMCB). VM Control Block is a structure that contains several important items about the VM. It's defined as: 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  contains the bit flags that you can examine to find out about the state of the VM. CB_High_Linear  is the starting linear address of the mirror of the VM in the shared system region (above 3 GB). This concept requires an explanation. Under Windows 95, a VxD should not touch the V86 region directly instead the VMM maps the whole V86 region of every VM to the shared system region. When a VxD wants to modify/touch the memory in V86 region of the VM, it should do so to the high-linear area of the VM. For example, if the video memory is at 0B8000h and your VxD needs to touch that area, it should add the value in CB_High_Linear to 0B8000h and touch that area instead. The changes you made to the high-linear mirror will be reflected to the VM because both areas share the same page directory entry. Using the high-linear mirror is better in most situation because you can modify the VM even if it's not the current VM. CB_Client_Pointer contains the address of the client register structure. The client register structure contains the values of all registers of the interrupted V86 or protected mode application in the VM. If your VxD wants to know/modify the state of the V86 or PM application, it can modify the members of the client register structure and the changes will propagate to the application when the VMM resumes its execution. CB_VMID  The numeric identifer of the VM. The VMM assigns this number when it creates the VM. The system VM has the VMID of 1. CB_Signature contains the string "VMcb". This member is used in checking if the VM handle is valid.

    Displaying a MessageBox

    A VxD can use Virtual Shell Device services to communicate to the users. One such service we will use in this example is SHELL_Message. SHELL_Message is a register-based service. You pass parameters to it via registers. ebx  Handle of the VM that is responsible for the message eax  MessageBox flags. You can look them up in shell.inc. They start with MB_. ecx  32-bit linear address of the message to display edi  32-bit linear address of the message box caption esi  32-bit linear address of the callback function in case you need to know the response of the user to the message box. If you don't want to know, use NULL. edx  Reference data that will be passed to your callback (if you specify one in esi) On return, the carry flag is clear if the call is successful. The carry flag is set otherwise.

    The example

    .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

    Analysis:

    Begin_control_dispatch MESSAGE     Control_Dispatch Create_VM, OnVMCreate     Control_Dispatch VM_Terminate2, OnVMClose End_control_dispatch MESSAGE The VxD processes two control messages, Create_VM and VM_Terminate2. When Create_VM control message is received, it calls OnVMCreate procedure. And when it receives VM_Terminate2 message, it calls OnVMClose procedure. 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 We put the data in the pageable data segment. 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 OnVMCreate procedure is created using BeginProc and EndProc macros. It puts the parameters for SHELL_Message service into the registers. Since we want to display the message box in the system VM, we cannot use the value in ebx (which is the handle of the VM that is being created). Instead, we use a VMM service, Get_Sys_VM_Handle, to obtain the VM handle of the system VM. This service returns the VM handle in ebx. We put the addresses of the message and the caption into ecx and edi, respectively. We don't want to know the response of the user, so we zero out esi and edx. When all parameters are in the appropriate registers, we call SHELL_Message to display the message box. BeginProc OnVMClose     mov ecx,OFFSET32 VMDestroyed     jmp CommonCode EndProc OnVMClose OnVMCloseprocedure is simplicity in itself. Since it uses identical code as OnVMCreate, it initializes ecx with the address of the different message and then jumps to the code inside OnVMCreate.

    Module Definition File

    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

    Assembling process

     ml -coff -c -Cx  -DMASM6 -DBLD_COFF -DIS_32 message.asm

     link -vxd -def:message.def message.obj

    VxD Installation

    Put message.vxd in /system folder add the following line inside [386enh] section of system.ini device=message.vxd reboot your computer

    Testing the VxD

    Create a DOS box. You will see the message box, displaying the message, "A VM is created". When you close the DOS box, a message box appears with the message, "A VM is destroyed".
    [Iczelion's Win32 Assembly Homepage]

    最新回复(0)