我有一个客户的minidump。我想找出加载的.NET dll的汇编版本。我已经在互联网上搜索了好几个小时了,但找不到有用的方法。 我有windbg并加载了SOS扩展,并且需要clr.dll和mscordacwks。
使用lm -v
仅显示非托管dll。我确信我忽略了一些非常简单的事情。
答案 0 :(得分:6)
好吧,经过一些更多的研究后,我得出的结论是,这种信息在小型转储中不适用于那些dll。无论如何,我至少能够获得有关文件的更多信息,这可能对将来的其他人有用。
你至少可以获得dll的metata信息,也许你可以在那里找到有用的东西。以下是如何做到这一点:
首先获得域名:
!dumpdomain
您最终可能会遇到大量列出的程序集。现在,您可以使用以下方式手动查找:
!dumpassembly ADDRESS
或者你可以使用懒惰的方式:安装windbg(http://pykd.codeplex.com/)的python扩展并使用以下脚本快速忽略(它可能不是最好的脚本,但它正在工作而我没有想投入更多时间):
import pykd
def dump_assemblies():
assemblies = 0
addrs = pykd.dbgCommand("!dumpdomain").splitlines()
for x in addrs:
if x[:8] == "Assembly":
assemblies = assemblies + 1
print "### retrieving assembly " + x[-8:]
print pykd.dbgCommand("!dumpassembly " + x[-8:])
print "### found " + str(assemblies) + " assemblies."
dump_assemblies()
您现在可以为dll进行文本搜索(CTRL + F)。一旦找到它,就可以找到模块名称旁边的偏移量(看起来像12327C8 C:\ Program Files \ MyApp \ MyDLL.dll)。
您现在可以使用以下方式转储模块:
!dumpmodule 12327C8
将引导您:
Name: C:\Program Files\MyApp\MyDLL.dll
Attributes: PEFile
Assembly: 131a22e2
LoaderHeap: 00000000
TypeDefToMethodTableMap: 19220010
TypeRefToMethodTableMap: 134303e0
MethodDefToDescMap: 13430740
FieldDefToDescMap: 13433964
MemberRefToDescMap: 134350c8
FileReferencesMap: 13435918
AssemblyReferencesMap: 1343591c
MetaData start address: 1c1aaa4c (4248 bytes)
现在您只需使用以下命令检查dll的元数据:
dc 1c1aaa4c 1c1aaa4c + 4248
这是我能够获得有关DLL的更多信息的最接近的信息。不幸的是,文件版本没有写在那里,只是其他一些更通用的信息。无论如何,我会尝试再次与客户取得联系。无论如何,谢谢你的答案。
答案 1 :(得分:5)
WinDbg的lm v
显示了托管和非托管的所有DLL。在那个级别上,程序集只是一个DLL,只是一个模块。
使用WinDbg 6.3.9600,lm v
甚至可以显示模块是否具有CLR标头的信息:
0:008> lmv m MyApp
start end module name
10310000 10574000 MyApp(deferred)
Image path: C:\...\MyApp.exe
Image name: MyApp.exe
Has CLR image header, track-debug-data flag not set
Timestamp: Wed May 21 16:34:02 2014 (537CB95A)
...
ProductVersion: 1.8.0.44
FileVersion: 1.8.0.44
...
但是,FileVersion和ProductVersion仍然是编译到DLL的本机资源部分的非托管信息。
我建议您使用!SaveModule <start address> <filename>
将文件保存在磁盘上,然后使用dotPeek之类的反射工具打开它并从那里获取程序集信息,这将为您提供名称,版本,文化和公钥令牌。
要保存所有模块,Naveen有written a script,请执行以下操作:
!for_each_module .if ($spat ("${@#ImageName}","*.exe")) { !SaveModule ${@#Base} c:\temp\${@#ModuleName}.exe } .else { !SaveModule ${@#Base} c:\temp\${@#ModuleName}.dll }