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

 

 

Глава 18. Упаковщики и распаковка  419

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Распознавание упакованных программ

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

Признаки упакованной программы

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

Программа импортирует слишком мало вызовов, особенно если это только

LoadLibrary и GetProcAddress.

Если открыть программу в IDA Pro, автоматический анализ распознает лишь небольшую часть кода.

При открытии файла в OllyDbg вы видите предупреждение о том, что программа может быть упакована.

Программа содержит разделы, чьи имена указывают на определенный упаковщик (такой как UPX0).

Разделы программы имеют необычный размер: например, если у раздела .text в поле Size of Raw Data указано значение 0, а в Virtual Size — ненулевое значение.

Для обнаружения упаковщиков можно использовать специальные инструменты, такие как PEiD.

Вычисление энтропии

Упакованные исполняемые файлы можно также распознать с помощью методики, известной как вычисление энтропии. Энтропия определяет уровень «беспорядка»

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

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

Эвристические методы, в том числе и на основе энтропии, часто применяются

винструментах для автоматического определения упакованных программ. Один

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

420  Часть V  •  Противодействие обратному проектированию

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

 

 

 

 

из таких инструментов, Mandiant Red Curtain, распространяется бесплатно и использует такие характеристики, как энтропия, для вычисления степени угрозы со стороны исполняемых файлов. Эта утилита умеет сканировать файловую систему на предмет упакованных двоичных файлов.

Способы распаковки

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

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

Автоматизированная распаковка

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

Для работы с EXE- и DLL-файлами можно использовать бесплатную программу PE Explorer. В ее стандартную поставку входит несколько плагинов для статической распаковки, которые умеют работать с такими упаковщиками, как NSPack, UPack и UPX. Распаковка файлов с помощью PE Explorer происходит максимально просто: если обнаружится, что выбранная вами программа упакована, из нее автоматически будет извлечен исполняемый файл. Если вы хотите исследовать результат распаковки вне PE Explorer, вам сначала нужно его сохранить.

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

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

 

 

 

 

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

 

 

Глава 18. Упаковщики и распаковка  421

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

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

Ручная распаковка

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

Существует два подхода к ручной распаковке программ.

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

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

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

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

422  Часть V  •  Противодействие обратному проектированию

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

 

 

 

 

OllyDump поддерживает два варианта распаковки: он может сбросить на диск память текущего процесса или найти ОТВ для упакованного исполняемого файла.

Выберите в OllyDbg пункт меню Plugins OllyDump Find OEP by Section Hop

(Плагины OllyDump Найти ОТВ по границе раздела). Программа столкнется с точкой останова прямо перед выполнением ОТВ.

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

Отладчик остановится на инструкции, которая играет роль ОТВ. Запишите ее значение, но не закрывайте OllyDbg.

Теперь мы воспользуемся плагином OllyDump, чтобы сбросить исполняемый файл на диск. Выберите пункт меню Plugins OllyDump Dump Debugged Process (Плаги­ ны OllyDump Сбросить на диск отлаживаемый процесс). На экране можно увидеть несколько вариантов выполнения данной процедуры.

Если отладчик OllyDbg сбросит программу на диск без каких-либо изменений, она будет содержать PE-заголовок упакованного исполняемого файла, а это не то же самое, что PE-заголовок распакованной программы. Нам придется внести два изменения.

1.Восстановить таблицу импорта.

2.Связать точку входа в PE-заголовке с ОТВ.

Если не трогать параметры в окне сброса, OllyDump выполнит эти действия автоматически. Точка входа в исполняемый файл будет вести к указателю на текущую инструкцию, которой в данном случае является ОТВ, а таблица импорта будет перестроена. Нажмите кнопку Dump (Сбросить), чтобы завершить распаковку этого исполняемого файла. Нам удалось распаковать данную программу всего за несколько простых шагов, поскольку была найдена оригинальная точка входа и плагин OllyDump смог автоматически восстановить таблицу импорта. При работе с более сложными распаковщиками вы столкнетесь с дополнительными трудностями. Оставшаяся часть главы посвящена ситуации, когда OllyDump не в состоянии выдать корректный результат.

Реконструкция таблицы импорта с помощью Import Reconstructor

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

 

 

 

 

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

 

 

Глава 18. Упаковщики и распаковка  423

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

OllyDbg не дает нужного результата, имеет смысл воспользоваться утилитой Import Reconstructor (ImpRec).

