- •Основы исследование безопасности программного обеспечения
- •Оглавление
- •Обращение к читателю
- •Введение
- •С чего начать
- •Инструменты исследователя
- •Установка исследуемой программы
- •Типовая защита «Запрос пароля» или «Запрос ввода регистрационного номера»
- •Исследование типовой защиты в отладчике OllyDbg
- •Исследование типовой защиты в дизассемблере ida Pro
- •Типовая защита «Запрос пароля» или «Запрос ввода регистрационного номера» с шифрованием сообщения
- •Технологии защиты программного кода от исследования и отладки
- •Как не надо проектировать защиту программ
- •Как обмануть отладчик и дизассемблер
- •Приложение 1. Ассемблер в Windows
- •О стеке
- •Команды передачи управления
- •Литература для дополнительного изучения
- •Приложение 2. Отладчик OllyDbg
- •Откуда скачать программу
- •Установка и настройка программы
- •Дизассемблированный код (листинг)
- •Регистры
- •Наиболее полезные клавиши в OllyDbg
- •Подключение плагинов в OllyDbg
- •Встроенный язык ida Pro
- •Плагины ida Pro
- •Литература для дополнительного изучения
- •Задание для самостоятельного выполнения
- •Список используемой литературы
Технологии защиты программного кода от исследования и отладки
-
Проверка даты и времени
При запуске программа проверяет текущую дату (год, месяц, день и т.д.), если она не совпадает с запланированной, то программа отказывается работать или работает неправильно. Для обхода защиты злоумышленник перехватывает в программе проверку даты и устанавливает требуемую дату.
-
Фиксированное количество запусков
Trial-программы запускаются фиксированное число раз: программа записывает количество запусков в реестр (или в «специальный» файл) при установке (или при первом запуске) на компьютер пользователя. Для обхода защиты злоумышленник может воспользоваться, например, программами-мониторами, отслеживающими обращение программы к реестру (или каким-либо файлам).
-
Шифрование всей программы или ее частей
Программа разбивается на несколько частей. Загрузчик программы загружает первую часть программы в память и расшифровывает его в памяти. После расшифровки управление передается на эту часть программы. После того как эта часть программы отработала, загрузчик удаляет ее из памяти, расшифровывает вторую часть программы в памяти, передав на нее управление и т.д. После того как вся программа отработает, загрузчик удаляет ее из памяти. На этом методе основана работа некоторых упаковщиков и протекторов.
-
Проверка на основе динамически изменяющихся параметров
Параметры каждого компьютера уникальны, можно выдавать регистрационные данные на конкретный компьютер. Недостаток метода – частая смена конфигурации компьютера.
-
Регистрация online
Программа в реальном времени связывается с сайтом разработчиков и передает туда некоторый код (серийный номер диска и др.), в ответ программе передается регистрационная информация. К недостаткам метода относят безопасность передаваемых данных, обязательное наличие доступа в Интернет.
Как не надо проектировать защиту программ
Необходимо определить уровень злоумышленника, который может попытаться обойти защиту. В условиях жесткой конкуренции нет смысла тратить столько же времени на разработку защиты, сколько заняла разработка самой программы. Возможно, что дешевле будет приобрести готовую защиту.
Защита не должна основываться на одном лишь предположении, что ее не смогут изучить. Отсутствие исходных текстов не является препятствием к изучению и модификации программы.
Рассмотрим защиту, основанную на вводе регистрационного кода. Злоумышленник в этом случае может:
-
установить точки останова на функции считывания текста;
-
«отловить» адрес памяти, по которому будет записан пароль.
Для затруднения обхода защиты нельзя:
-
использовать стандартные обработчики компонентов (кнопок, флажков и т.д.), организовывать проверки в цикле сообщений;
-
применять стандартные способы ввода пароля, лучше написать свои визуальные компоненты для ввода регистрационного кода;
-
хранить введенный код в одной части программы;
-
хранить введенный код открытым текстом;
-
анализировать пароль сразу после его ввода;
-
проверять код только в одном месте;
-
создавать для проверки функцию или библиотеку;
-
проверять пароль только одним алгоритмом;
-
выполнять действия, связанные с проверкой, сразу после самой проверки (желательно добавить отвлекающие функции проверок);
-
использовать переменную для хранения результатов проверки;
-
хранить результаты проверки в реестре или на диске;
-
определять дату и время стандартными способами и т.д.