现在,可以看出 IOCTL 是 Win32 应用程序的一种后门,通过 IOCTL ,程序可以执行几乎所有的操作,而在此之前,这些操作仅允许特权模块执行 。当然,这需要首先编写一个特权级的模块,但是,一旦你拥有一个运行于系统中的 Spy 模块,一切就变得很简单了 。本书的两个目标是:详细展示如何编写内核模式的驱动程序以及一个可以完成很多让人惊异的事的驱动程序的示例代码 。
Windows 2000 的 Killer Device
在开始更高级的驱动程序工程之前,让我们先看看一个非常简单的驱动程序 。在第一章中,我介绍了 Windows 2000 的 Killer Device----w2k_kill.sys ,它被设计为引发一个良性的系统崩溃 。这个驱动程序并不需要 示例 3-3 中的大多数代码,因为它在有机会收到第一个 I/O 请求包之前就会使系统崩溃 。示例 3-7 给出了它的实现代码 。这里没有给出 w2k_kill.h 文件,因为它不不包含任何我们感兴趣的代码 。
示列 3-7 中的代码没有在 DriverEntry() 中执行初始化操作,因为系统会在 DriverEntry() 返回前就崩溃,所以没有必要进行这些额外的工作 。
#define _W2K_KILL_SYS_
#include
#include "w2k_kill.h"
// =================================================================
// DISCARDABLE FUNCTIONS
// =================================================================
NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject,
PUNICODE_STRING pusRegistryPath);
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#endif
// =================================================================
// DRIVER INITIALIZATION
// =================================================================
NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject,
PUNICODE_STRING pusRegistryPath)
{
return *((NTSTATUS *) 0);
}
// =================================================================
// END OF PROGRAM
// =================================================================
示列 3-7. 一个小巧的系统崩溃者
加载 / 卸载驱动程序
在完成一个内核驱动程序之后,你可能会想立即执行它 。怎么做呢?典型的做法是,在系统启动时加载驱动程序并执行之 。但这是不是就意味着我们每次更新驱动程序后,都必须重新启动系统呢?很幸运,这并不是必须的 。Windows 2000 的一个特色就是提供了一个 Win32 接口以允许在运行时加载或卸载驱动程序 。这是由服务控制管理器( Service Control Manager , SCM )完成的,下面的将详细介绍它的用法 。
服务控制管理器
“服务控制管理器”这个名字容易让人误解,因为它暗示该组件仅用于服务的管理 。服务( Service )是 Windows 2000 的一类非常强大的模块,它们在后台运行配套的程序,并且不需要用户交互(也就是说没有常见的用户界面或者控制台) 。换句话说,一个服务就是一个始终运行于系统中的 Win32 进程,即使没有用户登陆进来也如此 。尽管开发服务是一个令人兴奋的话题,但它并不属于本书的范畴 。想进一步了解服务的开发,请阅读 Windows Developer"s Journal ( WDJ )( Tomlinson 1996a )中 Paula Tomlinson 提供的非常不错的教程,以及随后在她的 WDJ 专栏 ----Understanding NT 中发表的有关服务的论文 。
SC 管理器(即服务控制管理器)可以控制服务和驱动程序 。为了简单起见,我在这里使用“服务”一词来代表 SC 管理器控制的所有对象,这包括严格意义上的服务和内核驱动程 。SC 的接口对于 Win32 程序是可用的,它由 Win32 子系统组件 ----advapi32.dll 提供,这个 DLL 还提供了很多有趣的 API 函数 。表 3-3 给出了用于加载、控制和卸载服务的 API 函数的名称,同时还给出了简单的描述 。在你可以加载或访问任何服务之前,你必须获取 SC 管理器的句柄(通过调用 OpenSCManager() ),在随后的讨论中,该句柄将被称为:管理器句柄 。CreateService() 和 OpenService() 都需要此句柄,而这些函数返回的句柄将被称为:服务句柄 。这种类型的句柄可以传递给需要引用一个服务的函数,如 ControlService() 、 DeleteService() 和 StartService()。这两种类型的 SC 句柄都通过 CloseServiceHandle() 函数来释放 。
推荐阅读
- 暗恋橘生淮南是在哪拍的
- 9 《Undocumented Windows 2000 Secrets》翻译 --- 第四章
- 奶酪陷阱大结局是什么
- 叶澜依结局
- 安装Microsoft Windows 2000 恢复控制台
- 4 《Undocumented Windows 2000 Secrets》翻译 --- 第三章
- 1 《Undocumented Windows 2000 Secrets》翻译 --- 第二章
- 浅谈非系统管理员用户本地登录Windows 2000 server
- 同床异梦秋瓷炫多少期
- Windows 2000进程细述