Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Майкл_Сикорски,_Эндрю_Хониг_Вскрытие_покажет!_Практический_анализ.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

 

.

 

 

 

 

 

8

 

 

 

 

 

 

.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

 

 

 

 

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

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

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

В следующих двух главах мы рассмотрим два отладчика: OllyDbg и 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

 

 

Глава 8. Отладка  193

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

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

Аналитики безопасности активно применяют отладчики уровня ассемблера, поскольку они не требуют доступа к исходному коду.

Отладка на уровне ядра и пользователя

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

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

ПРИМЕЧАНИЕ

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

Для отладки в режиме пользователя и ядра существуют разные программные пакеты. Единственным популярным отладчиком с поддержкой ядра является WinDbg. OllyDbg считается самым популярным продуктом для отладки вредоносного кода, однако он не поддерживает режим ядра. WinDbg подходит и для пользовательских приложений, а IDA Pro имеет встроенный отладчик, но ни один из этих инструментов не сравнится по своим возможностям и простоте с OllyDbg.

Использование отладчика

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

194  Часть 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

 

 

 

 

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

Пошаговое выполнение

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

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

На примере листинга 8.1 показано, каким образом отладчик помогает понять участок дизассемблированного кода.

Листинг 8.1. Пошаговое выполнение кода

mov

edi, DWORD_00406904

mov

ecx, 0x0d

 

LOC_040106B2

 

xor

[edi], 0x9C

inc

edi

 

loopw

LOC_040106B2

...

 

 

DWORD:00406904:

F8FDF3D0

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

Если бы мы пошагово выполнили этот цикл, используя WinDbg или OllyDbg, мы бы увидели, что данные в нем изменяются. Например, в листинге 8.2 показано, как представленная выше функция модифицирует 13 байт, изменяя их при каждой итерации цикла (рядом с адресами приводятся как сами байты, так и их представление в формате ASCII).

Листинг 8.2. Пошагово проходим по участку кода, чтобы увидеть, как он изменяет память

D0F3FDF8 D0F5FEEE FDEEE5DD 9C (.............

)

4CF3FDF8 D0F5FEEE FDEEE5DD 9C (L............

)

4C6FFDF8 D0F5FEEE FDEEE5DD 9C

(Lo...........

)

4C6F61F8 D0F5FEEE FDEEE5DD 9C

(Loa..........

)

. . . SNIP . . .

 

 

4C6F6164 4C696272 61727941 00

(LoadLibraryA.)

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

 

 

 

 

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

 

 

Глава 8. Отладка  195

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

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

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

ПРИМЕЧАНИЕ

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

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

Приостановка выполнения с помощью точек останова

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

196  Часть 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

 

 

 

 

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

Листинг 8.3. Обращение к EAX

00401008

mov

ecx, [ebp+arg_0]

0040100B

mov

eax, [edx]

0040100D

call

eax

В листинге 8.4 показано начало функции с вызовом CreateFile, который открывает файловый дескриптор. В ассемблерном коде сложно определить имя файла, хотя оно частично передается в виде аргумента функции. Вы можете воспользоваться IDA Pro, чтобы найти все вызовы этой функции и посмотреть, какие аргументы ей передаются, но эти значения сами могут оказаться аргументами, передаваемыми извне, или результатом выполнения других функций. Очень быстро эта задача может стать слишком сложной. Упростить ее можно с помощью отладчика.

Листинг 8.4. Использование отладчика для определения имени файла

0040100B

xor

eax, esp

 

0040100D

mov

[esp+0D0h+var_4], eax

00401014

mov

eax, edx

 

00401016

mov

[esp+0D0h+NumberOfBytesWritten], 0

0040101D

add

eax, 0FFFFFFFEh

 

00401020

mov

cx, [eax+2]

 

00401024

add

eax, 2

 

00401027

test

cx, cx

 

0040102A

jnz

short loc_401020

 

0040102C

mov

ecx, dword ptr ds:a_txt ; ".txt"

00401032

push

0

; hTemplateFile

00401034

push

0

; dwFlagsAndAttributes

00401036

push

2

; dwCreationDisposition

00401038

mov

[eax], ecx

 

0040103A

mov

ecx, dword ptr ds:a_txt+4

00401040

push

0

; lpSecurityAttributes

00401042

push

0

; dwShareMode

00401044

mov

[eax+4], ecx

 

00401047

mov

cx, word ptr ds:a_txt+8

0040104E

push

0

; dwDesiredAccess

00401050

push

edx

; lpFileName

00401051

mov

[eax+8], cx

 

00401055

call

CreateFileW ; CreateFileW(x,x,x,x,x,x,x)

