33

我们的夜间构建过程被破坏了很长时间,以至于它生成的 PDB 文件与相应的图像文件的年龄相差几个小时。我已经解决了这个问题。

但是,我想开始使用符号服务器,但由于必须使用这些年龄不匹配的 pdb 文件而不能。我通过在 windbg 中使用 .symopt +0x40 方法解决了这个问题。这意味着我必须手动组织我所有的 pdb 文件,并且经过多年的发布,这些文件加起来。

我正在寻找一种方法来修改 windbg 用来标记 pdb 年龄的机制,并强制它与我的图像文件匹配。实用程序ChkMatch执行类似的操作,但用于 pdb 签名。开发人员在页面“ChkMatch 能够使可执行文件和 PDB 文件匹配,如果它们具有不同的签名但相同的年龄(有关 PDB 签名和年龄的更多信息,请参阅本文)。如果年龄不同,该工具无法使文件匹配。”

我查看了 hexeditor 内部,甚至找到了与年龄相对应的位,但它必须在内部提取更多技巧,因为我无法让它工作。

有任何想法吗?

编辑:我不知道这是否有帮助,但在我的特殊情况下,年龄差异是由不必要的重新链接 dll 引起的,这也会重新创建 PDB 文件。但是,我们的构建过程是存储原始 dll(重新链接之前)和重新链接之后的 pdb。我想过以某种方式手动重现这种情况。意思是,强制重新链接 DLL,但在两种情况下都保存 pdb。然后我可以对这两个文件进行二进制比较,看看它们是如何变化的。也许运行某种自动执行此操作的修补软件?通过查看我的控制案例中究竟发生了什么变化,也许我可以对保存在我公司构建过程中的 DLL 和 PDB 做同样的事情?

编辑:我想通了!!!!感谢对第一个答案的评论之一,我查看了“未记录的 Windows 2000 秘密:程序员食谱”一书的 pdf 链接。作者详细介绍了 pdb 文件格式。正如我之前所说,我已经将 pdb 加载到十六进制编辑器中并翻转了一些位,似乎我进行了年龄/签名匹配,但它不起作用。好吧,在使用 W2k 机密书中的实用程序将 pdb“爆炸”到包含的流中之后,我发现它们在流 3 中隐藏了另一个对年龄的引用!!!!!!!!!!一旦我也翻转了那个,它就在windbg中匹配了。这是巨大的!!!!非常感谢....符号服务器我来了!

4

4 回答 4

12

windbg 不会修改 pdb 的年龄 - 它只会查找它以匹配可执行文件的年龄 - 编译器在它(重新)生成可执行文件和调试文件时会这样做。

现在,根据 debuginfo.com 文章,到达正确的调试目录(codeview 类型),将其与 PDB7 签名匹配并修改可执行文件中的年龄或 GUID 并不难。为什么这不是一个选择?

我想,你想更新 pdb 吗?恐怕,pdb 是一种专有格式。有多个只读 API(dbghelp.dll 和 dia sdk),但就修改而言,您需要猜测细节才能修改。

于 2009-04-14T10:05:53.293 回答
12

或者您可以使用此处的建议让 windbg 忽略不匹配的签名和年龄:

http://www.debuginfo.com/articles/debuginfomatch.html

...虽然默认情况下 [windbg] 也不允许加载不匹配的调试信息,但 .symopt 调试器命令可以更改默认行为。在我们发出“.symopt+0x40”命令后,调试器将愉快地接受并加载不匹配的 PDB 和 DBG 文件。

希望这可以帮助。

于 2011-12-07T21:05:34.607 回答
5

虽然正如 SamB 所说,在 PDB 中(格式 7,我的测试是基于 VS2010 生成的 .exe 和 .pdb,以及 windbg 6.9.0003.113 X86)有一个额外的年龄参考,所以在 PDB 文件中总共会有 3 个年龄需要修改. 不幸的是,SamB 没有告诉我们如何找到魔法 3rd age,stream 3?不!根据我的测试,我提取了 100 多个 pdb 流,我尝试了 02(如果 SamB 是 0 索引)和 03,两者都找不到年龄。

只要你有一个十六进制编辑器和windbg,修复其他两个年龄就很容易了。

  • 查找 GUID 和年龄

使用 symchk 获取不匹配的 PDB 文件的签名(GUID): symchk your.exe /v /s 。

通常输出将包含:

[SYMCHK] ------------------------------------
SymbolCheckVersion  0x00000002
Result              0x00010001
DbgFilename         CPP_Snippet.dbg
DbgTimeDateStamp    0x00000000
DbgSizeOfImage      0x00000000
DbgChecksum         0x00000000
PdbFilename         E:\zrf\C_CPP\CPP_Snippet.pdb
PdbSignature        {6D8D99B0-E96B-4093-9D97-8BDC5152B6E0}
PdbDbiAge           0x00000188
  • 修复 2 个更容易的年龄

搜索 GUID 的最后一部分:8BDC5152B6E0,因为只有最后一部分与大端/小端问题无关,它与 pdb 文件中的完全相同。小心搜索原始十六进制值,以使其更准确,您应该验证 GUID 中的其他值(需要在 X86 中反转字节顺序)完全匹配。在 PDB 文件中将恰好找到 2 个 GUID,伴随的年龄正好在 GUID 的第一个字节之前。修改它。就是这样!

  • 我用粗鲁的方法找出第三个年龄。

    转储 PDB 文件的十六进制数,每行一个字节(2 个十六进制数)。od -v -t x1 your.pdb | sed 's/^[0-9a-f]* //;s/ /\n/g' > age_offset.txt

    获取每个匹配年龄的行号,在我的情况下,它是 4 个连续行,其值为 88 01 00 00,vim age_offset.txt :g/88\n01\n00\n00/s/^/\= (line('. ') . ':')/

    这是一个 ex 模式命令,最近版本的 vim 应该支持它。

    :v/:/d

    这将删除所有不包含':'的行,剩余的行是行号,它是每个匹配年龄的偏移量。

    :%s/:.*//

    这将修剪 :88 并单独留下偏移量。

    :%s/.*/\=(子匹配(0) - 1)/

    该命令将每个数字减 1,我这样做是因为 vim 中的行号是 1-index,并且每个年龄的字节偏移量应该是 0-index 以使同事实用程序满意。

    :w

    保存文件

    现在我们得到一个文本文件,每一行都包含一个十进制数,代表一个偏移量,从这个偏移量开始,接下来的 4 个字节就是你梦想年龄的候选。

    接下来,我尝试修改每个潜在的年龄,然后尝试通过 symchk 检查它直到匹配,每次只修补一个偏移量。

    首先,我将备份一个修改了 2 个年龄(和 GUID)的 PDB。我们称之为 ori.pdb

    这是完成艰苦工作的批处理脚本:

for /F usebackq %%i in (`type age_offset.txt`) DO (
  copy /y ori.pdb CPP_Snippet.pdb
  @rem dd if=ori.pdb bs=1c count=4 skip=%%i | xxd -g1 | grep "88 01 00 00" || echo "Bad data at %%i" && goto exit
  dd if=pdb_age.dat of=CPP_Snippet.pdb bs=1c count=4 seek=%%i conv=notrunc
  symchk CPP_Snippet.exe /s . && echo "Found it at offset %%i" && goto exit
  )
:exit

幸运的是,我在第 38 个偏移处找到了正确的位置。

这不是尝试错误修复要修补的正确偏移量的最快方法,但它对我有用,这是我的原型,以确保只有 1 个额外的年龄需要修复,否则,可能的组合是巨大的(我有 111 个年龄候选人尝试),因此尝试错误的方式不实用。

我认为编写一个实用程序以更快的方式完成相同的工作非常容易。

顺便说一句:根据我的测试。chkmatch 可能会报告匹配,而 symchk 和 windbg vs 认为它​​不匹配。

windbg 命令 !itoldyouso 匹配,而 .reload /f your_module.exe 仍然无法匹配。

修复了3个年龄后,不仅windbg,Visual Studio也可以加载pdb文件。

于 2012-09-03T11:28:55.400 回答
1

使用symopt命令启用SYMOPT_LOAD_ANYTHING

.symopt+ 0x40

文档

此符号选项减少了符号处理程序在尝试匹配符号时的挑剔性。

此选项在所有调试器中默认关闭。调试器运行后,可以分别使用.symopt+0x40或打开或关闭它.symopt-0x40

此选项在 DBH 中默认关闭。symopt +40DBH 运行后,可分别使用或开启或关闭symopt -40

有关更多信息,请参阅http://ntcoder.com/bab/2012/03/06/how-to-force-symbol-loading-in-windbg/

于 2021-04-03T05:11:35.007 回答