Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Майкл_Сикорски,_Эндрю_Хониг_Вскрытие_покажет!_Практический_анализ.pdf
Скачиваний:
18
Добавлен:
19.04.2024
Размер:
17.17 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Глава 10. Отладка ядра с помощью WinDbg   237

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Рис. 10.3. Запуск сеанса отладки ядра в WinDbg

Использование WinDbg

Большинство возможностей WinDbg предоставляются в виде интерфейса командной строки. Здесь мы рассмотрим самые важные команды. Их полный список можно найти в справочном меню WinDbg.

Чтение из памяти

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

dx адресДляЧтения

x — это один из параметров, определяющих способ отображения информации. Самые популярные из них перечислены в табл. 10.1.

Таблица 10.1. Параметры чтения в WinDbg

Параметр

Описание

 

 

da

Читает из памяти и выводит результат в формате ASCII

 

 

du

Читает из памяти и выводит результат в формате Unicode

 

 

dd

Читает из памяти и выводит результат в виде 32-битных слов типа double

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

238  Часть III  •  Продвинутый динамический анализ

w Click

 

 

 

 

 

 

 

 

 

 

 

o

m

 

w

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Например, чтобы вывести строку со сдвигом 0x401020, нужно использовать команду da 0x401020.

Аналогичным образом применяется команда e, предназначенная для изменения значений в памяти. Она имеет следующий синтаксис:

ex адресДляЗаписи данныеДляЗаписи

x здесь имеет то же значение, что и в командах dx. В справочных файлах описано множество дополнительных параметров.

Использование арифметических операций

Манипулировать памятью и регистрами можно напрямую из командной строки, используя такие арифметические операции, как сложение (+), вычитание (-), умножение (*) и деление (/). Параметры командной строки предназначены для сокращенной записи и могут пригодиться при создании выражений для условных точек останова.

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

du dwo (esp+4)

Здесь esp+4 представляет собой местоположение аргумента. Оператор dwo находит указатель на строку, а du заставляет WinDbg вывести ее содержимое.

Создание точки останова

Для создания простых точек останова в WinDbg используется команда bp. Вы также можете указать команды, которые будут автоматически выполняться при срабатывании точки останова, перед тем как управление будет передано пользователю. Вместе с этим можно указать команду g, чтобы после выполнения команд программа не ждала пользователя, а сразу продолжила работу. Например, следующая команда будет выводить второй аргумент при каждом вызове функции GetProcAddress, не останавливая выполнение программы:

bp GetProcAddress "da dwo(esp+8); g"

Так на экран будет выводиться имя функции, запрашиваемой при каждом вызове GetProcAddress. Это довольно полезная возможность, поскольку точка останова, которая не возвращает управление пользователю и не ждет от него выполнения коман­ды, работает намного быстрее. По мере добавления условных выражений, таких как оператор .if и цикл .while, команда может становиться достаточно сложной, поэтому WinDbg позволяет поместить ее внутрь скрипта.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

ПРИМЕЧАНИЕ

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Глава 10. Отладка ядра с помощью WinDbg   239

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Иногда команды пытаются получить доступ к некорректному участку памяти. Например, вторым аргументом функции GetProcAddress может быть либо строка, либо порядковый номер. Во втором случае WinDbg попытается разыменовать неправильный адрес. К счастью, это не приведет к сбою — просто в качестве значения по этому адресу будет выведено «????».

Вывод списка модулей

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

Отладочные символы Microsoft

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

Вданном контексте символ — это всего лишь название некоего адреса в памяти.

Вбольшинстве случаев эти адреса связаны с функциями, но иногда они указывают местоположение данных. Например, без символьной информации функция по адресу 8050f1a2 не будет промаркирована. Если же эта информация присутствует, WinDbg покажет, что функция называется MmCreateProcessAddressSpace (если она находится по указанному адресу). Сложно что-то сказать об этой функции, имея лишь ее адрес, однако ее имя говорит нам о том, что она создает адресное пространство для процесса. Кроме того, с помощью символьных имен можно искать функции и данные в памяти.

Поиск символов

Следующий синтаксис позволяет сослаться на символ в WinDbg:

имяМодуля!имяСимвола

Этот формат подходит для любого участка памяти с адресом. Здесь имяМоду- ля — это имя типа .exe, .dll или .sys, который содержит символ (без расширения), а имяСимвола — это имя, связанное с этим адресом. Исключением является файл ntoskrnl.exe, у которого имя модуля выглядит как nt, а не ntoskrnl. Например, чтобы просмотреть дизассемблированный код функции NtCreateProcess внутри ntoskrnl.exe, используется команда u (от англ. unassemble — «дизассемблировать») с параметром nt!NtCreateProcess. Если не указать имя библиотеки, WinDbg

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

240  Часть III  •  Продвинутый динамический анализ

w Click

 

 

 

 

 

 

 

 

 

 

 

o

m

 

