Средства отладки режима ядра операционной системы Windows. Хардкорная отладка с Linice: учимся работать в консольном отладчике ядра Что такое отладка ядра

💖 Нравится? Поделись с друзьями ссылкой

Введение

1. Типы Windows-отладчиков

2. Отладчики режима пользователя

3. Отладчики режима ядра

3.1 Отладчик WDEB386

3.2 Отладчик I386KD

3.3 Отладчик Win DBG

3.4 Отладчик SoftICE

4. Общий вопрос отладки

5. Автоматический запуск приложений в отладчике

5.1 Быстрые клавиши прерываний

Заключение

Литература

Введение

Изучение механизма работы программных инструментов - наиболее трудная часть отладочного процесса. Только понимая возможности и ограничения инструментов, можно получать от них большую отдачу и тратить меньше времени на отладку. Как правило, отладчики чрезвычайно полезны, но могут привести к довольно тонким проблемам, заводящим программиста в тупик. В этой главе показано, что такое отладчик и как различные отладчики работают в операционных системах Win32 (32-разрядных операционных системах Windows фирмы Microsoft).

При этом сосредоточимся на тех специальных свойствах отладчиков вообще, которые включены, когда под управлением последних выполняется какой-то программный процесс. Кроме того, здесь поясняются возможности усиления некоторых свойств 32-разрядных операционных систем Windows, позволяющие облегчить процесс отладки. Будут представлены два авторских отладчика, исходный код которых можно найти на сопровождающем компакт-диске. Первый (MinDBG) имеет достаточные возможности для того, чтобы его называли отладчиком. Второй (WDBG) - пример отладчика Microsoft Windows, который делает почти все, что и реальный системный отладчик, включая манипулирование таблицами символов, обработку точек прерывания, генерацию кода дизассемблера и координирование с графическим интерфейсом пользователя (GUI). При обсуждении WDBG мы покажем, как работают точки прерывания, и обсудим, что представляют собой различные файлы символов (symbol files).

Прежде чем переходить к основному материалу этой главы, определим два стандартных термина, которые будут часто использоваться в этой книге: основной (или базовый) отладчик (debugger) и подчиненный отладчик (debuggee). Проще говоря, основной отладчик - это процесс, который в отладочном отношении может контролировать другой процесс, а подчиненный отладчик - это процесс, запускаемый под основным отладчиком. В некоторых операционных системах основной отладчик называют родительским процессом, а подчиненный - дочерним.

Отла́дчик (деба́ггер, англ. debugger от bug) - компьютерная программа, предназначенная для поиска ошибок в других программах, ядрах операционных систем, SQL-запросах и других видах кода. Отладчик позволяет выполнять трассировку, отслеживать, устанавливать или изменять значения переменных в процессе выполнения кода, устанавливать и удалять контрольные точки или условия остановки и т.д.

Большинству разработчиков больше знакомы отладчики пользовательского режима. Не удивительно, что отладчики этого режима предназначены для отладки приложений пользовательского режима (user-mode applications). Главный пример отладчика режима пользователя - отладчик Microsoft Visual C++. Отладчики режима ядра, как следует из их названия, - это такие отладчики, которые позволяют отлаживать ядро операционной системы. Они используются главным образом теми, кто пишет (и отлаживает, конечно) драйверы устройств.

2. Отладчики режима пользователя

Отладчики режима пользователя предназначены для отладки любого приложения, выполняющегося в режиме пользователя, включая любые GUI-программы, а также такие не совсем обычные приложения, как службы (services) Windows 2000. В общем случае, отладчики этого типа поддерживают графический интерфейс пользователя (GUI1). Главный признак таких отладчиков - они используют отладочный интерфейс прикладного программирования (отладочный API) Win32. Поскольку операционная система помечает подчиненный отладчик как "выполняющийся в специальном режиме", то, чтобы выяснить, выполняется ли ваш процесс под отладчиком, можно использовать API-функцию IsDebuggerPresent.

При поставке отладочного API Win32 подразумевается следующее соглашение: раз процесс выполняется под отладочным API (и делает его, таким образом, подчиненным процессом), основной отладчик не может отделиться от данного процесса. Эти симбиозные отношения означают, что если основной отладчик завершает работу, то завершается также и подчиненный отладчик. Основной отладчик ограничивается отладкой только подчиненного отладчика и любых порожденных им процессов (если основной отладчик поддерживает процессы-потомки).

GUI - Graphical User Interface. - Пер.

Для интерпретируемых языков и исполнительных (run-time) систем, которые используют подход виртуальной машины, полную отладочную среду обеспечивают сами виртуальные машины, и они не используют отладочный API Win32. Вот некоторые примеры таких типов сред: виртуальные Java-машины (JVM) фирм Microsoft или Sun, среда сценариев для Web-приложений фирмы Microsoft, и интерпретатор р-кода в системе Microsoft Visual Basic.

отладчик ядро операционная система

