VxD

部署运行你感兴趣的模型镜像

VxD 程序设计入门

We 我们在上一节学会了如何编写一个什么事也不做的VxD程序。在这一节里,我们要给它增加处理控制消息的功能。

VxD的初始化和结束

VxD程序分为两种:静态的和动态的。每种的加载方法都不同,接受到的初始化和结束的控制消息也不同。

静态VxD:

下列情况下,VMM加载一个静态VxD:
  • 一个实模式常驻程序通过调用中断2FH,1605H,来调用此VxD。
  • 此VxD在注册表中的如下位置有定义:
    • HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/VxD/key/StaticVxD=VxD带路径文件名
  • 此VxD在system.ini中的[386enh]行下有定义:[386enh] section:

    • device=VxD带路径文件名
在开发的时候,我建议你从system.ini载入VxD程序,因为这样如果你的VxD程序有错而导致Windows不能启动的话,你可以在Dos下修改system.ini,而如果你使用的注册表载入的办法,就无法修改了。
当VMM加载你的静态VxD程序时,你的VxD程序会按以下顺序接收到三个系统控制消息:
  • Sys_Critical_Init  VMM在转入到保护模式后,开放中断前发出这个控制消息。大多数VxD程序到不要用到这个消息,除非:
    • 你的VxD程序要接管一些其他VxD程序或者保护模式程序要用到的中断。既然你处理这个消息的时候这个中断还没有打开,你就可以确定在你接管这个中断的时候此中断不会被调用。
    • 你的VxD程序为其他的VxD程序提供了一些VxD服务。例如,一些在你的VxD程序后加载的VxD程序在处理Device_Init控制消息时需要调用一些你的VxD服务,既然Sys_Critical_Init 控制消息在Device_Init消息之前被发送,所以你应该在Sys_Critical_Init 消息发送时初始化你的程序。
    如果你要对这消息进行处理,你应该尽可能快的做完初始化工作,以免太长的执行时间导致的硬中断丢失。(记住:中断还没打开)
  • Device_Init VMM在开放中断后发送此信息。大多数VxD程序都在得到这个消息时初始化。因为中断都开放了,所以耗时的操作也可以在这里执行而不必怕会导致硬中断的丢失。你可以在这时进行初始化(如果你需要的话)。
  • Init_Complete 在所有的VxD程序处理完Device_Init 消息之后,VMM释放初始化段(ICODE和RCODE段类)之前,VMM发出这个控制消息。只有少数几个VxD要处理这个消息。
你的VxD程序在成功地初始化后,必须将返回标志清零,反之,必须在返回之前把返回标志设为出错信息。如果你的VxD不需要初始化,你就不必对这些消息进行处理。
当要结束静态VxD的时候,VMM发送如下的控制消息:
  • System_Exit2  当你的VxD程序收到这个消息,Windows95正在关闭系统,除了系统虚拟机所有其他虚拟机都已经退出了。尽管如此,CPU仍然处于保护模式下,在系统虚拟机上执行实模式编码也是安全的。在这时Kernel32.dll也已经被卸载了。
  • Sys_Critical_Exit2  当所有的VxD完成对System_Exit2的响应处理并且中断都被关闭后,你的VxD收到到这个消息。
许多VxD程序并不要响应这两个消息,除非你要为系统做转换到实模式的准备。要知道,当Window95关闭时,它进入到实模式。所以如果你的VxD程序对实模式影像做了一些会导致它不稳定的操作,它就需要在这时进行恢复。
你也许会感到奇怪:为什么这两个消息后面都跟着个“2" ”。这是因为:在VMM加载VxD程序的时候,它是按照初始化顺序值小的VxD先加载的顺序加载的,这样VxD程序就可以使用那些在它们之前加载的VxD程序提供的服务。例如,VxD2要用到VxD1中的服务,它就必须把它的初始化顺序值定义的比VxD小。加载的顺序是:
..... VxD1 ===>  VxD2 ===> VxD3 .....
那么卸载的时候,理所当然的是初始化顺序值大的VxD程序先被卸载,这样他们仍然可以使用比它们后加载的那些VxD程序提供的服务。如上面的例子,次序是:
.... VxD3 ===> VxD2 ===> VxD1.....
在上边的例子中,如果VxD2在初始化时调用了VxD1中的某些服务,那么卸载时它可能也要再次用到一些VxD1中的服务。System_Exit2Sys_Critical_Exit2反初始化顺序发送的。这表示,当VxD2接受到这些消息时,VxD1还没有被卸载,它仍可以调用VxD1的服务,而System_ExitSys_Critical_Exit消息不是按照反初始化顺序发送的。这意味着,你不能肯定你是否仍能调用在你之前加载的VxD提供的VxD服务。新一代的VxD程序不应该使用这些消息。
还有两种退出消息:
  • Device_Reboot_Notify2  告诉VxD程序VMM正在准备重新启动系统。这时候中断还是开放的。
  • Crit_Reboot_Notify2  告诉VxD程序VMM正在准备重新启动系统。这时候中断已经被关闭了。
