Getting started with windows debugging

Содержание:

Введение

WinDBG (произносится как «Wind bag») это инструментарий для отладки, созданный Microsoft. Высокий уровень совместимости ReactOS с Windows и возможность компиляции ReactOS при помощи компилятора от Microsoft позволяет использовать WinDBG для отладки ядра и компонентов, работающих пользовательском режиме системы.

Прежде всего пользователю необходимо скомпилировать ReactOS из исходных кодов при помощи инструментария от Microsoft. При этом будут созданы исполняемые файлы и символы отладки Program DataBase Symbols (PDB), используемые WinDBG для отладки кода. Кроме того, как минимум потребуется скачать cmake и ninja (см. Среда сборки), и версия компилятора от Microsoft (он входит в состав версий Visual Studio).

Пользователь должен создать образ загрузочного диска (bootcd) используя инструментарий Microsoft, а затем загрузить его в виртуальной машине. В самом начале загрузки вы, скорее всего, увидите просто чёрный экран, это нормально, поскольку ядро ReactOS ожидает присоединения к нему WinDBG, после чего процесс загрузки будет продолжен. Подключение к виртуальной машине производится при помощи именованного канала. На странице отладка имеются рекомендации по настройке и подключению к ВМ при помощи именованного канала. В WinDBG в меню выберите File->Kernel Debug (или нажмите ctrl+K), COM, установите соответствующий флаг (я также установил переподключение), и в качестве порта укажите имя канала, т.е., \\.\pipe\ros_pipe.

ReactOS подключится и начнёт установку, так что установите её и перезагрузите машину для перехода ко второй стадии установки. Для использования WinDBG, в меню загрузчика freeloader выберите ReactOS (Debug) (и вновь система не будет загружаться ожидая соединения с отладчиком). Не забывайте, что при подключенном WinDBG ReactOS загружается и работает значительно медленнее.

Для начала отладки ядра нажмите ctrl+break в графическом интерфейсе WinDBG (или ctrl+c если пользуетесь версией для командной строки), кроме того, для перехода к отладке можно нажать tab+k в ReactOS. Теперь вы можете устанавливать точки останова и производить пошаговую отладку кода, но до начала полноценной работы необходимо сделать ещё кое-что. Для перезапуска машины используется команда ‘g’.

Символы

Использование символов совместно с WinDBG делает работу с отладчиком значительно более удобной, и пользователь может настроить их использование в отдельности для каждого отдельного экземпляра WinDBG или глобально при помощи переменных окружения. Вначале рассмотрим способ с установкой переменных окружения.

Установим _NT_SYMBOL_PATH в значение C:\path\to\reactos\output-VS11-i386\reactos

Иногда бывает удобно использовать ещё и символы от Microsoft, это не представляет проблемы и не будет иметь никакого отрицательного эффекта, так что вместо указанного выше нужно использовать

Исходный код

Для прерывания выполнения кода и работы с полноценным кодом на C, в меню File->Open Source File (ctrl+o) выберите файл с кодом ядра. Работа в пользовательском режиме имеет свои особенности, о которых рассказано в самом низу этой страницы.

