- •Методы защиты программного обеспечения и способы их обхода.
- •Классификация систем защиты программного обеспечения. Классификация по методу установки, по используемым механизмам защиты, по принципу функционирования.
- •Упаковщики/шифраторы. Достоинства и недостатки.
- •Форматы исполняемых файлов. Формат Portable Executable. Relative Virtual Address.
- •Форматы исполняемых файлов. Формат Portable Executable. Поле ImageBase структуры image_optional_header. Настройка адресов. Секция .Reloc.
- •Стандартный механизм импорта
- •Форматы исполняемых файлов. Формат Portable Executable. Секция .Export. Как работает механизм экспортируемых функций?
- •Антиотладочные приёмы. Использование функции FindWindow и защита от неё.
- •Виды точек останова в отладчике. Алгоритм работы точек останова.
- •Антиотладочные приёмы. Использование функции IsDebuggerPresent и защита от неё.
- •Антиотладочные приёмы. Использование функций Proccess32First и Process32Next и защита от них.
- •Антиотладочные приёмы. Обнаружение отладчика по имени процесса и защита от данного приёма.
Форматы исполняемых файлов. Формат Portable Executable. Relative Virtual Address.
Portable Executable — (PE— переносимый исполняемый) — формат исполняемых файлов, объектного кода и динамических библиотек, используемый в 32- и 64-битных версиях операционной системы Microsoft Windows. Формат PE представляет собой структуру данных, содержащую всю информацию, необходимую PE загрузчику для проецирования файла в память. Исполняемый код включает в себя ссылки для связывания динамически загружаемых библиотек, таблицы экспорта и импорта API функций, данные для управления ресурсами и данные локальной памяти потока (TLS). В операционных системах семейства Windows NT формат PE используется для EXE, DLL, SYS (драйверов устройств), и других типов файлов.
Основные понятия PE
Секция – содержит либо код программ, либо данные
RVA – относительный виртуальный адрес
Базовый адрес – адрес, с которого начинается отображение секций в память
HINSTANCE – instance handle, дескриптор образца.
Структура файла PE
RVA
RVA (Relative Virtual Address) — относительный виртуальный адрес. RVA — это смещение данного элемента по отношению к адресу, с которого начинается отображение файла в памяти.
Например: загрузчик Windows отобразил РЕ-файл в память, начиная с адреса 0х400000 в виртуальном адресном пространстве. Если некая таблица в отображении начинается с адреса 0х401464, то RVA данной таблицы 0х1464:
(виртуальный адрес 0х401464) - (базовый адрес 0х400000) = RVA 0х1464
Форматы исполняемых файлов. Формат Portable Executable. Поле ImageBase структуры image_optional_header. Настройка адресов. Секция .Reloc.
В опциональном заголовке храниться более специфическая информация о приложении и его потребностях. В WINNT.H опциональный заголовок – это структура IMAGE_OPTIONAL_HEADER.
DWORD ImageBase;
При запуске PE-файла он будет отображен по частям, начиная с некоторого адреса в памяти. Адрес отображения называется базовым адресом для данного файла. В данном поле храниться базовый адрес PE-файла. Этот файл естественно является VA. От него отсчитываются все RVA. Еcли файл не загружается по каким-то причинам (по этому адресу помять уже зарезервирована) по данному адресу, то загрузчику необходимо применять базовые поправки. Обычно файл загружается по базовому адресу и базовые поправки не нужны. Это позволяет использовать базовые поправки в своих целях. Для компоновщиков, по умолчанию устанавливается базовый адрес 400000H.
Секция .reloc.
Функция, ответственная за этот этап - make_reloc_section.
Заключительная секция релокации содержит исправления для единственного абсолютного адреса в сборке, который находится в точке входа jmp dword ptr ds:[x] в секции ".cli". Адрес x надо исправить, если сборка грузится по адресу, отличному от базового. Сгенерированная секция ".reloc" содержит единственную структуру RELOC_SECTION, в которой есть все необходимые поля для исправления.
Поле PageRVA содержит адрес страницы, в которой надо произвести исправление. Заполняется значением макроса RVA_OF_CLI. Поле BlockSize заполняется значением макроса SIZEOF_RELOC_NOTALIGNED, который определен так:
#define SIZEOF_RELOC_NOTALIGNED sizeof(struct RELOC_SECTION).
В сборках .NET в качестве типа исправления используется значение 3. Смещение адреса x на странице равно 2, т.к. расположение секций в памяти выровнено по страницам:
struct RELOC_SECTION
{
unsigned long PageRVA; // адрес страницы
unsigned long BlockSize; // размер блока
unsigned short TypeOffset; // тип исправления и
// смещение на странице
unsigned short Padding; // завершающие нули
};
Структура записывается в конец файла после секции ".cli". Чтобы размер файла был кратен inP->FileAlignment, в него дописывается определенное количество нулей.
Сегменты .data и .bss. Местонахождение локальных переменных, инициализированных и неинициализированных глобальных и статических переменных, строковых литералов.
Форматы исполняемых файлов. Формат Portable Executable. Секция .import. Механизм импортируемых функций. Вызов импортируемых функций.
Когда загружается исполняемый файл, то загрузчик использует таблицу импорта, чтобы узнать какие функции импортирует данный модуль. Потом загрузчик загружает библиотеки содержащие данные функции, если они не загружены, с помощью функции LoadLibrary. LoadLibrary возвращает адрес библиотеки в адресном пространстве текущего процесса. Чтобы получить адрес функции надо использовать функцию GetProcAddress. Ей передается имя функции и базовый адрес библиотеки. Т.о. в таблицу импорта добавляются адреса нужных функций при загрузке, а потом используются после загрузки.
