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

我们可以从SthVxD.c中看到CVxD_Dynamic_Init和CVxD_Dynamic_Exit这两个函数的定义。

ifdef _VxD_SERVICES

extrn _CVxD_Get_Version:near

endif

extrn _CVxD_V86API@12:near

extrn _CVxD_PMAPI@12:near

extrn C EnableHlt: dword

BeginProc CVxD_Control

Control_Dispatch SYS_DYNAMIC_DEVICE_INIT,

CVxD_Dynamic_Init, sCall

Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT,

CVxD_Dynamic_Exit, sCall

Control_Dispatch W32_DEVICEIOCONTROL,

CVxD_W32_DeviceIOControl,

sCall, <ebp, ecx, ebx, edx, esi>

clc

ret

EndProc CVxD_Contro

这是一段消息处理函数。

当VxD初始化时,发生SYS_DYNAMIC_DEVICE_INIT的消息而转入CVxD_Dynamic_Init函数中进行处理。

W32_DEVICEIOCONTROL是宏来定义的,设备控制程序CVxD_W32_DeviceIOControl,<ebp, ecx, ebx, edx, esi>是调用函数时用来传递参数的寄存器的名字。CVxD_W32_DeviceIOControl是留给应用程序的接口函数。当VxD的应用运行后,它和VxD进行数据交换就通过此函数来实现。因为它是用汇编编写的,所以,所有的参数都使用寄存器来传递。

 接下来可以看见三个函数

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; 内核空闲(IDLE)时调用此函数

;;

;; 使用HLT指令可以降低CPU的温度

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BeginProc _IDLEHandleProc

mov eax,[EnableHlt]

test eax,eax

jnz NEXT  ;查看EnableHlt是否为真,当EnableHlt为真时

;(即允许用降温功能)转入NEXT

;当EnableHlt为假时,清去零标志位,返回系统中。

stc

ret

NEXT:

sti ;必须打开中断, 如果没有打开中断,CPU就不能响应中断,

;就会死机。当中断打开时,当运行HLT指令后,

;机器一直停止直到外部有一个中断。

;例如敲键或移动鼠标时,当中断处理写成后,

;会从下一条指令开始执行,就不会死在HLT指令处。

hlt ;CPU停机,停机就是使得CPU不工作,

;当CPU不工作时,CPU的功耗就很小,所以能降低温度

stc ;当有事件产生时,清去零标志位,

;返回系统中去处理其程序;

ret

EndProc _IDLEHandleProc

内核空闲(IDLE)时,调用_IDLEHandleProc函数,通过HLT指令达到降温

的目的。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; 安装内核空闲(IDLE)时调用的函数

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BeginProc _InstallIDLEProc

push esi

lea esi,[_IDLEHandleProc]

VMMCall Call_When_Idle

pop esi

mov eax,0

setnc al

ret

EndProc _InstallIDLEProc

_InstallIDLEProc函数是在SthVxD.c的CVxD_Dynamic_Init(void)的函数中

被调用的,当它被装入后,VMM空闲时,就自动地调用函数

_IDLEHandleProc。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; 取消安装内核空闲(IDLE)时调用的函数

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BeginProc _UnInstallIDLEProc

push esi

lea esi,[_IDLEHandleProc]

VMMCall Cancel_Call_When_Idle

pop esi

mov eax,0

setnc al

ret

EndProc _UnInstallIDLEProc

_UnInstallIDLEProc函数和_InstallIDLEProc函数一样,也是在SthVxD.c中被CVxD_Dynamic_Exit(void)函数调用的。它的作用是去掉VMM注册的空闲函数。

;**************************************************

; V86模式调用的入口

;

; 把调用转变成对C函数的调用, 以便于开发功能强大的处理能力

;

;**************************************************

BeginProc CVxD_V86

scall CVxD_V86API,

<[ebp].Client_EAX, [ebp].Client_EBX, [ebp].Client_ECX>

mov [ebp].Client_EAX,eax ; put return code

ret

EndProc CVxD_V86

;**************************************************

; 保护模式调用的入口

;

; 把调用转变成对C函数的调用, 以便于开发功能强大的处理能力

;**************************************************

BeginProc CVxD_PM

scall CVxD_PMAPI,

<[ebp].Client_EAX, [ebp].Client_EBX, [ebp].Client_ECX>

mov [ebp].Client_EAX,eax

ret

EndProc CVxD_PM

VxD_LOCKED_CODE_ENDS

以上CVxD_V86和CVxD_PM两个函数都在SthVxD.c中定义。它们是V86模式和保护模式调用的入口,其实,它们的代码分别为CVxD_V86API和CVxD_PMAPI。此处只有函数定义,没有具体的实现功能。

VxD不光可以给WIN32位程序调用,WIN16和DOS程序都可以调用VxD提供的功能,它们都通过中断2FH来调用,并设置相应的参数。保护模式与此也是一样的,不过要用到VxD的号码。

;*************************************************;

; 不是动态的VxD时,在Window启动时会被实模式调用

;

;**************************************************

VxD_REAL_INIT_SEG

BeginProc CVxD_Real_Init

xor bx, bx

xor si, si

xor edx, edx

mov ax, Device_Load_Ok

ret

EndProc CVxD_Real_Init

VxD_REAL_INIT_ENDS

END CVxD_Real_Init

以上是一段实模式的初始化调用的函数,主要是用在Windows 9x启动时。当Windows 9x启动时,就会调用到这个函数。这是一个实模式代码,可以看到代码段和寄存器是不同的。这不过是一个框架程序,它会将对汇编的调用全部转变成对C的调用。这样就很方便开发程序。

相关推荐
上弦月-编程7 小时前
递归实现C语言菱形图案打印
c语言
Mrlxl.cn7 小时前
计算机网络——网络层
c语言·数据结构·计算机网络·考研
叶子野格9 小时前
《C语言学习:指针》12
c语言·开发语言·c++·学习·visual studio
一口Linux10 小时前
Linux C编程 | 从0实现telnet获取程序终端控制权
linux·运维·c语言
Mrlxl.cn10 小时前
计算机网络——传输层
c语言·计算机网络·考研·排序算法
aacd271910 小时前
C语言之预处理详解ヾ(•ω•`)o
c语言·学习
handler0111 小时前
Linux 进程探索:从 PCB 管理到 fork() 的写时拷贝
linux·c语言·c++·笔记·学习
宣宣猪的小花园.12 小时前
C语言重难点全解析:指针到内存四区
c语言·开发语言
老花眼猫13 小时前
三角函数绘制椭圆和椭圆旋转
c语言·经验分享·青少年编程·课程设计
代码中介商13 小时前
C语言操作符深度解析:从基础到高级应用
c语言·开发语言