当前位置: 首页 > news >正文

第3章 Windows运行机理-3.1 内核分析(7)

(2)用Win32应用程序里的 CreateFile API。你在调用CreateFile时,动态VxD要以下面的格式填写:

\\.\VxD完整路径名

例如,如果要加载一个在当前目录下名为SthVxD的动态VxD,则需要做如下的工作,一般可以直接用C来编写主功能,然后和汇编进行连接:

hCVxD = CreateFile("\\\\.\\SthVxD", 0,0,0, CREATE_NEW,

FILE_FLAG_DELETE_ON_CLOSE, 0);

FILE_FLAG_DELETE_ON_CLOSE 这个标志用来说明该VxD在CreateFile返回的句柄关闭时被卸载。

如果用CreateFile来加载一个动态VxD,那么这个动态VxD必须处理w32_DeviceIoControl 消息。当动态VxD第一次被CreateFile函数加载的时候,WIN32向VxD发出这个消息。VxD响应这个消息,返回时,eax中的值必须为零。当应用程序调用DeviceIoControl API来与一个动态VxD通信时,w32_DeviceIoControl消息也被发送。

(3)当一个动态VxD在初始化时收到一个消息:

Sys_Dynamic_Device_Init

在结束时也收到一个控制消息:

Sys_Dynamic_Device_Exit

但动态VxD不会收到Sys_Critical_Init, Device_Init和Init_Complete控制消息,因为这些消息是在系统虚拟机初始化时发送的。除了这三个消息,动态VxD能收到所有的控制消息,只要它还在内存里。它可以做静态VxD可以做的所有事情。简单地说,动态VxD除了加载机制和接收到的初始化/结束消息跟静态VxD不同以外,它能做静态VxD所能做的一切。

当VxD在内存里的时候,除了接收和初始化及结束相关的消息外,它还要收到许多别的控制消息。这些消息有的是关于虚拟机管理器的,有的是关于各种事件的。例如,关于虚拟机的消息如下:

Create_VM

VM_Critical_Init

VM_Suspend

VM_Resume

Close_VM_Notify

Destroy_VM

选择地响应你所感兴趣的消息是你自己的责任。

(4)在VxD内创建函数

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

VxD_PAGEABLE_CODE_SEG

(你的函数写在这里)

VxD_PAGEABLE_CODE_ENDS

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

(5)要用BeginProc和EndProc 宏来定义函数:

BeginProc 函数名

EndProc 函数名

使用BeginProc 宏还可以加上一些参数,想了解这些细节,你可以看看Win95 DDK的文档。大多数时候,你只用填写函数的名字就够了。

因为BeginProc-EndProc 宏比proc-endp 指令的功能要强,所以你应该用BeginProc-EndProc宏来代替proc-endp指令

3. VxD编程约定

① 寄存器的使用

VxD程序可以使用所有的寄存器,FS和GS。但是在改动段寄存器的时候一定要小心。尤其是,一定不要改动CS和SS的内容,除非你对将发生的事情有绝对的把握。你可以使用DS和ES,但一定要记住在返回时恢复它们的初值。有两个特征位尤其重要:方向和中断特征位。不要长时间地屏蔽中断。还有,如果你要改动方向特征位,不要忘了在返回之前恢复它的初值。

② 数传递约定

VxD服务函数有两种调用约定:寄存器法和堆栈法。调用寄存器法服务函数时,通过各种寄存器来传递服务函数的参数。并且,在调用完成后,检查寄存器的值来看操作是否成功。不要总是以为在调用服务函数后,主要寄存器的值还和以前一样。当调用堆栈法服务函数时,你把要传递的参数压栈,在eax得到返回值。堆栈调用法的服务函数保存ebx,esi,edi和ebp的值。许多寄存器调用法服务函数都源于Windows 3.x的时代。

在大多数时候,可以通过名字来区分这两种服务函数。如果一个函数的名字以下划线开头,如_HeapAllocate,它就是一个堆栈法的服务函数(除了少数从VWIN32.VxD导出的函数)。如果函数名不是以下划线开头,它就是一个寄存器法的服务函数。

③ 调用VxD服务函数

可以通过VMMCall和VxDCall 宏来调用VMM和VxD服务。这两个宏的语法是一样的。当你要调用VMM导出的VxD服务函数时,用VMMCall。当要用其他VxD程序导出的VxD服务函数时,用VxDCall。