到这里,你可以猜到还有Device_Reboot_NotifyCrit_Reboot_Notify 消息,但它们并不是像“2”版本的消息一样按反初始化顺序发送的。

动态VxD:

动态VxD在Windows9x里可以动态的被加载和卸载。这个特点在Window3.x下是没有的。动态VxD程序的主要作用是用来支持某些动态的硬件设备的重装,比如:即插即用设备。尽管如此,你可以从你的Win32程序中加载/卸载它,也可以把它看作是你的程序的一个到ring-0的扩展。
上一节我们提到的例子是一个静态的VxD,你可以把它转换成一个动态的VxD,只要在.def文件中VxD标记的后面加上关键字DYNAMIC
VxD   FIRSTVxD   DYNAMIC
这就是你把一个静态VxD转换成一个动态的VxD所要做的一切。
一个动态的VxD可以按以下的方法被加载:
  • 把它放到你的Windows目录下的/SYSTEM/IOSUBSYS目录中。在这个目录里的VxD会被输入输出监视器(ios)加载。这些VxD必须支持层设备驱动。所以用这种方法加载你的动态VxD并不是一个好办法。
  • 用VxD加载服务。 VxDLDR是一个可以加载动态VxD的静态VxD。你可以在其他VxD里面或者在16位代码里面调用它的服务。
  • 用Win32应用程序里的 CreateFile API。你在调用CreateFile时,你的动态VxD要以下面的格式填写:

    • //./VxD完整路径名


    例如,如果你要加载一个在当前目录下名为FirstVxD的动态VxD,你需要做如下的工作:

    .data
    VxDName db "//./FirstVxD.VxD",0
    ......
    .data?
    hDevice dd ?
    .....
    .code
    .....
    invoke CreateFile, addr VxDName,0,0,0,0, FILE_FLAG_DELETE_ON_CLOSE,0
    mov hDevice,eax
    ......
    invoke CloseHandle,hDevice
    ......
     

FILE_FLAG_DELETE_ON_CLOSE 这个标志用来说明该VxD在CreateFile返回的句柄关闭时被卸载。
如果你用CreateFile来加载一个动态VxD,那么这个动态VxD必须处理w32_DeviceIoControl 消息。当你的动态VxD第一次被CreateFile函数加载的时候,VWIN32 向你的VxD发出这个消息。你的VxD响应这个消息,返回时eax中的值必须为零。当应用程序调用DeviceIoControl API来与一个动态VxD通讯时,w32_DeviceIoControl消息也被发送。我们会在下一章讲到DeviceIoControl接口。
一个动态VxD在初始化时收到一个消息:
  • Sys_Dynamic_Device_Init
在结束时也收到一个控制消息:
  • Sys_Dynamic_Device_Exit
动态VxD不会收到Sys_Critical_Init, Device_InitInit_Complete控制消息,因为这些消息是在系统虚拟机初始化时发送的。除了这三个消息,动态VxD能收到所有的控制消息,只要它还在内存里。它可以做静态VxD可以做的所有事情。简单的说,动态VxD除了加载机制和接收到的初始化/结束消息跟静态VxD不同以外,它能做静态VxD所能做的一切。

其它系统控制消息

当VxD在内存里的时候,除了接收和初始化及结束相关的消息外,它还要收到许多别的控制消息。有些消息是关于虚拟机管理器的,有的是关于各种事件的。例如,关于虚拟机的消息如下:
  • Create_VM
  • VM_Critical_Init
  • VM_Suspend
  • VM_Resume
  • Close_VM_Notify
  • Destroy_VM
选择地响应你所感兴趣的消息是你自己的责任。

在VxD内创建函数

你要在一个段里面定义你的函数。你应该首先定义一个段,然后把你的函数放进去。例如,如果你要把你的函数放到一个可调页段中。你应该先定义一个可调页段,像这样:
VxD_PAGEABLE_CODE_SEG

