Используя отладчики, искушенные в своем деле системные программисты рано или поздно смогут обнаружить и отключить (или обмануть) средства защиты.
Сейчас мы поговорим о некоторых приемах, позволяющих затруднить обнаружение средства защиты.
Стандартным методом, использующимся для обнаружения средств защиты от копирования, является дизассемблирование программы установки программного пакета или выполнение его под управлением пошагового отладчика. Листинг, получаемый в процессе дизассемблирования, оказывает большую услугу при использовании отладчика, поэтому эти два средства - дизассемблирование и использование отладчика - обычно используют вместе.
Соответственно требуются отдельные средства для борьбы с дизассемблером и для защиты от отладчиков.
Для затруднения дизассемблирования лучше всего подходит шифрование отдельных участков программ или всей программы целиком. Например, часть программы-инсталлятора можно оформить в виде отдельной COM-программы. После трансляции исходного текста этой программы ее можно зашифровать тем или иным способом и в зашифрованном виде подгружать в память как программный оверлей. После загрузки программу следует расшифровать в оперативной памяти и передать ей управление.
Еще лучше выполнять динамическое расшифрование программы по мере ее выполнения, когда участки программы расшифровываются непосредственно перед использованием и после использования сразу же уничтожаются.
При расшифровании можно копировать участки программы в другое место оперативной памяти. Пусть, например, программа состоит из нескольких частей. После загрузки ее в оперативную память управление передается первой части программы. Эта часть предназначена для расшифровки второй части, располагающейся в памяти вслед за первой.
Задача второй части - перемещение третьей части программы на место уже использованной первой части и расшифровка ее там.
Третья часть, получив управление, может проверить свое расположение относительно префикса программного сегмента и, в случае правильного расположения (сразу вслед за PSP), начать загрузку сегментных регистров такими значениями, которые необходимы для выполнения четвертой, инсталляционной части программы.
Если попытаться дизассемблировать программу, составленную подобным образом, то из этого ничего не получится.
Второй способ борьбы с дизассемблером является по сути борьбой с человеком, занимающимся дизассемблированием. Он заключается в увеличении размера загрузочного модуля до сотни-другой килобайт и в усложнении структуры программы.
Объем листинга, получающегося при дизассемблировании программы размером в 30-40 килобайт, достигает 1-1.5 мегабайта. Поэтому большие размеры инсталляционной программы могут сильно увеличить время обнаружения средств защиты.
Что такое усложнение структуры программы, достаточно понятно само по себе. Существует программа, использующая для обращения к одной и той же области памяти, содержащей многочисленные переменные, разные сегментные адреса. Поэтому очень трудно догадаться, что на самом деле программа работает с одной и той же областью памяти.
Перейдем теперь к борьбе с трассировкой программы пошаговыми
отладчиками. Стандартные отладчики реального режима используют для
работы два вектора:
Еще более изящно использовать вектора отладчика в своих целях. Например, вы можете переназначить 21 вектор на 3 и обращаться к MSDOS не через int 21h, а через int 3h это короче на 1 байт и поэтому не позволит взломщику произвести обратную замену.
Слово состояния процессора:
17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
VM
R
|
| NT
| I/O PL
| OF
| DF
| IF
| TF
| SF
| ZF
|
| AF
|
| PF
|
| FC
| |
VM - виртуальный режим
mov bp,sp mov ax,'a1' mov [bp-2],ax ..... // не использовать стек!!! cmp word ptr [bp-2],'a1' jne a61 // под отладчикомПри работе в реальном режиме использование инструкций вида mov sp, 1 приводит к генерации int 06(invalid opcode). Вы можете маскировать прерывания на период выполнения критической части программы:
CS:0100 E421 in al,21h CS:0102 0C02 or al,00000010b ;IRQ 1 keyboard irq CS:0104 E621 out 21h,alили
CS:0100 E461 in al,61 CS:0102 0C80 or al,10000000b ; bit 7 - disable kbd CS:0104 E661 out 61h,alили
CS:0100 B4AD mov al, 0ADh ; disable keyboard CS:0102 E664 out 64h,alМаскировка немаскируемого прерывания NMI на AT:
mov al,0ADh out 70h,alРазрешить NMI:
mov al,2Dh out 70h,al
Очень хорошие результаты дает распаковка следующих инструкций по сложному самомодифицирующемуся алгоритму обработчиком Int 8 или Int 1.
Необходимо не забывать о возможности закомментировать проверяющие механизмы в вашей программе. Программа должна периодически просчитывать и проверять контрольные суммы участков программы.
Например, перед переключением в защищенный режим вы сможите подготовить в памяти массив контрольной информации. Расшифровка и проверка этого массива, а также запись данных в нестандартные секторы инсталляционной дискеты могут выполнятся в защищенном режиме. При этом пользуясь обычными отладчиками невозможно определить действия, выполняемые в защищенном режиме. Особенно если участок программы, работающей в зашифрованном режиме зашифрован и после выполнения затирается. Далее процессор можно вернуть в реальный режим и продолжить процесс инсталляции.
Находясь в защищенном режиме вы не можете обращаться к функциям DOS и BIOS, - вы можете читать и писать секторы дискеты только используя уровень портов ввода/вывода контроллера флопи-диска.
© Колесников Дмитрий Геннадьевич
Учебник по СайтоСтроению
-
|