logo
622231 / 622221с / очн 622221с / ПАЗИ 622221с / КЛ_ПАЗИ

Защита от исследований в режиме отладки.

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

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

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

Напомним также традиционные методы защиты .

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

Известно, что выполнение программы в режиме трассировки значительно уменьшает ее быстродействие. Поэтому по времени "прохода" отдельных кусков защищаемого ПО можно определить работу под отладчиком. По таймеру (например, запустив его 2-й канал) заранее просчитывают скорость выполнения некоторого участка и сравнивают его со значением, полученным в ходе работы программы. Если есть существенное расхождение в полученных результатах, то можно сделать вывод о выполнении данного участка под контролем. Из недостатков метода отметим лишь разное быстродействие процессоров на разных ПЭВМ, которое следует учитывать.

Интересный способ выматывания "исследователя" – применение достаточно больших процедур, производящих некоторую сложную и, на первый взгляд, важную работу, но на самом деле, не имеющих никакого отношения к логике работы программы, так называемых "пустышек". Для лучшей имитации их важности можно включать в них перехват 13h, 21h, 25h и 26h прерываний (обслуживающих ввод-вывод информации на внешние устройства), что, безусловно, заинтересует хакера.

Оригинальный способ защиты ПО от исследования, примененный в пакете COPYLOCK, использует конвейер шины данных микропроцессора. На рис. 4.2 изображен его фрагмент. (Надеемся, что не навлечем на себя гнев цивилизованных пользователей, афишируя некоторые тонкости программы: все равно она безнадежно устарела, да и не вскрыта лишь самыми ленивыми. А начинающим специалистам рекомендуем ознакомиться с ее работой. Полный листинг опубликован в электронном журнале "НСК", N1, 1992 г.). Фрагмент дан со значением смещений относительно кодового сегмента, чтобы читатель смог увидеть, как команда REP STOSW в подпрограмме SUBR затирает значением из регистра AX область ОЗУ, в которой находится и сама подпрограмма. Тем не менее, SUBR нормально отрабатывает и возвращает управление в точку вызова (но только не в пошаговом режиме).

Трюк очень прост: так как длина конвейера не менее 4-х байт, то, очевидно, команды, расположенные за REP STOSW, уже находятся в нем до ее выполнения, что и обеспечивает нормальную работу подпрограммы даже после затирания ее кода в ОЗУ. Выполнение же по одному шагу (то есть по трассировочному прерыванию) нарушает очередность засылки кодов в МП и приводит к непредсказуемому результату. Пример на рис. 4.3 демонстрирует более изящное использование конвейера. Он определяет - идет ли выполнение программы с трассировкой или нет, и осуществляет ветвление (команда JMP с меткой m:) в зависимости от этого. Здесь ветвление служит лишь для индикации работы под отладчиком, но вы можете применить его по своему усмотрению.

На рис. 4.4 использование конвейера шины данных в иной интерпретации и в более завуалированном виде. По существу, это вариация на ту же тему и демонстрирует лишь разнообразие способов работы с конвейером.

Аномальные явления, с которыми приходится сталкиваться при программировании МП Intel 80x86, не менее интересная тема при рассмотрении построения защитных механизмов. Информацию о них программист чаще всего получает экспериментальным путем (что становится его "ноу-хау"). Отступлений от стандарта обычно немного (исключение составляют машины фирмы Compaq с длинным перечнем особенностей). Об одном упоминалось в печати [2] - это потеря трассировочного прерывания после команд, связанных с пересылкой сегментных регистров типа MOV SEG.REG,R/M и POP SEG.REG. К сожалению, в статье результаты исследований описаны неполно. Во-первых, для МП 8086/8088 (а точнее, японского аналога V20) существует еще один тип команд, заставляющий пропускать трассировочное прерывание: MOV R/M,SEG.REG. Во-вторых, для МП с более высоким номером также идет потеря трассировки, но только для стекового сегментного регистра. Это свойство с успехом можно применить для определения трассировки и типа машин.

Известно, что отладчики при обработке 1-го прерывания анализируют текущую команду на PUSHF (код 9Ch) и сбрасывают Т-бит. Поэтому последовательность команд PUSHF, POP AX под отладчиком не позволит получить установленный 8-й бит в регистре AX. На рис. 4.5 представлен текст короткой программы, использующей эту особенность. Команда POP SS заставляет отладчик пропустить следующую за ней команду PUSHF из-за потери трассировки, и, благодаря этому, выявляется факт работы под отладчиком.

Образцом знания особенностей работы МП и наиболее лаконичным вариантом распознавания его типа мы считаем подпрограмму, текст которой приведен в статье "Intel insight on specific instructions" [3]. Вот два примера из нее:

1) Для определения типа МП, начиная с 80186 и выше, используется тот факт, что для них в счетчиках сдвигов (линейных и циклических) маскируются все биты, кроме 5-и младших, ограничивая тем самым величину сдвига 31 битом.

2) Начиная с МП 80286, характерна следующая особенность: команда PUSH SP заносит в стек значение SP с учетом его декремента, а более низшие типы МП - без.

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

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