ZX-Ревю 1992 №1-2 1991 г.

Защита программ - исключение возможности остановки Basic программ.


МИХАЙЛЕНКО В.С.

ЗАЩИТА ПРОГРАММ

Сегодня мы начинаем печатать объемный труд нашего читателя из г. Минска Михайленко В.С., посвященный вопросам защиты компьютерных программ. Книга написана им специально для "ZX-РЕВЮ".

Мы очень рады, что лед тронулся и стали появляться крупные работы отечественных авторов. За те несколько лет, что мы работаем в области информационного обеспечения "Синклер"-совместимых машин, мы очень хорошо узнали, как много у нас талантливейших программистов, способных разработчиков. Но с другой стороны, мы хорошо знаем и то, как трудно их подвинуть на то, чтобы написать хорошую книгу, статью, цикл статей. "Сделаю все, что угодно, но писать книгу - разве что под дулом пистолета", - вот типичный ответ нашего разработчика. Значительно меньшая часть все-таки соглашается, причем охотно, но после первого порыва быстро охладевает и на этом все кончается.

Откуда же мы знаем о существовании этой армии талантов, если они ничего не пишут? - может спросить внимательный читатель. Оказывается, все-таки пишут. Они пишут интересные, хорошо проработанные, наполненные точным, конкретным содержанием критические письма на то, что читают в "ZX-РЕВЮ". Мы благодарны им за это, но увы должны отметить, что собраться и написать пять-шесть страниц, блещущих идеями, нашему разработчику проще, чем собраться с духом и подготовить нормальный законченный материал, освещающий хотя бы одну идею, и который с интересом и пониманием будут читать миллионы начинающих поклонников "Спектрума", а именно такой цифрой мы и оцениваем на сегодняшний день тех, кто уже включился в это всенародное движение.

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

Работа прошла техническое и литературное редактирование "ИНФОРКОМа".

ЧАСТЬ 1

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

Для компьютера "ZX SPECTRUM" существует система мер по защите "Бейсиковских" программ и программ в машинных кодах. Этот цикл статей посвящается защите Бейсик-программ.

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

1. Исключить возможность остановки (прерывания работы программы).

2. Сделать листинг программ нечитаемым.

ГЛАВА 1. Исключение возможности остановки программ.

1.1. Общие рекомендации.

Самое первое, что необходимо сделать - это выполнить программу автостартующей со строки с номером n. Это выполняется при записи программы на ленту командой:

SAVE "имя" LINE n

Теперь после загрузки программа сама будет стартовать с указанной строки. Тем не менее, она может быть остановлена командой BREAK или по сообщению об ошибке.

Отключить клавишу BREAK можно, если в той строке, с которой происходит автостарт, поместить команду POKE 23613, PEEK 23730-5. Кроме этого, возможно отключение клавиши BREAK за счет использования подпрограммы в машинных кодах, которая будет описана

ниже.

Если же Вы по каким-то причинам не желаете использовать подпрограммы в машинных кодах то необходимо помнить следующее.

Для хорошо отлаженной программы остановку по ошибке можно исключить. Надо знать, что чаще всего при взломе программы сознательно вносят ошибку во время исполнения оператора INPUT. Например, если программа просит от пользователя ввести какое-либо число, он сознательно вводит букву. Программа останавливается с сообщением VARIABLE NOT FOUND (переменной нет). Чтобы избежать этого рекомендуется не использовать оператор INPUT, а организовывать опрос клавиатуры на основе функции INKEY.

Если же Вам необходимо использование оператора INPUT (например при вводе многозначных чисел), то с целью защиты от прерывания можно сделать, чтобы программа либо "зависала" (или самосбрасывалась при остановке), либо вместо сообщения об ошибке осуществляла переход на заранее заданную строку.

Самосброс программы дает использование нижеприведенных команд. Так, если поместить их в строке автостарта, то при попытке сделать BREAK или появлении сообщения об ошибке программа будет сбрасываться:

LET ERROR=256*PEEK 23614+PEEK 23613: POKE ERROR, 0: POKE ERROR+1, 0

Для обеспечения зависания программы используется размещение в стартовой строке команды:

POKE 23659, 0

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

Эти программы и методы их использования описаны в следующей статье.

1.2 Подпрограмма обработки сообщений с кодами D, H, L.

Нажатие клавиши BREAK во время исполнения программы (или же ей аналогичное STOP IN INPUT) в обычном режиме может приводить к одному из следующих сообщений:

D: BREAK - CONT REPEATS

Клавиша BREAK нажата во время действия периферийной операции. Действие CONTINUE после этого оператора обычное, т.е. то, что указано в операторе.

H: STOP IN INPUT

Некоторые введенные данные начинаются с оператора STOP, или была нажата INPUT

LINE.

Действие CONTINUE обычное.

