Ранние версии WinDbg‘а от Microsoft не пользовались у хакеров большой популярностью и все дружно налегали на Soft-Ice, но теперь, когда поддержка последнего прекращена и он обречен на медленное, но неотвратимое умирание, возникает вопрос: как дальше жить и чем ломать? Тем временем WinDbg сильно повзрослел, и хотя он и отстой, но по целому ряду характеристик он обгоняет Soft-Ice. Сейчас я покажу, как использовать WinDbg в качестве API- и RPC-шпиона.

API- и RPC-шпионы входят в активный инструментарий хакера. Эти орудия борьбы должны быть всегда остро заточены и стоять наготове к десантированию в тыл врага для сбора информации о вызываемых функциях. Зная, какие функции (и с какими аргументами) вызывает защита, мы можем ставить точки останова, всплывая отладчиком в непосредственной близости от штаб-квартиры врага. Если же этой информации у нас нет, точки останова приходится вставить вслепую, гадая, какой именно API-функцией воспользовалась программа. В частности, одних только функций для чтения текущей даты (необходимой защите для определения периода истечения триала) существует с полдесятка, и без шпиона нет никакой возможности
угадать, какой именно из них воспользовался разработчик.

То же самое относится и к RPC-вызовам (Remote Procedure Calls), своеобразному фундаменту множества служб, к числу которых принадлежит Служба печати, да и, естественно, не только она одна.

В общем, без шпионов ломать становится совсем хреново. Но Soft-Ice не предоставляет таких возможностей, и приходится использовать сторонние средства, большинство из которых способны шпионить только за честными программами. К тому же, неудобно каждый раз выходить из отладчика, чтобы запустить очередную утилу. Намного комфортнее держать весь хакерский арсенал в одном месте. И этим местом постепенно становиться Microsoft Windows Debugger, поддерживающий множество полезных расширений на все случаи жизни и, естественно, позволяющий писать нужные нам расширения самостоятельно.

Преодолевая стойкое убеждение перед продукцией Microsoft, все же скачаем этого зверя и посмотрим, на что он способен.

 

Первое знакомство с WinDbg

Microsoft Windows Debugger (далее по тексту просто WinDeb) входит в состав множества продуктов: Platform SDK, DDK, WDF, а также поставляется вместе с самостоятельным пакетом «Debugging Tools for Windows», занимающим чуть больше 15 Мб. Причем версия WinDeb из комплекта «Debugging Tools for Windows» обычно самая свежая и содержит наибольшее количество всяких полезных расширений. Скачать ее можно с www.microsoft.com/whdc/devtools/debugging (32-битная и 64-битная версии). Microsoft устроила бесплатную раздачу, не требуя даже проверки подлинности копии Windows. По крайней мере, пока. В любом случае, этот пакет валяется на многих сайтах, но далеко не всегда первой свежести.

Отладчик WinDbg представлен в двух «ипостасях»: i386kd.exe (для 64-битной версии — ia64kd.exe) — консольный kernel-debugger, отлаживающий только драйверы вместе с дампами памяти ядра и требующий как минимум двух машин, связанных com-шнурком или взаимодействующих через сеть. Если двух машин нет, можно воспользоваться VMWare, поддерживающим виртуальные сетевые адаптеры и позволяющим загонять com-порт (виртуальный, естественно) в пайп. Несмотря на то, что i386kd.exe — довольно мощная и хорошая штука (подробно описанная у Шрайбера в его «Недокументированных возможностях Windows 2000»), для наших хакерских целей она не потребуется.

WinDbg.exe — представляет собой типичное GUI-приложение, довольствующееся одним компьютером и позволяющее отлаживать прикладные программы, анализировать дампы памяти, шпионить за событиями, происходящими в системе. А вот для отладки драйверов опять-таки понадобится второй компьютер, соединенный сетью или шнурком, но мы обойдемся и без шнурка.

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

ОК, начинаем рыть в глубь. В каталогах w2kchk и w2kfre валяются модули расширения для Windows 2000, конструктивно выполненные в виде динамических библиотек. Содержание обоих каталогов идентично, и разница между ними заключается в том, что *chk работает с отладочной версией ядра (checking build), а *fre — с финальной (release).
Посмотрим, что у нас здесь находится:

