![](https://habrastorage.org/files/29b/1a1/c2c/29b1a1c2c9fa4696ac1fdd88f40f9a99.gif)
В таких ситуациях помогает использование виртуальной машины с подключённым к ней отладчиком (например, GDB или IDA). Это если программа не пытается «сломаться» и в виртуальной машине тоже.
Если вам повезло, и программа не против запуститься в виртуальной машине, то с помощью GDB можно походить по её внутренностям и даже сопоставить их с исходными текстами, если в бинарнике есть отладочная информация в формате DWARF.
![](https://habrastorage.org/files/5c2/d6b/02b/5c2d6b02b5ff4a02a4162257f6642d27.png)
![](https://habrastorage.org/files/506/fe7/45c/506fe745ce55467b8c855d743813d218.png)
Смотрим на ядро Windows через WinDbg и GDB
Если же программа собрана в Visual Studio, то показать отладочную информацию GDB не сможет. Про имена API-функций Windows в листинге тоже можно забыть. Здесь мог бы пригодиться WinDbg, но как им подключиться к виртуальной машине, если отладочный режим ОС нас не устраивает?
Вот было бы здорово, если бы в какой-нибудь виртуальной машине был бы интерфейс удалённой отладки, подобный тому, что использует GDB, — подумали мы и написали такой модуль для виртуальной машины QEMU. Всё выложено в виде исходников и бинарников для Windows, так что каждый может попробовать его применить.
Про удалённую отладку с помощью WinDbg уже есть материал на хабре. Там рассказывается как включить отладочный режим Windows и использовать его для удалённого подключения WinDbg. Отладчик подключается через виртуальный COM-порт, связанный с именованным каналом Windows.
![](https://habrastorage.org/files/346/320/3ad/3463203ad44d45f895e54e42c74451a4.png)
Обычный порошок против отладочного сервера, встроенного в QEMU
В нашем случае QEMU без участия гостевой системы подключится к этому именованному каналу, чтобы выдавать отладчику информацию о происходящем внутри Windows. Сама операционная система не знает, что её отлаживают, поэтому отладка получается в некотором роде скрытой.
Чтобы запустить QEMU в таком режиме, понадобится ключ -windbg:
qemu-system-i386.exe -windbg pipe:windbg -hda disk.qcow2
После этого QEMU будет ждать подключения отладчика. Его нужно запустить такой командой:
windbg.exe -b -k com:pipe,baud=115200,port=\\.\pipe\windbg,resets=0
Когда начнётся эмуляция, выбираем режим работы без отладочного модуля Windows:
![](https://habrastorage.org/files/7b7/e82/586/7b7e8258629942c8b65803d4406fa93b.png)
Через некоторое время ОС инициализирует всё что нужно для работы отладчика, он остановит работу эмулятора и предложит вводить команды:
![](https://habrastorage.org/files/c3f/31c/898/c3f31c8985674d4bbf086f5df73ef30f.png)
WinDbg сразу же пишет, что не найдена символьная информация:
Symbol search path is: *** Invalid ***
Загрузить символьную информацию о системных библиотеках можно парой команд .symfix и .reload.То же самое можно сделать и через меню File -> Symbol File Path..., где указать пути к временному каталогу и серверу Microsoft srv*d:\tmp*http://msdl.microsoft.com/download/symbols
![](https://habrastorage.org/files/23d/262/9ae/23d2629ae84b4945b0bb89fd643f06dd.png)
Теперь WinDbg будет знать названия внутренних структур и функций Windows и имена библиотечных функций. Они показываются в листингах, к ним можно привязывать точки останова и т.п.
После этого продолжим загрузку ОС командой g и запустим там нужные приложения
Например, команда !dlls покажет нам список модулей, загруженных в текущем процессе:
![](https://habrastorage.org/files/820/0e1/57c/8200e157caa340d988d2daf2774d72b8.png)
Понятие «текущий процесс» появляется при удалённой отладке. Ведь ОС постоянно переключает виртуальные адресные пространства, привязанные к задачам. Команда !dml_proc выводит список запущенных процессов:
![](https://habrastorage.org/files/08a/b6c/a90/08ab6ca906334cb5928f85b3115077aa.png)
Видно, что в системе работает приложение CrashMe (я взял его с сайта www.windbg.info). Запущенного отладчика в системе оно не нашло.
![](https://habrastorage.org/files/6c2/33a/36b/6c233a36b9ff4dd2879c88bc7a7ff58d.png)
Чтобы поотлаживать эту программу, переключимся в ее контекст с помощью команды .process. Её параметр — это адрес структуры EPROCESS, который указан в первой колонке вывода команды !dml_proc. Проверить, что всё получилось, можно командой !peb:
![](https://habrastorage.org/files/cb0/2a9/a0d/cb02a9a0de624c6f9fbbe9e8c32c6d77.png)
Чтобы отладка была комфортной, загрузим символьную информацию и укажем где хранятся исходные тексты этой программы. После этого командой bp можно создать точку останова:
.sympath+ E:\QemuImages\CrashMe\debug
.reload /user
.srcpath+ E:\QemuImages\CrashMe\CrashMe
bp CCrashMeDlg::OnBnClicked_CallingConvention
g
Теперь при нажатии кнопки «Test Calling Conventions» на форме приложения мы вывалимся в отладчик:
![](https://habrastorage.org/files/a83/217/722/a83217722cb145f58a9669280f9f9bbc.png)
Дальше можно открыть файл с исходным текстом:
![](https://habrastorage.org/files/63a/d16/b94/63ad16b94184400a9d44357422f750e4.png)
Проверить стек вызовов:
![](https://habrastorage.org/files/6cb/132/b43/6cb132b437b94621b9572cbba220e9ff.png)
Или изучить локальные переменные:
![](https://habrastorage.org/files/06e/e3c/833/06ee3c833cb443f18ad86249079433ec.png)
Другая полезная возможность WinDbg — фильтры событий. Можно поставить прерывание работы на разные исключительные ситуации, на событие загрузки модуля или запуска приложения. Обычно сообщения о таких событиях посылает отладочный сервер в гостевой системе, а в WinDbg настраиваются фильтры для них в окне Debug > Event Filters:
![](https://habrastorage.org/files/2e9/a2d/af6/2e9a2daf65834a37962452b87555d14f.png)
Перехват событий и исключительных ситуаций мы пока не реализовывали никак.
Если с int 3 или делением на 0 довольно просто разобраться на уровне эмулятора, то для выявления создания процесса надо проделать намного больше работы.
Все остальные функции WinDbg должны хорошо работать для 32-битных систем, а 64-битными мы пока толком не занялись, сейчас готовим патчи, чтобы все эти функции были доступны всем пользователям QEMU по умолчанию.
Ссылки
- Сборку QEMU под Windows с возможностью скрытого подключения WinDbg можно скачать здесь
- Если вас устраивает отладочный режим работы Windows, то здесь написано как его можно использовать в QEMU
- А здесь то же самое про VirtualBox с акцентом на отладку драйверов
- Описание некоторых команд и расширений WinDbg
- Ещё один список команд
- Подборка ссылок про WinDbg
- Про отладку .NET-приложений в WinDbg
Поделиться с друзьями
maxdm
Нереально круто! Спасибо.