Debugging Tools for Windows

使用页面换出的文件头读取符号

内核调试器必须读取每个已加载模块的映像头部来确定匹配该模块的符号。

如果模块的头部被换页到磁盘上,调试器就不能加载该模块的符号。如果这发生在被调试进程的核心模块上,就会成为严重问题。

下面是用来解决该问题的步骤。

获得换出的文件头的符号
  1. 制作一个内核本身的拷贝。将它放到网络共享上可能是最方便的。
  2. 将该共享的根目录加入符号路径。查看符号路径获得修改符号路径的方法。
  3. 使用.reload (Reload Module)命令。
  4. 使用!sym noisy扩展命令来查看详细输出。如果这样,就可以哪些符号是从目标机上的模块映像加载,哪些是从内核模块的拷贝加载的。

这种技术需要小心的使用,因为调试器没有办法验证这个拷贝文件是否和原始文件真正匹配。所以目标机和网络共享上的Windows版本匹配是至关重要的。

该技术仅用于内核调试。用户模式调试时,系统会负责将所有需要的头换页进内存(除非包含页面文件的磁盘被卸载 (dismounted)或者不能访问)。

这是使用该技术的一个例子:

kd> .reload
Connected to Windows XP 2268 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
..........Unable to read image header for dmload.sys at fe0be000 - NTSTATUS 0xC0000001
..........Unable to read image header for dmboot.sys at fda93000 - NTSTATUS 0xC0000001
.....................................Unable to read image header for fdc.sys at fdfc2000 - NTSTATUS 0xC0000001
...Unable to read image header for flpydisk.sys at fde4a000 - NTSTATUS 0xC0000001
.Unable to read image header for Fs_Rec.SYS at fe0c8000 - NTSTATUS 0xC0000001
.Unable to read image header for Null.SYS at fe2c4000 - NTSTATUS 0xC0000001
...................Unable to read image header for win32k.sys at a0000000 - NTSTATUS 0xC0000001
..Unable to read image header for dxg.sys at a0194000 - NTSTATUS 0xC0000001
.......Unable to read image header for ati2draa.dll at a01a4000 - NTSTATUS 0xC0000001
..Unable to read image header for ParVdm.SYS at fe116000 - NTSTATUS 0xC0000001
.......
Loading unloaded module list
..............
Loading User Symbols
Unable to retrieve the PEB address. This is usually caused
by being in the wrong process context or by paging

注意很多映像没有可访问的头。检查某个文件的符号(本例中为fs_rec.sys):

kd> x fs_rec!*
*** ERROR: Module load completed but symbols could not be loaded for fs_rec.sys

头部明显被换出了。所以需要将合适的映像加入到符号路径中:

kd> .sympath+ \\myserver\myshare\symbols\x86fre\symbols
Symbol search path is: symsrv*symsrv.dll*c:\localcache*http://msdl.microsoft.com/download/symbols;\\myserver\myshare\symbols\x86fre\symbols

kd> .reload
Connected to Windows XP 2268 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
..........Unable to read image header for dmload.sys at fe0be000 - NTSTATUS 0xC0000001
..........Unable to read image header for dmboot.sys at fda93000 - NTSTATUS 0xC0000001
.....................................Unable to read image header for fdc.sys at fdfc2000 - NTSTATUS 0xC0000001
...Unable to read image header for flpydisk.sys at fde4a000 - NTSTATUS 0xC0000001
.Unable to read image header for Fs_Rec.SYS at fe0c8000 - NTSTATUS 0xC0000001
.Unable to read image header for Null.SYS at fe2c4000 - NTSTATUS 0xC0000001
...................Unable to read image header for win32k.sys at a0000000 - NTSTATUS 0xC0000001
..Unable to read image header for dxg.sys at a0194000 - NTSTATUS 0xC0000001
.......Unable to read image header for ati2draa.dll at a01a4000 - NTSTATUS 0xC0000001
..Unable to read image header for ParVdm.SYS at fe116000 - NTSTATUS 0xC0000001
.......
Loading unloaded module list
..............
Loading User Symbols
Unable to retrieve the PEB address. This is usually caused
by being in the wrong process context or by paging

会出现同样的警告,但是符号本身已经可用了:

kd> x fs_Rec!*
fe0c8358  Fs_Rec!_imp___allmul
fe0c8310  Fs_Rec!_imp__IoCreateDevice
fe0c835c  Fs_Rec!_imp___allshr
........
fe0c8360  Fs_Rec!ntoskrnl_NULL_THUNK_DATA
fe0c832c  Fs_Rec!_imp__KeSetEvent
fe0c9570  Fs_Rec!_NULL_IMPORT_DESCRIPTOR

Build machine: CAPEBUILD