Отладка дочерних процессов в Windbg

Вчера столкнулся с интересной проблемой. При установке одного из приложений на 64-битной версии Vista выдавалось сообщение об ошибке при регистрации DLL. Причем ошибка возникала только во время инсталляции. Регистрация “вручную” - через regsvr32 работала.

Первые попытки поймать загрузку нужной библиотеки повалились. Выяснилось, что в процессе инсталляции инсталлятор создает множество процессов для выполнения каких-то своих задач. Эта цепочка выглядела так: setup.exe вызывает msiexec.exe (Windows Installer), который обращается к службе “Windows Installer”, которая, в свою очередь, создает еще несколько дочерних процессов. Регистрация DLL выполнялась в одном из них, но вот в каком?

Первым делом я нашел PID процесса службы “Windows Installer”. Исполняемый модуль этой службы - всё тот же msiexec.exe. Открываем Process Explorer и видим единственный запущенный msiexec.exe в списке системных процессов:

Запускаем windbg и подсоединяемся к интересующему нас процессу. Сразу после этого выполняем команду:

.childdbg 1

“1” переводит windbg в режим отладки дочерних процессов:

Открываем окно Event Filters и перехватываем загрузку интересующей нас DLL - “ZRush_ShipRush3_QB”. Также стоит отключить события “Create Process”, “Initial breakpoint” и “WOW64 breakpoint”, иначе отладчик будет прерываться каждый раз при создании нового процесса.

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

К этому моменту к списоку процессов добавилось три новых экземпляра msiexec.exe:

Теперь можно анализировать процесс загрузки библиотеки, перехватывать вызовы библиотечных функций и т.д.:

PS: Помимо перехвата загрузки библиотеки, можно также использовать “неразрешенные” точки останова (unresolved breakpoints), которые устанавливаются с помощью команды “bu”.

comments powered by Disqus