(你的函数写在这里)

VxD_PAGEABLE_CODE_ENDS

你可以在一个段里面插入多个的函数。作为一个VxD编写者,你必须决定每一个函数应该放到哪个段里面去。如果你的函数必须时刻存在于内存中,如某些硬件中断处理程序,就把它们放到锁定

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>嗯,用户这次问的是VxD接口技术,看来ta对Windows底层驱动开发感兴趣。之前讨论网卡天线时用户表现出对硬件通信的深入关注,这次转向系统内核接口,可能是想了解驱动开发或系统优化。用户特意强调要参考之前的对话,但之前的内容与VxD并无直接关联,所以需要独立解释清楚这个历史技术。 VxD是90年代Windows 9x时代的产物,现代Windows早已用WDM和WDF替代它。用户可能遇到遗留系统维护需求,或是研究计算机发展史。考虑到技术深度,需要从三个维度展开:首先说明VxD的核心机制(虚拟化、ring0权限),然后解释其数据结构(设备描述块、服务表),最后对比现代替代方案。要特别注意避免过度技术术语,比如用“接管硬件操作”代替“硬件抽象层交互”。 用户没有暴露具体应用场景,但突然从无线硬件转向系统内核,猜测可能是想解决老旧工控设备的驱动兼容问题。因此补充了实模式调用和现代替代方案的内容,这对实际开发更有参考价值。最后生成的问题特意包含64位系统兼容性,因为这是VxD用户最常遇到的痛点。 需要警惕的是,中文资料常混淆VxD和WDM的概念,必须明确区分两者的架构代差。微软官方文档已弃用VxD内容,但OSR等专业论坛仍有讨论,回答时需标注技术过时警告。 </think> VxD(Virtual Device Driver)是Windows 9x/ME时代的**内核级设备驱动程序架构**,用于管理系统硬件资源和扩展操作系统功能。以下是核心解析: --- ### 一、VxD核心特性与工作原理 1. **设计目标** - **硬件虚拟化**:通过**VMM(虚拟机管理器)** 在Ring 0权限层直接控制硬件[^1] - **实时响应**:支持硬件中断处理(如键盘、磁盘I/O) - **系统扩展**:提供API供应用程序调用内核功能(如`VxDCall`指令) 2. **运行机制** ```c // VxD服务调用示例(汇编) mov eax, VxD_Service_ID // 服务号存入EAX mov edi, Device_ID // 设备标识符 VxDcall // 触发软中断进入内核 ``` - **动态加载**:通过`DEVICE=xxx.VXD`在`SYSTEM.INI`中声明[^2] - **内存驻留**:常驻系统地址空间0xC0000000-0xFFFFFFFF --- ### 二、关键数据结构 1. **设备控制块(DDB)** ```c struct DDB { DWORD DDB_Req_Device_Number; // 设备ID DWORD DDB_Dev_Major_Version; // 主版本号 DWORD DDB_Dev_Minor_Version; // 次版本号 DWORD DDB_Control_Proc; // 控制入口点 ... }; ``` - 定义驱动入口点(如初始化、中断处理) 2. **服务表(Service Table)** - 以函数指针数组形式导出VxD服务 - 应用程序通过`GetVxDServiceAddress`获取服务地址[^3] --- ### 三、与现代驱动架构对比 | **特性** | **VxD** | **WDM/WDF(现代驱动)** | |------------------|-----------------------------|-----------------------------| | **系统支持** | Windows 95/98/ME | Windows 2000及以上 | | **稳定性** | 易致蓝屏(无隔离机制) | 支持驱动隔离与沙箱 | | **开发复杂度** | 需汇编/低级C语言 | 高级语言(C++)框架支持 | | **电源管理** | 有限支持 | 完善ACPI支持 | > **注**:Windows XP后完全弃用VxD,改用**WDM(Windows Driver Model)** 和**WDF(Windows Driver Framework)** [^4]。 --- ### 四、典型应用场景 1. **硬件控制** - 直接操作端口(如`in/out`指令控制串口) - 中断钩子(键盘记录、鼠标事件捕获) 2. **系统监控** - 文件系统过滤(如早期杀毒软件) - 进程守护(通过`IFSMgr_InstallFileSystemApiHook`)[^3] 3. **性能优化** - 自定义磁盘缓存(绕过系统缓存机制) > **警告**:现代Windows禁用VxD加载,强行使用需关闭驱动签名强制(仅限测试环境)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值