Мы доберемся до отладки в Visual Basic в главе 7, но знайте, что интерфейс р-кода Visual Basic не документирован. Не будем вникать в отладочные интерфейсы Java и сценариев, эти темы выходят за рамки данной книги. Дополнительную информацию по отладке и профилированию Microsoft JVM ищите в разделе "Debugging and Profiling Java Applications" (Отладка и профилирование приложений Java) на MSDN. Набор таких интерфейсов весьма богат и разнообразен и позволяет полностью управлять работой JVM. Информацию о написании отладчика сценария можно найти в разделе MSDN "Active Script Debugging API Objects" (Активные объекты отладочных API-сценариев). Подобно JVM, объекты отладчика сценариев обеспечивают богатый интерфейс для сценариев доступа и документирования.

Отладочный API Win32 использует удивительно много программ. К ним относятся: отладчик Visual C++, который подробно рассматривается в главах 5 и 6; отладчик Windows (WinDBG), который обсуждается в следующем разделе (посвященном отладчику режима ядра); программа BoundsChecker фирмы Compuware NuMega; программа Platform SDK HeapWalker; программа Platform SDK Depends; отладчики Borland Delphi и C++ Builder, а также символический отладчик NT Symbolic Debugger (NTSD). Я уверен, что их намного больше.

3. Отладчики режима ядра

Отладчики режима ядра находятся между CPU и операционной системой. Это означает, что, когда вы останавливаете отладчик режима ядра, операционная система также полностью останавливается. Нетрудно сообразить, что переход операционной системы к резкому останову полезен, когда вы работаете с таймером и над проблемами синхронизации. Все-таки, за исключением одного отладчика, о котором будет рассказано ниже (в разделе "Отладчик SoftlCE" данной главы), нельзя отлаживать код пользовательского режима с помощью отладчиков режима ядра.

Отладчиков режима ядра не так много. Вот некоторые из них: Windows 80386 Debugger (WDEB386), Kernel Debugger (1386KD), WinDBG и SoftlCE. Каждый из этих отладчиков кратко описан в следующих разделах.

3.1 Отладчик WDEB386

WDEB386 - это отладчик режима ядра Windows 98, распространяемый в составе Platform SDK. Этот отладчик полезен только для разработчиков, пишущих драйверы виртуальных устройств Windows 98 (VxD). Подобно большинству отладчиков режима ядра для операционных систем Windows, отладчик WDEB386 требует для работы две машины и нуль-модемный кабель. Две машины необходимы потому, что часть отладчика, которая выполняется на целевой машине, имеет ограниченный доступ к ее аппаратным средствам, так что он посылает свой вывод и получает команды от другой машины.

Отладчик WDEB386 имеет интересную историю. Он начинался как внутренний фоновый инструмент Microsoft в эпоху Windows 3.0. Его было трудно использовать, и он не имел достаточной поддержки для отладки исходного кода и других приятных свойств, которыми нас испортили отладчики Visual C++ и Visual Basic.

"Точечные" (DOT) команды - наиболее важная особенность WDEB386. Через прерывание INT 41 можно расширять WDEB386 с целью добавления команд. Эта расширяемость позволяет авторам VxD-драйверов создавать заказные отладочные команды, которые дают им свободный доступ к информации в их виртуальных устройствах. Отладочная версия Windows 98 поддерживает множество DOT-команд, которые позволяют наблюдать точное состояние операционной системы в любой точке процесса отладки.

3.2 Отладчик I386KD

Windows 2000 отличается от Windows 98 тем, что реально действующая часть отладчика режима ядра является частьюNTOSKRNL. EXE - файла главного ядра операционной системы Windows 2000. Этот отладчик доступен как в свободных (выпускных), так и в проверенных (отладочных) конфигурациях операционной системы. Чтобы включить отладку в режиме ядра, установите параметр загрузчика /DEBUG в BOOT. INI и, дополнительно, опцию загрузчика /DEBUGPORT, если необходимо установить значение коммуникационного порта отладчика режима ядра, отличающееся от умалчиваемого (СОМ1). I386KD выполняется на своей собственной машине и сообщается с машиной Windows 2000 через кабель нуль-модема.

Отладчик режима ядра NTOSKRNL. EXE делает только то, что достаточно для управления CPU, так чтобы операционная система могла быть отлажена. Большая часть отладочной работы - обработка символов, расширенные точки прерывания и дизассемблирование - выполняется на стороне 1386KD. Одно время Windows NT 4 Device Driver Kit (DDK) документировал протокол, используемый в кабеле нуль-модема. Однако Microsoft больше его не документирует.

Мощь 1386KD очевидна, если посмотреть на все команды, которые он предлагает для доступа к внутреннему состоянию Windows 2000. Знание механизма работы драйверов устройств в Windows 2000 поможет программисту следить за выводом многих команд. Не смотря на всю свою мощь, i386KD почти никогда не применяется, потому что это консольное приложение, которое очень утомительно использовать для отладок исходного уровня.

3.3 Отладчик Win DBG

WinDBG - это отладчик, который поставляется в составе Platform SDK. Можно также загрузить его с#"897008.files/image001.gif">

Рис 1. Вывод программы GFLAGS. EXE

Листинг 4-1. Пример разрушения heap-области Windows 2000

void main (void)

HANDLE hHeap = HeapCreate (0, 128, 0);

// Распределить память для блока размером в 10 байтов.

LPVOID pMem = HeapAlloc (hHeap, 0,10);

// Записать 12 байт в 10-байтовый блок (переполнение heap-области).