启动记事本并附加 WinDbgLaunch Notepad and attach WinDbg

  1. 导航到安装目录,然后打开 WinDbg.exe。Navigate to your installation directory, and open WinDbg.exe.

  2. 也可在线 (docs.microsoft.com) 找到调试程序文档。The debugger documentation is also available on line at docs.microsoft.com.

  3. 在“文件”菜单上,选择“打开可执行文件” 。On the File menu, choose Open Executable. 在“打开可执行文件”对话框中,导航到包含 notepad.exe 的文件夹(例如,C:\Windows\System32)。In the Open Executable dialog box, navigate to the folder that contains notepad.exe (for example, C:\Windows\System32). 输入 notepad.exe 作为“文件名称” 。For File name, enter notepad.exe. 选择“打开” 。Select Open.

  4. 在 WinDbg 窗口底部的命令行中,输入以下命令:Near the bottom of the WinDbg window, in the command line, enter this command:

    输出类似于以下内容:The output is similar to this:

    符号搜索路径指示 WinDbg 查找符号 (PDB) 文件的位置。The symbol search path tells WinDbg where to look for symbol (PDB) files. 调试器需要符号文件来获取有关代码模块的信息(函数名、变量名等)。The debugger needs symbol files to obtain information about code modules (function names, variable names, and the like).

    输入此命令,它会通知 WinDbg 进行符号文件的初始查找和加载:Enter this command, which tells WinDbg to do its initial finding and loading of symbol files:

  5. 若要查看 Notepad.exe 模块的符号,请输入以下命令:To see the symbols for the Notepad.exe module, enter this command:

    注意  如果没有看到任何输出,请再次输入 .reload。Note  If you don’t see any output, enter .reload again.

    若要查看 Notepad.exe 模块中包含 main 的符号,请输入以下命令:To see symbols in the Notepad.exe module that contain main, enter this command:

    输出类似于以下内容:The output is similar to this:

  6. 在记事本上设置 notepad!WinMain,输入以下命令:To put a breakpoint at notepad!WinMain, enter this command:

    若要验证是否已设置断点,请输入以下命令:To verify that your breakpoint was set, enter this command:

    输出类似于以下内容:The output is similar to this:

  7. 若要启动记事本运行,请输入以下命令:To start Notepad running, enter this command:

    记事本将一直运行,直到进入“WinMain”函数,然后中断到调试器 。Notepad runs until it comes to the WinMain function, and then breaks in to the debugger.

    若要查看在记事本进程中加载的代码模块列表,请输入以下命令:To see a list of code modules that are loaded in the Notepad process, enter this command:

    输出类似于以下内容:The output is similar to this:

    若要查看堆栈跟踪,请输入以下命令:To see a stack trace, enter this command:

    输出类似于以下内容:The output is similar to this:

  8. 若要再次启动记事本运行,请输入以下命令:To start Notepad running again, enter this command:

  9. 若要中断记事本,请从“调试”菜单中选择“中断”。To break in to Notepad, choose Break from the Debug menu.

  10. 若要在 ZwWriteFile 设置并验证断点,请输入以下命令 :To set and verify a breakpoint at ZwWriteFile, enter these commands:

  11. 输入 g 重新启动记事本。Enter g to start Notepad running again. 在“记事本”窗口中,输入一些文本并从“文件”菜单中选择“保存”。In the Notepad window, enter some text and choose Save from the File menu. 当遇到 ZwCreateFile 时,正在运行的代码会中断 。The running code breaks in when it comes to ZwCreateFile. 输入 k 以查看堆栈跟踪。Enter k to see the stack trace.

    在 WinDbg 窗口的命令行左侧,注意处理器和线程号。In the WinDbg window, just to the left of the command line, notice the processor and thread numbers. 在本例中,当前处理器号为 0,当前线程号为 11。In this example the current processor number is 0, and the current thread number is 11. 因此,我们正在查看线程 11 的堆栈跟踪(它正好在处理器 0 上运行)。So we are looking at the stack trace for thread 11 (which happens to be running on processor 0).

  12. 若要查看记事本进程中所有线程的列表,请输入以下命令(波形符):To see a list of all threads in the Notepad process, enter this command (the tilde):

    输出类似于以下内容:The output is similar to this:

    在本例中,有 12 个线程的索引为 0 到 11。In this example, there are 12 threads with indexes 0 through 11.

  13. 若要查看线程 0 的堆栈跟踪,请输入以下命令:To look at the stack trace for thread 0, enter these commands:

    输出类似于以下内容:The output is similar to this:

  14. 若要退出调试并从记事本进程分离,请输入以下命令:To quit debugging and detach from the Notepad process, enter this command:

Raspberry Pi 2 или 3 (RPi2 или RPi3)Raspberry Pi 2 or 3 (RPi2 or RPi3)

Вы можете подключить WinDbg к Raspberry Pi 2 или 3 с помощью последовательного подключения.You can connect WinDbg to the Raspberry Pi 2 or 3 using a serial connection.

Настройка последовательного подключенияSetup serial connection

Чтобы включить отладку ядра с помощью WinDbg через последовательное подключение, убедитесь, что:In order to enable kernel debugging with WinDbg over a serial connection, ensure that:

  • У вас есть отладочный кабель, такой как последовательный кабель от USB до TTL от Adafruit или фтди.You have a debug cable such as the USB-to-TTL Serial Cable from Adafruit or FTDI.

  • Кабель Ethernet или активный WiFi, соединяющий устройство Raspberry Pi 2 или 3 с вашей сетью (для IP-подключений, таких как SSH или PowerShell).An Ethernet cable or active WiFi connecting your Raspberry Pi 2 or 3 device to your network (for IP connections like SSH or PowerShell)

  • Устройство Raspberry Pi 2 или 3 имеет допустимый IP-адрес в сетиThe Raspberry Pi 2 or 3 device has a valid IP address in your network

  • Активное подключение к устройству Raspberry Pi 2 или 3 с помощью PowerShell или SSHAn active connection to the Raspberry Pi 2 or 3 device via PowerShell or SSH

UART0 будет использоваться на устройстве Raspberry Pi 2 или 3 для подключения отладки ядра.UART0 will be used on the Raspberry Pi 2 or 3 device for the kernel debugging connection. Ниже показаны сопоставления ПИН-кода для Raspberry Pi 2 или 3, а также последовательных кабелей:The following shows the pin mappings for the Raspberry Pi 2 or 3 as well as the serial cables:

Основная идея для создания правильных последовательных подключений заключается в том, что хотя одно устройство использует его для передачи данных, другое устройство использует RX для получения данных.The basic idea for making the correct serial connections is to remember that while one device uses its TX to transmit data, the other device uses its RX to receive the data. Ниже перечислены рекомендуемые подключения.Recommended connections are listed below:

Примечание

Соединение ЕФИЕСП больше не создается.The EFIESP junction is no longer created. Его необходимо подключить самостоятельно. для получения идентификатора GUID можно использовать команду mountvol.You’ll have to mount it yourself,you can use mountvol command to get the GUID.

Используя активное подключение PowerShell, выполните следующие команды на устройстве Raspberry Pi 2 или 3, чтобы включить отладку по последовательному подключению.Using the active PowerShell connection, execute the following commands on the Raspberry Pi 2 or 3 device to enable debugging over the serial connection.

    • Приведенная выше команда включает последовательное подключение для отладки.The above command enables the serial connection for debugging
    • Скорость передачи для Raspberry Pi 2 или 3 жестко запрограммирована на 921600, поэтому вам не нужно указывать его.The baud-rate for the Raspberry Pi 2 or 3 is hard-coded to 921600, so you don’t have to specify it
  • Эта команда включает отладку на устройствеThis command turns on debugging on the device

На компьютере разработчика получите порт номера порта COM, назначенный в системе для кабеля USB – TTL.On the developer PC, get the COM port number PORT assigned in the system for the USB-to-TTL cable. Он будет доступен в Device Manager в разделе «порты (COM & LPT)».This will be available in Device Manager under «Ports (COM & LPT)».

  • Запуск WinDbg с номером портаStart WinDbg with the PORT number

Примечание

Если вы установили любой из установленных комплектов Windows, вы можете найти WinDbg в разделеIf you have any of the Windows kits installed, you may find WinDbg under

Перезагрузка устройства Иоткоре для повторного подключения к отладчикуReboot the IoTCore device to reconnect to the debugger

Патчим ndiskd

