Debugging Tools for Windows |
!chkimg 扩展通过比较可执行文件映像和符号存储或者其他地方的拷贝,来检测其中被改动过的内容。
已经在内存中的可执行映像(即被扫描的那个)会被移动,因为调试器总是会重定位它所加载的映像。
该开关仅在操作系统已经移动了原始映像的时候才有用。如果映像并没有被移动,!chkimg和调试器会移动它。一般都不需要使用这个开关。
日志选项 | 日志文件中包含的信息 |
---|---|
v | 不匹配的内容的虚拟地址 |
r | 不匹配内容在模块中的偏移(相对地址) |
s | 和不匹配内容地址对应的符号 |
S | 包含不匹配内容的节的名字 |
e | 不匹配位置的原始值 |
w | 不匹配位置的当前值 |
LogOptions 也可以包含下面这些附加选项的一个、多个或者0个。
日志选项 | 作用 |
---|---|
o | 如果LogFile 名字的文件已经存在,则覆盖该文件。默认情况下,调试器会将新信息添加到已存在的文件末尾。 |
tString | 在日志文件中添加一个额外的列。该列中每一项都包含String。tString 选项在将新信息添加到已存在的日志文件时,可以用来和旧的纪录区分开。在t和String之间不能有空格。如果使用tIString选项,它必须是LogOptions 的最后一个选项,因为String包括下一个空格之前的所有字符。 |
例如,如果 LogOptions 是rSewo,则日志中每一行包括不匹配项的相对地址、节名、该地址的原始值和实际值。该选项也使得任何先前的文件都会被覆盖。如果想创建多个具有不同选项的日志文件,可以使用-mmw多次。一次最多创建10个日志文件。
Windows 2000 | Ext.dll |
Windows XP 和之后 | Ext.dll |
只能在基于x86的目标机上使用!chkimg 扩展命令。
使用!chkimg时,它会比较内存中的可执行映像和符号存储中的文件拷贝。
文件中除了可抛弃的、可写得、不可执行的、名字中有"PAGE"的或者INITKDBG 中的节之外,所有节都会被比较。可以使用-ss、-as、或-r 开关来改变这个行为。
!chkimg 会显示文件和内存映像中所有不匹配的地方,除了下面的例外:
注意 如果使用了-f选项来修正不匹配的内容,!chkimg 仅修正被认为是不匹配的地方。例如,没有包含-noplock时,!chkimg不会将0x90改为0xF0。
包含-d选项时,!chkimg 显示扫描中遇到的不匹配内容的摘要。每个不匹配位置都显示为两行。第一行包含该位置的起始地址、大小、和起始地址对应的符号名和偏移、以及和上一个错误位置之间有多少个字节(圆括号中)。第二行用中括号括起来,包含原始的16进制值、一个冒号、以及当前映像中实际的16进制值。如果该区域大于8个字节,在冒号前后都只会显示8个字节。下面是一个例子。
[ 85 dd:95 23 ]
有时候,驱动程序会通过hook、重定向或其它方法改变Microsoft Windows内核的一部分。即使是不在堆栈上的驱动也可能改变内核。可以使用!chkimg 扩展作为文件比较工具来查看Windows内核(或任何其它映像)被某些驱动改变了,以及具体是怎么改变的。这种比较在完整dump文件上非常有效。
也可以将!chkimg 和!for_each_module扩展一起使用来检查所有已加载模块的映像。下面是这种情况的示例。
例如,假设遇到了bug check,以使用!analyze开始。
....
BugCheck 1000008E, {c0000005, bf920e48, baf75b38, 0}
Probably caused by : memory_corruption
CHKIMG_EXTENSION: !chkimg !win32k
....
例中 !analyze 的输出提示可能遇到了内存错误,并且包含了一个CHKIMG_EXTENSION 行提示被破坏的模块可能是Win32k.sys。(即使不存在这一行,也应该考虑可能调用堆栈顶部的模块被破坏了。)不带任何参数使用!chkimg ,如下。
Number of different bytes for win32k: 31
下面的例子说明确实有内存错误。使用!chkimg -d 来显示模块Win32k 中的所有错误。
bf920e40-bf920e46 7 bytes - win32k!HFDBASIS32::vSteadyState+1f
[ 78 08 d3 78 0c c2 04:00 00 00 00 00 01 00 ]
bf920e48-bf920e5f 24 bytes - win32k!HFDBASIS32::vHalveStepSize (+0x08)
[ 8b 51 0c 8b 41 08 56 8b:00 00 00 00 00 00 00 00 ]
Number of different bytes for win32k: 31
当尝试反汇编列出来的第二个被破坏的映像位置时,可能会有下面这样的输出。
win32k!HFDBASIS32::vHalveStepSize:
bf920e48 0000 add [eax],al
bf920e4a 0000 add [eax],al
bf920e4c 0000 add [eax],al
bf920e4e 0000 add [eax],al
bf920e50 7808 js win32k!HFDBASIS32::vHalveStepSize+0x12 (bf920e5a)
bf920e52 d3780c sar dword ptr [eax+0xc],cl
bf920e55 c20400 ret 0x4
bf920e58 8b510c mov edx,[ecx+0xc]
然后,使用!chkimg –f来修正内存错误。
Warning: Any detected errors will be fixed to what we expect!
Number of different bytes for win32k: 31 (fixed)
现在可以反汇编正确的内容并且查看有些什么改变。
win32k!HFDBASIS32::vHalveStepSize:
bf920e48 8b510c mov edx,[ecx+0xc]
bf920e4b 8b4108 mov eax,[ecx+0x8]
bf920e4e 56 push esi
bf920e4f 8b7104 mov esi,[ecx+0x4]
bf920e52 03c2 add eax,edx
bf920e54 c1f803 sar eax,0x3
bf920e57 2bf0 sub esi,eax
bf920e59 d1fe sar esi,1