memset (pMem, OxAC,

// Распределить новый блок размером 20 байт.

LPVOID pMem2 = HeapAlloc (hHeap, 0, 20);

// Записать 1 байт во второй блок.

char * pUnder = (char *) ((DWORD) pMem2 - 1);

// Освободить первый блок. Это обращение к HeapFree будет

// инициировать точку прерывания в коде отладочной heap-области

// операционной системы.

HeapFree (hHeap, 0, pMem);

// Освободить второй блок. Заметим, что этот вызов не будет

// выдавать соообщения о неполадке

HeapFree (hHeap, 0, pMem2);

// Освободить фиктивный блок. Заметим, что этот вызов не будет

// выдавать сообщения о неполадке

Если установить те же флажки, что на рис.4.1, и повторить выполнение HEAPER. EXE, то будет получен следующий, более многословный вывод:

PAGEHEAP: process 0x490 created debug heap 00430000

(flags 0xl, 50, 25, 0, 0): process 0x490 created debug heap 00CF0000

(flags Oxl, 50, 25, 0, - 0): process 0x490 created debug heap 01600000

(flags Oxl, 50, 25, 0, 0): Tail fill corruption detected:at 0x01606FF0size 0x0000000Asize 0x00000010at Ox01606FFA: Attempt to reference block which is not allocated

Содержимое листинга объясняют названия флажков, установленных панелью Global Flags.

Обсуждая программу GFLAGS. EXE, я хочу указать на одну очень полезную опцию - Show Loader Snaps. Если вы установите этот флажок и выполните приложение, то увидите то, что называют снимком (snap) приложения, в котором видно, где Windows 2000 загружает DLL-файлы и как она начинает организацию импорта. Если необходимо точно видеть, что делает загрузчик Windows 2000 при загрузке приложения (особенно в том случае, когда в нем обнаружена проблема), то включение этой опции может оказаться весьма полезным мероприятием. Дополнительную информацию по снимкам загрузчика можно получить в колонке Мэта Пьетрека "Under the Hood" в сентябрьском выпуске Microsoft Systems Journal за 1999 год.

5. Автоматический запуск приложений в отладчике

Самыми трудными для отладки типами приложений являются те приложения, которые запускаются другим процессом. В эту категорию нападают службы Windows 2000 и внепроцессные (out-of-process) СОМ-серверы (СОМ out-of-process servers). Чтобы заставить отладчик прикрепиться к процессу, во многих случаях можно использовать API-функцию DebugBreak. В двух случаях, однако, эта функция работать не будет. Во-первых, она иногда не работает со службами Windows 2000. Если нужно отладить запуск службы, то вызов DebugBreak присоединит отладчик, но к тому времени, когда отладчик запустится, может быть исчерпан интервал тайм-аута службы, и Windows 2000 остановит ее. Во-вторых, DebugBreak не будет работать, когда нужно отлаживать внепроцессный СОМ-сервер. Если вы вызовете DebugBreak, обработчик СОМ-ошибок отловит исключение точки прерывания и завершит СОМ-сервер. К счастью, Windows 2000 позволяет указать, что приложение должно стартовать в отладчике. Это свойство позволяет начать отладку прямо с первой инструкции. Однако, прежде чем вы включите это свойство для службы Windows 2000, удостоверьтесь, что в этой службе сконфигурирована возможность взаимодействия с рабочим столом Windows 2000.

Свойство запуска с отладчиком можно включить двумя способами. Самый легкий - запустить утилиту GFLAGS. EXE и выбрать переключатель Image File Options (см. рис.4.1). После ввода в редактируемое поле Image File Name имени двоичного файла программы установите флажок Debugger в группе Image Debugger Options ) и введите в редактируемое поле рядом с этим флажком полный путь к отладчику.

Более трудный способ: нужно вручную установить необходимые параметры з подходящие разделы реестра (с помощью редактора RegEdit). В разделе_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NTXCurrent Version\Image Tile Execution Options

создайте подраздел, имя которого совпадает с именем файла вашего приложения. Например, если имя приложения - FOO. EXE, то имя подраздела реестра тоже FOO. EXE. В этом подразделе создайте новый строковый параметр с именем Debugger. В диалоговом окне Изменение строкового параметра введите с клавиатуры полное (вместе с путем к каталогу) имя файла выбранного вами отладчика. Если вы указали GFLAGS. EXE и установили некоторые глобальные опции, то сможете заметить в ключе вашего приложения строчное значение GiobaiFiag.

Теперь при запуске вашего приложения автоматически загружается и запускается и отладчик. Опции командной строки для отладчика также можно определить в строковом параметре Debugger (вслед за именем программы отладчика). Например, для того чтобы использовать отладчик WinDBG и автоматически инициировать отладку, как только стартует WinDBG, нужно в диалоговом окне изменения строкового параметра Debugger ввести значение d: \platform sdk\bin\windbg. exe - g.

5.1 Быстрые клавиши прерываний

Иногда нужно быстро войти в отладчик. Если вы отлаживаете консольные приложения, то нажатие клавиш + или + вызовет специальное исключение (с именем DBG_CONTROL_C). Это исключение переведет вас прямо в отладчик и позволит стартовать отладку.

