+ Reply to Thread
Results 1 to 2 of 2

Thread: Exploit Development Course Part 1: WinDbg (Перевод: klaus)

  1. #1
    klaus's Avatar

    Default Exploit Development Course Part 1: WinDbg (Перевод: klaus)

    Перейти к содержанию


    Введение

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

    Версия

    Во избежание проблем используйте 32-х разрядную версию WinDbg для отладки 32-х битных выполняемых файлов. Для отладки 64-х битных исполняемых файлов соответственно используйте 64-х битную версию WinDbg.
    Альтернативный вариант: Вы можете переключать WinDbg между 32-х и 64-х битными режимами следующей командой:
    Code:
    !wow64exts.sw
    Символы

    Откройте новый экземпляр WinDbg (если Вы отлаживаете процесс с помощью WinDbg, закройте WinDbg и откройте снова).
    В окне File→Symbol File Path введите:
    Code:
    SRV*C:\windbgsymbols*http://msdl.microsoft.com/download/symbols
    Сохраните рабочее окружение (File→Save Workspace).
    Звездочки это разделители. WinDbg будет использовать первую директорию которую мы указали выше в качестве локального кэша для символов. Путь после второй звёздочки (разделен «;» если более одного) указывает местоположение где могут быть найдены символы.

    Добавление символов на протяжении отладки

    Для добавления пути поиска символов к стандартному на протяжении отладки используйте:
    Code:
    .sympath+ c:\symbolpath
    (Команда без «+» заменит стандартный путь поиска символов а не добавит ещё один.)
    Теперь перезагрузите символы:
    Code:
    .reload
    Проверка символов

    Символы, если они доступны, загружаются по мере надобности. Что бы посмотреть какие модули имеют загруженные символы, используйте следующую команду:
    Code:
    x *!
    Команда «х» поддерживает шаблоны (подстановочные знаки) и может быть использована для поиска символов в одном или более модулях. Для примера, мы можем найти все символы в kernel32 имя которых начинается с «virtual» следующим путем:
    Code:
    0:000> x kernel32!virtual*
    757d4b5f          kernel32!VirtualQueryExStub (<no parameter info>)
    7576d950          kernel32!VirtualAllocExStub (<no parameter info>)
    757f66f1          kernel32!VirtualAllocExNuma (<no parameter info>)
    757d4b4f          kernel32!VirtualProtectExStub (<no parameter info>)
    757542ff          kernel32!VirtualProtectStub (<no parameter info>)
    7576d975          kernel32!VirtualFreeEx (<no parameter info>)
    7575184b          kernel32!VirtualFree (<no parameter info>)
    75751833          kernel32!VirtualAlloc (<no parameter info>)
    757543ef          kernel32!VirtualQuery (<no parameter info>)
    757510c8          kernel32!VirtualProtect (<no parameter info>)
    757ff14d          kernel32!VirtualProtectEx (<no parameter info>)
    7575183e          kernel32!VirtualFreeStub (<no parameter info>)
    75751826          kernel32!VirtualAllocStub (<no parameter info>)
    7576d968          kernel32!VirtualFreeExStub (<no parameter info>)
    757543fa          kernel32!VirtualQueryStub (<no parameter info>)
    7576eee1          kernel32!VirtualUnlock (<no parameter info>)
    7576ebdb          kernel32!VirtualLock (<no parameter info>)
    7576d95d          kernel32!VirtualAllocEx (<no parameter info>)
    757d4b3f          kernel32!VirtualAllocExNumaStub (<no parameter info>)
    757ff158          kernel32!VirtualQueryEx (<no parameter info>)
    Символы подстановки также могут быть использованы в модульной части:
    Code:
    0:000> x *!messagebox*
    7539fbd1          USER32!MessageBoxIndirectA (<no parameter info>)
    7539fcfa          USER32!MessageBoxExW (<no parameter info>)
    7539f7af          USER32!MessageBoxWorker (<no parameter info>)
    7539fcd6          USER32!MessageBoxExA (<no parameter info>)
    7539fc9d          USER32!MessageBoxIndirectW (<no parameter info>)
    7539fd1e          USER32!MessageBoxA (<no parameter info>)
    7539fd3f          USER32!MessageBoxW (<no parameter info>)
    7539fb28          USER32!MessageBoxTimeoutA (<no parameter info>)
    7539facd          USER32!MessageBoxTimeoutW (<no parameter info>)
    Вы можете заставить WinDbg загрузить символы для всех модулей:
    Code:
    ld*
    Выполнение данной команды займет некоторое время. Выполните Debug→Break для остановки выполнения операции.

    Помощь

    Просто введите:
    Code:
    .hh
    или нажмите F1 для открытия окна помощи.
    Для получения помощи по определенной команды наберите следующее:
    Code:
    .hh <команда>
    Где <команда> это интересующая Вас команда, или нажмите F1 и выберите раздел, в котором вы можете найти интересующую вас команду или тему.

    Режимы отладки

    Локально

    Вы можете отлаживать новый процесс, или процесс, который уже запущен:
    1. Запустить новый процесс для отладки выполнив File→Open Executable.
    2. Присоединиться к уже запущенному процессу выполнив File→Attach to a Process.

    Удаленно

    Для отладки программы удаленно есть по крайней мере два варианта:
    1. Если Вы в данный момент отлаживаете программу локально на машине А, Вы можете ввести следующую команду (выберите порт (port) который вам надо):
      Code:
      .server tcp:port=1234
      Это запустит сервер в WinDbg.
      На машине В запустите WinDbg и выполните File→Connect to Remote Session и введите:

      Code:
      tcp:Port=1234,Server=<IP машины А>
      Укажите правильный порт и IP.

      На машине А запустите dbgsrv так, как показано ниже:

      Code:
      dbgsrv.exe -t tcp:port=1234
      Это запустит сервер на машине А.
    2. На машине В запустите WinDbg и выполните File→Connect to Remote Stub, после чего введите:

      Code:
      tcp:Port=1234,Server=< IP машины А >
      с соответствующими параметрами.

      Вы увидите что File→Open Executable не активна, но Вы можете выбрать File→Attach to a Process. В данном случае Вы увидите список процессов на машине А. Что бы остановить сервер на машине А можно использовать диспетчер задач и убить процесс dbgsrv.exe.

    Модули

    Когда вы загружаете исполняемый файл или присоединяетесь к процессу, WinDbg выведет список загруженных модулей. Если вы хотите увидеть список модулей еще раз, введите:

    Code:
    lmf
    Что бы перечислить конкретные модули, скажем ntdll.dll, используйте:

    Code:
    lmf m ntdll
    Получить информация образа заголовка (image header) модуля, скажем, ntdll.dll, можно набрав:
    Code:
    !dh ntdll
    Знак «!» означает что команда это расширение, к примеру, внешняя команда, которая экспортируется из внешней DLL и вызывается внутри WinDbg. Пользователи могут создавать собственные расширения с целью увеличения функциональности WinDbg.

    Вы можете так же использовать начальный адрес модуля:

    Code:
    0:000> lmf m ntdll
    start    end        module name
    77790000 77910000   ntdll    ntdll.dll   
    0:000> !dh 77790000
    Выражения

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

    К примеру, если EIP равен 77c6cb70, тогда:

    Code:
    bp 77c6cb71
    и

    Code:
    bp EIP+1
    эквивалентны.

    Вы также можете использовать символы:

    Code:
    u ntdll!CsrSetPriorityClass+0x41
    и регистры:

    Code:
    dd ebp+4
    Числа по стандарту в шестнадцатеричной системе исчисления. Что бы явно указать какую базу использовать (2, 8, 10, 16) используйте префикс:

    Code:
    0x123: base 16 (hexadecimal)
    0n123: base 10 (decimal)
    0t123: base 8 (octal)
    0y111: base 2 (binary)
    Для отображения значения в разных форматах используйте команду .format:

    Code:
    0:000> .formats 123
     Evaluate expression:
     Hex:     00000000`00000123
     Decimal: 291
     Octal:   0000000000000000000443
     Binary:  00000000 00000000 00000000 00000000 00000000 00000000 00000001 00100011
     Chars:   .......#
     Time:    Thu Jan 01 01:04:51 1970
     Float:   low 4.07778e-043 high 0
     Double:  1.43773e-321
    Для вычисления выражения используйте «?»:
    Code:
    ? eax+4

    Регистры и псевдорегистры

    WinDbg поддерживает несколько псевдорегистров которые содержат определенные значения. Псевдорегистры обозначаются префиксом «$». Когда используются регистры или псевдорегистры, одни могут добавлять префикс «@» который говорит WinDbg о том, что следует после значений регистр а не символ. Если «@» не используется WinDbg сперва попытается интерпретировать имя как символ.

    Вот несколько примеров псевдорегистров:
    • $teb или @$teb (адрес TEB)
    • $peb или @$peb (адрес PEB)
    • $thread или @$thread (текущий поток)

    Исключения

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

    Code:
    sxe ld <имя модуля 1>,...,<имя модуля N>
    Пример:

    Code:
    sxe ld user32
    Увидеть список исключений:

    Code:
    sx
    Игнорировать исключение:

    Code:
    sxi ld
    Это отменит эффект от первой нашей команды.

    WinDbg прерывается на первичные и вторичные исключения (single-chance exceptions and second-chance exceptions пр. переводчика). Это не разные виды исключений. Как только появляется исключение, WinDbg останавливает выполнение и сообщает что появилось первичное исключение. Первичное исключение – это исключение, которое еще не было отослано отлаживаемой программе но уже возбудилось. Когда мы продолжим выполнение WinDbg пошлет исключение в отлаживаемую программу. Если отлаживаемая программа не обработает исключение, WinDbg снова останавливает выполнение и сообщает о вторичном исключении.

    Когда будем исследовать EMET 5.2, нам надо будет игнорировать первичные исключение на первых шагах программы. Что бы сделать это мы можем использовать следующую команду:

    Code:
    sxd sse
    Точки останова

    Программные точки останова

    Когда вы ставите точку останова на инструкцию, WinDbg сохраняет в память первый байт инструкции и перезаписывает остальную часть байтом 0xCC который является опкодом для “int 3“.

    Когда “int 3“ выполнен, срабатывает точка останова, выполнение останавливается и WinDbg восстанавливает инструкцию методом восстановления её первого байта.

    Для установки точки останова на инструкцию по адресу 0x4110a0 введите:

    Code:
    bp 4110a0
    Вы можете также указать количество пропусков для активации точки останова:

    Code:
    bp 4110a0 3
    Это означает, что точка останова будет игнорироваться первые 2 раза при попадании на инструкцию. Что бы продолжить выполнение (и остановиться на первой встречной точке останова) наберите:

    Code:
    g
    что является сокращение для “go“.

    Выполнять программу до определенного адреса (содержащего код), введите:

    Code:
    g <размещение кода>
    Внутренний механизм работы данной команды таков: WinDbg установит программную точку останова, но после её срабатывания он её удалит. То есть, такая точка останова одноразовая.

    Аппаратная точка останова

    Аппаратные точки останова используют конкретные регистры процессора и являются более универсальными нежели программные точки останова. По сути, одни могут срабатывать на выполнении или на доступе к памяти. Аппаратные точки останова не изменяют код, так что они могут быть использованы вместе с модифицирующимся кодом. К несчастью, Вы не можете установить более 4-х таких точек останова.

    В простой форме, формат команды следующий:

    Code:
    ba <режим> <размер> <адрес> <пропуски (по стандарту=1)>
    где <режим> может быть
    1. ‘e‘ для выполнения
    2. ‘r‘ для установки доступа к памяти на чтение/запись
    3. ‘w‘ для установки доступа к памяти на запись

    <размер> указывает размер местоположения в байтах для мониторинга доступа (всегда 1 если <режим> ‘e‘). <адрес> это местоположение установки точки останова и <пропуски> это количество нужных пропусков для активации точки останова (смотрите ‘bp‘ в качестве примера использования).

    К сведению: Невозможно использовать аппаратные точки останова для процесса до начала его запуска из-за того, что устанавливаются изменением регистров процессора (dr0, dr1, и т.д.) и когда процесс запускается, его поток создается и сбрасывает регистры.

    Обработка точек останова

    Вывести список точек останова можно так:

    Code:
    bl
    где ‘bl‘ означает «список точек останова».

    Пример:

    Code:
    0:000> bl
    0 e 77c6cb70     0002 (0002)  0:**** ntdll!CsrSetPriorityClass+0x40
    Где поля слева на право значат следующее:
    • 0: идентификатор точки останова (ID)
    • e: статус точки останова; может быть включена (e) или выключена (d)
    • 77c6cb70: адрес памяти
    • 0002 (0002): количество пропусков оставшееся до активации
    • 0:****: связанные процесс или поток. Звездочки указывают на то, что точка останова не потоко-зависимая.
    • ntdll!CsrSetPriorityClass+0x40: модуль, функция и смещение где точка останова размещена

    Отключить точку останова:

    Code:
    bd <идентификатор точки останова>
    Удалить точку останова:

    Code:
    bd < идентификатор точки останова >
    Удалить все точки останова:

    Code:
    bc *
    Команды точек останова

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

    Code:
    bp 40a410 ".echo \"Тут регистры:\n\"; r"
    Вот другой пример:

    Code:
    bp jscript9+c2c47 ".printf \"new Array Data: addr = 0x%p\\n\",eax;g"
    Пошаговое выполнение

    Есть по крайней мере три типа пошагового выполнение программы:
    1. step-in / trace (команда: t)
      Данная команда делает прерывание после каждой инструкции. Если вы на call или int, команда прервется на первой инструкции вызываемой функции или на обработчике прерывания int соответственно.
    2. step-over (команда: p)
      Данная команда делает прерывание после каждой инструкции без захода в функции по call или в обработчик прерывания int. К примеру, если вы на инструкции call или int, то команда прервется на инструкции сразу после call или int.
    3. step-out (команда: gu)
      Эта команда (go up) продолжает выполнение и прерывается сразу после следующей ret инструкции.
      Две другие команды для выхода из функций:
      • tt (trace to next return): эквивалентно использованию команды ‘t‘ неоднократно и остановки на первой встречной инструкции ret.
      • pt (step to next return): эквивалентно использованию команды ‘p‘неоднократно и остановки на первой встречной инструкции ret.
      Заметьте, tt также заходит внутрь функций, если Вы хотите получить ret инструкцию текущей функции, используйте pt.
      Разница между pt и gu в том, что pt прерывается на ret инструкцию, в то время как gu прерывается на инструкцию после ret.
      Ниже перечислены варианты ‘p‘ и ‘t‘:
      • pa/ta <address>: step/trace к адресу
      • pc/tc: step/trace к следующей инструкции call/int
      • pt/tt: step/trace к следующей инструкции ret (рассказано в 3 пункте)
      • pct/tct: step/trace к следующей call/int ret инструкцие
      • ph/th: step/trace к следующей условной инструкции

    Отображение памяти

    Отобразить содержимое памяти Вы можете используя ‘d‘ или один из её вариантов:
    • db: отобразить байты
    • dw: отобразить слова(2 байта)
    • dd: отобразить двойные слова(4 байта)
    • dq: отобразить учетверенные слова(8 байт)
    • dyb: отобразить биты
    • da: отобразить нуль-терминальные ASCII строки
    • du: отобразить нуль-терминальные Unicode строки

    Напечатайте .hh d что бы увидеть другие разновидности команды.
    Команда ‘d‘ отображает данные в том же формате что и последние d* команды.

    Упрощенный формат этих команд таков:
    Code:
    d* [диапазон]
    Здесь звездочка используется для представления всех вариаций который мы перечислили выше. Скобки обозначают диапазон который не обязателен. Если диапазон отсутствует, d* отобразит участок памяти сразу после участка, который был отображен предыдущей командой d*.

    Диапазоны можно указывать разными способами:
    1. <начальный адрес> <конечный адрес>
      К примеру:
      Code:
      db 77cac000 77cac0ff
    2. <начальный адрес> L<количество элементов>
      К примеру:
      Code:
      dd 77cac000 L10

      Отобразит десять двойных слова (DWORD) начиная с указанного адреса (77cac000).
    3. <начальный адрес>
      Когда указана только начальный адрес, WinDbg отобразит следующих 128 байт.

    Редактирование памяти

    Вы можете редактировать память используя:

    Code:
    e[d|w|b] <адрес> [<новое значение 1> ... <новое значение N>]
    где e[d|w|b] необязательные параметры и задают размер элементов для редактирования (d = dword, w = word, b = byte). Если новые значения опущены, WinDbg запросит у вас их интерактивный ввод.

    Пример:

    Code:
    ed eip cc cc
    Данная команда перепишет первые два dword по адресу в eip значением 0xCC.

    Поиск в памяти

    Для поиска по памяти используйте команду ‘s‘. Её формат таков:

    Code:
    s [-d|-w|-b|-a|-u] <начальный адрес> L?<количество элементов > <искомые значения>
    где d, w, b, a и u означают dword, word, byte, ascii и unicode.

    <искомые значения> - это последовательность значений для поиска.

    Пример:

    Code:
    s -d eip L?1000 cc cc
    Ищет две последовательности двойных слов 0xcc 0xcc в памяти в диапазоне [eip, eip + 1000*4 – 1].

    Указатели

    Вам может понадобиться разыменовать указатель. Что бы сделать это, надо использовать оператор poi:

    Code:
    dd poi(ebp+4)
    В данной команде poi(ebp+4) приводиться к dword (или qword в 64-х битном режиме) по адресу ebp+4.

    Другие полезные команды

    Отобразить регистры:

    Code:
    r
    Отобразить конкретные регистры, скажем eax и edx:

    Code:
    r eax, edx
    Вывести первые 3 инструкции на которые указывает EIP:

    Code:
    u EIP L3
    где ‘u‘ это сокращение от unassemble (дизассемблировать) и ‘L‘ позволяет вам указать количество строк для отображения.

    Вывести стек вызовов:

    Code:
    k
    Дамп структур

    Здесь находятся команды для отображения структур:


    Предполагаемая настройка


    Сохраните рабочее окружение (File→Save Workspace) после настройки всех окон.

    © Translated by klaus (r0 Crew)
    Last edited by klaus; 26-06-2015 at 08:34.
    Do not follow the ancient masters, seek what they sought. (c) Matsuo Bashō

  2. 7 пользователя(ей) сказали cпасибо:
    Dark Koder (22-06-2015) Darwin (21-06-2015) benedict (21-06-2015) dukeBarman (21-06-2015) gavz (29-01-2016) nosos (21-06-2015) root (21-06-2015)
  3. #2
    root's Avatar

    Default Re: Exploit Development Course Part 1: WinDbg

    Спасибо, давно мы не брались за переводы =)
    Успех – это путь от провала до провала без потери энтузиазма. (В. Черчиль)

    Не бойся идти медленно, бойся остановиться. (Китайская пословица)

    When you lose fun and start doing things only for the payback, you're dead. (c) TCLH (Phrack 65, Intro)

+ Reply to Thread

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
All times are GMT. The time now is 12:28
vBulletin® Copyright ©2000 - 2017
www.reverse4you.org