Модули расширения для WinDbg, предназначенные для Windows 2000

Содержимое папки C:\Program Files\Debugging Tools for Windows\w2kfre

13.08.2005  20:19       <DIR>          .
13.08.2005  20:19       <DIR>          ..
06.02.2004  01:38              105 499 acpikd.dll
06.02.2004  01:38              179 227 gdikdx.dll
06.02.2004  01:38              302 620 userkdx.dll
06.02.2004  01:38              106 524 vdmexts.dll
              11 файлов      3 845 428 байт
               2 папок     995 536 896 байт свободно

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

Модули расширения для WinDbg, предназначенные для Windows XP

Содержимое папки C:\Program Files\Debugging Tools for Windows\winxp

13.08.2005  20:19       <DIR>          .
13.08.2005  20:19       <DIR>          ..
21.01.2004  10:43               73 728 acpikd.dll
28.06.2002  15:47                4 841 default.tmf
24.02.2004  13:01              285 696 exts.dll
19.02.2004  18:19            1 096 192 kdexts.dll
21.01.2004  12:30               66 048 minipkd.dll
21.01.2004  10:26               50 176 wmitrace.dll
21.01.2004  10:37               77 312 wow64exts.dll
              17 файлов      2 653 500 байт
               2 папок     995 532 800 байт свободно

Как видно, набор расширений для XP намного богаче, но я все равно не изменю своей любимой Windows 2000, под которой сидел, сижу и буду сидеть, а когда же она окончательно одряхлеет, мигрирую на FreeBSD, тем более что расширения, ответственные за шпионов, хранятся в каталоге winext, общем для всех систем.

Модули расширения для WinDbg, предназначенные для осей всех типов

Содержимое папки C:\Program Files\Debugging Tools for Windows\winext

13.08.2005  20:19       <DIR>          .
13.08.2005  20:19       <DIR>          ..
24.02.2004  13:01              612 864 ext.dll
24.02.2004  13:01              174 592 kext.dll
19.02.2004  18:44              228 864 logexts.dll
13.08.2005  20:19       <DIR>          manifest
24.02.2004  13:01               53 760 uext.dll
21.01.2004  12:28               22 528 wdfkd.dll
               5 файлов      1 092 608 байт
               3 папок     995 524 608 байт свободно

Файл с ничего не говорящим именем logexts.dll — это и есть шпионский компонент (ну, для шпионов маскироваться — вполне нормально и ничего удивительного тут нет).

Теперь — что касается самого WinDeb. Раскладку окон, цвет и гарнитуру шрифтов каждый может настроить под свой вкус, поскольку в конфигурации по умолчанию с отладчиком долго работать невозможно, иначе глаза опустятся куда-то в район хвоста, а для хакеров глаза — второй инструмент после серого мозгового вещества!

Так что первое, что нужно сделать с WinDeb, — это настроить его под свой собственный вкус (а вкусы, как известно, у всех разные).

 

Техника API-шпионажа

В состав Platform SDK изначально входило какое-то подобие API-шпиона (точнее, пародия на API-шпиона), расположенное в \Microsoft Platform SDK\Bin\WinNT\Apimon.Exe, однако оно выдавало только общую статистку по API-вызовам без учета их хронологии и постоянно падало при попытке загрузить в него что-то более сложное, чем notepad. Короче, для взлома Apimon.exe не годился. Однозначно!

Посмотрим на WinDbg, что же в нем изменилось? Забегая вперед, скажем: абсолютно все! Microsoft предоставила нам сложный и могущественный инструмент, способный решать широкий круг задач и противостоять различным антиотладочным приемам, которыми понапичканы современные защитные механизмами.

Короче, будем считать, что я тебя соблазнил. Приступаем к экспериментам. Первым делом загружаем в отладчик файл, за которым мы будем шпионить, например, все тот же блокнот. Делается это так: «File -> Open executable -> notepad.exe». Или так: нажимаем <CTRL-E>, вбиваем «notepad.exe». В крайнем случае файл можно загрузить из командной строки. Только не нажимай раскрывающуюся папку на панели инструментов — это все равно не поможет, так как она предназначена для работы с исходными текстами и их окружением, которых в нашем распоряжении, естественно, нет.