Полезным свойством как Windows 2000, так и Windows NT 4 является возможность в любое время переходить в отладчик также и в GUI-приложениях. При выполнении под отладчиком нажатие клавиши приводит (по умолчанию) к вызову функции DebugBreak. Интересный аспект обработки этой клавиши заключается в том, что, даже если вы используете ее как акселератор или как-то иначе обрабатываете сообщения клавиатуры для этой клавиши, она все еще будет подключать вас к отладчику.

В Windows NT 4 быстрая клавиша прерывания назначена по умолчанию, однако в Windows 2000 вы можете сами определить, какую клавишу следует использовать для этих целей. Для чего в разделе реестра

HKEY_LOCAL_MACHINE\SOFTWARE\ Microsoft\WindowsNT\CurrentVersion\AeDebug

установите для параметра userDebuggerHotKey значение кода клавиши (VK_*). Например, чтобы использовать клавишу для подключения к отладчику, следует установить значение UserDebuggerHotKey равным 0x91. Изменения вступают в силу после перезагрузки компьютера.

Заключение

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

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


Литература

1.. aspx?.aspx?id=553022>

2. https: // ru. wikipedia.org/wiki/%D0%9E%D1%82%D0%BB%D0%B0%D0%B4%D1%87%D0%B8%D0%BA

Http://bourabai. kz/alg/debug4. htm

4. Костюхин К. - ОТЛАДКА СИСТЕМ РЕАЛЬНОГО ВРЕМЕНИ. Обзор

Эта серия статей появилась по двум причинам. Во-первых, мне нравится работать с проектом HackSysExtremeVulnerableDriver . Во-вторых, я получил массу пожеланий , чтобы осветить эту тему.

Весь код, используемый при написании этой серии, находится в моем репозитории .

В данном цикле статей мы рассмотрим написание эксплоитов уровня ядра в ОС Windows. Важно отметить, что мы будем иметь дело с известными уязвимостями, и в реверс-инжиниринге нет необходимости (по крайней мере, для драйвера).

Предполагается, что после ознакомления со всеми статьями вы будете знать все наиболее распространенные классы брешей и методы эксплуатации, а также сможете портировать эксплоиты с архитектуры x86 на архитектуру x64 (если возможно) и ознакомитесь с новыми методами защиты в Windows 10.

Схема отладки ядра

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

Дополнительный материал для изучения:

Эксплуатация уязвимостей ядра

Этот процесс проходит намного веселее, чем эксплуатация на уровне пользователя J.

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

Темы статей этого цикла

  • Часть 1: Настройка рабочей среды
    • Конфигурирование трех виртуальных машин и системы, которая будет выступать в роли отладчика.
    • Конфигурирование отладчика WinDBG.
  • Часть 2: Полезные нагрузки
    • Изучение наиболее распространенных полезных нагрузок. В последующих частях будут рассматриваться конкретные уязвимости и, при необходимости, указываться ссылки на эту статью.
  • Остальные части.
    • Рассмотрение уязвимостей.

Жизненный цикл разработки эксплоита уровня ядра

  • Нахождение уязвимости . Эта тема не будет рассматриваться в данном цикле, поскольку мы уже точно знаем, где находятся бреши.
  • Перехват потока выполнения . Некоторые уязвимости предусматривают выполнение кода, для некоторых есть дополнительные требования.
  • Расширение привилегий . Главная цель – получить шелл с системными привилегиями.
  • Восстановление потока выполнения . Неучтенные исключения на уровне ядра приводят к краху системы. Если вы не собираетесь писать эксплоит для DoS-атаки, следует учитывать этот факт.

Типы целевых систем

Мы будем работать с уязвимостями в следующих системах (конкретная версия не принципиальна):

  • Win7 x86 VM
  • Win7 x64 VM
  • Win10 x64 VM

Начнем с архитектуры x86, и далее будем портировать эксплоит для системы Win7 x64. Некоторые эксплоиты не будут запускать на машинах с Win10 из-за присутствия новых защит. В этом случае мы либо будем изменять логику работы эксплоита, либо будем использовать полностью другой подход.

Используемое программное обеспечение:

  • Гипервизор (масса вариантов).
  • Windows 7 x86 VM
  • Windows 7 x64 VM
  • Windows 10 x64 VM

Настройка систем для отладки

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

На каждой машине, которая будет отлаживаться, нужно сделать следующее:

  • Внутри директории VirtualKD запустите файл target\vminstall.exe. Добавится новая загрузочная запись и будут доступны функции отладки и автоматическое подключение к серверу VirtualKD, установленному в системе, которая выступает в роли отладчика.

В случае с Windows 10 VM необходимо включить режим test signing, который позволяет загружать неподписанные драйвера в ядро.

После выполнения команды bcdedit /set testsinging on и перезагрузки на рабочем столе появится надпись «Test Mode».

Краткое описание модуля HEVD