С помощью ImpRec можно восстановить таблицу импорта упакованной программы. Запустите эту утилиту и щелкните на выпадающем списке в верхней части окна. Вы должны увидеть перечень активных процессов. Выберите упакованный исполняемый файл. Затем введите значение RVA для ОТВ (не весь адрес целиком) в поле OEP справа. Например, если базовый адрес равен 0x400000, а ОТВ ведет к 0x403904, вы должны ввести 0x3904. Теперь нажмите кнопку IAT autosearch (Автопоиск IAT). На экране должно появиться окно с сообщением о том, что утилита ImpRec нашла исходную таблицу адресов импорта (import address table, IAT). Нажмите кнопку GetImports. В левой части главного окна должен появиться список всех файлов с импортированными функциями. Если функция GetImports завершилась успешно, все импорты будут помечены как valid:YES. Если что-то пошло не так, это означает, что ImpRec не может исправить таблицу импорта автоматически.

Стратегии ручного восстановления таблицы будут рассмотрены позже в этой главе. Пока мы исходим из того, что у нас получилось найти все импорты. Нажмите кнопку Fix Dump (Исправить файл). Вас попросят указать путь к файлу, который вы сбросили на диск ранее, используя OllyDump. После этого ImpRec запишет новый файл, к имени которого будет добавлен знак подчеркивания.

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

Как упоминалось ранее, самой сложной частью ручной распаковки является поиск ОТВ. Этим мы и займемся далее.

Поиск ОТВ

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

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

Чтобы найти ОТВ, нужно запустить вредоносную программу в отладчике с использованием пошагового выполнения и точек останова. Вспомним разные виды точек останова из главы 8, которые срабатывают в разных условиях. OllyDbg поддерживает четыре из них: это стандартные точки останова (на основе прерывания INT 3), размещаемые в памяти (предоставляются отладчиком), аппаратные точки

итрассировка выполнения с остановкой по условию.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

424  Часть V  •  Противодействие обратному проектированию

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

 

 

 

 

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

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

Использование автоматизированных инструментов для поиска ОТВ

В предыдущем примере мы искали ОТВ с помощью автоматической утилиты. Самым популярным инструментом для этой задачи является плагин OllyDump для OllyDbg, который вызывается из меню Find OEP by Section Hop(Найти ОТВ по границе раздела). Обычно заглушка-распаковщик и сам исполняемый файл находятся в разных разделах. OllyDbg распознает переход от одного раздела к другому и останавливает выполнение в этом месте, используя шаг с обходом или входом. Шаг с обходом пропустит любые инструкции call; они часто используются для выполнения кода из другого раздела, и данный способ не дает OllyDbg ошибочно принять эти вызовы за ОТВ. Но если инструкция call ничего не возвращает, OllyDbg не сможет найти точку входа.

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

Поиск ОТВ вручную

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

Хвостовая рекурсия часто оказывается последним корректным блоком кода перед последовательностью байтов, которая не складывается в нормальные инструкции. Эти байты нужны для выравнивания раздела, чтобы тот имел правильный сдвиг. Как правило, для поиска хвостовой рекурсии в упакованном исполняемом файле используется IDA Pro. В листинге 18.1 показан простой пример.

Листинг 18.1. Простая хвостовая рекурсия

00416C31

PUSH EDI

00416C32

CALL EBP

00416C34

POP EAX

 

 

 

 

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

 

 

 

 

00416C35

00416C36

00416C3A

00416C3C

00416C3E

00416C40

00416C43

00416C48

00416C49

00416C4A

00416C4B

00416C4C

00416C4D

00416C4E

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Глава 18. Упаковщики и распаковка  425

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

POPAD

LEA EAX,DWORD PTR SS:[ESP-80]

PUSH 0

CMP ESP,EAX

JNZ SHORT Sample84.00416C3A

SUB ESP,-80

JMP Sample84.00401000

DB 00

DB 00

DB 00

DB 00

DB 00

DB 00

DB 00

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

У этого перехода есть еще одно необычное свойство — его размер. Переходы, как правило, используются в условных выражениях и циклах, ведя к адресу на расстоянии нескольких сотен байт, но эта инструкция ведет к участку, до которого 0x15C43 байт. Это не похоже на нормальную инструкцию jmp.

Хвостовую рекурсию часто легко выявить в графическом представлении IDA Pro, как это показано на рис. 18.5. Если среда IDA Pro не может определить, куда ведет переход, она выделяет его красным цветом. Обычно переходы выполняются

впределах одной функции, и IDA Pro соединяет стрелкой инструкцию jmp и конечную точку. Но хвостовая рекурсия воспринимается как ошибка и выделяется красным.

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

вкоторый происходит переход, когда программа загружена в OllyDbg. Инструкция DD BYTE PTR DS:[EAX],AL соответствует двум байтам 0x00. Они не представляют собой корректный код, но OllyDbg все равно их дизассемблирует.

Листинг 18.2. Байты инструкции, хранящиеся в ОТВ до распаковки оригинальной программы

00401000 ADD BYTE PTR DS:[EAX],AL

00401002 ADD BYTE PTR DS:[EAX],AL

