MS-DOS для программиста© Александр Фролов, Григорий ФроловТом 19, М.: Диалог-МИФИ, 1995, 253 стр. 5.3. Защита программ от трассировкиЗащищая свои программы от несанкционированного копирования, не следует забывать о таких средствах "взлома", как пошаговые отладчики - Turbo Debugger , CodeView , Advanced Fullscreen Debug , AT86 и т. п. Используя отладчики, искушенные в своем деле системные программисты рано или поздно смогут обнаружить и отключить (или обмануть) средства защиты от копирования. В этом разделе книги мы расскажем о некоторых приемах, позволяющих затруднить обнаружение средств защиты. Стандартный метод обнаружения средств защиты от копирования - дизассемблирование программы установки или выполнение ее под управлением пошагового отладчика. Листинг, получаемый в процессе дизассемблирования, оказывает большую услугу при использовании отладчика, поэтому эти два средства - дизассемблирование и использование отладчика - обычно используются вместе. Соответственно, требуются специальные приемы программирования для борьбы с дизассемблером и защиты от отладчиков. Для затруднения дизассемблирования лучше всего подходит шифрование отдельных участков программ или всей программы целиком. После загрузки программу следует расшифровать в оперативной памяти и передать ей управление. Еще лучше выполнять динамическое расшифровывание программы по мере ее выполнения, когда участки программы расшифровываются непосредственно перед использованием и после использования сразу же уничтожаются. При расшифровывании можно копировать участки программы в другое место оперативной памяти. Пусть, например, программа состоит из нескольких частей. После ее загрузки в оперативную память управление передается первой части программы. Эта часть предназначена для расшифровки второй части, которая находится в памяти вслед за первой. Задача второй части - перемещение третьей части программы на место уже использованной первой части и расшифровка ее там. Третья часть, получив управление, может проверить свое расположение относительно префикса программного сегмента и, в случае правильного расположения (сразу вслед за PSP), начать загрузку сегментных регистров такими значениями, которые необходимы для выполнения четвертой (установочной) части программы. Если попытаться дизассемблировать программу, составленную подобным образом, то из этого ничего не получится. Второй способ борьбы с дизассемблером является, по своей сути, борьбой с человеком, занимающимся дизассемблированием. Он заключается в увеличении размера загрузочного модуля программы до сотни-другой Кбайт и в усложнении структуры программы. Объем листинга, получающегося при дизассемблировании программы размером в 30 - 40 Кбайт, достигает 1 - 1,5 Мбайт. Поэтому большие размеры установочной программы могут сильно увеличить время обнаружения средств защиты. Что такое усложнение структуры программы, достаточно понятно само по себе. Авторам известна программа, использующая для обращения к одной и той же области памяти, содержащей многочисленные переменные, разные сегментные адреса. Поэтому очень трудно сразу догадаться, что на самом деле программа работает с одной и той же областью памяти. Мы не будем дальше рассказывать о способах усложнения структуры программы, оставив простор для фантазии читателя. Вместо этого перейдем к борьбе с трассировкой программы пошаговыми отладчиками. Можно предложить две группы средств защиты от трассировки. В первую группу входят средства блокировки работы самих отладчиков, делающие невозможным трассировку программы. Вторая группа средств направлена на определение факта работы программы под управлением отладчика. К первой группе средств относится:
Напомним, что прерывание INT 1 и INT 3 (соответственно, прерывание для пошаговой работы и прерывание по однобайтовой команде INT) интенсивно используются отладчиками. Первое прерывание позволяет отладчику получать управление после выполнения каждой команды трассируемой программы. С помощью второго прерывания отладчик может устанавливать точки останова, заменяя байты программы на команду однобайтового прерывания. Защищенная от трассировки программа должна подготовить свои собственные обработчики для этих прерываний и "незаметно" для человека, занимающегося трассировкой, записать их адреса в таблицу векторов прерываний. Эти обработчики прерываний могут не делать ничего, то есть состоять из одной команды IRET, или выполнять какие-либо действия, фиксирующие факт работы программы под контролем отладчика. В ходе трассировки программы (при ее пошаговом выполнении) вам необходимо нажимать на клавиши - для перехода к очередной команде. Это можно использовать для блокировки отладчика. Запретив прерывания командой CLI и переназначив прерывание от клавиатуры на себя, программа установки может выполнять какие-либо действия, не требующие работы оператора с клавиатурой. Обработчик клавиатурного прерывания защищенной от трассировки программы должен фиксировать прерывания, например, установкой флага. Если программа работает не под контролем отладчика, прерывания во время этого участка программы невозможны (они запрещены командой CLI). Если же используется режим пошагового выполнения программы под управлением отладчика, отладчик разрешает клавиатурные прерывания, невзирая на то, что была выдана команда CLI. Наш обработчик клавиатурного прерывания в этом случае зафиксирует работу в режиме трассировки. Аналогично можно воспользоваться прерыванием таймера. Защищенная программа устанавливает свой обработчик для прерывания таймера, который устанавливает флаг в случае появления прерывания от таймера. В подходящий момент времени она запрещает прерывания и выполняет какую-либо работу, периодически проверяя флаг. Если программа работает в пошаговом режиме, команда запрета прерываний CLI не работает, и флаг будет взведен, сигнализируя работу под контролем отладчика. |