ЧИТАТЕЛЬ - ЧИТАТЕЛЮ
ПРОСМОТР ЗАЩИЩЕННЫХ ПРОГРАММ
Письмо на тему взлома защищенных Бейсик-программ прислал нам наш юный читатель из г. Чехова Бессонов Александр. Ему всего 14 лет, но несмотря на это, он предложил вполне профессиональную и достаточно квалифицированную программу. Вот, что он пишет.
"Еще полгода назад я написал программу "LOOK BASIC PROGRAMS" (далее LBP). Я использую ее уже долгое время и она позволяет взламывать все программы (я работаю с дисководом и не уважаю клавишу "MAGIC", предпочитаю переписывать игры с ленты на диск по файлам). Также я использую программу "PAKET", состоящую из LBP, MONS4, LOAD/MERGE (последнюю можно взять, например, в БАЙТЕКе N 1 за 1992 г.).
Я писал эту программу, основываясь на том, что главными способами защиты являются управляющие символы и 5-байтное представление чисел. Введя программу из листинга 1, Вы получите LBP с адреса 55000. Теперь можете выполнить NEW и загружать защищенную программу (через MERGE или "LOAD/MERGE"). Вызов LBP - RANDOMIZE USR 65000.
Формат, в котором LBP выводит Бейсик-программу:
10 [23775] (20) REM <<<<<<<<< IPF BAV 1992 IP Здесь 10 - номер строки;
[23755] - адрес начала строки (в инверсном виде); (20) - длина строки (может быть ложной).
Далее идет обозначение управляющих символов (все в инверсном виде): I - INK (CHR$ 16,N) P - PAPER (CHR$ 17,N) F - FLASH (CHR$ 18,N) B - BRIGHT (CHR$ 19,N) V - INVERSE (CHR$ 20,N) А - AT (CHR$ 22, X, Y) T - ТАВ (CHR$ 23, N, 0) < - BACK (CHR$ 8).
После каждого числа LBP выводит в квадратных скобках и в инверсном виде настоящее число, представленное в пятибайтной форме. Например:
10 [23755] (20) REM <<<<<<<<< IP BAV 1992 IP
20 [23779] (30) INK 6Е4 [0]: PAPER 12,5 [3]: LOAD ""CODE 12345 [30000] 30 [23803] (10) RANDOMIZE USR 0 [30000.12]
В строке 30 напечатано число 0, а по-настоящему здесь число 30000.12. Это сделано для того, чтобы "вручную" разгадать это число было трудно, а функция USR просто откинет дробную часть.
Примечания:
1. Если после того, как Вы напечатали RAND. USR 65000 Вам выдался не весь листинг, то выполните: CLS: RANDOMIZE USR 65000.
2. LBP не проверяет наличие программы в ОЗУ. Если ее нет, то просто экран заполнится разными символами и в ответ на запрос да в Бейсик."
Комментарий ИНФОРКОМА: это касается второго пункта примечаний. Наличие программы не проверяется не потому, что это недостаток программы LBP, а потому, что заранее невозможно предвидеть, какими способами защиты воспользовался автор защищенной программы. Вам предоставляется "листинг" в том виде, как он может быть интерпретирован Бейсиком, а Вы уже сами должны решать, программа это или случайный набор символов.
Текст программы LBP представлен в Листинге 1.
Листинг 1.
10 CLEAR 64999: LET C=0: FOR t=65000 TO 65343: READ a: LET c=c+a: POKE t,a: NEXT t
20 IF c<>46381 THEN PRINT "ERROR !": STOP
2000 DATA 62,2,205,1,22,205,3,255,42,83,92,237,91,75,92,237,83,253,254,62,13,205,255,254,62, 13,205,255,254,229,205,40,26,225,229,229,193,205,43,45,62,123,205,255,254,253,203,87, 214,205
2010 DATA 227,45,253,203,87,150,62,125,205,255,254,225,35,35,78,35,70,35,62,40,205,255,254, 229,205,43,45,205,227,45,225,62,41,205,255,254,126,254,32,48,124,253,203,87,214,254,1 6,204,148,254
2020 DATA 254,17,204,156,254,254,18,204,160,254,254,19,204,164,254,254,20,204,168,254,254, 21,204,172,254,254,22,204,176,254,254,23,204,181,254,254,8,204,186,254,253,203,87,150 ,254,14,204,198,254,254
2030 DATA 13,32,16,35,229,237,91,253,254,167,237,82,124,181,225,194,251,253,201,35,24,170, 62,73,205,255,254,175,35,201,62,80,24,246,62,70,24,242,62,66,24,238,62,86,24,234,62,7 9,24,230
2040 DATA 62,65,35,24,225,62,84,35,24,220,62,60,43,24,215,205,255,254,35,195,62,254,35,62, 91,205,255,254,221,229,229,221,225,221,126,0,221,94,1,221,86,2,221,78,3,221,70,4,221, 225
2050 DATA 229,205,182,42,253,203,87,214,205,227,45,253,203,87,150,225,62,93,205,255,254,17, 4,0,25,175,201,0,0,229,215,225,201,17,11,255,175,205,10,12,201,128,13,126,76,79,79,75 ,32,66
2060 DATA 65,83,73,67,32,80,82,79,71,82,65,77,83,126,13,65,89,32,66,69,83,83,79,78,79,86,32, 65,46,13,18,1,66,65,86,32,127,49,57,57,49,18,0,141
Дисассемблер машинно-кодового блока программы LBP представлен в Листинге 2.
В заключение мы хотим от всей души поздравить начинающего автора с удачным дебютом в "ZX-РЕВЮ".
Листинг 2.
FDE8 |
3E02 |
LD |
A,#02 |
Открыть канал |
FDEA |
CD0116 |
CALL |
#1601 |
экрана. |
FDED |
CD03FF |
CALL |
#FF03 |
Вывод сообщения об авторе. |
FDF0 |
2А535С |
LD |
HL,(#5C53) |
Значение сист. перем. PROG. |
FDF3 |
ED5B4B5C |
LD |
DE,^^) |
Значение сист. перем. VARS. |
FDF7 |
ЕD53FDFE |
LD |
(#FEFD),DE |
Сохранение его в ячейке. |
FDFB |
3E0D |
STROK LD |
A,#0D |
В A - код "ENTER". |
FDFD |
CDFFFE |
CALL |
#FEFF |
Печать этого символа. |
FE00 |
3E0D |
LD |
A,#0D |
В A - код "ENTER". |
FE02 |
CDFFFE |
CALL |
#FEFF |
Печать этого символа. |
FE05 |
Е5 |
PUSH |
HL |
Печать |
FE06 |
CD281A |
CALL |
#1А28 |
номера |
FE09 |
E1 |
POP |
HL |
строки. |
FE0A |
Е5 |
PUSH |
HL |
Сохр. адреса на стеке. |
FE0B |
Е5 |
PUSH |
HL |
Перезапись |
FE0C |
C1 |
POP |
BC |
из HL в BC |
FE0D |
CD2B2D |
CALL |
#2D2B |
Передача ВС на стек калькул. |
FE10 |
3E7B |
LD |
A,#7B |
в A - код "[". |
FE12 |
CDFFFE |
CALL |
#FEFF |
Печать этого символа. |
FE15 |
FDCB57D6 |
SET |
2,(IY+87) |
Включение инверсии. |
FE19 |
CDE32D |
CALL |
#2DE3 |
Печать значения числа, представленного в 5-байт. виде. |
FE1C |
FDCB5796 |
RES |
2,(IY+87) |
Выключение инверсии. |
FE20 |
3E7D |
LD |
А,#7В |
В A - код "]". |
FE22 |
CDFFFE |
CALL |
#FEFF |
Печать этого символа. |
FE25 |
E1 |
POP |
HL |
В HL - адрес начала строки. |
FE26 |
23 |
INC |
HL |
Теперь в HL - адрес пары |
FE27 |
23 |
INC |
HL |
ячеек с длиной строки. |
FE28 |
4Е |
LD |
C, (HL) |
Перезапись |
FE29 |
23 |
INC |
HL |
длины строки |
FE2A |
46 |
LD |
B,(HL) |
в регистровую |
FE2B |
23 |
INC |
HL |
пару BC. |
FE2C |
3E28 |
LD |
A,#28 |
В A - код "(". |
FE2E |
CDFFFE |
CALL |
#FEFF |
Печать этого символа. |
FE31 |
E5 |
|
PUSH |
HL |
FE32 |
CD2B2D |
|
CALL |
#2D2B |
FE35 |
CDE32D |
|
CALL |
#2DE3 |
FE38 |
E1 |
|
POP |
HL |
FE39 |
3E29 |
|
LD |
A,#29 |
FE3B |
CDFFFE |
|
CALL |
#FEFF |
FE3B |
7E INF |
|
LD |
A,(HL) |
FE3F |
FE20 |
|
CP |
#20 |
FE41 |
307C |
|
JR |
NC,#FEBF |
FE43 |
FDCB57D6 |
|
SET |
2,(IY+87) |
FE47 |
FE10 |
|
CP |
#10 |
FE49 |
CC94FE |
|
CALL |
Z,#FE94 |
FE4C |
FE11 |
|
CP |
#11 |
FE4E |
CC9CFE |
|
CALL |
Z,#FE9C |
FE51 |
FE12 |
|
CP |
#12 |
ре53 |
CCA0FE |
|
CALL |
Z,#FEA0 |
FE56 |
FE13 |
|
CP |
#13 |
FE58 |
CCA4FE |
|
CALL |
Z,#FEA4 |
FE5B |
FE14 |
|
CP |
#14 |
FE5D |
CCA8FE |
|
CALL |
Z,#FEA8 |
FE60 |
FE15 |
|
CP |
#15 |
FЕ62 |
CCACFE |
|
CALL |
Z,#FEAC |
FE65 |
FE16 |
|
CP |
#16 |
FE67 |
CCB0FE |
|
CALL |
Z,#FEB0 |
FE6A |
FE17 |
|
CP |
#17 |
FE6C |
CCB5FE |
|
CALL |
Z,#FEB5 |
FE6F |
FE08 |
|
CP |
#08 |
FE71 |
CCBAFE |
|
CALL |
Z,#FEBA |
FE74 |
FDCB5796 |
|
RES |
2,(IY+87) |
FE78 |
FE0E |
|
CP |
#0E |
FE7A |
CCC6FE |
|
CALL |
Z,#FEC6 |
FE7D |
FE0D |
|
CP |
#0D |
FE7F |
2010 |
|
JR |
NZ,#FE91 |
FE81 |
23 |
|
INC |
HL |
FE82 |
E5 |
|
PUSH |
HL |
FE83 |
ED5BFDFE |
|
LD |
DE,(#FEFD)) |
FE87 |
A7 |
|
AND |
A |
FE88 |
ED52 |
|
SBC |
HL,DE |
FE8A |
7C |
|
LD |
A,H |
FE8B |
B5 |
|
OR |
L |
FE8C |
E1 |
|
POP |
HL |
FE8D |
C2FBFD |
|
JP |
NZ,#FDFB |
FE90 |
C9 |
|
RET |
|
FE91 |
23 |
PROB |
INC |
HL |
FE92 |
18AA |
|
JR |
#FE3E |
FE94 |
3E49 |
INK |
LD |
A,#49 |
FE96 |
CDFFFE |
KOL |
CALL |
#FEFF |
FE99 |
AF |
|
XOR |
A |
FE9A |
23 |
|
INC |
HL |
FE9B |
C9 |
|
RET |
|
FE9C |
3E50 |
PAPER |
LD |
A,#50 |
FE9E |
18F6 |
|
JR |
#FE96 |
FEA0 |
3E46 |
FLASH |
LD |
A,#46 |
FEA2 |
18F2 |
|
JR |
#FE96 |
FEA4 |
3E42 |
BRIGHT LD |
A,#42 |
FEA6 |
18EE |
|
JR |
#FE96 |
FEA8 |
3E56 |
INV |
LD |
A,#56 |
FEAA |
18EA |
|
JR |
#FE96 |
FEAC |
3E4F |
OVER |
LD |
A,#4F |
FEAE |
18E6 |
|
JR |
#FE96 |
FEB0 |
3E41 |
AT |
LD |
A,#41 |
Печать значения длины строки.
В A - код ")". Печать этого символа. В A - код из памяти. Проверка, что за код? Если печатный символ, то переход на PRINT. Если упр. код, то вкл. инверсии и проверка, что за код.
Проверка |
INK. |
|
Если да, |
то выполн. |
INK. |
Проверка |
PAPER. |
|
Если да, |
то выполн. |
PAPER. |
Проверка |
FLASH. |
|
Если да, |
то выполн. |
FLASH. |
Проверка |
BRIGHT. |
|
Если да, |
то выполн. |
BRIGHT |
Проверка |
INVERSE. |
|
Если да, |
то выполн. |
INV. |
Проверка |
OVER. |
|
Если да, |
то выполн. |
OVER. |
Проверка |
AT. |
|
Если да, |
то выполн. |
AT. |
Проверка |
TAB. |
|
Если да, |
то выполн. |
TAB. |
Проверка |
BACK. |
|
Если да, |
то выполн. |
BACK. |
Отключение инверсии. Проверка "ЧИСЛО". Если да, то выполн. Проверка "КОНЕЦ СТРОКИ". Если это код от 18 до 31, то переход на PROB. Переход к следующему адресу. Сохранение его на стеке. в DE - значение VARS. Сброс флага переноса. Проверка на достижение области VARS, а следовательно, конца листинга.
Если не конец, то на STROK. Если конец, то выход. Переход к следующему адресу и повторение INF. В А - код " ". Печать этого символа. Обнуление аккумулятора. Переход к следующему адресу и возврат. В А - код "P". Переход на KOL. В A - код "F". Переход на KOL. В A - код "B". Переход на KOL. В A - код "V". переход на KOL. В А - код "0". Переход на KOL. В A - код "A".
FEB2 |
23 |
|
INC |
HL |
Пропуск аргумента AT. |
FEB3 |
18E1 |
|
JR |
#FE96 |
Переход на KOL. |
FEB5 |
3E54 |
TAB |
LD |
A,#54 |
В A - код "Т". |
FEB7 |
23 |
|
INC |
HL |
Пропуск аргумента TAB. |
FEB8 |
18DC |
|
JR |
#FE96 |
Переход на KOL. |
FEBA |
3E3C |
BACK |
LD |
A,#3C |
В A - код "<". |
FEBC |
2B |
|
DEC |
HL |
Переход к предыдущему адр. |
FEBD |
18D7 |
|
JR |
#FE96 |
Переход на KOL. |
FEBF |
C2FFFE |
PRINT |
CALL |
#FEFF |
Печать символа и |
FEC2 |
23 |
|
INC |
HL |
переход к следущему адр. |
FEC3 |
C33EFE |
|
JP |
#FE3E |
Возврат на INF. |
FEC6 |
23 |
CHISL |
INC |
HL |
Переход к следующему адр. |
FEC7 |
3E5B |
|
LD |
A,#5B |
В A - код "[". |
FEC9 |
CDFFFE |
|
CALL |
#FEFF |
Печать этого символа. |
FECC |
DDE5 |
|
PUSH |
IX |
|
FECE |
E5 |
|
PUSH |
HL |
Перезапись значения HL. |
FECF |
DDE1 |
|
POP |
IX |
в регистр. пару IX. |
FED1 |
DD7E00 |
|
LD |
A,(IX+0) |
Подготовка |
FED4 |
DD5E01 |
|
LD |
E,(IX+1) |
данных |
FED7 |
DD5602 |
|
LD |
D,(IX+2) |
для рассчета |
FEDA |
DD4E03 |
|
LD |
C,(IX+3) |
значения числа |
FEDD |
DD4604 |
|
LD |
B,(IX+4) |
в 5-байтном виде. |
FEE0 |
DDE1 |
|
POP |
IX |
|
FEE2 |
E5 |
|
PUSH |
HL |
|
FEE3 |
CDB62A |
|
CALL |
#2AB6 |
Передача регистров на стек |
FEE6 |
FECB5706 |
|
SET |
2,(IY+87) |
Включение инверсии. |
FEEA |
CDE32D |
|
CALL |
#2DE3 |
Печать значения числа. |
FEED |
FDCB5796 |
|
RES |
2,(IY+87) |
Выключение инверсии. |
FEF1 |
E1 |
|
POP |
HL |
|
FEF2 |
3E5D |
|
LD |
A,#5D |
В А - код "]". |
FEF4 |
CDFFFE |
|
CALL |
#FEFF |
Печать этого символа. |
FEF7 |
110400 |
|
LD |
DE,#0004 |
Переход на оставшиеся |
FEFA |
19 |
|
ADD |
HL,DE |
4 байта вперед. |
FEFB |
AF |
|
XOR |
A |
Обнуление аккумулятора. |
FEFC |
C9 |
|
RET |
|
|
FEFB |
0000 |
POKE |
DEFS |
2 |
Здесь хранится VARS. |
FEFF |
E5 |
WRITE |
PUSH |
HL |
Процедура |
FF00 |
D7 |
|
RST |
#10 |
печати |
FF01 |
E1 |
|
POP |
HL |
символа. |
FF02 |
C9 |
|
RET |
|
|
FF03 |
110BFF |
AWTOR |
LD |
DE,#FF0B |
Вывод |
FF06 |
AF |
|
XOR |
A |
сообщения |
FF07 |
CD0A0C |
|
CALL |
#0C0А |
об авторе. |
FF0A |
C9 |
|
RET |
|
|
FF0B |
800D |
SOOB |
DEFB |
128,13 |
|
FF0D |
|
|
DEFM |
"'LOOK BASIC PROGRAMS'" |
FF22 |
0D |
|
DEFB |
13 |
|
FF23 |
|
|
DEFM |
"BY BESSONOV A." |
|
FF31 |
0D1201 |
|
DEFB |
13,18,1 ; |
|
FF34 |
|
|
DEFM |
"BAV " С 1991 |
|
FF3D |
12008D |
|
DEFB |
18,0,13+128; |
|
1992(C) Свиридов Константин Викторович Моск. обл. г. Мытищи.