L: BREAK INTO PROGRAM (BREAK во время исполнения программы)

Нажата клавиша BREAK; это было обнаружено между исполнением двух операторов. Строка и номер оператора в строке указывают на оператор, выполненный перед нажатием BREAK, но CONTINUE переходит к следующему оператору.

Чтобы во время нажатия клавиши BREAK остановки не произошло, может быть использована, например подпрограмма в машинных кодах ON BREAK GO TO (подпрограмма N66 из инструментального пакета SUPERCODE 3.5).

Если Вы запустите эту подпрограмму со строки aвтocтapтa, то типы остановок D,H,L будут игнорироваться, а программа будет переходить к заранее заданному Вами номеру строки (Первоначально задана строка 9495).

Для тех, кто не располагает пакетом SUPERCODE 3.5, мы приводим дисассемблер данной процедуры.

ORG 60899

60899 CD7C00 CALL 0124 60902 3B DEC SP

60903

3B

DEC SP

60904

E1

POP HL

60905

010F00

LD BC,15

60908

09

ADD HL,BC

60909

EB

EX DE,HL

60910

2A3D5C

LD HL,(23613)

60913

73

LD (HL),E

60914

23

INC HL

60915

72

LD (HL),D

60916

C9

RET

60917

76

HALT

60918

CD8E02

CALL 654

60921

7B

LD A,E

60922

FEFF

CP 255

60924

20F8

JR NZ,60918

60926

3A3A5C

LD A,(23610)

60929

FE0C

CD 12

60931

280A

JR Z,60943

60933

FE10

CP 16

60935

2806

JR Z,60943

60937

FE14

CP 20

60939

2802

JR Z,60943

60941

1819

JR 60968

60943

3C

INC A

60944

32815C

LD (23681),A

60947

FD3600FF

LD (IY+0),255

60951

211725

LD HL,9495

60954

22425C

LD (23618),HL

60957

210000

LD HL,0

60960

22445C

LD (23620),HL

60963

3B

DEC SP

60964

3B

DEC SP

60965

C37D1B

JP 7037

60968

C30313

JP 4867

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

5 CLEAR 24999 10 FOR 1=25000 TO 25071 20 READ A: POKE I,A 30 NEXT I

40 DATA 205,124,0,59,59,225,1,15,0,9,235,42,51,92,115,35,114,201,118,205,142,2,

123,254,255,32,248,58,58,92 50 DATA 254,12,40,10,254,16,40,6,254,20,40,2,24,25,60,50,129,92,253,54,0,255,33, 23,37,34,66,92,33,0,0,34,68,92,59,59,195,125,27,195,3,19

Данная Бейсик-программа позволяет вводить эту подпрограмму в любое место оперативной памяти. Теоретически возможны 3 варианта:

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

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

3) Вы совмещаете программу на Бейсике и эту программу в кодах с использованием оператора REM методом который будет описан в одной из следующих глав и затем сразу после загрузки, непосредственно из Бейсика запускаете эту процедуру.

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

загрузка номера строки перехода в Бейсике.

1.3. Подпрограмма обработки сообщений об ошибке, кроме 0:ОК; 8:END OF

FILE; 9:STOP STATEMENT.

Многие программы имеют возможность ввода ошибки, т.е. останавливаются из-за неправильной своей работы. В этом случае на экране дисплея индицируется сообщение об ошибке. Чтобы этого не происходило, а вместо выдачи сообщений осуществлялся переход к заранее заданной строке Бейсик-программы, используется процедура: ON ERROR GO TO (процедура N 65 из программы SUPERCODE).

Ниже приведена Бейсик-программа, с помощью которой можно загрузить процедуру : "ON ERROR GO ТО" в любое место оперативной памяти, в моем примере загрузка осуществляется с адреса 25000.

10 CLEAR 24999 20 LET A=25000 30 FOR I=0 TO 72 40 READ B 50 POKE A+I, B 60 NEXT I

70 REM ЗАПУСК ПРОГРАММЫ 80 RANDOMIZE USR 25000

90 DATA 205,124,0,59,59,225,1,15,0,9,235,42,61,92,115,35,114,201,59,59,205,142,2,123, 254,255,32,248,58,58

10O DATA 92,254,255,40,33,254,1,40,29,254,8,40,25,60,50,129,92,253,54,0,255,33,23,37,

34,66,92,175,50,68 110 DATA92,253,203,7,254,195,125,27,51,51,195,3,19

Процедура "ON ERROR GO TO" имеет длину 73 байта и осуществляет переход к строке Бейсика 9495 (допустимы изменения).

Рассмотрим, для чего же употребляется эта программа. В разделе 1.1. было сказано, что одним из методов взлома является ввод несуществующей переменной вместо числа в операторе INPUT. На уровне Бейсика рекомендовалось использовать опрос клавиатуры с помощью INKEY$. Данная процедура самостоятельно анализирует подобного рода ошибки и осуществляет переход к строке 9495. При этом по адресу 23681 можно узнать код ошибки.