Процедура DriverEntry является стартовой для каждого драйвера:

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {
UINT32 i = 0;
PDEVICE_OBJECT DeviceObject = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNICODE_STRING DeviceName, DosDeviceName = {0};

UNREFERENCED_PARAMETER(RegistryPath);
PAGED_CODE();

RtlInitUnicodeString(&DeviceName, L"\\Device\\HackSysExtremeVulnerableDriver");
RtlInitUnicodeString(&DosDeviceName, L"\\DosDevices\\HackSysExtremeVulnerableDriver");

// Create the device
Status = IoCreateDevice(DriverObject,
0,
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DeviceObject);

  • Эта процедура содержит вызов функции IoCreateDevice, содержащей имя драйвера, которое мы будем использовать во время коммуникации.
  • В объект DriverObject будут добавлены нужные структуры и указатели на функции.
  • Для нас важен указатель функции, связанный с процедурой DriverObject->MajorFunction , отвечающей за обработку IOCTL (I/O Control; управление вводом/выводом);
  • В HEVD эта функция называется IrpDeviceIoCtlHandler , которая представляет собой большое условное выражение со множеством ответвлений для каждого IOCTL. Каждая уязвимость имеет уникальный IOCTL.

Пример: HACKSYS_EVD_IOCTL_STACK_OVERFLOW представляет собой IOCTL, используемый для активации бреши, связанной с переполнением стека.

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

P.S. Я понимаю, что существует масса тонкостей и проблем, с которыми вы можете столкнуться. Поскольку в этом цикле основное внимание уделяется разработке эксплоитов, вам придется решать все попутные проблемы самостоятельно. Однако все возникающие вопросы вы можете задавать в комментариях.

Как запустить отладчик ядра?

Ответ мастера:

В процессе разработки программного обеспечения есть одна очень важная составляющая – это отладка. По отношению к прикладным программам она осуществляется средствами, которые работают в пользовательском режиме и часто встроенными в IDE. Для того чтобы была возможность отладить, например, драйвера, необходимо запустить отладчик ядра.

Нужно запустить процессор командный cmd. Откройте меню «Пуск» на панели задач. В появившемся окне кликните на пункт «Выполнить…». Появится окно «Запуск программы». В текстовом поле введите cmd, после этого нажмите кнопку «ОК».

Теперь создайте резервную копию файла boot.ini. Сначала узнайте установочный путь текущей копии Windows, воспользовавшись командой: echo %SystemRoot%

Далее перейдите на диск, с установленной операционной системой, введя литеры устройства, а после них, поставив двоеточие. С помощью команды cd, перейдите в корневой каталог. Теперь используя команду attrib, снимите с файла boot.ini атрибуты «скрытый», «только для чтения» и «системный». Командой copy создайте резервную копию, а затем установите атрибуты на место.

Для выведения текущего списка вариантов загрузки, воспользуйтесь командой bootcfg /query. Просмотрите список и определите тот элемент, на основании которого будут создаваться новые настройки с возможностью отладки в режиме ядра. Идентификатор загрузочной записи следует запомнить.

Воспользуйтесь командой bootcfg/copy для создания загрузочной записи. Для того чтобы указать идентификатора записи, которую будете копировать, воспользуйтесь параметром /id. Используя параметр /d, задайте имя записи, которая будет отображаться. Теперь нужно снова перейти к списку вариантов загрузки, используя команду bootcfg/query ,и посмотрите идентификатор добавленной записи.

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

Если вы хотите осуществить удаленную отладку с подключением целевого компьютера через com-порт к хост-машине, то воспользуйтесь опциями /port и /baud для того чтобы указать номер порта и скорость обмена.

Если вы будете производить удаленную отладку с подключением через кабель FireWire (интерфейс IEEE 1394), то для того чтобы включить соответствующий режим используйте опцию /dbg1394 и для того чтобы указать номер канала опцию /ch.

Чтобы убедиться в том, что изменения внесены, проверьте загрузочные используя команду bootcfg с параметром /query. Осуществив команду exit, закройте окно командного процессора.

При необходимости измените параметры загрузки операционной системы. Откройте через меню «Пуск» панель управления, и уже в ней откройте элемент «Система». В открывшемся окне «Свойства системы» выберите вкладку «Дополнительно». В этой вкладке выберите раздел с названием «Загрузка и восстановление» и в нем нажмите на кнопку «Параметры». В появившемся окне «Загрузка и восстановление» нужно активировать опцию «Отображать список операционных систем». Закройте оба диалоговых окна кнопкой «ОК».

Выполните перезагрузку компьютера. Выберите загрузку с отладчиком. Выполните вход в систему и начинайте работать на целевой машине или начните удаленную отладку. Воспользуйтесь такими средствами как WinDbg и KD.

Иногда у меня возникает ситуация, когда Windows ожидает время загрузки для отладчика ядра. Вы видите текст «Windows start», но не логотип.

Если я присоединяю отладчик сейчас, воспроизводится анимация логотипа Windows 7. После этого логотип начинает пульсировать. На этом этапе процесс загрузки больше не продвигается. Загрузка процессора снижается до минимума. Я жду обычно несколько минут, но ничего не происходит.

Это происходит не всегда. Однако, если это произойдет, сброс VM не поможет. Для устранения этой проблемы мне нужно использовать ремонт при запуске. К сожалению, это длится вечно.

Любые идеи, что я могу сделать, кроме запуска ремонта при запуске?

Заранее спасибо!

3

2 ответы

Чтобы устранить проблему, с которой вы столкнулись, достаточно просто нажать F10 во время загрузки. И удалить/отладить и связанные параметры. Затем нажмите enter.

Предложение: Не используйте параметр/debug для параметра меню загрузки по умолчанию. Скопируйте конфигурацию загрузки в новую запись. Затем установите его в режим отладки. Windows не знает, когда вы будете использовать отладчик. Поэтому он должен ждать.

Достойных отладчиков ядерного уровня и под Windows немного, а в Linux их можно пересчитать по пальцам одной руки, да и те большей частью сырые, недоделанные или же заброшенные и мхом заросшие… Сегодня мы поговорим о самом популярном и наиболее интересном из них -
Linice .

Введение

Как уже можно догадаться по названию, Linice – это неофициальный «порт» легендарного
SoftICE под Linux , сохранивший интерфейс, систему команд и большинство возможностей последнего: всплытие по горячей клавише (в Linice это ); установка аппаратных точек останова на все функции и системные вызовы; просмотр GDT/LDT/IDT, физических страниц памяти; возможности, позаимствованные из GDB (вызов произвольной функции командой CALL, сохранение/восстановление контекста регистров, внутренние переменные и т.д.).

В отличие от большинства других отладчиков, работающих через нереентерабельный и легко обнаруживаемый защитами механизм ptrace (Windows-аналогом которого является DEBUG_PROCESS, используемый прикладными отладчиками), Linice использует нативную трассировку, такую же, как в SoftICE, что позволяет обоим отладчикам отлаживать круто защищенные программы, с которыми другие уже не справляются.

На самом деле, это никакой не порт (отсюда и кавычки), а независимый проект, написанный с нуля и распространяющийся в исходных текстах на бесплатной основе (от SoftICE там только вдохновение). Основная часть кода, предназначенная для ядра 2.4, была написана немецким хакером Гораном Девиком, однако поддержкой ядра 2.6 занимались уже совсем другие люди: Daniel Reznick, Peter K. и Carlos Manuel Duclos Vergara. А наш соотечественник - Олег Худаков - переписал ассемблерные файлы с nasm"а на
gcc.

Исходные тексты лежат на официальном сайте проекта -
Linice%0A.com">www.Linice.com , там же находится документация, короткий FAQ и ссылка на форум
Linice%0A">groups.google.com/group/Linice . Готовые бинарные сборки отсутствуют.
Создатели проекта открыли свой собственный аккаунт на SourceForge, но поленились выложить на него какие бы то ни было файлы, представив на обозрение всего лишь 3 screenshot"а весьма низкого качества:
.

Системные требования

Последняя версия Linice носит номер 2.6 и датируется 28 июлем 2005 года, полностью поддерживая ядро 2.4.x и консольный VGA-режим. С более новыми ядрами наблюдаются серьезные проблемы, и ядро 2.6.x поддерживается лишь в ограниченном режиме.
Отладчик разрабатывался и тестировался под Debian 2.6. Его совместимость с остальными дистрибутивами не гарантируется, что вынуждает нас прибегать к бубну, но в некоторых случаях не помогает и бубен. Вообще-то, держать на своей машине Debian только для того, чтобы работать с Linice , – это вполне нормально. Давным-давно, когда реализации SoftICE для NT еще не существовало, многие хакеры инсталлировали Win 9x только для того, чтобы ломать программы, хотя сами сидели под
NT. Поскольку охватить все тонкости установки Linice в рамках одной статьи практически не реально, я ограничусь описанием процесса компиляции и запуска Linice под одним конкретным дистрибутивом - Knoppix 3.7 с ядром 2.4.1 в консольном VGA-режиме.
Linice поддерживает ACPI и многопроцессорные машины, но плохо дружит с X"ми, особенно на видеокартах, отличных от nVidia. 24-битную глубину цветности он вообще не воспринимает, «переваривая» только 8, 16 и 32 бита, поэтому отладку X-приложений удобнее вести через удаленный терминал, подключенный через COM-порт по протоколу VT100. При этом локальная клавиатура также будет работать с
Linice !

Компиляция и конфигурирование Linice

Скачиваем gzip-архив исходных текстов www.Linice .devic.us/Linice -2.6.tar.gz, занимающий чуть меньше мегабайта, распаковываем его на диск, заходим в каталог./docs и из файла readme узнаем, что сборка отладчика под ядро 2.4 осуществляется так:

# cd build
# ./make_bin-2.4
# cd ../bin
# make clean; mak e

Однако перед запуском make необходимо открыть файл./bin-2.4/Makefile и отредактировать строку «TARGET» в соответствии с конфигурацией и архитектурой целевой платформы. В частности, на ACPI-машинах с многоядерными или HyperThreading-процессорами она будет выглядеть так:

TARGET = -DSMP -DIO_APIC

После завершения компиляции в каталоге./bin появится множество файлов и каталогов, но значимыми из них являются только:

linsym – загрузочный модуль отладчика;
linince.dat – файл конфигурации;
xice – поддержка X"ов, при работе в текстовом режиме его можно удалить;
./Linice_2.4.27/Linice.o – загружаемый модуль ядра, содержащий непосредственно сам отладчик.

Процесс сборки Linice

Собрав минимально работающий комплект, неплохо бы получить и все остальное - демонстрационные отладочные примеры, находящиеся в каталоге./test и компилируемые скриптом compile, а также модуль расширения (по-нашему, плагин), лежащий в каталоге./ext, собираемый командой make и загружаемый командой insmod. Никакой пользы от него нет, но, изучив исходный текст, мы сможем писать свои собственные модули, расширяющие функциональность
Linice .

При загрузке Knoppix"а в нижней строке экрана появляется приглашение «boot:» где необходимо ввести «knoppix 2 vga=normal». Cheat-код «knoppix» выбирает ядро 2.4 (автоматически загружаемое по умолчанию, поэтому «knoppix» можно опустить), «2» блокирует загрузку X"ов, а «vga=normal» устанавливает стандартный vga-режим с разрешением 80x25.

Дождавшись завершения загрузки, говорим «su», затем «passwd» и вводим новый пароль для root"a, под которым тут же заходим в систему, воспользовавшись командой login. Если этого не сделать, попытка запуска Linice закончится сокрушительным провалом с воплем «segmentation fault».

При загрузке Knoppix"а с жесткого диска (на который его можно установить командой «sudo knoppix-installer», набранной в окне терминала из-под LiveCD-сессии) появится стартовое меню со списком доступных ядер. Выбираем Linux(2.4)-1 и нажимаем для задания параметров загрузки - «2 vga=normal». Слово «knoppix» писать не нужно, поскольку ядро уже и так выбрано. После завершения загрузки даем команду login и входим в систему под root"ом (предполагается, что аккаунт был создан ранее).

Запуск отладчика осуществляется командой./linsym –i, после чего тот немедленно появляется на экране. Если же этого не происходит, попробуй указать ключ "--verbose 3" для вывода диагностических сообщений.
Одной из причин отказа в загрузке может быть отсутствие файла /boot/System.map, содержащего адреса ядерных функций. Загрузка провалится и в том случае, если содержимое System.map не соответствует текущему ядру, что может произойти, например, при его рекомпиляции. Некоторые составители дистрибутивов либо вообще не включают System.map (полагая, что это усилит безопасность системы, так как rootkit"ам будет сложнее осуществить перехват syscall"ов), либо помещают сюда что-то совершенно левое и вообще непонятно откуда взявшееся. В таких случаях достаточно просто перекомпилировать ядро, указав отладчику путь к файлу System.map с помощью ключа "-m", если он расположен не в /boot, а где-нибудь в другом месте. Таким образом, и безопасность не пострадает, и Linice сможет работать!
Возврат из отладчика в систему происходит по или с помощью команды «x ». Комбинация вызывает отладчик из любой программы. Однако вовсе не факт, что мы очутимся в ее контексте, ведь Linux - многозадачная система, переключающая процессы один за другим, а команды ADDR (переключающей контексты) в «лексиконе» Linice все еще не существует, и когда она появится - неизвестно. Поэтому приходится хитрить, устанавливая точки останова на системные вызовы, используемые конкретной программой, или врываясь в процесс по методу INT 03h, о чем мы сейчас и поговорим.

За выгрузку отладчика (если его действительно хочется выгрузить) отвечает ключ "-x", переданный все тому же linsym"у.

Основы работы с Linice

Для тех, кто уже работал с SoftICE, освоение Linice не представит никакой проблемы. Здесь используются все те же команды: D – дамп памяти, E – редактирование памяти, T – пошаговая трассировка, P – трассировка без захода в функции, R – просмотр/модификация регистров, BPM/BPX – установка точки останова на доступ/исполнение памяти и т.д. Полный перечень команд содержится как во встроенной справке, вызываемой по HELP (кстати, «HELP имя_команды» выдает дополнительную информацию по команде), так и в штатной документации.

Давай нажмем и пороемся в списке процессов, выводимых на экран командой PROC, причем текущий процесс выделяется голубым цветом:

:PROC

1 0000 C1C3E000 SLEEPING 0 0 init
2 0000 F7EE8000 SLEEPING 0 0 keventd
3 0000 F7EE2000 SLEEPING 0 0 ksoftirqd_CPU0
4 0000 F7EE0000 SLEEPING 0 0 ksoftirqd_CPU1
5 0000 F7ED0000 SLEEPING 0 0 kswapd
6 0000 F7EAA000 SLEEPING 0 0 bdflush
7 0000 F7EA8000 SLEEPING 0 0 kupdated
56 0000 F6A36000 SLEEPING 0 0 kjournald
1006 0000 F7A34000 RUNNING 0 0 automount
1013 0000 F68E6000 SLEEPING 0 0 cupsd
...
1105 0000 F6DDE000 SLEEPING 0 0 mc
1106 0000 F6DD4000 SLEEPING 0 0 cons.saver

Процессы - это, конечно, хорошо, но как же все-таки нам отлаживать программы? Самое простое – воткнуть в точку входа машинную команду CCh, соответствующую инструкции INT 03h, предварительно записав содержимое оригинального байта. Это можно сделать любым hex-редактором, например, неоднократно упоминаемым мной
HTE.

Загрузив файл в редактор, нажимаем (mode), выбираем elf/image, подгоняем курсор к «entrypoint:», давим (edit) и изменяем первый байт на CCh, сохраняем изменения по (save) и выходим. При запуске пропатченной программы Linice немедленно всплывает, потревоженный исключением, сгенерированным CCh, после которого EIP указывает на конец
CCh.

Состояние программы c пропатченной точкой входа в момент всплытия отладчика

0023:080482C0 CC int 3
0023:080482C1 ED in eax, dx
0023:080482C2 5E pop esi
0023:080482C3 89E1 mov ecx, esp

Курсор указывает на инструкцию in eax,dx (EDh), представляющую собой осколок от пропатченной команды xor ebp,ebp (31h EDh). Теперь (по идее) мы должны восстановить оригинальный байт, поменяв CCh на 31h, уменьшить регистр EIP на единицу и продолжить трассировку в обычном режиме.

Да вот не тут-то было! Linice - это, конечно, порт, но только очень сырой, и модифицировать память страничного имиджа он не умеет, даже если предварительно открыть кодовый сегмент на запись. Ни E (редактирование), ни F (заполнение), ни M (копирование памяти) не работают! Зато работает запись в стек, и нам, хакерам, этого вполне достаточно.

Запоминаем текущее значение регистра EIP; копируем пропатченную машинную команду на вершину стека; восстанавливаем там байт CCh; передаем на нее управление, меняя значение EIP; выполняем ее, совершив единичный акт трассировки; и возвращаем EIP на место, то есть на следующую машинную команду:

Восстановление оригинального байта, замененного инструкцией INT 03h

; Смотрим, что находится на вершине стека (из чистого любопытства).
:d esp-10
0018:BFFFEFC0 C0 82 04 08 00 00 00 00 5D 0C 00 40 DC EF FF BF

; Копируем пропатченную машинную команду на вершину стека.
; Число 10h - максимально возможный размер машинной команды на x86.
:m eip-1 L 10 esp-10

; Смотрим, как изменился стек.
:d esp-10
0018:BFFFEFC0 CC ED 5E 89 E1 83 E4 F0 50 54 52 68 F0 85 04 08

; Ага! Стек действительно изменился, самое время исправлять CCh на 31h.
:e esp-10 31
Edit immediate data not implemented yet.

; Упс! Непосредственное присвоение данных в Linice не реализовано,
; но мы можем отредактировать дамп в интерактивном режиме (так же,
; как в SoftICE) или дать команду F esp-10 L 1 31, только учти,
; что, в отличие от SoftICE, отладчик Linice не обновляет окно дампа,
; поэтому после выполнения команды F может показаться, что
; результата нет; на самом деле, это не так, стоит только обновить
; дамп командой D esp-10, и все встанет на свои места.

; Передаем управление на команду, скопированную в стек,
; запоминаем значение регистра EIP.
:r eip (esp-10)
reg: eip = BFFFEFC0

; Совершаем единичный акт трассировки.
:t
0023:BFFFEFC2 5E pop esi

; Как мы видим, регистр EIP увеличился на 2 (BFFFEFC2h - BFFFEFC0h) = 02h,
; следовательно, адрес следующей команды равен: 080482C1h - 01h + 02h = 080482C2h,
; где 080482C1h - начальное значение EIP при входе в программу, а 01h - размер INT 03h.

; Устанавливаем EIP на команду, следующую за пропатченной инструкцией.
:r eip 80482C2
reg: eip = 80482C2

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

Команда exp выводит имена, экспортируемые ядром, любое из которых может фигурировать в выражениях, например, «bpx do_bkr» эквивалентно «bpx C012C9E8».

Вывод имен, экспортируемых ядром

:exp
kernel
C0320364 mmu_cr4_features
C02AC3A4 acpi_disabled
C02AC8A0 i8253_lock
...
C012BDA8 do_mmap_pgoff
C012C764 do_munmap
C012C9E8 do_brk
C011E990 exit_mm
C011E69C exit_files

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

Таблица системных вызов, как известно, представляет собой массив двойных слов, начинающийся с адреса sys_call_table (эта переменная экспортируется ядром).

Таблица системных вызовов

; Переводим отладчик в режим отображения двойных слов.
:dd

; Выводим таблицу на экран.
:d sys_call_table
0018:C02AB6A8 C0126ACC F8932650 F89326A0 C013DC10
0018:C02AB6B8 C013DD18 C013D5C8 C013D724 C011F3BC
0018:C02AB6C8 C013D664 C014A8E0 C014A3B4 F893020C

Каждый элемент таблицы соответствует своему системному вызову, а каждый вызов имеет свой номер, который можно узнать, заглянув в файл /usr/include/sys/syscall.h, но лучше это делать не под Linux, где никаких непосредственных номеров нет, а позаимствовать тот же самый файл из BSD – все равно номера основных системных вызовов на всех системах совпадают. В частности, системный вызов open проходит под номером 5.

Чтобы установить точку останова на open, необходимо узнать его адрес, находящийся в пятом двойном слове таблицы системных вызовов, считая от нуля, и равный (в данном случае) C013D5C8h.

Установка точки останова на системный вызов open

; Устанавливаем точку останова на системный вызов open,
:bpx C013D5C8
; выходим из отладчика,
:x
...
# открываем какой-нибудь файл,
...
; отладчик тут же всплывает, сообщая нам об этом,
:Breakpoint due to BPX 01

; даем команду proc, чтобы убедиться, что мы вклинились в свой процесс.
:proс
PID TSS Task state uid gid name
1049 0000 F6364000 SLEEPING 0 0 getty
1145 0000 F61CC000 SLEEPING 0 0 mc
1146 0000 F614A000 SLEEPING 0 0 cons.saver

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

Заключение

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

Рассказать друзьям