假设有
_NT_SYMBOL_PATH=srv*X:\sym*http://msdl.microsoft.com/download/symbols
在"X:\sym\"下发现除了PDB文件,还有些PE文件。比如:
X:\sym\ntoskrnl.exe\6180891781b000\ntoskrnl.exe
X:\sym\lsasrv.dll\615BDF92179000\lsasrv.dllhttp://msdl.microsoft.com/download/symbols/ntoskrnl.exe/6180891781b000/ntoskrnl.exe
http://msdl.microsoft.com/download/symbols/lsasrv.dll/615BDF92179000/lsasrv.dll
过去一直未深究过,为什么会出现这种情况?最近因某个实际需求出现,对此探索了一番。
假设用windbg调试"crash dump",调试机与目标机不是同一套系统,在调试机上打开目标机产生的"crash dump"时需要加载目标机上的PE,此时就会从微软符号服务器下载PE文件。还有一些其他情况,比如Host+Guest+kd,总之,当windbg需要加载的PE因故无法访问时,就会从微软符号服务器下载PE文件。dbgsrv这种Process Servers应该不涉及。
dbghelp!SymFindFileInPath用于下载、加载PE文件。当加载PE时,需要从PE头析取TimeDateStamp、SizeOfImage两个字段,以构造下载URL。用CFF Explorer看
Nt Headers
File Header
TimeDateStamp
Optional Header
SizeOfImage
调试器中"lmv m"、"!lmi"都可以看
kd> lmv m lsass
start end module name
00007ff7`72ec0000 00007ff7`72ed1000 lsass
...
Image name: lsass.exe
Timestamp: Tue Oct 5 13:21:17 2021 (615BE0CD)
...
ImageSize: 00011000
...kd> !lmi lsass
Loaded Module Info: [lsass]
...
Time Stamp: 615be0cd Tue Oct 5 13:21:17 2021
Size: 11000
...
具体拼接时,相当于
sprintf( buf, "%X%X", TimeDateStamp, SizeOfImage )http://msdl.microsoft.com/download/symbols/lsass.exe/615BE0CD11000/lsass.exe
本地缓存
X:\sym\lsass.exe\615BE0CD11000\lsass.exe