Точно такой же переход эта программа будет осуществлять, если будет произведена попытка деления на 0. Оператор PRINT попытается распечатать символ с помощью управляющего кода AT за пределами экрана; встретится RETURN без GO SUB или NEXT без FOR и др.

Наилучшим способом использования данной процедуры является совмещение ее с Бейсик-программой с использованием оператора REM методом, который будет ниже.

Чтобы подготовиться к его выполнению, Вам необходимо сформировать эту программу в произвольной области ОЗУ, используя Бейсик-программу данного раздела и записать ее на магнитофон в виде отдельного файла CODE.

1.4. Метод защиты, основанный на совмещении Бейсика и программы в

машинных кодах.

Многие пользователи компьютера ZX SPECTRUM бывают удивлены, когда после загрузки всего лишь одного Бейсик-файла программы на экране возникают эффекты, которые на Бейсике создать заведомо невозможно. Такое же чувство возникает и тогда, когда после загрузки первого Бейсик файла дальнейшая загрузка ведется необычным способом, несмотря на то, что загружался именно Бейсик-файл (свидетельством этого является то, что Вы подали команду LOAD "").

Все дело в том, что в данном случае использован прием, позволяющий совместить в первом загружающемся файле как Бейсик-команды, так и машинные коды.

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

Один из приемов состоит в том, чтобы разместить программу в кодах после оператора REM, т.к. текст, следующий после этого оператора, не обрабатывается компьютером. (Подобное совмещение также накладывает ограничение на использование кодов в программе. Ни один код этой программы не должен быть равен 13(DEC), 0D(HEX), поскольку в Бейсике этот код свидетельствует об окончании строки и символы, следующие за ним, обрабатываются как новая строка Бейсика).

Для того, чтобы осуществить совмещение, нам необходимо сформировать строку с оператором REM так, чтобы количество символов, следующих после REM, было равно числу байтов программы в кодах, т.е. n.

Для этого наберем с клавиатуры: 1 REM LLLL...LLLL

Мной был использован символ L но в принципе можно использовать к любой другой.

Как Вы уже обратили внимание, строка с оператором REM должна идти первой в программе. Это необходимо для того, чтобы легко можно было определить адрес, по которому нужно грузить машинные коды и из которого вызывать их на исполнение.

Если Вы не изменяли системную переменную PROG, то она указывает на начало Бейсик программы по адресу 23755.

Следовательно, загрузку кодов нам необходимо начинать с адреса 23760 (Это объясняется тем, что первые два кода Бейсик-строки характеризуют ее номер, следующие два - ее длину и пятый символ - это код оператора, в данном случае REM).

Теперь заменим набранные нами символы в количестве n байтов на программу в машинных кодах аналогичной длины. Подадим команду LOAD "" CODE 23760, N