Неверное определение точки входа при загрузке исполняемого файла в WinDbg

CommandLine: C:\WINNT\NOTEPAD.EXE 
Symbol search path is: *** Invalid ***
Executable search path is: 
ModLoad: 01000000 01010000   notepad.exe
ModLoad: 77f80000 77ffd000   ntdll.dll
ModLoad: 76ae0000 76b1e000   C:\WINNT\system32\comdlg32.dll
ModLoad: 772c0000 77326000   C:\WINNT\system32\SHLWAPI.DLL
ModLoad: 79060000 790c5000   C:\WINNT\system32\ADVAPI32.dll 
ModLoad: 71710000 71794000   C:\WINNT\system32\COMCTL32.DLL
ModLoad: 7ce80000 7d0c6000   C:\WINNT\system32\SHELL32.DLL
ModLoad: 777d0000 777ee000   C:\WINNT\system32\WINSPOOL.DRV
ModLoad: 79500000 79511000   C:\WINNT\system32\MPR.DLL
(510.508): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00071f04 ecx=00000009 edx=00000000 esi=7ffdf000 edi=00071f70
eip=77f9193c esp=0006f984 ebp=0006fc98 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - 
ntdll!DbgBreakPoint:
77f9193c cc               int     3

Отладчик послушно загружает файл, отображая все динамические библиотеки, перечисленные в таблице импорта, показывает содержимое регистров и устанавливает точку останова в EntryPoint. На самом деле, это мы думаем, что отладчик устанавливает точку останова в EntryPoint, а в действительности все обстоит не так! Судя по адресу 77F9193Ch, лежащему глубоко внутри NTDLL.DLL, это не совсем EntryPoint, точнее, совсем не EntryPoint, а native-API-функция DbgBreakPoint, которую можно трассировать до конца света, но так ни к чему и не прийти. Приходится выкручиваться и применять всякие недетские извращения (впрочем, для хакеров они вполне типичны).

Загружаем notepad.exe в наш любимый hiew.exe (или любой другой hex-редактор), жмем на <ENTER> для перехода в hex-режим, давим <F8> для отображения заголовка и переходим в истинную точку входа по <F5>, адрес которой (в моем случае равный 1006420h) высвечивается в левом верхнем углу экрана.

Возвращаемся в WinDbg и, находясь в окне команд (такая строчка с деловито мерцающим курсором), пишем «BP 1006420», устанавливая точку останова, после чего жмем <F5> (или даем команду g — в смысле «goto», продолжение выполнения) и ждем развития событий. А события ждать себя не заставляют:

Ручная установка бряка на истинную точку входа

0:000> BP 1006420
0:000> g
ModLoad: 75e00000 75e1a000   C:\WINNT\system32\IMM32.DLL
ModLoad: 10000000 10005000   C:\WINNT\system32\wmfhotfix.dll
Breakpoint 0 hit
eax=00000000 ebx=7ffdf000 ecx=00010101 edx=ffffffff esi=0009a0f0 edi=017af640
eip=01006420 esp=0006ffc4 ebp=0006fff0 iopl=0         nv up ei pl zr na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
notepad+0x6420:
01006420 55               push    ebp

Отладчик подгружает еще две динамические библиотеки (одна из которых — wmfhotfix.dll, заплатка от Ильфака), радостно сообщает, что «Breakpoint 0 hit» (сработала точка останова), выводит значения регистров (ну куда же без них) и первую машинную команду, стоящую в точке входа, — push ebp.

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

Дизассемблирование окрестностей точки входа

0:000> u
notepad+0x6420:
01006420 55               push    ebp
01006421 8bec             mov     ebp,esp
01006423 6aff             push    0xff
01006425 6888180001       push    0x1001888
0100642a 68d0650001       push    0x10065d0
0100642f 64a100000000     mov     eax,fs:[00000000]
01006435 50               push    eax
01006436 64892500000000   mov     fs:[00000000],esp

