一般而言,VXD与WIN32 应用程序通讯是使用DEVICEIOCONTROL,并且在NT中也是如此.
但WIN95与98提供了另外一种通讯方式.而且介绍VXD的书都或多或少提及,可是没有
具体的编程例子.下面我们来讨论这种方法.
Sleep(xx)是一常用函数,它是由Vmm32.vxD实现的,在经过一系列的中间代码之后
push xx ;xx 是立即数
push 00000009 ;高16位的0 是vmm32.vxd的ID号,底16位的9是此函数在VMM32.VXD
;中的编号.
call VXDCALL ;实现通讯的函数
这是书中对这种通讯方式的介绍.但如何编程,我们一步一步来.
1.系统使用的数据结构如下:
typedef struct { unsigned int No;//VXD提供的接口函数个数
unsigned int NULL;//为空,0
(??? *)fun1; //第一个函数的指针
unsigned int parameter1No;//第一个函数的参数个数
(??? *)fun2; //第二个函数的指针
unsigned int parameter2No;//第二个函数的参数个数
(??? *)fun3; //第三个函数的指针
unsigned int parameter3No;//第三个函数的参数个数
(??? *)fun4; //第四个函数的指针
unsigned int parameter4No;//第四个函数的参数个数
....
} win32service;
次数据结构的描述在VMM.INC中有.
2.使用的函数:
Register_Win32_Services按说明可以实现,但是参数的次序必须反过来,VC6的编译
器通不过,底版本可以通过.为了在任意版本中都可以,通过对此函数的跟踪,可以用内
嵌汇编的方法来实现.
在VMM.INC中查看DDB的结构描述,在DDB_VxD_Service_Table_Ptr;
DDB_VxD_Service_Table_Size;
之后是 DDB_Win32_Service_Table_Ptr;
DDB_Win32_Service_Table_Size;
Register..函数就是将win32service的指针放在此处.
因此,如何解决,大家就明白了
3.vxd的注意事项
一般vxd的???_DeviceID定义为UNDEFINED_DEVICE_ID
现在要在vtoolsd/include/vmm.h中定义一个值,例如为0x1234
4.如何调用:
现在情况类似于Sleep()的方式.
例如,vxd输出4个函数,欲调用第3个,而此函数有4个参数.
asm { push para1
push para2
push para3
push para4
push 12340002h
mov eax,bff713d4h
call eax
}
解释:1234H是此VXD的ID值,0002是被调用函数的编号(从0开始).
vxdcall的入口地址是0xbff713d4(无论是95或是98,地址不变).
现在,大家就可以直接调用vxd了.
更多驱动信息请到: http://www.qudong360.com