VMMCall service ; 调用寄存器法服务函数

VMMCall _service, <argument list> ; 调用堆栈法服务函数

当调用堆栈法服务时,必须用角括号把你的参数列括起来。

VMMCall _HeapAllocate, <<size mybuffer>, HeapLockedIfDP>

_HeapAllocate是一个堆栈法服务函数。它有两个参数,我们必须用角括号把它们括起来。由于第一个参数是一个宏,这个宏不能正确解释表达式,所以我们要再用一个角括号把它括起来。

4. VxD函数的调用方法

我们知道,VxD程序都有一个VxD的DDB列表,当VxD被加载时,DDB就会被装到Windows 95的系统内存里,Windows 95就是通过这个表把所有的VxD作为一个链表来进行管理的。Windows 95使用INT 20H来进行功能调用,凡是新VxD文件被装入内存的时候,都会产生一个INT 20H,在其后会紧跟着DDB的ID号码和服务函数号码。系统处理INT 20H时,就会去查找INT 20H的服务函数链表,当查找到函数ID和地址相同,就替换掉程序本身的指令。

VxD程序,包括VMM在内,通常要导出一系列的被别的VxD程序调用的公共函数,这些函数被称为VxD服务。调用这些服务的机制和在第三层级别运行的应用程序有很大的不同:每个导出VxD服务的VxD程序必须有一个惟一的ID,你可以从Microsoft得到一个这样的ID。这个ID是一个包含了一个VxD惟一的身份验证的16位的数字,例如:

UNDEFINED_DEVICE_ID EQU 00000H

VMM_DEVICE_ID EQU 00001H

DEBUG_DEVICE_ID EQU 00002H

VPICD_DEVICE_ID EQU 00003H

VDMAD_DEVICE_ID EQU 00004H

VTD_DEVICE_ID EQU 00005H

http://www.jsqmd.com/news/399194/

相关文章:

  • 2026年永真片市场概览:哪些品牌口碑与销量俱佳?永真片/生脉饮/养胃颗粒/抗衰老片/人参方,永真片品牌推荐排行榜单 - 品牌推荐师
  • 深入浅出Java线程池(二)
  • 本科生收藏!千笔,备受推崇的AI论文平台
  • vue+springboot校园学生健康监测数据管理系统的设计与实现
  • vue+springboot校园活动报名系统 场地预约系统
  • vue+springboot微信小程序 网上订餐配送系统
  • vue+springboot新农村信息平台建设——土地资源管理子系统
  • 浮点数在内存中的存储结构
  • [杂] 稍后再看
  • Kafka生态深化——Schema与Connect、CDC入湖的链路与一致性挑战
  • [杂] 网易云评论区评论烟之暗面
  • 研究生必看!圈粉无数的降AIGC软件 —— 千笔·降AIGC助手
  • 真空管市场2026新观察:这些厂商为何备受瞩目?液氩/真空管/液氧/制氮机/液氮/二氧化碳,真空管直销厂家找哪家 - 品牌推荐师
  • 京东e卡回收新思路,让闲置卡券“活”成现金流 - 京顺回收
  • 2026中低压管件生产新趋势,高压管件实力厂商盘点,管件/保温管道/工厂预制化管道/三通管件,高压管件供应商排行 - 品牌推荐师
  • 交稿前一晚!本科生必备的降AI率网站 —— 千笔·降AI率助手
  • 直接上结论:更贴合本科生的AI论文网站,千笔AI VS Checkjie!
  • 大模型推理引擎vLLM(9): vLLM 基本代码结构
  • 大模型推理引擎vLLM(10): vLLM 分布式推理源码结构解析
  • 大专数据可视化技术专业学习数据分析的价值
  • 高职统计与会计核算专业学数据分析的价值分析
  • Manim CE v0.20.0 发布:动画构建更丝滑,随机性终于“可控”了!
  • 2026年苏州可靠的家教机构怎么收费,家教/全托补习班/一对一家教试听课/上门家教/师范家教/全托冲刺,家教机构有哪些 - 品牌推荐师
  • k8s服务发现
  • Verify-in-the-Graph 利用交互式图表示增强实体消歧的复杂声明验证方法
  • nsq阅读(2)——diskqueue
  • golang sync包源码阅读
  • CausalMamba 面向时序谣言因果关系的可解释状态空间建模
  • 质数筛小记