Теперь, когда все подготовительные мероприятия завершены, необходимо подключить модуль расширения. Для этого даем команду !load <name>, где name — имя модуля расширения без «.dll» (в данном случае — logexts). Полностью вся команда выглядит так:

0:000> !load logexts

Отладчик проглатывает ее как ни в чем не бывало, и создается впечатление, что ничего не происходит. Но это не так! Чтобы убедиться, что модуль расширения успешно загружен, вызовем его локальную справку, набрав команду !logexts.help. Мы видим, сколько тут всего, хорошего и разного! С одного захода это даже не разгрызть, но мы все-таки попробуем. Команда !loge [dir] активирует шпионаж за API-функциями, при желании позволяя указать каталог, в котором будет автоматически создана поддиректория LogExts для хранения логов. Логи могут писаться как в текстовом, там и в двоичном формате (формат вывода задается командой !logo), причем имя лога соответствует имени исполняемого файла, за которым он
шпионил (например, noTEPAD.EXE.txt — да-да, вот именно в таком регистре он и записывается).

Вызванная без параметров команда !logo выводит текущий формат лога. Чтобы включить текстовый формат, необходимо набрать «!logo e t», а чтобы включить все 3 параметра, необходимо трижды вызвать !logo с разными ключами. К сожалению, конструкцию «!logo e dtv» отладчик не переваривает. Редиска!

Для сокращения размеров лога и выкидывания заведомо ненужной информации WinDbg поддерживает категории API-вызовов, список которых можно вывести на экран командой !logc:

Просмотр категорий API-функций

0:000> !logc
Categories:
1 AdvApi32                        Enabled
2 AtomFunctions                   Enabled
3 AVIFileExports                  Enabled
4 Clipboard                       Enabled
5 ComponentObjectModel            Enabled
6 DebuggingAndErrorHandling       Enabled
7 DeviceFunctions                 Enabled
8 Direct3D                        Enabled
9 DirectDraw                      Enabled
...
25 User32StringExports             Enabled
26 Version                         Enabled
27 WinSock2                        Enabled

Как видно, всего имеется 27 категорий, и для просмотра функций, входящих в каждую из категорий, можно воспользоваться командой !logic p #, где # — номер категории, например, 16 — MemoryManagementFunctions.

Просмотр имен API-функций, входящих в категорию MemoryManagementFunctions

0:000> !logc p 16
MemoryManagementFunctions:
  AllocateUserPhysicalPages       KERNEL32.DLL
  FreeUserPhysicalPages           KERNEL32.DLL
  GetProcessHeap                  KERNEL32.DLL
  GetProcessHeaps                 KERNEL32.DLL
…
  OpenFileMappingA                KERNEL32.DLL
  OpenFileMappingW                KERNEL32.DLL
  UnmapViewOfFile                 KERNEL32.DLL

Для шпионажа за определенными категориями функций даем команду !logc e # # #, где e — включить (enable) шпионаж, а # — перечень категорий. Ключ ‘d’ (disable), соответственно, означает исключить данную категорию (категории) API-функций из круга подозреваемых и не шпионить за ними. Команда !logc e * включает все категории (и это основной режим шпиона, в котором гоняют его хакеры при первом знакомстве с ломаемой программой).

При желании можно указать перечень динамических библиотек, за которыми следует/не следует следить. Зачастую это намного проще, чем возиться с категориями. Отображением списка текущих поднадзорных библиотек занимается команда !logm:

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

0:000> !logm
Included modules:
USER32.DLL      
GDI32.DLL       
ADVAPI32.DLL

Просматривая этот список, мы с удивлением обнаруживаем в нем отсутствие KERNEL32.DLL — базовой ядерной библиотеки, содержащей максимум интересующих нас функций. Попытка включить ее в список командой !logm i KERNEL32.DLL приводит к появлению многоэтажного матерного ругательства: мол, KERNEL32.DLL обязательно должна быть исключена и включению не подлежит:

Категорический отказ отладчика шпионить за KERNEL32.DLL

0:000> !logm i KERNEL32.DLL
KERNEL32.DLL is mandatory for exclusion so it can't be included.
Included modules:

На самом деле, стоит только нажать «F5», как в логе (параллельно выводимом на экран и в файл) появятся перехваченные имена API-функций, принадлежащих KERNEL32.DLL:

Фрагмент шпионского протокола, содержащего всю необходимую нам инфу

Thrd 4c4 010029BD GetProcAddress( NULL "RegisterPenApp") -> NULL [FAIL]
Thrd 4c4 77E202F2 LoadLibraryExW("INDICDLL.dll" NULL ALTERED_SRCH_PATH) -> 0x6E380000
Thrd 4c4 77106CF2 GetProcAddress( 0x77F80000 "NtQuerySystemInformation") -> 0x77F889DC
Thrd 4c4 77106D0D GetProcAddress( 0x77F80000 "NtOpenFile") -> 0x77F886AC
Thrd 4c4 77106D1A GetProcAddress( 0x77F80000 "RtlInitUnicodeString") -> 0x77FABE9C
Thrd 4c4 77E202F2 LoadLibraryExW("PDSHELL.DLL" NULL ALTERED_SRCH_PATH) -> 0x00F30000
Thrd 4c4 77E202F2 LoadLibraryExW("SSSensor.dll" NULL ALTERED_SRCH_PATH) -> 0x013B0000
Thrd 4c4 76AE1DAB GetProcAddress( 0x79430000 "GetUserDefaultUILanguage") -> 0x7947106B
Thrd 4c4 7CEAAF39 GetProcAddress( 0x77E10000 "GetSystemMetrics") -> 0x77E33277
Thrd 4c4 7CEAAF4A GetProcAddress( 0x77E10000 "MonitorFromWindow") -> 0x77E2920B
Thrd 4c4 7CEAAF5B GetProcAddress( 0x77E10000 "MonitorFromRect") -> 0x77E20D54
Thrd 4c4 7CEAAF6C GetProcAddress( 0x77E10000 "MonitorFromPoint") -> 0x77E2A0F2
Thrd 4c4 7CEAAF7D GetProcAddress( 0x77E10000 "EnumDisplayMonitors") -> 0x77E1F61D
Thrd 4c4 7CEAAF8E GetProcAddress( 0x77E10000 "EnumDisplayDevicesW") -> 0x77E18A08
Thrd 4c4 7CEAAFAE GetProcAddress( 0x77E10000 "GetMonitorInfoW") -> 0x77E2A07E

В наше распоряжение попадают номера потоков (thrd), адреса вызова API-функций вместе с передаваемыми ими аргументами. По приведенному выше фрагменту лога видно, что, вызвав функцию GetProcAddress(NULL "RegisterPenApp") по адресу 010029BDh, блокнот погрузился в пучину системных библиотек, лежащих далеко за пределами принадлежащей ему области адресов. Но это не главное. Главное то, что шпион от Microsoft работает и успешно шпионит, практически ни в чем не уступая большинству своих конкурентов, а кое в чем их даже и обгоняя!

 

Техника RPC-шпионажа

RPC-шпионаж осуществляется во всем аналогично API-шпионажу (ну, практически аналогично), только вместо logexts используется расширение rpcexts, загружаемое командой !load rpcexts и выдающее справку по своим ключам командой !rpcexts.help.

Ключи же настолько обширны, что требуют для своего описания целой статьи. Но в большинстве случаев встроенного хелпа вполне достаточно!

 

Заключение

Мы рассмотрели всего лишь 2 расширения отладчика WinDbg из очень многих! Ну так чего же мы сидим? Чего ждем?! Загружаем все расширения одно за другим, даем команду !name.help, смотрим, курим, читаем, втыкаем, после чего экспериментируем, постигая все новые границы и мысленно сравнивая возможности WinDbg и Soft-Ice. Но, несмотря ни на что, Soft-Ice все-таки жалко. Хороший был отладчик…


Полную версию статьи и дополнительные материалы на диске ты можешь найти в февральском номере Хакера!

Оставить мнение

Check Also

Цифровой паноптикум. Настоящее и будущее тотальной слежки за пользователями

Даже если ты тщательно заботишься о защите своих данных, это не даст тебе желаемой приватн…