Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции (2).doc
Скачиваний:
254
Добавлен:
28.06.2014
Размер:
2.41 Mб
Скачать
  1. Защита программных средств от изучения.

Защита программных средств от изучения

  • Противодействие использованию отладчиков.

  • Противодействие дизассемблерам и декомпиляторам.

  • Искусственное запутывание механизма защиты (obfuscation, обфускация) как общий метод защиты.

Методы «снятия» защиты

  • Изучение алгоритма проверки ключевой информации для генерации правильных регистрационных ключей (например, программной эмуляции работы поставляемого с программой USB-ключа).

  • Изучение алгоритма проверки ключевой информации для отключения работы соответствующего участка кода программы защиты.

Противодействие использованию отладчиков

  1. Обнаружение работы программы под управлением отладчика или программы мониторинга типа FileMon или RegMon.

  2. Реакция на обнаружение отладчика.

Обнаружение работы программы под управлением отладчика

  • Использование функций из набора Windows API (EnumWindows, IsDebuggerPresent, функций библиотеки toolhelp.dll).

  • Проверка установки точек прерывания (байт 0xCC) на функции программы или Windows API.

  • Изучение переменных системного окружения (функция Windows API GetEnvironmentStrings).

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

Реакция на обнаружение отладчика

  1. Вызов аварийного завершения отладчика:

  • «порча» стека или вызов функции Windows API DestroyWindow для главного окна отладчика;

  • некорректное взаимодействие с отладчиком по протоколам DDE или COM (передача «мусора», преждевременный вызов метода Release).

  1. Выключение механизма защиты (для «обмана» взломщика и выигрыша о времени).

Противодействие дизассемблированию

  • Создание самомодифицирующегося кода (шифрование и расшифрование фрагментов кода, полное изменение исполнимого кода путем замены команд на эквивалентные в соответствии с некоторой таблицей и т..). Требуется использование языка ассемблера.

  • Использование методов запутывания (обфускации).

Методы запутывающего кодирования

  1. Лексические трансформации (запутывание кода).

  2. Запутывание структур данных.

Изменение потока выполнения программы

Запутывание кода

  1. Асимметричная криптография:

  • Данные, представленные покупателем, шифруются на закрытом ключе изготовителя и передаются покупателю вместе с защищенной программой и открытым ключом.

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

  • Использование при проверке ключевой информации необратимой функции (например, хеширования).

  • Использование функции преобразования проверяемых данных F (Y=F(X)), являющейся суперпозицией функций H1 и H2, и реализация в системе защиты Z1=H1 (X), Z2=H2-1(Y), сравнения Z1 и Z2 (X – хранящийся в системе защиты эталон, Y – вводимая информация).

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

  • Имитация проверки введенных данных в разных местах программы.

  • Использование в программе различных функций с одинаковым действием.

Запутывание структур данных

  1. Использование системных ресурсов (памяти окна, атомов и т.п.) для хранения данных, используемых при проверке ключевой информации.

  2. Создание нескольких различных переменных с разными значениями для представления одного и того же результата.

  3. Использование косвенной адресации для доступа к переменным, участвующим в процессе проверки.

Изменение потока выполнения программы

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

  2. Вынесение проверки в обработку сообщений типа WM_PAINT (подмена кодов сообщений может выполняться непосредственно в цикле обработки сообщений).

Виды обфускации

  • на уровне исходного кода;

  • на уровне машинного кода;

  • на уровне промежуточного кода (например, на уровне байт-кода программ на языке Java).

Пример обфускации на уровне исходного кода на языке C++

int nCount = 100;

float fTaxRate = 0.2, orig_price[1000], tax[1000], price [1000];

for (int i=0; i< nCount; i++)

{

tax[i] = orig_price[i] * fTaxRate;

price[i] = orig_price[i] + tax[i];

}

  • Код после обфускации:

float b[1000], c[1000], d[1000];

for(int a=0;a<100;a++){b[a]=c[a]*0.2;d[a]=c[a]+b[a];}

Достоинства программ-обфускаторов

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

Недостатки обфускаторов

  • код программы после ее обфускации может стать более зависимым от программно-аппаратной платформы или компилятора;

  • обфускатор не даёт постороннему выяснить, что делает код, но и не даёт разработчику отлаживать его, поэтому при отладке системы защиты приходится отключать обфускатор;

  • ни один из существующих обфускаторов не гарантирует сложности декомпиляции и не обеспечивает безопасности, сопоставимой с уровнем современных криптографических алгоритмов;

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

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