WinDbg славится обилием различных расширений. Загрузка расширения делается командой .load имя_расширения, а выгрузка – командой .unload.

К сожалению, довольно удобный плагин для отладки ndis-драйверов, ndiskd, отказался работать в моем Windbg 6.11.1.404 (ndiskd.dll можно найти в WDK или в директории \Debugging Tools for Windows (x64)\winxp). Например, при попытке выполнить команду

ответ был неизменным: «Can’t get offset of Link in NDIS_IF_BLOCK!». Аналогичный результат давало выполнение команд opens, protocols и остальных. Перезагрузка символов результата не давала, все структуры были в порядке. Отказываться от такого удобного расширения у меня не было желания, поэтому я решил прибегнуть к патчу, если это возможно (были бы исходники – можно было бы переписать, например). Загружаю плагин в Ida. Начнем исследование с команды interfaces. Все команды, имеющиеся в расширении – это экспортируемые функции (что очень упрощает мою задачу). То есть достаточно найти функцию interfaces в экспорте и проанализировать ее.

Что ж, приступим:

Видим вывод сообщения о том, что невозможно получить смещение поля Link в структуре NDIS_IF_BLOCK_NAME. Посмотрим, что за строка NDIS_IF_BLOCK_NAME.

Выполнение команды:

Сразу дает ответ, почему плагин рушится: «Symbol ndis!NDIS_IF_BLOCK not found». Тогда как dt ndis!_NDIS_IF_BLOCK нормально выводит структуру.

Очевидно, надо изменить строки и ссылки на них, чтобы все работало нормально. Для нашей задачи воспользуемся каким-нибудь адекватным hex-редактором.

Мне нравится 010 Editor. Исправим строки. В основном выравнивание позволяет нам безболезненно добавлять 1 символ в строку, не сдвигая остальные, но для пары строк это не так. Поэтому нужно найти ссылки на эти строки и исправить их. На каждую строку в данном случае по одной ссылке, находящейся в секции данных, на которую ссылаются инструкции, поэтому достаточно исправить ее. Например, на строку «ndis!LIST_ENTRY» ссылка выглядит так:

Смотрим, что в хексе это соответствует последовательности «68 14 00 80 01 00 00 00». Теперь нужно найти ее в хекс-редакторе и исправить первые байты.

После этого небольшого патча ndiskd выводит всю нужную информацию.

蓝屏和崩溃转储文件Blue screens and crash dump files

如果 Windows 停止工作并显示一个蓝屏,则表示为防止数据丢失,计算机已突然关闭,并显示一个 Bug 检查代码。If Windows stops working and displays a blue screen, the computer has shut down abruptly to protect itself from data loss and displays a bug check code. 有关详细信息,请参阅 Bug 检查(蓝屏)。For more information, see Bug Checks (Blue Screens). 可以使用 WinDbg 和其他 Windows 调试程序来分析 Windows 关闭时创建的故障转储文件。You analyze crash dump files that are created when Windows shuts down by using WinDbg and other Windows debuggers. 有关详细信息,请参阅使用 Windows 调试程序 (WinDbg) 进行故障转储分析。For more information, see Crash dump analysis using the Windows debuggers (WinDbg).

Adding Symbols to a Symbol Server

To add, delete or edit files on a symbol server share, use the symstore.exe tool. This tool is part of the Microsoft Debugging Tools for Windows package. Full documentation on symbol servers, the symstore tool, and indexing symbols is included in the Debugging Tools for Windows package.

You may want to add symbols directly to your own symbol server, as part of a build process, or to make symbols available to your whole team for third-party libraries or tools. The process of adding a symbol to a symbol server file share is called indexing symbols. There are two common ways to index symbols. A symbol file can be copied to the symbol server. Or, a pointer to the location of the symbol can be copied to the symbol server. If you have an archive folder that contains your old builds, you may want to index pointers to the PDB files that are already on the share, instead of duplicating symbols. Because symbols can sometimes be tens of megabytes in size, it’s a good idea to plan ahead for how much space you may require to archive all the builds of your project throughout development. If you index only pointers to symbols, you may have problems if you remove old builds, or change the name of a file share.

