zoukankan      html  css  js  c++  java
  • PDB files out of the debugger

    我想我不需要强调在调试时拥有有效的PDB文件有多重要。通常,PDB文件是由调试器静默加载的,并且您很高兴在modules窗口中看到解析的所有符号。不幸的是,您还可能遇到调试器找不到匹配符号的情况。其原因可能与断开的互联网连接或更复杂的签名不匹配一样微不足道。在本文中,我将向您展示如何在调试之前检查符号文件,以及如何从中提取源文件信息。由于有不同的方法(和工具)来操作符号文件,我将介绍我所知道的那些。

    下载给定PE文件的PDB文件

    由于PDB文件格式是微软的秘密,所以我介绍的所有工具都只是API的包装器。要处理PDB文件,我们首先需要获取它们。让我们列出能帮助我们的工具。

    symchk.exe

    符号检查器(Symchk.exe)是一个应用程序,它将可执行文件与符号文件进行比较,以验证匹配的符号是否可用。Symchk也可以用于填充符号缓存。它可以从PE文件(exe,dll)、转储文件和进程中读取符号信息。它还支持递归目录搜索和批处理文件。

    我们将从加载kernel32.dll库的符号开始:

    c:WindowsSystem32>echo %_NT_SYMBOL_PATH%
     
    c:WindowsSystem32>symchk /v /os kernel32.dll
    [SYMCHK] Searching for symbols to c:WindowsSystem32kernel32.dll in path SRV*C:SymbolsMSS*http://referencesource.microsoft.com/symbols;SRV*C:SymbolsMSS*http://msdl.microsoft.com/download/symbols
    DBGHELP: Symbol Search Path: SRV*C:SymbolsMSS*http://referencesource.microsoft.com/symbols;SRV*C:SymbolsMSS*http://msdl.microsoft.com/download/symbols
    [SYMCHK] Using search path "SRV*C:SymbolsMSS*http://referencesource.microsoft.com/symbols;SRV*C:SymbolsMSS*http://msdl.microsoft.com/download/symbols"
    DBGHELP: No header for c:WindowsSystem32kernel32.dll.  Searching for image on disk
    DBGHELP: c:WindowsSystem32kernel32.dll - OK
    SYMSRV:  C:SymbolsMSSkernel32.pdb9B30FD7CD6B44975BF34B43B6EF668212kernel32.pdb not found
    SYMSRV:  kernel32.pdb from http://msdl.microsoft.com/download/symbols: 704453 bytes - copied
    DBGHELP: kernel32 - public symbols
             C:SymbolsMSSkernel32.pdb9B30FD7CD6B44975BF34B43B6EF668212kernel32.pdb
    [SYMCHK] MODULE64 Info ----------------------
    [SYMCHK] Struct size: 1680 bytes
    [SYMCHK] Base: 0x0000000078D20000
    [SYMCHK] Image size: 1175552 bytes
    [SYMCHK] Date: 0x4e21213b
    [SYMCHK] Checksum: 0x0012386d
    [SYMCHK] NumSyms: 0
    [SYMCHK] SymType: SymPDB
    [SYMCHK] ModName: kernel32
    [SYMCHK] ImageName: c:WindowsSystem32kernel32.dll
    [SYMCHK] LoadedImage: c:WindowsSystem32kernel32.dll
    [SYMCHK] PDB: "C:SymbolsMSSkernel32.pdb9B30FD7CD6B44975BF34B43B6EF668212kernel32.pdb"
    [SYMCHK] CV: RSDS
    [SYMCHK] CV DWORD: 0x53445352
    [SYMCHK] CV Data:  kernel32.pdb
    [SYMCHK] PDB Sig:  0
    [SYMCHK] PDB7 Sig: {9B30FD7C-D6B4-4975-BF34-B43B6EF66821}
    [SYMCHK] Age: 2
    [SYMCHK] PDB Matched:  TRUE
    [SYMCHK] DBG Matched:  TRUE
    [SYMCHK] Line nubmers: FALSE
    [SYMCHK] Global syms:  FALSE
    [SYMCHK] Type Info:    FALSE
    [SYMCHK] ------------------------------------
    SymbolCheckVersion  0x00000002
    Result              0x00030001
    DbgFilename
    DbgTimeDateStamp    0x4e21213b
    DbgSizeOfImage      0x0011f000
    DbgChecksum         0x0012386d
    PdbFilename         C:SymbolsMSSkernel32.pdb9B30FD7CD6B44975BF34B43B6EF668212kernel32.pdb
    PdbSignature        {9B30FD7C-D6B4-4975-BF34-B43B6EF66821}
    PdbDbiAge           0x00000002
    [SYMCHK] [ 0x00000000 - 0x00030001 ] Checked "c:WindowsSystem32kernel32.dll"
     
    SYMCHK: FAILED files = 0
    SYMCHK: PASSED + IGNORED files = 1

    正如您在详细模式(/v开关)中看到的,您收到了很多关于symchk正在做什么的信息。我们甚至可以读取它使用的符号API(dbghelp消息)。/os开关通知symchk打印输出消息中符号文件的完整路径。运行此命令后,kernel32.pdb文件应该在符号存储中。如果您想索引整个System32目录,您需要使用/r开关,它通知symchk递归地遍历提供的目录并下载找到的所有文件的符号,eg. symchk /r /v c:windowssystem32*.dll

    让我们尝试加载notepad.exe进程的符号:

    c: empsymtest>tasklist /FI "IMAGENAME eq notepad.exe"
     
    Image Name                     PID Session Name        Session#    Mem Usage
    ========================= ======== ================ =========== ============
    notepad.exe                   2264 Console                    1      6 036 K
     
    c: empsymtest>symchk /ip 2264 /s SRV*.*http://msdl.microsoft.com/download/symbols
     
    SYMCHK: FAILED files = 0
    SYMCHK: PASSED + IGNORED files = 26

    使用/ip开关,我们可以只提供进程ID,symchk将为进程中加载的所有模块下载符号文件。在这个例子中,我们还使用了/s开关,它为symchk提供它应该使用的符号路径(如果设置了,则覆盖symchk的_NT_SYMBOL_PATH)。在我们的例子中,我们将符号文件从Microsoft公共服务器下载到当前目录。运行此命令后,此目录的列表如下所示:

    c: empsymtest>tree .
    Folder PATH listing
    Volume serial number is 00000002 C622:C13F
    C:TEMPSYMTEST
    ├───advapi32.pdb
    │   └───6AEFDCFF7F2A429B8532CD2BFDDF85D12
    ├───CLBCatQ.pdb
    │   └───60B9D310C472440BA13F66BFF0FC39E32
    ├───comctl32.pdb
    │   └───943BA638A2CD4D88A1C7E7418EAF796C1
    ├───comdlg32.pdb
    │   └───631B57376F8549FDB2E7A8AB3D2D1FDF2
    ├───cryptbase.pdb
    │   └───F03E074BB9E74C9F9BBFB0E42EF3A0AB2
    ├───dwmapi.pdb
    │   └───8683ED0C3DBE4053883EC22FD9B4F2102
    ├───gdi32.pdb
    │   └───FB9403C3B1304DA192C4D0E3485E25ED2
    ├───imm32.pdb
    │   └───98F27BA5AEE541ECBEE00CD03AD50FEE2
    ├───kernel32.pdb
    │   └───9B30FD7CD6B44975BF34B43B6EF668212
    ├───kernelbase.pdb
    │   └───61044362232B410AA600843CEBFD11612
    ...

    另一个有趣的开关是(/id),它使您能够调试转储文件。symchk.exe的另一个伟大功能是称为清单文件的东西。清单文件包含有关必须下载的所有符号的信息。然后,可以使用/om开关运行symchk,该开关将生成清单文件,而无需下载任何符号。然后,可以将清单文件复制到具有Internet连接的任何计算机上,并使用/im开关下载符号文件。下面的代码片段显示了一个使用示例:

    c: empsymtest>symchk /om notepad-symbols.man /ip 2264
     
    SYMCHK: FAILED files = 0
    SYMCHK: PASSED + IGNORED files = 26
     
    c: empsymtest>type notepad-symbols.man
    notepad.pdb,36CFD5F9888C4483B522B9DB242D84782,1
    notepad.exe,4a5bc9b335000,1
    ntdll.pdb,6192BFDB9F04442995FFCB0BE95172E12,1
    ntdll.dll,4ce7c8f91a9000,1
    kernel32.pdb,9B30FD7CD6B44975BF34B43B6EF668212,1
    kernel32.dll,4e21213b11f000,1
    kernelbase.pdb,61044362232B410AA600843CEBFD11612,1
    KernelBase.dll,4e21213c6c000,1
    ...
    c: empsymtest>symchk /im notepad-symbols.man /s SRV*.*http://msdl.microsoft.com/download/symbols
     
    SYMCHK: FAILED files = 0
    SYMCHK: PASSED + IGNORED files = 52

    dbh.exe

    这个工具是DbgHelp.dll库的包装器,它揭示了几乎所有的功能。我们将只看一个使用示例,因此如果您想更深入地了解Windows帮助的调试工具。当以模块名作为参数运行dbh.exe时,它将自动下载符号文件。因此,只要调用dbh c: windowssystem32kernel32.dll info,您就可以下载符号文件(使用了_NT_SYMBOL_PATH环境变量),并打印有关该文件及其PE文件(kernel32.dll)的信息:

    c: emp>dbh c:windowssystem32kernel32.dll info
     
        SizeOfStruct : 0x690
         BaseOfImage : 0x1677721664x
           ImageSize : 0x1000000
       TimeDateStamp : 0x4e21213b
            CheckSum : 0x12386d
             NumSyms : 0x0
             SymType : SymPdb
          ModuleName : kernel32
           ImageName : c:windowssystem32kernel32.dll
     LoadedImageName : c:windowssystem32kernel32.dll
       LoadedPdbName : C:SymbolsMSSkernel32.pdb9B30FD7CD6B44975BF34B43B6EF668212kernel32.pdb
               CVSig : 0x53445352
              CVData : kernel32.pdb
              PdbSig : 0x0
            PdbSig70 : 0x9b30fd7c, 0xd6b4, 0x4975, 0xbf, 0x34, 0xb4, 0x3b, 0x6e, 0xf6, 0x68, 0x21
              PdbAge : 0x2
        PdbUnmatched : false
        DbgUnmatched : false
         LineNumbers : false
       GlobalSymbols : false
            TypeInfo : false
       SourceIndexed : false
       PublicSymbols : true
         MachineType : X64

    如果您想查看有关加载的PDB文件的详细信息,请使用-n开关。要更改默认符号路径(或覆盖符号路径设置),请使用-s:开关。

    dumpbin.exe

    您可能会惊讶于这个工具出现在这里,但是您是否注意到它的/PDBPATH[:VERBOSE]开关?在kernel32.dll库中发出dumpbin/pdbpath:verbose将导致从公共符号存储下载PDB文件:

    c: empsymtest>dumpbin /pdbpath:verbose c:windowssystem32kernel32.dll
    Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
    Copyright (C) Microsoft Corporation.  All rights reserved.
     
    Dump of file c:windowssystem32kernel32.dll
     
    File Type: DLL
      PDB file 'c:windowssystem32kernel32.pdb' checked.  (File not found)
      PDB file 'c: empsymtestkernel32.pdb' checked.  (File not found)
      PDB file found at 'C:SymbolsMSSkernel32.pdb9B30FD7CD6B44975BF34B43B6EF668212kernel32.pdb'
     
      Summary
     
            2000 .data
            A000 .pdata
           6E000 .rdata
            8000 .reloc
            1000 .rsrc
           9B000 .text

    从源服务器下载源代码

    srctool.exe

    这个工具非常有趣,因为它允许您检查PDB文件中索引的源文件,并最终提取它们。使用-r开关,您可以检查PDB文件中哪些源代码路径是硬编码的

    c: emp>srctool -r ConsoleApplication1.pdb
    D:labsymbols-labsymbolsConsoleApplication1Program.cs
    D:labsymbols-labsymbolsConsoleApplication1AdvertQuickView.cs

    没有任何开关,SRCooT将检查PDB文件中的源服务器流(如果存在)和将执行以提取源文件的打印命令,例如:

    c: emp>srctool ConsoleApplication1.pdb
    [D:labsymbols-labsymbolsConsoleApplication1Program.cs] cmd: cmd /c svn.exe cat "svn://localhost/test2/Program.cs@1" --non-interactive --username admin --password admin > "
    [D:labsymbols-labsymbolsConsoleApplication1AdvertQuickView.cs] cmd: cmd /c svn.exe cat "svn://localhost/test2/AdvertQuickView.cs@1" --non-interactive --username admin --password admin > "
     
    ConsoleApplication1.pdb: 2 source files are indexed

    要运行命令并提取源文件,只需在上面的调用中添加-x开关。此外,还可以使用-d开关指定要将源文件提取到的目录(默认情况下是当前目录)。

    pdbstr

    如果希望更好地控制源服务器流,可以检查pdbstr命令。借助它,您可以读取和更新PDB文件中的源服务器信息。源服务器流实际上是一个带有预定义节的文本块(可以在这里找到更多信息)。您可以通过发布以下内容来转储其内容:

    c: emp>pdbstr -r -p:ConsoleApplication1.pdb -s:srcsrv > stream.txt

    stream.txt文件应包含如下内容:

    SRCSRV: ini ------------------------------------------------
    VERSION=1
    INDEXVERSION=2
    VERCTRL=Subversion
    DATETIME=Thu Nov 17 13:31:46 2011
    SRCSRV: variables ------------------------------------------
    SVNUSER=admin
    SVNPASS=admin
    SVN_EXTRACT_TARGET=%targ%\%fnbksl%(%var3%)\%var4%\%fnfile%(%var1%)
    SVN_EXTRACT_CMD=cmd /c svn.exe cat "%var2%%var3%@%var4%" --non-interactive --username %svnuser% --password %svnpass% > "
    %svn_extract_target%"
    SRCSRVTRG=%SVN_extract_target%
    SRCSRVCMD=%SVN_extract_cmd%
    SRCSRV: source files ---------------------------------------
    D:labsymbols-labsymbolsConsoleApplication1Program.cs*svn://localhost/*test2/Program.cs*1
    D:labsymbols-labsymbolsConsoleApplication1AdvertQuickView.cs*svn://localhost/*test2/AdvertQuickView.cs*1
    SRCSRV: end ------------------------------------------------
    然后,可以应用所需的更改并将新的源流定义保存回PDB文件:
    c: emp>pdbstr -w -p:ConsoleApplication1.pdb -s:srcsrv -i:stream.txt

    Pdbstr不会为您提取源代码文件,而是从源流内容中提取,您可以很容易地在哪里找到它们。这将结束我们的PDB工具列表-我希望您会发现它很有用。

  • 相关阅读:
    Silverlight学习(五)图形标绘
    Silverlight学习(四) domainservice动态多条件查询
    MySQL之单表查询
    mysql外键的三种关系
    mysql之完整性约束
    接口类和抽象类的区别
    mysql中的sql_mode
    html5本地存储技术 localstorage
    mysql数值类型
    mysql
  • 原文地址:https://www.cnblogs.com/yilang/p/12038509.html
Copyright © 2011-2022 走看看