- •Внимание!
- •Об авторах
- •О техническом редакторе
- •О соавторах
- •Предисловие
- •Благодарности
- •Отдельное спасибо
- •Введение
- •Необходимая квалификация
- •Изучение на примерах
- •Структура книги
- •Глава 0. Анализ вредоносных программ для начинающих
- •Цель анализа вредоносных программ
- •Методики анализа вредоносного ПО
- •Общие правила анализа вредоносного ПО
- •Глава 1. Основные статические методики
- •Сканирование антивирусом: первый шаг
- •Хеширование: отпечатки пальцев злоумышленника
- •Поиск строк
- •Упакованное и обфусцированное вредоносное ПО
- •Формат переносимых исполняемых файлов
- •Компонуемые библиотеки и функции
- •Статический анализ на практике
- •Заголовки и разделы PE-файла
- •Итоги главы
- •Глава 2. Анализ вредоносных программ в виртуальных машинах
- •Структура виртуальной машины
- •Запуск виртуальной машины для анализа вредоносного ПО
- •Использование виртуальной машины для анализа безопасности
- •Риски при использовании VMware для анализа безопасности
- •Запись/воспроизведение работы компьютера
- •Итоги главы
- •Глава 3. Основы динамического анализа
- •Песочницы: решение на скорую руку
- •Запуск вредоносных программ
- •Мониторинг с помощью Process Monitor
- •Сравнение снимков реестра с помощью Regshot
- •Симуляция сети
- •Перехват пакетов с помощью Wireshark
- •Использование INetSim
- •Применение основных инструментов для динамического анализа
- •Итоги главы
- •Уровни абстракции
- •Архитектура x86
- •Итоги главы
- •Глава 5. IDA Pro
- •Загрузка исполняемого файла
- •Интерфейс IDA Pro
- •Использование перекрестных ссылок
- •Анализ функций
- •Схематическое представление
- •Повышение эффективности дизассемблирования
- •Плагины к IDA Pro
- •Итоги главы
- •Глава 6. Распознавание конструкций языка C в ассемблере
- •Переменные: локальные и глобальные
- •Дизассемблирование арифметических операций
- •Распознавание выражений if
- •Распознавание циклов
- •Соглашения, касающиеся вызова функций
- •Анализ выражений switch
- •Дизассемблирование массивов
- •Распознавание структур
- •Анализ обхода связного списка
- •Итоги главы
- •Глава 7. Анализ вредоносных программ для Windows
- •Windows API
- •Реестр Windows
- •API для работы с сетью
- •Отслеживание запущенной вредоносной программы
- •Сравнение режимов ядра и пользователя
- •Native API
- •Итоги главы
- •Глава 8. Отладка
- •Сравнение отладки на уровне исходного и дизассемблированного кода
- •Отладка на уровне ядра и пользователя
- •Использование отладчика
- •Исключения
- •Управление выполнением с помощью отладчика
- •Изменение хода выполнения программы на практике
- •Итоги главы
- •Глава 9. OllyDbg
- •Загрузка вредоносного ПО
- •Пользовательский интерфейс OllyDbg
- •Карта памяти
- •Просмотр потоков и стеков
- •Выполнение кода
- •Точки останова
- •Трассировка
- •Обработка исключений
- •Редактирование кода
- •Анализ кода командной оболочки
- •Вспомогательные возможности
- •Подключаемые модули
- •Отладка с использованием скриптов
- •Итоги главы
- •Драйверы и код ядра
- •Подготовка к отладке ядра
- •Использование WinDbg
- •Отладочные символы Microsoft
- •Отладка ядра на практике
- •Руткиты
- •Загрузка драйверов
- •Итоги главы
- •Глава 11. Поведение вредоносных программ
- •Программы для загрузки и запуска ПО
- •Бэкдоры
- •Похищение учетных данных
- •Механизм постоянного присутствия
- •Повышение привилегий
- •Заметая следы: руткиты, работающие в пользовательском режиме
- •Итоги главы
- •Глава 12. Скрытый запуск вредоносного ПО
- •Загрузчики
- •Внедрение в процесс
- •Подмена процесса
- •Внедрение перехватчиков
- •Detours
- •Внедрение асинхронных процедур
- •Итоги главы
- •Глава 13. Кодирование данных
- •Простые шифры
- •Распространенные криптографические алгоритмы
- •Нестандартное кодирование
- •Декодирование
- •Итоги главы
- •Глава 14. Сетевые сигнатуры, нацеленные на вредоносное ПО
- •Сетевые контрмеры
- •Безопасное расследование вредоносной деятельности в Интернете
- •Контрмеры, основанные на сетевом трафике
- •Углубленный анализ
- •Сочетание динамических и статических методик анализа
- •Понимание психологии злоумышленника
- •Итоги главы
- •Искажение алгоритмов дизассемблирования
- •Срыв анализа слоя стека
- •Итоги главы
- •Глава 16. Антиотладка
- •Обнаружение отладчика в Windows
- •Распознавание поведения отладчика
- •Искажение работы отладчика
- •Уязвимости отладчиков
- •Итоги главы
- •Глава 17. Методы противодействия виртуальным машинам
- •Признаки присутствия VMware
- •Уязвимые инструкции
- •Изменение настроек
- •Побег из виртуальной машины
- •Итоги главы
- •Глава 18. Упаковщики и распаковка
- •Анатомия упаковщика
- •Распознавание упакованных программ
- •Способы распаковки
- •Автоматизированная распаковка
- •Ручная распаковка
- •Советы и приемы для работы с распространенными упаковщиками
- •Анализ без полной распаковки
- •Итоги главы
- •Глава 19. Анализ кода командной оболочки
- •Загрузка кода командной оболочки для анализа
- •Позиционно-независимый код
- •Определение адреса выполнения
- •Поиск символов вручную
- •Окончательная версия программы Hello World
- •Кодировки кода командной оболочки
- •NOP-цепочки
- •Поиск кода командной оболочки
- •Итоги главы
- •Глава 20. Анализ кода на C++
- •Объектно-ориентированное программирование
- •Обычные и виртуальные функции
- •Создание и уничтожение объектов
- •Итоги главы
- •Какой смысл в 64-битном вредоносном ПО?
- •Особенности архитектуры x64
- •Признаки вредоносного кода на платформе x64
- •Итоги главы
- •Приложения
|
|
|
|
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 |
|
|
|
|
Глава 20. Анализ кода на C++
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
467 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Рис. 20.3. Перекрестные ссылки для виртуальной функции
Ниже представлена расширенная версия листинга 20.6, которая содержит vtable для двух классов (листинг 20.7).
Листинг 20.7. Таблицы виртуальных методов для двух разных классов
004020DC off_4020DC |
dd offset sub_401100 |
|
004020E0 |
|
dd offset sub_4010C0 |
004020E4 |
|
dd offset sub_4010E0 |
004020E8 |
|
dd offset sub_401120 |
004020EC |
|
dd offset unk_402198 |
004020F0 |
off_4020F0 |
dd offset sub_4010A0 |
004020F4 |
|
dd offset sub_4010C0 |
004020F8 |
|
dd offset sub_4010E0 |
Обратите внимание на то, что в строках и указана одна и та же функция и что на рис. 20.3 она имеет две перекрестные ссылки. Эти ссылки находятся в разных таблицах, но ведут к одной функции, что свидетельствует о наследовании.
Помните, что дочерний класс автоматически включает в себя все методы своего родителя (если только он их не переопределяет). В листинге 20.7 метка sub_4010E0 в строках и относится к функции из родительского класса, которая также содержится в vtable потомка, поскольку она может вызываться и из него тоже.
Отличить родительский класс от дочернего можно не всегда, но если одна таблица виртуальных методов больше другой, это значит, что она принадлежит подклассу. В этом примере vtable со сдвигом 4020F0 относится к родителю, а vtable со сдвигом 4020DC — к потомку (потому что она больше). Не забывайте, что в дополнение к родительским функциям дочерний класс может содержать и свои собственные.
Создание и уничтожение объектов
У классов в C++ есть два специальных метода: конструктор и деструктор. Первый вызывается при создании объекта, а второй — при его уничтожении.
Конструктор занимается инициализацией, необходимой объекту. Экземпляр класса может быть создан в стеке или куче. В первом случае не нужно заниматься выделением памяти — объект просто будет находиться в стеке вместе с другими локальными переменными.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
468 Часть VI • Специальные темы |
||||
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 |
|
|
|
|
Деструктор вызывается автоматически, когда объект выходит за пределы области видимости. Иногда это усложняет дизассемблирование, поскольку для гарантированного вызова деструктора компилятор может добавить код обработки исключений.
Если объекты хранятся не в стеке, память для них выделяется с помощью оператора new. Это ключевое слово в языке C++, которое создает пространство в куче и вызывает конструктор. В ассемблерном коде оператор new обычно представлен
ввиде функции импорта, которую легко заметить. Этот случай проиллюстрирован
влистинге 20.8, сгенерированном с помощью IDA Pro. Поскольку эта функция является оператором, она имеет необычное имя. IDA Pro корректно распознает ее как оператор new и помечает соответствующим образом. Точно так же при удалении объекта из кучи вызывается оператор delete.
ПРИМЕЧАНИЕ
Создание и удаление объектов — это ключевые элементы потока выполнения в программах на языке C++. Их разбор может пролить свет на структуру объекта и помочь в анализе других его функций.
Листинг 20.8. Оператор new в дизассемблированном виде
00401070 |
push |
ebp |
|
00401071 |
mov |
ebp, esp |
|
00401073 |
sub |
esp, 1Ch |
|
00401076 |
mov |
[ebp+var_10], |
offset off_4020F0 |
0040107D |
mov |
[ebp+var_10], |
offset off_4020DC |
00401084 |
mov |
[ebp+var_4], offset off_4020F0 |
|
0040108B |
push |
4 |
|
0040108D |
call |
??2@YAPAXI@Z ; оператор new(uint) |
В листинге 20.8 представлен объект, хранящийся в стеке. Сдвиг, перемещенный по адресу var_10, указывает на vtable. Здесь компилятор ведет себя немного необычно, дважды подряд направляя сдвиги в одно и то же место. Инструкция бесполезна, потому что второй сдвиг перезапишет то, что хранится в строке .
Если взглянуть на сдвиги для этого кода, можно увидеть, что они ведут к таблицам виртуальных методов для двух классов. Первый сдвиг относится к vtable родительского класса, а второй ведет к таблице класса создаваемого объекта.
Итоги главы
Чтобы проанализировать вредоносную программу на языке C++, вам необходимо понимать возможности этого языка и то, как они влияют на ассемблерный код. Если вы будете знать, что такое наследование, таблицы виртуальных методов, указатель this и коррекция имен, то код, написанный на C++, не застанет вас врасплох. Вы сможете успешно использовать «улики», которые оставляют дополнительные структуры, созданные классами C++.
|
|
|
|
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 |
|
|
|||
Глава 20. Анализ кода на C++ 469 |
to |
|
|
|
|
|
||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Лабораторные работы
Лабораторная работа 20.1
Цель этой лабораторной — продемонстрировать использование указателя this. Проанализируйте вредоносную программу Lab20-01.exe.
Вопросы
1.Принимает ли какие-либо параметры функция по адресу 0x401040?
2.Какой URL-адрес используется в вызове URLDownloadToFile?
3.Каково назначение этой программы?
Лабораторная работа 20.2
Цель этой работы — демонстрация виртуальных функций. Проанализируйте вредоносную программу Lab20-02.exe.
ПРИМЕЧАНИЕ
Эта программа не угрожает безопасности вашего компьютера, но она попытается загрузить из вашей системы конфиденциальные данные.
Вопросы
1.Что вы можете сказать о подозрительных строках этой программы?
2.О чем говорят импорты?
3.Что делает объект, который создается по адресу 0x4011D9? Есть ли у него какие-либо виртуальные функции?
4.Какие функции теоретически могут быть вызваны с помощью инструкции call [edx] по адресу 0x401349?
5.Как проще всего подготовить сервер, к которому обращается вредонос, чтобы полностью его проанализировать без доступа к Интернету?
6.Каково назначение этой программы?
7.Зачем в этой программе был реализован вызов виртуальной функции?
Лабораторная работа 20.3
Здесь мы рассмотрим более объемную и реалистичную вредоносную программу. У нее есть конфигурационный файл config.dat; он должен находиться в одном каталоге с ней, иначе она не сможет корректно работать. Проанализируйте файл Lab20-03.exe.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
w |
|
|
to |
|
|
470 Часть VI • Специальные темы |
||||
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 |
|
|
|
|
1.Что вы можете сказать о подозрительных строках этой программы?
2.О чем говорят импорты?
3.По адресу 0x4036F0 находится вызов функции, которая принимает строку Config error. Несколькими инструкциями ниже находится вызов CxxThrowException. Принимает ли эта функция какие-нибудь другие аргументы? Возвращает ли она что-нибудь? Что вы можете сказать о ней с точки зрения контекста, в котором она используется?
4.Для чего нужны шесть записей в таблице переключателей по адресу 0x4025C8?
5.Каково назначение этой программы?