(В случае, если системная переменная PROG у Вас смещена, то Вам необходимо узнать адрес начала загрузки кодов, подав следующую команду с клавиатуры: PRINT (РЕЕК 23635+256 * РЕЕК 23636+5)

Теперь, при загрузке кодов, вместо адреса 23760 укажите адрес, который Вы получили. Загрузив коды, мы добились поставленной цели. Теперь в Бейсике находится программа в кодах, которую при желании можно запустить, подав в одной из нижеследующих строк Бейсик-программы, команду RANDOMIZE USR 23760

В случае смещенной системной переменной PROG, Вам будет необходимо видоизменить команду:

RANDOMIZE USR (PEEK 23635+256 * РЕЕК 23636+5)

Метод совмещения чаще всего используется, когда Вы хотите защитить наиболее уязвимые места программы, которые Вам наиболее дороги и Вам бы не хотелось, чтобы они были кем-либо изменены. Кроме этого, такой подход позволяет загружать машинные коды без "заголовка" методом, который будет описан далее, что затрудняет вскрытие данного машиннокодового блока, поскольку не известен его адрес.

Как Вы уже обратили внимание, обычно загружающийся программный блок состоит из двух частей. Первая часть является тем заголовком, который содержит название программы, ее длину и адрес, начиная с которого она располагается в памяти компьютера, а вторая часть - это уже непосредственно коды. Следует отметить, что аналогичную структуру имеет и Бейсик программа и массивы, но "заголовки" этих блоков имеют принципиальные различия.

Среди наиболее любопытных особенностей метода скрывания машинного кода в строке REM следует отметить тот факт, что после подачи команды LIST распечатка может быть остановлена с сообщением о неправильном цвете (INVALID COLOR). Это объясняется тем, что в машинных кодах могут встретиться команды, код которых не может быть опознан компьютером в строке Бейсик-программы. И этот любопытный факт, совместно с использованием метода зануления, который будет описан в следующей главе, дает великолепную защиту от листинга. Необходимо, однако, предупредить читателя, что создавая программы в кодах, для их последующего размещения в Бейсике, необходимо сразу определиться в адресах, т.е. точно установить адреса, где данная программа будет находиться и работать, чтобы не было сбоев из-за неправильной адресации.

Если Вы все же хотите использовать программу в кодах, которая была рассчитана на определенное место в памяти, то чтобы ничего не переделывать, Вам просто необходимо дополнить ее размещенным в начале блоком переноса с использованием команды LDIR (более подробное описание этой команды дано в соответствующих методических разработках "Инфоркома").

1.5. Оригинальный метод защиты, использующийся при загрузке машинных

кодов.

Самые первые программы для ZX SPECTRUM отличались примитивностью в плане защиты (да и не только защиты). Обычно они состояли из Бейсик-программы, управляющей загрузкой, которая загружала коды и запускала их с определенного адреса. Взломщик мог беспрепятственно смотреть как Бейсик программу, так и программу в кодах.

Более поздние авторские разработки были гораздо лучше продуманы в отношении защиты.

Как известно, загружающаяся программа состоит из заголовка и самой программы. В заголовке находится описание типа программы: Бейсик, CODE, SCREEN$ и т.д. Кроме этого, там находится название программы и адрес в памяти, с которого начнется загрузка, а также длина программы (для программ в машинных кодах).

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

Это делается с использованием специальной процедуры в кодах, которая в некоторых случаях совмещается с программой на Бейсике с использованием оператора REM.

К программам, использующим данный метод загрузки, относятся MAT II, RAMBO III и

др.

Рассмотрим, как этот прием реализован программе MAT II. Ниже приведен листинг загрузчика.

0 REM CRACKED BY MIHAILENKO VS 1991 10 FOR n=0 TO 12: READ a: POKE 64000+n, a 20 NEXT n

30 DATA 55, 62, 255, 221, 33, 0, 64, 17, 254, 27, 195, 86, 5 40 RANDOMIZE USR 64000

Фактически Бейсик-программа служит лишь для того, чтобы сформировать и запустить процедуру в машинных кодах. Запуск осуществляется в строке 40, а строки 10...30 ответственны за формирование этой процедуры, начиная с адреса 64000. Ниже приведен дисассемблированный текст данной процедуры.

64000 SCF

64001 LD A,255 64003 LD IX,16384 64007 LD DE,7166 64010 JP 1366

Действует эта программа следующим образом. В регистр IX загружается адрес начала загрузки кодов, в регистр DE - общая длина программы в кодах, остальная система команд необходима для правильной работы встроенной в ПЗУ программы загрузчика с ленты. Переход на эту программу осуществляется в строке 64010. (Все используемые величины - десятеричные).

Этот тип загрузки используется во многих программах. В частности, программа GREEN BERET использует встроенную процедуру загрузки как подпрограмму, вызывая ее по

CALL 1366 для загрузки нескольких блоков кодов.

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

1.6. Метод защиты, используемый в программе FIST III.

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

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

BORDER 0: POKE 23624, 0: POKE 23570, 16

Этот метод защиты легко можно разблокировать, подав команды: BORDER 7: POKE 23570, 6

Кроме защиты, эта программа имеет еще одну особенность, на которую могли не обратить внимание пользователя: заставка в середине экрана формируется на Бейсике. Создана она довольно оригинальным способом, но самым любопытным является то, что системная переменная, используемая в этой программе, в фирменном описании компьютера (автор - Виккерс) охарактеризована, как неиспользующаяся.

Ниже приведем текст программы, после выполнения которой в середине экрана очень крупным шрифтом появляется надпись: GOOD LUCK TO YOU

10 REM CRACKED BY MIHAILENKO VADIM MINSK 1991

20 FOR I=72 TO 79

25 POKE 23681, I

30 LPRINT "GOOD LUCK TO YOU"

40 NEXT I

В данном случае авторы используют команду вывода на печатающее устройство LPRINT для поэтапного высвечивания на экране вышеуказанной надписи.

Если Вы хотите получить подобное изображение не в середине, а в верхней части экрана, то Вам необходимо подобрать соответствующим образом изменение переменной I.

Любопытный эффект получается при использовании изменения 20 FOR I=72 TO 78 и т.д.




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
ZX-Обоз - Обзор электронной прессы: Nicron 95-98, C-Net Week 15.
IRYSOU-201 - Научно-фантастический рассказ (часть 1-4).
Форум - Д.Федоров: Печать картинки с маской с точностью до пиксела. Алгоритм расчета адреса по координатам с точностью до пиксела.
history - краткая история minsk.zx-net'a.
Содержание - содержание газеты

В этот день...   21 ноября