For example, to index recursively all the symbols in c:\dxsym\Extras\Symbols that you obtained from the October 2006 DirectX SDK onto a symbol server file share called \\mainserver\symbols, you can use the following command:

The /t «comment» parameter is used to add a description to the transaction that added the symbols. This can be useful when performing administrative tasks on the symbols.

Setting Up a Symbol Server

Setting up a symbol server is very simple. It is useful for the following reasons:

  • To save bandwidth, or to speed up symbol resolution for your company, team or product. An internal symbol server on a local file share on your network caches any references to external symbol servers, such as the Microsoft symbol server. A local or internal symbol server can be accessed quickly by many people at the same time. Therefore, it saves bandwidth and the latency that duplicate symbol requests can create.
  • To store symbols for old builds, versions or external releases of your application. By storing the symbols for these builds on a symbol server that you can easily access, you can debug crashes and problems in these builds on any computer that has a debugger and a connection to the local symbol server. This is particularly useful if you debug mini-dumps that are generated by executables that you did not build yourself—that is, builds that were generated by another programmer or by a build machine. If the symbols for these builds are stored on your symbol server, you will have reliable and accurate debugging.
  • To keep symbols up to date. When components are updated, such as OS components that are modified by Windows Update or by the DirectX SDK, you can still debug by using all the latest symbols.

Setting up a symbol server on your own local network is as simple as creating a file share on a server and giving users full permissions to access the share, to create files and folders. This share should be created on a server operating system, such as Windows Server 2003, so that the number of people who can access the share simultaneously is not limited.

For example, if you set up a file share on \\mainserver\symbols, then the members of your team set the _NT_SYMBOL_PATH to the following:

As symbols are retrieved, files and folders appear in the \\mainserver\symbols shared directory, as well as in individual caches, in the c:\symbols directory.

This is typically all that is involved in setting up and using either your own symbol server, or the Microsoft symbol server.

Анализ аварийного дампа памяти в WinDBG

Отладчик WinDBG открывает файл дампа и загружает необходимые символы для отладки из локальной папки или из интернета. Во время этого процесса вы не можете использовать WinDBG. Внизу окна (в командной строке отладчика) появляется надпись Debugee not connected.

Команды вводятся в командную строку, расположенную внизу окна.

Самое главное, на что нужно обратить внимание – это код ошибки, который всегда указывается в шестнадцатеричном значении и имеет вид 0xXXXXXXXX (указываются в одном из вариантов — STOP: 0x0000007B, 02.07.2019 0008F, 0x8F). В нашем примере код ошибки 0х139

Полный справочник ошибок можно посмотреть здесь.

Отладчик предлагает выполнить команду !analyze -v, достаточно навести указатель мыши на ссылку и кликнуть. Для чего нужна эта команда?

  • Она выполняет предварительный анализ дампа памяти и предоставляет подробную информацию для начала анализа.
  • Эта команда отобразит STOP-код и символическое имя ошибки.
  • Она показывает стек вызовов команд, которые привели к аварийному завершению.
  • Кроме того, здесь отображаются неисправности IP-адреса, процессов и регистров.
  • Команда может предоставить готовые рекомендации по решению проблемы.

Основные моменты, на которые вы должны обратить внимание при анализе после выполнения команды !analyze –v (листинг неполный). 1: kd>

1: kd>

Символическое имя STOP-ошибки (BugCheck)Описание ошибки (Компонент ядра повредил критическую структуру данных. Это повреждение потенциально может позволить злоумышленнику получить контроль над этой машиной):

Аргументы ошибки:

Счетчик показывает сколько раз система упала с аналогичной ошибкой:

Основная категория текущего сбоя:

Код STOP-ошибки в сокращенном формате:

Процесс, во время исполнения которого произошел сбой (не обязательно причина ошибки, просто в момент сбоя в памяти выполнялся этот процесс):

CURRENT_IRQL: 2

Расшифровка кода ошибки: В этом приложении система обнаружила переполнение буфера стека, что может позволить злоумышленнику получить контроль над этим приложением.

Последний вызов в стеке:

Стек вызовов в момент сбоя:

Участок кода, где возникла ошибка:

Имя модуля в таблице объектов ядра. Если анализатору удалось обнаружить проблемный драйвер, имя отображается в полях MODULE_NAME и IMAGE_NAME:

1: kd>

В приведенном примере анализ указал на файл ядра ntkrnlmp.exe. Когда анализ дампа памяти указывает на системный драйвер (например, win32k.sys) или файл ядра (как в нашем примере ntkrnlmp.exe), вероятнее всего данный файл не является причиной проблемы. Очень часто оказывается, что проблема кроется в драйвере устройства, настройках BIOS или в неисправности оборудования.

Если вы увидели, что BSOD возник из-за стороннего драйвера, его имя будет указано в значениях MODULE_NAME и IMAGE_NAME.

Например:

Откройте свойсва файла драйвера и проверьте его версию. В большинстве случаев проблема с драйверами решается их обнвовлением.

Getting the Symbols You Need

Visual Studio and other Microsoft debuggers, such as WinDbg, are typically set up to just work if you are building an application and debugging it on your own computer. If you need to give your executable to someone else, if you have multiple versions of a DLL or an .exe file on your computer, or if you want to accurately debug an application that uses Windows or other libraries, such as DirectX, you need to understand how debuggers find and load symbols. The debugger uses either the symbol search path that is specified by the user—which is found in Options\Debugging\Symbols in Visual Studio—or the _NT_SYMBOL_PATH environment variable. Typically, the debugger searches for matching PDBs in the following locations:

  • The location that is specified inside the DLL or the executable file.

    If you have built a DLL or an executable file on your computer, by default the linker places the full path and file name of the associated PDB file inside the DLL or the executable file. When you debug, the debugger first checks to see if the symbol file exists in the location that is specified inside the DLL or the executable file. This is helpful, because you always have symbols available for code that you have compiled on your computer.

  • PDBs that may be present in the same folder as the DLL or executable file.

  • Any local symbol cache folders.

  • Any local network file share symbol servers.

  • Any Internet symbol servers, such as the Microsoft symbol server.

To make sure that you have all the PDBs that you need for accurate debugging, install the debugging tools for Windows. The 32 and 64 bit versions can be found at Debugging Tools for Windows.

A useful tool that is installed with this package is symchk.exe. It can help to identify missing or incorrect symbols. This tool has a large number of potential command line options. Here are two of the more useful and commonly used ones.

Check if all the DLLs and executable files in a set of folders have matching PDBs

The /r option sets symchk to recursively traverse through folders, to check that all the executable files have matching PDBs. Without the /s option, symchk uses the current _NT_SYMBOL_PATH to search for symbols on any private or local server, or on the Microsoft symbol servers. The symchk tool searches only for symbols for executable files (.exe, .dll, and similar). You cannot use wild cards search for symbols for non-executable files.

How symchk Works

When the linker generates .dll, executable, and PDB files, it stores identical GUIDs in each file. The GUID is used by tools to determine if a given PDB file matches a DLL or an executable file. If you alter a DLL or an executable file—by using a resource editor or copy protection encoding, or by altering its version information—the GUID is updated and the debugger cannot load the PDB file. For this reason, it’s very important to avoid manipulating the DLL or executable file after it is created by the linker.

You can also use the DUMPBIN utility that comes with VS.NET to show the symbol paths that are searched, and to see if symbol files are found that match a given DLL or executable file. For example:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *