引子
WRK 是微软于 2006 年针对教育和学术界开放的 Windows 内核的部分源码,WRK(Windows Research
Kernel)也就是 Windows 研究内核,在 WRK 中不仅仅只提供了 Windows 内核模块的部分代码,其还提供了编译
工具,也就是通过这个编译工具,你可以将你的 WRK 编译成一个 EXE 文件,也就是内核可执行模块,然后你可
以利用这个 EXE 文件来取代操作系统本身的内核,这样的话,下次开机的时候操作系统所加载的内核就是您编译
的那个 EXE 了。
工具软件
Intel x86 CPU;
VMware 6.5;
Windows Server 2003 SP1(用于测试 WRK 编译结果);
Windows 7(用来编译 WRK);
WRK 1.2 ;
概览 WRK
首先我们来找到当前 Windows 操作系统下的内核模块文件,所谓的内核模块文件呢,其实就可以看做是
Windows的内核,其由执行体和微内核组成,该文件名为 ntoskrnl.exe ,即一个二进制模块,该文件位于:
C:\Windows\System32 ;
而我们的 WRK 编译后所得的结果应该也是一个内核模块文件,也就是说我们编译所得的结果应该就是这个
ntoskrnl.exe ,当然编译后的名称是可以不同的,默认编译所得为 wrkx86.exe (这是 x86 环境下的默认编译
结果名称)
下面来分析 WRK 中目录结构:
首先来看WS03SP1HALS目录:
WS03SP1HALS 代表的意思即 Windows Server2003 SP1 HALS,也就是在 Windows Server 2003 SP1下的
HAL(硬件抽象层)。
在 Windows 操作系统中,HAL其实是一个独立的DLL(在这里你就可以简单的将 HAL 看做一个 DLL)
通过HAL可以实现隔离掉硬件的差异,也就是上层的模块无需考虑下层真实硬件之间的差异性,因为上层模块不
能够直接访问硬件,而是通过HAL 来访问硬件的,所以对于硬件的差异性,在 HAL 中即可以解决掉,而不需要
上层模块来解决,这样做的好处是很显然的,那就是我们的上层模块都是一样的,也就是当硬件改动时不需要
变,只要提供针对不同的硬件的HAL 即可以实现在不同的硬件上运转我们的上层模块。
由于我们的PC上的硬件不一致,所以必须有多个HAL,比如我的PC的处理器是Intel的,而你的PC 的处理
器是AMD 的,我的处理器为单核的,而你的处理器为四核的,那么这就会造成硬件上的不一致,为了解决这种不
一致呢,Windows 在打包的时候会打包多个HAL 进来,比如一个HAL 针对单核,一个HAL 针对多核,Windows
在安装的时候就会自动的识别出你的处理器是AMD 还是 Intel ,是多核还是单核处理器,然后Windows 就会自
动选择一个合适的HAL给你安装,同时,将HAL名字修改为HAL.DLL,而在WS03SP1HALS 目录下的也就是这
些个HAL .
比如我的PC 的处理器为Intel x86 系列的双核处理器,自然在安装 Windows 的时候,就会自
动选择合适的HAL ,比如halmps.dll 作为HAL之一,在安装 Windows 的时候会将这个HAL 复制进
系统盘,然后将halmps.dll 改名为 hal.dll(为了统一所以改名)
这样就可以得到我们下面看到的在 C:\Windows\System32\hal.dll 了。
再来看 Public 目录:
在这个目录下包含的是一些头文件,也就是 .h 文件,而且这些文件都是被各个组件所共享使用的,也就是公用的。
其中含有 ddk , internal 等等,其中 internal 表示为内部使用的,也就是内核自身需要使用到的头文件。
再来看Tools目录:
前面提到,WRK 中不仅仅包含了微软公开的关于 Windows 内核的部分源代码,还包括了用来编译这部分源代码的工具,而这些编译工具自然就在这个 Tools 目录下了。在后面我们编译这个 WRK 源代码的时候就会用到这个 Tools 目录下的工具了。
最后看Base目录,其中 Base 目录下的 ntos 目录为 Windows 内核模块的主目录:
下面就来逐一的介绍这些个目录中的文件的含义:
build | WRK 只公开了部分源代码,那些未公开的则以二进制目标代码的形式存在于这个目录下。 |
cache | 缓存管理器的实现的源文件。 |
config | 注册表的实现的源文件。 |
dbgk | 调试子系统的内核模式部分的源文件。 |
ex | 执行体层函数(内核堆 , 同步 , 定时器等)的源文件。 |
fsrtl | 文件系统运行库的源文件。 |
fstub | 文件系统引导接口。 |
io | I/O 管理器,不包括即插即用管理器和电源管理器部分。 |
ke | (微)内核,包括线程调度器,CPU 管理以及底层的同步语义 |
lpc | 本地过程调用 (LPC) 机制的实现。 |
mm | 内存管理器。 |
ob | 内核对象管理器。 |
perf | 内核的性能日志记录功能。 |
ps | 进程和线程。 |
se | 安全引用监视器。 |
wmi | Windows 管理规范。 |
inc | 仅适用于 NTOS 部分的包含文件。 |
raw | RAW 文件系统驱动程序的实现的源文件。 |
rtl | 内核运行时库支持。 |
init | 内核启动部分的代码。 |
vdm | 虚拟 DOS 机。 |
verifier | 驱动程序检验器。 |
编译 WRK
首先是设置 WRK 根目录下的 Tools 子目录中的 x86 子目录到Path 环境变量中,
首先在控制台下进入到 WRK 根目录下的 Base 目录下的 Ntos 目录下,
然后输入命令:nmake –nologo x86= ;(如果是 AMD 的 CPU 的话命令会有所不同,而且环境变量的设置也不同)
然后就开始编译整个 WRK 了
编译完成:
此时就可以在目录:WRK-v1.2\base\ntos\build 下面找到编译好的 EXE 文件了。至此编译完成。
加载 WRK 编译所得的内核模块
前面我们已经由 WRK 编译得到了内核可执行模块,下面我们就要让操作系统启动的时候加载上编译所得的这
个内核可执行模块。我们使用的环境是在 VMware 6.5 中安装好 Windows Server 2003 SP1.
首先,我们将由 WRK 编译所得的 wrkx86.exe 拷贝到虚拟机中,并且将这个文件放置到目录(也就是 ntoskrnl.exe 所在目录):
然后再在其系统安装目录下(一般为 C: 盘)下面找到boot.ini文件(默认为隐藏)。
首先需要将这个文件的只读属性去掉,即将该文件改为可读写文件
然后用记事本打开这个boot.ini 文件
修改前的 boot.ini 文件:
再在 boot.ini 中添加如下行:
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, WRK" /kernel=wrkx86.exe /hal=hal.dll
修改后的 boot.ini 文件:
将上面的都设置好以后就重新启动 Windows Server 2003 SP1.
然后在启动画面中即可以看到如下画面:
我们选择Windows Server 2003 ,WRK启动 Windows操作系统,这样加载内核可执行模块的就
是我们由 WRK 编译所得的那个 wrkx86.exe 了。
总结
上面通过很多的截图来详细介绍了 WRK 的编译以及加载由 WRK 编译所得的内核模块的过程,对于WRK 有
什么作用呢?当然其是用来学习滴,也就是通过 WRK 的学习,可以更加深入的了解到 Windows的内核,等到
那一天有实力了,你大可以通过修改 WRK 源代码,然后再编译成内核模块,然后再让操作系统加载你自个的内核
模块,当然,这个不是很容易就可以达到的境界的!!!其实呢,对于 WRK 来说,还有一个调试环境的搭配,通
过这个调试环境,你可以在外面(指的是在虚拟机以外)通过 WinDbg 来调试这个内核,但是由于这个在后面介
绍驱动程序的时候我会再做说明,所以这里就不添乱了。