Подтвердить что ты не робот

Как вы можете изменить несоответствующий возрасту PDB, чтобы правильно соответствовать?

Наш ночной процесс сборки был сломан в течение длительного времени, так что он сгенерировал файлы PDB, которые были несколько разными по возрасту, чем соответствующие файлы изображений. С тех пор я исправил проблему.

Тем не менее, я хотел бы начать использовать сервер символов, но не могу из-за необходимости использовать эти несохраненные по возрасту файлы pdb. Я работаю над этой проблемой, используя метод .symopt + 0x40 в windbg. Это означает, что я должен организовать все мои файлы pdb вручную, и после многих лет выпуска, это добавляет.

Я ищу способ изменить механизм, который использует windbg для обозначения возраста pdb, и заставить его соответствовать моему файлу изображения. Утилита ChkMatch делает что-то подобное, но для подписи pdb. Разработчик заявляет на странице "ChkMatch способен сделать исполняемый файл и файл PDB совместимым, если у них разные подписи, но того же возраста" (см. Эту статью для получения дополнительной информации о подписи и возрасте PDB). Если возраст отличается, инструмент не может сделать файлы совпадают. "

Я заглянул внутрь гекседитора и даже нашел то, что было похоже на биты, соответствующие возрасту, но он должен вытащить еще несколько трюков изнутри, потому что я не мог заставить его работать.

Любые идеи?

ИЗМЕНИТЬ: Я не знаю, помогает ли это, но в моем конкретном случае разница по возрасту была вызвана ненужной перезагрузкой dll, которая также воссоздала бы файлы PDB. Однако в нашем процессе сборки хранились исходные dll (до релинка) и pdb после релинка. Я подумал о том, чтобы как-то воссоздать такую ​​ситуацию вручную. Значение, заставляющее перезагружать DLL, но сберегая pdb в обоих случаях. Затем я мог бы выполнить двоичное сравнение двух файлов, чтобы посмотреть, как они изменились. Возможно, запустите какое-то программное обеспечение для исправления, которое делает это автоматически? Увидев, что именно изменилось в моем контрольном случае, возможно, я мог бы сделать то же самое с DLL и PDB, сохраненными в процессе сборки моих компаний?

ИЗМЕНИТЬ: Я ПОНЯЛ!!!! Благодаря одному из комментариев по первому ответу я проверил ссылку на pdf-книги книги "Недокументированные секреты Windows 2000: кулинарная книга программистов". И автор подробно рассказывает о формате файла pdb. Как я уже говорил, я уже загрузил pdb в шестнадцатеричный редактор и перевернул несколько бит вокруг появляющихся, что я сделал совпадение по возрасту/подписи, но это не сработало. Ну, после использования утилиты из книги секретов W2k, чтобы "взорвать" pdb во включенных потоках, я обнаружил, что они скрывают другую ссылку на возраст в потоке 3!!!!!!! Как только я перевернул его, он подобрался в windbg. ЭТО ОГРОМНОЕ!!!! Большое вам спасибо... сервер символов ЗДЕСЬ Я ПРИХОДИТ!

4b9b3361

Ответ 1

windbg не будет изменять возраст pdb - он будет выглядеть только в соответствии с исполнением - компилятор делает, когда он (повторно) создает исполняемые и отладочные файлы.

теперь, основываясь на статье debuginfo.com, не так уж сложно получить правильный каталог отладки (типа codeview), сопоставить его с сигнатурой PDB7 и вносить изменения в возраст или GUID внутри исполняемого файла. почему это не вариант?

Я думаю, вы хотите обновить pdb вместо этого? боюсь, pdb - это фирменный формат. существует несколько API-интерфейсов только для чтения (dbghelp.dll и dia sdk), но по мере изменения вы должны угадать детали, которые можно изменить.

Ответ 2

Или вы могли бы просто использовать предложение здесь, чтобы windbg игнорировал несогласованные подписи и возраст:

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

... Хотя по умолчанию он [windbg] также не позволяет загружать непревзойденную информацию отладки, команда отладки команды .symopt может изменять поведение по умолчанию. После того, как мы выпустили команду ".symopt + 0x40", отладчик будет с радостью принимать и загружать несравненные файлы PDB и DBG.

Надеюсь, что это поможет.

Ответ 3

Хотя, как сказал SamB, в PDB (формат 7 мой тест основан на VS2010 сгенерированных .exe и .pdb и windbg 6.9.0003.113 X86), есть одна дополнительная ссылка на возраст, поэтому полностью будет существовать 3 возраста для изменения в файле PDB. К сожалению, SamB не сказал нам, как найти волшебный 3-й век, поток 3? нет! согласно моему тесту, я извлекаю более 100 потоков pdb, я пробовал 02 (если SamB 0-indexed) и 03, оба не могут найти возраст.

Фиксирование двух других возрастов легко, как только у вас есть редактор шестнадцатеричных и windbg.

  • Найдите GUID и возраст

используя symchk для получения Подписи (GUID) вашего несогласованного файла PDB: 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, потому что только последняя часть не имеет байтов без бай-иновских/мало-endian проблем, она точно такая же, как в файлах 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/^/\ = (строка ('.'). ':')/

    Это команда ex mode, которая должна поддерживаться последней версией vim.

    : V/:/д

    Это приведет к удалению всех строк, которые не содержат ":", оставшиеся строки - это номера строк, которые это смещение каждого совпадающего возраста.

    :% s/:.*//

    Это будет обрезать: 88 и оставить только смещение.

    :% s/.*/\= (отправка (0) - 1)/

    Эта команда вычитает каждое число на 1, я делаю это, потому что номер строки в vim является 1-индексом, а смещение байта для каждого возраста должно быть 0-индексом, чтобы сделать работу со-работника счастливой.

    : ш

    сохранить файл

    Теперь мы получаем текстовый файл, в котором каждая строка содержит десятичное число, представляющее смещение, из этого смещения следующие 4 байта являются кандидатами для вашего возраста мечты.

    Далее я пытаюсь изменить каждый потенциальный возраст, а затем попытаюсь проверить его с помощью symchk, пока он не будет соответствовать, каждый раз, когда будет исправлено только одно смещение.

    Прежде всего, я создам резервную копию PDB с 2 возрастом (и GUID). Пусть называется ori.pdb

    Здесь пакет script выполняет тяжелую работу:

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 дополнительный возраст, иначе возможная комбинация огромна (у меня есть Кандидат в возрасте 90 лет), и, таким образом, способ проверки ошибок не является прагматичным.

Я думаю, что очень легко написать утилиту для выполнения той же самой работы более быстрым способом.

Кстати: согласно моему тесту. chkmatch может сообщать о совпадении, в то время как symchk и windbg vs считают это несоответствием.

Команда windbg! itoldyouso соответствует while.reload/f. Ваш_module.exe по-прежнему не может соответствовать.

После фиксации трех возрастов не только windbg, но и визуальная студия могут загружать файлы pdb.