00401004 ADD BYTE PTR DS:[EAX],AL

00401006 ADD BYTE PTR DS:[EAX],AL

00401008 ADD BYTE PTR DS:[EAX],AL

0040100A ADD BYTE PTR DS:[EAX],AL

0040100C ADD BYTE PTR DS:[EAX],AL

0040100E ADD BYTE PTR DS:[EAX],AL

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

F

 

 

 

 

 

 

t

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

to

 

 

426  Часть V  •  Противодействие обратному проектированию

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

 

 

 

 

Рис. 18.5. В графическом представлении IDA Pro хвостовая рекурсия выделяется красным цветом

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

 

 

 

 

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

 

 

Глава 18. Упаковщики и распаковка  427

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Листинг 18.3. Байты инструкции, хранящиеся ОТВ после распаковки оригинальной программы

00401000

CALL Sample84.004010DC

00401005

TEST EAX,EAX

00401007

JNZ SHORT Sample84.0040100E

00401009

CALL Sample84.00401018

0040100E

PUSH EAX

0040100F

CALL DWORD PTR DS:[414304] ; kernel32.ExitProcess

00401015

RETN

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

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

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

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

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

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

Еще один способ хвостовой рекурсии состоит в создании точки останова на функции GetProcAddress. Большинство распаковщиков используют GetProcAddress для

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w

 

 

to

 

 

428  Часть V  •  Противодействие обратному проектированию

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

 

 

 

 

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

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

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

Впрограммах с графическим интерфейсом первой обычно вызывается функция GetModuleHandleA. Когда процесс остановится, изучите предыдущий слой стека, чтобы увидеть, откуда идет вызов. Очень может быть, что начало функции, которая вызвала GetModuleHandleA или GetVersion, является оригинальной точкой входа. Найдите инструкцию call и прокрутите вверх от нее, пока не найдете, где начинается функция. Чаще всего первой инструкцией является push ebp, за которой следует mov ebp, esp. Попробуйте сбросить программу на диск, выбрав начало этой функции в качестве ОТВ. Если вы угадали, ваша работа на этом закончена. Если нет, программа все равно сохранится на диск, поскольку заглушка-распаковщик уже завершилась. Вы сможете просматривать программу в IDA Pro, но при этом вы можете не знать, где она начинается. Если вам повезет, IDA Pro автоматически распознает функцию WinMain или DllMain.

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

вней нет ничего полезного, но сам факт ее наличия в PE-заголовке говорит о том, что загрузчик выделит для нее место в памяти. ОТВ всегда находится внутри исходного раздела .text и часто является первой инструкцией, которая в ней вызывается. Функция Run Trace позволяет создать точку останова, которая срабатывает при выполнении каждой инструкции внутри .text. Обычно для нахождения ОТВ достаточно первого срабатывания.

Восстановление таблицы импорта вручную

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

 

 

 

 

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

 

 

Глава 18. Упаковщики и распаковка  429

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Анализ вредоносного ПО без информации об импорте может оказаться чрезвычайно сложным, поэтому по возможности эту информацию лучше восстановить. Проще всего восстанавливать импорты по одному, по мере того как они попадаются вам в дизассемблированном коде. Для этого откройте файл в IDA Pro без каких-либо сведений об импорте. Сталкиваясь с функциями импорта, помечайте их соответствующим образом. Они представляют собой косвенные вызовы по адресам, которые находятся за пределами загруженной программы (листинг 18.4).

Листинг 18.4. Вызов импортированной функции в ситуации, когда таблица импорта не восстановлена как следует

push eax

call dword_401244

...

dword_401244: 0x7c4586c8

В листинге показана инструкция call, операндом которой является указатель типа DWORD. Если перейти по этому указателю в IDA Pro, можно увидеть, что его значение равно 0x7c4586c8 и находится за пределами загруженной программы. Теперь можно открыть OllyDbg и перейти по адресу 0x7c4586c8, чтобы увидеть, куда он ведет. В OllyDbg этот импортированный участок помечен как WriteFile, поэтому мы можем присвоить ему метку imp_WriteFile, чтобы знать его назначение. То же самое нужно повторить для каждого импорта, который вам встретится. После этого можно воспользоваться перекрестными ссылками в IDA Pro, чтобы пометить все вызовы функций импорта. Создав достаточное количество меток, вы сможете как следует проанализировать вредоносный код.

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

Другая стратегия, которая позволяет запускать распакованный код, состоит в ручном восстановлении исходной таблицы импорта. Для этого вам нужно найти таблицу функций импорта. Формат PE является открытым стандартом — вы можете добавлять импорты функций по одной или написать скрипт, который будет делать это за вас. Такой подход может оказаться очень трудоемким и занять много времени, что является его главным недостатком.