【问题标题】:How can I identify the version of a managed dll in windbg?如何识别 windbg 中托管 dll 的版本?
【发布时间】:2013-10-13 19:57:11
【问题描述】:

我有一个来自客户的小型转储。我想找出加载的 .NET dll 的程序集版本。我已经在互联网上搜索了几个小时,但找不到可用的方法。 我有 windbg 并已加载 SOS 扩展,并具有所需的 clr.dll 和 mscordacwks。

使用lm -v 只显示非托管dll。我确信我忽略了一些非常简单的事情。

【问题讨论】:

  • 它嵌入在程序集的非托管资源中,即版本资源。 “minidump”中的 mini 通常会阻止它进入您的机器,minidump 的设计并不完全适用于托管代码。没有包含完整的 GC 堆是另一个典型的障碍。只需向客户索取一份副本或回读您的“帮助”+“关于”对话框即可。
  • minidump 这个词是相当不幸的。根据给定的选项,它可能比完整转储更完整。通常对于托管应用程序 /ma 是理想的。您可以使用 || 检查转储类型命令。
  • 类型显示为“用户迷你转储”

标签: debugging dll windbg unmanaged


【解决方案1】:

好的,经过更多研究后,我得出的结论是,小型转储中的那些 dll 无法获得此类信息。无论如何,我至少能够获得有关文件的更多信息,也许这对将来的其他人有用。

你至少可以得到 dll 的元信息,也许你可以在那里找到一些有用的东西。这样做的方法如下:

先获取域名:

!dumpdomain

您最终可能会得到大量列出的程序集。现在您可以使用以下方法手动查找它们:

!dumpassembly ADDRESS

或者你可以使用懒惰的方式:安装windbg的python扩展(http://pykd.codeplex.com/)并使用下面的脚本快速浏览(它可能不是最好的脚本,但它正在工作,我不想投入更多时间):

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 的更多信息的最接近的信息。不幸的是,文件版本没有写在那里,只是一些其他更通用的信息。无论如何,我会尝试再次与客户取得联系。无论如何感谢您的回答。

【讨论】:

  • 元数据大小以十进制指定,所以你应该开始写0n4248:dc 1c1aaa4c 1c1aaa4c + 0n4248。否则,您将无法找到版本号。我无法编辑答案
【解决方案2】:

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这样的反射工具打开它并从那里获取程序集信息,它会给你名称、版本、文化和公钥令牌。

要保存所有模块,Naveenwritten a script 像这样:

!for_each_module .if ($spat ("${@#ImageName}","*.exe")) { !SaveModule ${@#Base} c:\temp\${@#ModuleName}.exe } .else { !SaveModule ${@#Base} c:\temp\${@#ModuleName}.dll }

【讨论】:

  • 工作就像一个魅力。这就是我想要多于一票的地方!
  • !SaveModule 为我工作,我能够从“属性”对话框的“详细信息”选项卡中获取版本
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 2019-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多