Укажем точку останова для вызова CreateFileW и посмотрим, какие значения хранятся в стеке при ее срабатывании. На рис. 8.1 показан снимок окна отладчика WinDbg с инструкцией в точке останова. После этой точки первый аргумент функции выводится в виде строки в формате ASCII (вы научитесь это делать в главе 10, посвященной 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

 

 

Глава 8. Отладка  197

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Рис. 8.1. Использование точки останова для просмотра аргументов вызова. Мы указали точку останова для функции CreateFileW, а затем изучили первый параметр стека

В этом случае очевидно, что создаваемый файл называется LogFile.txt. Мы мо­ гли бы определить это и с помощью IDA Pro, но отладчик позволил нам упростить и ускорить данную процедуру.

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

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

Листинг 8.5. Использование точки останова для просмотра данных до того, как они будут зашифрованы

004010D0

sub

esp, 0CCh

004010D6

mov

eax, dword_403000

004010DB

xor

eax, esp

004010DD

mov

[esp+0CCh+var_4], eax

004010E4

lea

eax, [esp+0CCh+buf]

004010E7

call

GetData

004010EC

lea

eax, [esp+0CCh+buf]

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

 

F

 

 

 

 

 

 

t

 

 

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

r

 

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

w

 

 

to

 

 

198   

Часть III 

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

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

o

m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

004010EF

call

EncryptData

 

 

 

 

 

 

 

 

 

004010F4

mov

ecx, s

 

 

 

 

 

 

 

 

 

004010FA

push

0

; flags

 

 

 

 

 

 

 

 

004010FC

push

0C8h

; len

 

 

 

 

 

 

 

 

00401101

lea

eax, [esp+0D4h+buf]

 

 

 

 

 

 

 

 

00401105

push

eax

; buf

 

 

 

 

 

 

 

 

00401106

push

ecx

; s

 

 

 

 

 

 

 

 

00401107

call

ds:Send

 

 

 

 

 

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

 

 

 

 

На рис. 8.2 показано окно отладчика OllyDbg, в котором выводится буфер памяти до того, как он передается в функцию шифрования. На верхней панели можно видеть инструкцию с точкой останова, а внизу — сообщение. В нашем случае отправляемые данные являются строкой Secret Message (см. столбец ASCII справа).

Рис. 8.2. Просмотр данных программы до того, как они попадают в функцию шифрования

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

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

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

Чтобы создать программную точку останова, отладчик перезаписывает первый байт инструкции с помощью значения 0xCC, которое соответствует прерыванию INT 3, предназначенному специально для отладчиков. При выполнении инструкции 0xCC ОС генерирует исключение и передает управление отладчику.

 

 

 

 

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

 

 

Глава 8. Отладка  199

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Втабл. 8.1 рядом показаны дамп памяти и дизассемблированный код функции

сзаданной точкой останова.

Таблица 8.1. Дизассемблированный код и дамп памяти функции с заданной точкой останова

Дизассемблированное представление

 

Дамп памяти

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

00401130

55

 

 

 

 

push

ebp

00401130

CC

8B

EC

83

00401131

8B

EC

 

 

 

mov

ebp, esp

00401134

E4

F8

81

EC

00401133

83

E4

F8

 

 

and

esp, 0FFFFFFF8h

00401138

A4

03

00

00

00401136

81

EC

A4

03

00

00 sub

esp, 3A4h

0040113C

A1

00

30

40

0040113C

A1

00

30

40

00

mov

eax, dword_403000

00401140

00

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Функция начинается с инструкции push ebp , которая соответствует опкоду 0x55, но в начале ее дампа памяти содержатся байты 0xCC , представляющие собой точку останова.

Вокне дизассемблирования отладчик выводит оригинальную инструкцию, но

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

Если эти байты поменяются во время выполнения программы, точка останова не сработает. Например, если точка останова указана для кода, который модифицирует сам себя или редактируется извне, она попросту исчезнет. Если прочитать содержимое памяти функции вне отладчика, вместо оригинального значения получится 0xCC. Кроме того, данное несоответствие будет замечено любой программой, которая проверяет целостность этой функции.

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

Аппаратные точки останова

Архитектура x86 предусматривает отдельные регистры для поддержки аппаратных точек останова. Каждый раз, когда процессор выполняет инструкцию, на аппаратном уровне происходит проверка тождественности указателя инструкции и адреса точки останова. В отличие от программных, аппаратные точки останова не зависят от того, какие значения хранятся по заданному адресу. Например, если вы укажете точку останова для адреса 0x00401234, процессор прервет выполнение в этом месте вне зависимости от того, что там находится. Это может оказаться существенным преимуществом при отладке кода, который сам себя модифицирует.

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

200  Часть 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

 

 

 

 

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

У аппаратных точек останова есть один существенный недостаток: для хранения их адресов отводится всего четыре физических регистра.

Еще одним минусом точек останова этого типа является то, что запускаемая программа может их легко модифицировать. Центральный процессор имеет восемь отладочных регистров, но используется только шесть из них. Первые четыре, DR0-DR3, хранят адрес точки останова. Управляющий отладочный регистр, DR7, определяет, активизирована ли точка останова и с какой операцией она связана — с чтением, записью или выполнением. Вредоносная программа может отредактировать эти регистры, пытаясь помешать процедуре отладки. К счастью, процессоры архитектуры x86 позволяют это предотвратить. Если установить флаг GD в регистр DR7, точка останова сработает до выполнения любой инструкции mov, которая может попытаться получить доступ к отладочному регистру. Таким образом вы сможете обнаружить изменение отладочных регистров. И хотя этот подход неидеален (он позволяет определить лишь инструкции mov, которые обращаются к отладочным регистрам), он все равно очень полезен.

Условные точки останова

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

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

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