w

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Команда bu позволяет использовать символы для создания отложенных точек останова в коде, который еще не был загружен. Точка останова называется отложенной, если она задается при загрузке модуля с указанным именем. Например, команда bu newModule!exportedFunction заставит WinDbg создать точку останова для exportedFunction, но только в момент загрузки модуля newModule. В ходе анализа модулей ядра этот подход крайне удачно сочетается с командой $iment, которая определяет точку входа заданного модуля. Команда $iment(driverName) создаст точку останова на входе в драйвер, до того как начнет выполняться его код.

Команда x позволяет искать функции или символы по шаблону. Например, если вам нужно найти функцию ядра, которая занимается созданием процесса, вы можете выполнить поиск по имени, которое содержит строку CreateProcess и находится в модуле ntoskrnl.exe. Команда x nt!*CreateProcess* выведет как экспортные, так и внутренние функции. Результат ее выполнения показан ниже:

0:003> x nt!*CreateProcess*

805c736a nt!NtCreateProcessEx = <no type information> 805c7420 nt!NtCreateProcess = <no type information> 805c6a8c nt!PspCreateProcess = <no type information> 804fe144 nt!ZwCreateProcess = <no type information> 804fe158 nt!ZwCreateProcessEx = <no type information>

8055a300 nt!PspCreateProcessNotifyRoutineCount = <no type information> 805c5e0a nt!PsSetCreateProcessNotifyRoutine = <no type information> 8050f1a2 nt!MmCreateProcessAddressSpace = <no type information> 8055a2e0 nt!PspCreateProcessNotifyRoutine = <no type information>

Еще одна полезная команда, ln, выводит символ, который находится ближе всего к заданному адресу в памяти. Таким образом можно определить, на какую функцию ссылается указатель. Представьте, к примеру, что вы увидели по адресу 0x805717aa функцию call и теперь хотите понять, что этот код делает. Для этого можно воспользоваться следующей командой:

0:002> ln 805717aa kd> ln ntreadfile

(805717aa) nt!NtReadFile | (80571d38) nt!NtReadFileScatter Exact matches:

nt!NtReadFile = <no type information>

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

Просмотр информации о структуре

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Глава 10. Отладка ядра с помощью WinDbg   241

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Листинг 10.2. Просмотр информации о типах внутри структуры

0:000> dt nt!_DRIVER_OBJECT

 

 

kd> dt nt!_DRIVER_OBJECT

 

 

+0x000

Type

: Int2B

 

+0x002

Size

: Int2B

 

+0x004

DeviceObject

: Ptr32 _DEVICE_OBJECT

+0x008

Flags

: Uint4B

 

+0x00c DriverStart

: Ptr32 Void

 

+0x010

DriverSize

: Uint4B

 

+0x014

DriverSection

: Ptr32 Void

 

+0x018

DriverExtension

: Ptr32 _DRIVER_EXTENSION

+0x01c DriverName

: _UNICODE_STRING

+0x024

HardwareDatabase

: Ptr32 _UNICODE_STRING

+0x028

FastIoDispatch

: Ptr32 _FAST_IO_DISPATCH

+0x02c DriverInit

: Ptr32

long

+0x030

DriverStartIo

: Ptr32

void

+0x034

DriverUnload

: Ptr32

void

+0x038

MajorFunction

: [28] Ptr32

long

Имена полей структуры позволяют догадаться, какие данные в ней хранятся. Например, по сдвигу 0x00c находится указатель, который показывает, на какой участок памяти загрузился драйвер.

WinDbg позволяет накладывать данные на структуру. Допустим, нам известно, что по сдвигу 828b2648 находится объект устройства, и мы хотим вывести его структуру со значениями из соответствующего драйвера. В листинге 10.3 показано, как этого добиться.

Листинг 10.3. Наложение данных на структуру

 

kd> dt nt!_DRIVER_OBJECT 828b2648

 

+0x000

Type

:

4

 

+0x002

Size

:

168

 

+0x004

DeviceObject

:

0x828b0a30 _DEVICE_OBJECT

+0x008

Flags

:

0x12

 

+0x00c DriverStart

:

0xf7adb000

 

+0x010

DriverSize

:

0x1080

 

+0x014

DriverSection

:

0x82ad8d78

 

+0x018

DriverExtension

:

0x828b26f0 _DRIVER_EXTENSION

+0x01c DriverName

:

_UNICODE_STRING "\Driver\Beep"

+0x024

HardwareDatabase

:

0x80670ae0 _UNICODE_STRING

"\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"

+0x028

FastIoDispatch

:

(null)

 

+0x02c DriverInit

:

0xf7adb66c

long Beep!DriverEntry+0

+0x030

DriverStartIo

:

0xf7adb51a

void Beep!BeepStartIo+0

+0x034

DriverUnload

:

0xf7adb620

void Beep!BeepUnload+0

+0x038

MajorFunction

:

[28] 0xf7adb46a

long Beep!BeepOpen+0