Debugging Tools for Windows

映射驱动文件

更换驱动文件可能是困难的。经常需要启动到Microsoft Windows安全版(safe build),替换驱动的二进制文件,然后再重新启动。

但是,Windows XP和之后版本的Windows支持一种更加简单的替换驱动文件的方法。可以使用它来替换任何内核模式驱动(包括显示驱动)、任何Windows子系统驱动或其他任何内核模式模块。本主题为了简单,将这些文件统称为驱动,但是可以对任何内核模块使用该方法。

只要WinDbg或KD作为内核调试器附加上来,任何时候都可以使用该方法。也可以对引导驱动使用,但是要困难一些。关于如何在引导驱动上使用的更多信息,查看替换引导驱动

以下面的方法使用驱动替换映射来替换驱动文件:

  1. 创建一个驱动替换映射文件(driver replacement map file)。该文件是列出了目标机上的驱动和主控机上的替代驱动的文本文件。可以替换任意数量的驱动。例如,可以在主控机上d:\Map_Files目录创建一个包含以下内容的名为Mymap.ini 的文件。

    map
    \Systemroot\system32\drivers\videoprt.sys
    \\myserver\myshare\new_drivers\videoprt.sys

    该文件的语法的更多信息,查看驱动替换映射文件格式

  2. 设置到目标机的内核调试连接,在主控机上启动内核调试器(KD或WinDbg)。 (不需要真的中断到目标机。)
  3. 以下面的方法加载驱动替换映射文件:

完成上面的步骤后,驱动替换映射就起作用了

当目标机加载驱动时,会询问主控机是否需要映射该驱动。如果需要,替换文件会通过内核连接传送过去并覆盖掉旧驱动。然后加载新驱动。

驱动替换映射文件格式

每个驱动文件替换由驱动替换映射文件中的三行指定。

可以这样重复指定任何多次。

路径和文件名是不区分大小写的,实际的驱动文件名可以不同。当目标机加载驱动之前,第二行的文件会被第三行指定的文件覆盖。

警告 旧驱动的路径和文件名必须是和保存在服务管理器(Service Control Manager (SCM))数据库中的路径和文件名不区分大小写的精确匹配。该路径经常以\SystemRoot\system32\drivers开头。但是,也可能有一些变形(例如,路径以\??\c:\windows\system32\drivers开头)。SCM数据库中的名字和传递给MmLoadSystemImage的名字一样。

文件中可以包含空白行,也可以包含以井号(#)开始的注释行。但是,在"map"出现之后,紧跟的两行必须是旧驱动和新驱动。 三行组成的块不能被空白行和注释行分割开。

下面是一个驱动替换映射文件的示例。

map
\Systemroot\system32\drivers\videoprt.sys
e:\MyNewDriver\binaries\videoprt.sys
map
\Systemroot\system32\mydriver.sys
\\myserver\myshare\new_drivers\mydriver0031.sys

# Here is a comment
map
\??\c:\windows\system32\beep.sys
\\myserver\myshare\new_drivers\new_beep.sys

驱动替换映射文件必须是一个文本文件,但是可以使用任何文件名和扩展名 (.ini,.txt, .map等等)。

其他注意事项

驱动替换发生时,调试器中会出现一条信息。

如果使用CTRL+D(KD中) 或CTRL+ALT+D (WinDBg中),可以看到替换请求的详细信息。当不知道自己列出的名字和SCM数据库中的是否匹配时,该信息非常有用。

如果内核调试器退出,则不会再继续进行驱动替换。但是,任何已经被替换掉的驱动不会再恢复成旧的二进制文件,因为驱动文件被实际覆盖掉了。

这种驱动替换功能自动绕过Windows文件保护(Windows File Protection (WFP))。

不需要重起目标机。目标机任何时候加载驱动时都会发生驱动替换,不管它是否经过了重新起动。当然,在大部分驱动在引导过程中就已经加载了,所以实际上还是需要在加载了映射文件之后重起目标机。

如果定义了_NT_KD_FILES 环境变量,指定的驱动替换映射文件在内核调试器启动时就会加载。如果使用了.kdfiles 命令,会立即读取指定文件。这时,调试器会验证文件是否具有map/行/行的格式。但是,实际的路径和文件名直到替换发生时才会进行验证。

映射文件读取之后,调试器会保存它的内容。如果之后修改了该文件,这些修改不会生效。(除非再使用.kdfiles 命令)。

对于大的驱动文件,建议使用1394内核连接。使用COM端口的调试连接可能花很长时间用来复制文件。

替换引导驱动

如果要使用驱动替换方法来替换一个引导驱动,必须将内核调试器连接到Windows boot loader(Ntldr),而不是Windows内核。进行这种连接时,必须安装一个特殊的启用调试的Ntldr版本。可以在Windows Driver Kit(WDK)的%DDKROOT%\debug目录中找到该版本的Ntldr。

由于目标机会忽略Boot.ini文件,所以这种情况下不能设置内核连接协议。必须通过COM1端口连接到目标机。波特率为115200。因此,主控机上的内核调试器需要设置为使用115200速度的COM连接。

这种特殊方法仅对引导驱动有效(即Acpi.sysClasspnp.sysDisk.sys和任何在Windows初始断点时使用!drivers命令能显示出来的驱动)。如果要替换引导完成之后使用 MmLoadSystemImage 加载的标准驱动,需要用前面描述的标准方法。

不能在使用EFI固件替代Boot.ini文件的计算机上替换引导驱动。(例如,基于Itanium的计算机。)。

Build machine: CAPEBUILD