2: kd> .reload
Connected to Windows Vista 6000 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
.............................................................................................................................
Loading User Symbols
Loading unloaded module list
........
2: kd> bl
0 eu 0001 (0001) (ntdll!ZwTerminateProcess)
使用.reload命令强制加载这个模块也不那么容易:
0: kd> .reload /s /f ntdll.dll
"ntdll.dll" was not found in the image list.
Debugger will attempt to load "ntdll.dll" at given base 00000000.
Please provide the full image name, including the extension (i.e. kernel32.dll)
for more reliable results.Base address and size overrides can be given as
.reload <image.ext>=<base>,<size>.
Unable to add module at 00000000
kd> .PROCESS 82748330
Implicit process is now 82748330
WARNING: .cache forcedecodeuser is not enabled
1.C 执行.reload或.reload /user重新加载符号:
kd> .reload
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
................................................................................................
Loading User Symbols
...............................
Loading unloaded module list
..............................
kd> lm m ntdll
start end module name
7c800000 7c8c3000 ntdll (pdb symbols) d:\symbols\ntdll.pdb\9A2A73EBE8194059A14361915257B0B01\ntdll.pdb
Breakpoint 2 hit
nt!NtTerminateProcess:
81a1b043 8bff mov edi,edi
0: kd> kv
ChildEBP RetAddr Args to Child
9f272d54 8188c96a 00000000 00000000 0021f998 nt!NtTerminateProcess
9f272d54 77c20f34 00000000 00000000 0021f998 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 9f272d64)
WARNING: Frame IP not in any known module. Following frames may be wrong.
0021f998 7682d873 00000000 77e8f3b0 ffffffff 0x77c20f34
...
0: kd> .reload
Connected to Windows Vista 6000 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
..............................................................................................................................
Loading User Symbols
..................
说到这里,谜团基本揭开了。事实上, 对于一个普通的进程,系统会把NTDLL的代码映射给它,如果这个进程始终很普通,那么它便会永远使用这份映射过来的代码。但是当它要修改代码时,系统会执行所谓的Copy on Write动作,为其复制一份,让它来写。结合我们的情况,当在用户态调试会话中向NTDLL中设置断点时,系统为其复制了一份代码,让它去写,因此它写入的断点只有它自己“撞的到”,不会影响其它进程。但是当在内核会话中写入断点时,因为是内核调试引擎执行的写动作,所以没有触发Copy on Write,因此KD写入的断点写在了公共的代码上,会影响到使用这个公共代码的所有进程。