МЕТОД ПАРОЛИРОВАНИЯ
КОДОВОГО ФАЙЛА.
(С) 2000 Макс/Compu-Studio Ltd
-----------------------------------------
Как обычно я не претендую на гениаль-
ность первооткрывателя в кодинге - этот
метод широко применяется на практике как
на iBM, так и на Спектруме (см. мой жур-
нал "ЧВ#2"). Тем не менее мне этот способ
кажется самым простым и довольно надёжным
с точки зрения его реализации.
Для начала немного теории, хотя и пос-
ле практические упражнения делать придёт-
ся вам самим. Итак, у нас есть какой-то
кодовый файл, который надо сделать недо-
ступным для посторонних. Что надо сделать
в первую очередь? Любой степени сложности
алгоритм ввода символов с клавиатуры. Вам
здесь развязываются руки в плане творчес-
ких решений ;)
Next. Символы пароля надо разместить в
специальном буфере. Теперь, собственно, о
самом методе паролирования. Схематически
это выглядит примерно так:
файл: |zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz|
пароль:|вася |
| вася |
| вася |
| вася |
| вася |
| вася |
| вася |
| вас|
Как видите, слово "вася" "шагает" по
кодовому файлу с шагом "на свою длину",
т.е. размер пароля в символах равен шагу,
нужному для дальнейшей кодировки. Чем ваш
пароль будет длиннее (в разумных пределах
конечно), тем больше шаг по файлу делать.
Ввод пароля не должен быть ограничен дли-
ной пароля, который вы придумали. Другими
словами - вам надо делать буфер для паро-
ля большим, но это вовсе не должно озна-
чать, что и сам пароль должен быть таких
же размеров. Это обстоятельство приведёт
в замешательство человека, который попы-
тается взломать пароль. Также надо иметь
ввиду и тот факт, что простое кодирование
нулей приведёт к тому, что если пират до-
думается защищённый файл просмотреть де-
буггером, то ваш "пароль" просто прочита-
ется в режиме дампа памяти. Не стоит так-
же делать сумму из чисел, составляющих КС
пароля, т.к. ксорка одним байтом тоже ма-
ло эффективна - всё те же нули...
Предлагаю самим напрячь мозги и приду-
мать какой-нибудь извращённый метод прев-
ращения символов пароля в коды для пере-
кодировки. Можно сделать что-то типа NEG,
или же CPL, или просто парные ADD и потом
ксорить файл.
Меры предосторожности при выборе файла
для паролирования. Если зараннее известно
о том, что файл закодирован, ну например,
программой HRUST с распаковщиком вначале,
то все труды по ксорке пойдут прахом, по-
тому что хакеру не составит труда восста-
новить по имеющемуся коду распаковщика в
считаные минуты "перевёрнутые" биты и тем
самым узнать пароль. Это, конечно, если у
него будет на это время: друг или ваш ре-
бёнок захотели посмотреть защищённый диск
без вашего ведома...
Ладно, это всё - фигня. Вывод из этого
всего водоворота следующий:
1) не делай буфер ввода равным длине па-
роля - незнание размера пароля затрудняет
его взлом.
2) не делай примитивных ксорок получен-
ным паролем.
3) не делай сверку пароля на правильное
значение методом сверки с шаблоном в ОЗУ.
4) не ксорь стандартно компрессированные
файлы или же никому не говори, что они у
тебя такие ;)
5) дай мне немного денег за идею...
А как же проверить качество пароля и
определиться с дальнейшими действиями? Да
всё очень просто - или в самом файле дер-
жи (в начале или конце), или где-то от-
дельно контрольные суммы этого файла. Не
рекомендую делать КС одним байтом, иначе
может просто совпасть эта самая КС с ка-
ким-нибудь паролем, набранным "от фонаря"
и тогда полная медитация... Лучше всего
надо сделать минимум два подсчёта КС, но
с разных мест файла. Например: первая КС
считается с начала файла и до конца, а
вторая КС с начала файла + 1 байт и тоже
до конца. Чем больше проверок КС, тем у
вас меньше шансов на роковое сложение бит
в ложную КС.
Вот и всё. Пишите письма...
-----
Далее в этом разделе идёт сборник txt-
файлов по кодингу. Некоторые уже раннее
где-то печатались, что делает их морально
устаревшими. А мне пофиг - не читай, если
не нравится! Но рекомендую дочитать...
PUSH=евский эффект.
(С) ACTIVATOR
-----------------------------------------
Во многих демухах, например U.S., ICE
CREAM, а также во многих boot-ах вы на-
верняка встречали такой эффект, как "ле-
тание сетки" по плавной траектории, т.е.
PUSH-евский эффект, как ещё его называют.
Принцип его не сложен, как может пока-
заться на первый взгляд. "фундаментом" в
нём является всё та же команда PUSH, ко-
торая за один раз может копировать 2 бай-
та. В этом тексте я приведу примеры прог-
рамм, которые вам помогут сделать такой
эффект.
Сначала мы должны построить табличку,
по которой будет летать ваш спрайт. Раз-
мер возьмём 2*16 (X - 2, Y - 16). Таблич-
ка строится обыкновенной программкой на
бейсике:
10 LET adr1=30000:LET adr2=30500
20 FOR n=0 ТО 2*PI STEP PI/64
30 РОКЕ adr1,128+127*SIN n:РОКЕ adr2,8
8+87*COS n
40 PLOT РЕЕК adr1,РЕЕК adr2
50 LET adr1=adr1+1:LET adr2=adr2+1:NEXT
n
В результате работы этого алгоритма в
памяти под адресом 30000 будут координаты
X таблички, а под 30500 - соответственные
ей координаты Y. Более понятливые могут
поэкспериментировать с 30-ой строкой, ме-
няя в ней значения SIN и COS и добавляя
что-то своё. Теперь спрайт у вас есть,
табличка есть, осталось самое главное -
коды. Перейдем к ним....
Для летания нам необходимо 256 спрай-
тов, сдвинутых циклически таким образом:
сначала сдигается первоначальный спрайт
16 раз вправо, затем на одну точку ниже и
опять 16 раз. Если вы всё проделали
правильно, то у вас должно получится 256
спрайтов общей длиной 8192 (длина спрайта
* количество = общая длина). Кто не хо-
чет, либо не может вручную сдигать этакую
армаду спрайтов, привожу программу, кото-
рая все сделает за вас, т.е. правильно
сдвинет все спрайты:
ORG 25000
LD HL,adres;вашего спрайта
LD DE,bufer;размером 8192 для
;сдвинутого спрайта.
;Допустим #С000.
LD ВС,size ;длина спрайта 32 б.
PUSH DE
LDIR
РОР HL
LD С,16
DEC1 CALL CRUNCH2
LD В,16
DEC2 CALL CRUNCH1
DJNZ DEC2
DEC С
JR NZ,DEC1
RET
CRUNCH1 PUSH ВС
LD ВС,32
LDIR
PUSH HL
LD В,16
CR1 INC HL
LD A,(HL)
RRA
DEC HL
RR (HL)
INC HL
RR (HL)
INC HL
DJNZ CR1
РОР HL
РОР ВС
RET
CRUNCH2 PUSH ВС
PUSH DE
PUSH HL
LD ВС,#001Е
ADD HL,ВС
LD Е,(HL)
INC HL
LD D,(HL)
PUSH DE
LD D,Н
LD Е,L
DEC HL
DEC HL
LDDR
ЕХ DE,HL
РОР DE
LD (HL),D
DEC HL
LD (HL),Е
РОР HL
РОР DE
РОР ВС
RET
После выполнения этой программки у вас
под адресом 49152 будут расположены эти
самые сдвинутые спрайты. Теперь как выг-
лядит процедура, которая рассчитывает но-
мер спрайта и выводит его из буфера, куда
его предварительно копирует.
ORG 30000
START1 LD HL,30000;адрес табл. по X
LD A,(HL)
AND A
JR NZ,LET1
LD HL,30000
LD (START1+1),HL
JR START1
LET1 LD (START1+1),HL
AND #OF
LD Н,0
LD L,A
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
PUSH HL
START2 LD HL,30500;адрес табл. по Y
LD A,(HL)
AND A
JR NZ,LET2
LD HL,30500
LD (START2+1),HL
JR START2
LET2 LD (START2+1),HL
AND #0F
LD Н,0
LD L,A
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
РОР DE
ADD HL,DE
LD DE,#FFFF-32;адрес буфера од-
;ного спрайта (32
;байта размером)
DUP 32 ;32 раза LDI
LDI
EDUP ;каманда ALASM`а!!!
LD (STACK+1),SP;запомнить стек
LD SP,#4000;на экран
LD HL,(65503+0);адрес буфера +0
DUP 8
PUSH HL
EDUP
LD SP,#4100
LD HL,(65503+2);адрес буфера +2
DUP 8
PUSH HL
EDUP
LD SP,#4200
LD HL,(65503+4);адрес буфера +4
DUP 8
PUSH HL
EDUP
LD SP,#4300
LD HL,(65503+6)
DUP 8
PUSH HL
EDUP
LD SP,#4400
LD HL,(65503+8)
DUP 8
PUSH HL
EDUP
LD SP,#4500
LD HL,(65503+10)
DUP 8
PUSH HL
EDUP
LD SP,#4600
LD HL,(65503+12)
DUP 8
PUSH HL
EDUP
LD SP,#4700
LD HL,(65503+14)
DUP 8
PUSH HL
EDUP
LD SP,#4020
LD HL,(65503+16)
DUP 8
PUSH HL
EDUP
LD SP,#4120
LD HL,(65503+18)
DUP 8
PUSH HL
EDUP
LD SP,#4220
LD HL,(65503+20)
DUP 8
PUSH HL
EDUP
LD SP,#4320
LD HL,(65503+22)
DUP 8
PUSH HL
EDUP
LD SP,#4420
LD HL,(65503+24)
DUP 8
PUSH HL
EDUP
LD SP,#4520
LD HL,(65503+26)
DUP 8
PUSH HL
EDUP
LD SP,#4620
LD HL,(65503+28)
DUP 8
PUSH HL
EDUP
LD SP,#4720
LD HL,(65503+30)
DUP 8
PUSH HL
EDUP
... ;и так далее
Вы можете размножать эту процедуру та-
ким образом, чтобы адрес буфера был с пе-
риодом от 0 до 30, после 30 опять 0 и
т.д. В самом конце вы должны сделать:
STACK LD SP,0 ;восстановление стека
RET
Теперь, если вы это запустите в цикле,
то на экране будет летать весьма красивая
штучка, сотоящая из вашего первоначально-
го спрайта.
Макс: не рекомендую делать цикл. Понимаю,
что размер алгоритма эффекта слишком ве-
лик получается и его можно сделать намно-
го короче, если сделать цикл и выборку из
таблицы при помощи индексных регистровых
пар, но все эти команды "тяжелы" с точки
зрения процессора по количеству затрачи-
ваемых тактов, поэтому будет жуткий тор-
моз при работе. Решать в конечном счёте
вам, но имейте это ввиду.
-----
Работа c диском
при включенных прерываниях
(С) 1998 Иван Рощин
-----------------------------------------
Теоретические сведения
В компьютере "ZX-Spectrum" выполнение
команд обмена информацией между оператив-
ной памятью и диском происходит при непо-
средственном участии центрального процес-
сора Z80:
Как видим, если во время выполнения
такой команды произойдет прерывание, Z80
отвлечется на его обработку и команда за-
вершится с ошибкой "потеря данных". Таким
образом, на работу с диском накладываются
определенные ограничения.
Следует заметить, что в современных
компьютерах используется так называемый
прямой доступ к памяти, когда обмен ин-
формацией между памятью и каким-либо
внешним устройством происходит без учас-
тия центрального процессора:
Спектрум - компьютер несовременный, и
недостаток аппаратных средств, которые
позволили бы "параллельно" работать с
диском и делать что-то еще, приходится
восполнять программной поддержкой. Для
этого прежде всего нужно разобраться, как
осуществляется выполнение команд ВГ93
(например, "чтение сектора") при включен-
ных прерываниях.
--------------------
Примечание: разумеется, все сказанное
о командах чтения относится и к командам
записи.
--------------------
Скорость обмена данными между ВГ93 и
Z80 равна 250 Кбит/с, а диск вращается со
скоростью 300 об/мин. Исходя из этих дан-
ных, определим количество байт на одной
дорожке (обратите внимание, что в расче-
тах 1 Кбит = 1000 бит, а не 1024):
(250*1000/8)*60/300 = 6250 байт
Примерно такое же значение (плюс-минус
пять байт) можно получить, воспользовав-
шись для определения длины дорожки прог-
раммой Afrodita 3.0.
Теперь вычислим, сколько прерываний
произойдет в течение одного оборота дис-
ка, если их частота известна и равна 50
Гц:
50*60/300 = 10
Таким образом, на каждый оборот диска
приходится ровно десять прерываний. Как
уже было сказано, если прерывание прои-
зойдет во время чтения сектора, то этот
сектор не будет прочитан. Получается, что
этот сектор нельзя будет прочитать и при
следующем обороте диска, т.к. во время
его чтения опять произойдет прерывание. И
мы приходим к выводу, что чтение секторов
при разрешенных прерываниях совершенно
невозможно.
--------------------
Примечание: все же есть способ осу-
ществить чтение в таких условиях. Если не
удалось прочитать сектор, надо рассинхро-
низировать процесс вращения диска и мо-
менты наступления прерываний. Сделать это
можно очень просто: остановить двигатель
дисковода, а затем снова запустить его.
После этого остается только повторить
чтение нужного сектора.
--------------------
А как же, спросите вы, работают раз-
личные demo, в которых чтение секторов
совмещено с проигрыванием музыки по пре-
рываниям? Оказывается, не все так плохо.
Дело в том, что на самом деле такой стро-
гой синхронизации нет. Так, на "Пентаго-
не" при тактовой частоте 3,5 МГц промежу-
ток между прерываниями составляет пример-
но 71680 тактов. В этом случае частота
прерываний равна:
3500000/71680 = 48,83 Гц
--------------------
Примечание: соответственно, такой же
будет и частота кадров у подключенного к
"Пентагону" монитора или телевизора. Как
видим, это немного отличается от стандар-
та (50 Гц). Также это приводит к тому,
что используемый во многих программах
таймер, работающий на прерываниях, будет
отставать на 1,4 секунды в минуту, в чем
можно легко убедиться.
--------------------
Теперь в течение одного оборота диска
произойдет 48,83*60/300 = 9,77 прерыва-
ний. Рассмотрим, сколько байт проходит
под магнитной головкой в промежутке между
двумя прерываниями:
6250/9,77 = 640 байт
Если считать, что первое прерывание
произошло в тот момент, когда магнитная
головка находилась в начале дорожки, по-
лучаем такую таблицу:
+------------------+--------------------+
| порядковый номер | смещение от начала |
| прерывания | дорожки, байт |
+------------------+--------------------+
| 1 | 0 |
| 2 | 640 |
| 3 | 1280 |
| 4 | 1920 |
| 5 | 2560 |
| 6 | 3200 |
| 7 | 3840 |
| 8 | 4480 |
| 9 | 5120 |
| 10 | 5760 |
| 11 | 150 (след. оборот)|
| 12 | 790 |
| 13 | 1430 |
| 14 | 2070 |
| 15 | 2710 |
| 16 | 3350 |
| 17 | 3990 |
| 18 | 4630 |
| 19 | 5270 |
| 20 | 5910 |
| 21 | 300 (след. оборот)|
| ... | ... |
+------------------+--------------------+
Видно, что даже если сектор не прочи-
тался на одном обороте дорожки, вполне
возможно, что он будет прочитан на сле-
дующем обороте, т.к. моменты наступления
прерываний будут смещены на 150 байт.
--------------------
Примечание: на моем "Пентагоне" в ре-
зультате экспериментов было установлено,
что из-за пониженной скорости вращения
диска (299,4 об/мин вместо 300) моменты
наступления прерываний смещаются не на
150, а на 138 байт. В дальнейших расчетах
будет фигурировать именно эта величина.
Для каждого компьютера она своя, и, как
мы увидим, именно от нее зависит степень
замедления чтения секторов.
--------------------
Вычислим, чему будет равно время пол-
ного чтения диска при запрещенных преры-
ваниях:
0,2*160 = 32 секунды
Теперь попробуем оценить, во сколько
раз замедлится чтение одной дорожки стан-
дартного TR-DOS диска при включенных пре-
рываниях.
--------------------
Примечание: будем считать, что при
чтении дорожки программа сначала считы-
вает все сектора подряд (при этом какие-
то из них, очевидно, не будут правильно
считаны из-за возникшего прерывания), а
затем при каждом следующем обороте диска
пытается прочитать все ранее неправильно
считанные сектора, и так до тех пор, пока
все сектора не будут прочитаны.
Необходимо учесть, что если последова-
тельно считываются несколько дорожек (на-
пример, 4), и каждая дорожка считывается,
например, за 2,5 оборота диска, то все 4
дорожки будут считаны не за 4*2,5 = 10, а
за 4*3 = 12 оборотов диска. Это связано с
тем, что когда мы отдаем команду пози-
ционирования на другую дорожку, а затем
отдаем команду чтения сектора, ВГ не сра-
зу начнет читать сектор, а будет ожидать
индексного импульса, указывающего на на-
чало дорожки.
--------------------
Очевидно, что время чтения одной до-
рожки (измеряемое в оборотах диска) будет
определяться временем чтения "наихудшего"
сектора, т.е. такого сектора, на чтение
которого будет затрачено наибольшее коли-
чество попыток.
Длина сектора на диске TR-DOS равна
256 байт. Рассмотрим на схеме, как может
происходить чтение такого сектора в
наихудшем случае:
Т.е. при первом обороте диска прерыва-
ние произойдет при чтении байта со смеще-
нием 0, при втором обороте момент наступ-
ления прерывания сместится на 138 байт
так, что сектор опять не будет считан, и,
наконец, при третьем обороте он прочи-
тается.
Итак, получили, что время чтения одной
дорожки замедлится в 3 раза. Соответст-
венно, весь диск прочитается за 32*3=96
секунд, что прекрасно согласуется с экс-
периментальными данными.
Теперь рассмотрим процесс чтения одной
дорожки диска MS-DOS. Размер сектора -
512 байт. В этом случае чтение "наихудше-
го" сектора может происходить по двум
возможным сценариям: либо он прочитается
на пятом обороте диска, либо на девятом.
Это показано на схеме:
Практика показывает, что время чтения
одной дорожки MS-DOS диска в среднем уве-
личивается в 7,6 раза, то есть второй ва-
риант реализуется немного чаще первого.
Видно, что из-за большей длины сектора
чтение замедляется еще сильнее, чем у
диска TR-DOS. В этом TR-DOS получает хоть
какое-то преимущество.
А вот работать с диском IS-DOS при
включенных прерываниях вообще нельзя. Ду-
маю, вы уже догадались, почему - сектор в
1024 байта будет считываться так долго,
что за это время обязательно произойдет
прерывание, а может быть, и не одно. По
той же причине при включенных прерываниях
нельзя форматировать диск или выполнять
команду чтения трека.
Как же реализовано одновременное про-
игрывание музыки и чтение диска (без вся-
кого замедления!) в таких demo, как POWER
UP и EYE ACHE-2? По-видимому, тут исполь-
зуется такой способ: процедура проигрыва-
ния музыки запускается после чтения оче-
редного сектора. Но при этом вызов проце-
дуры не синхронизируется с прерываниями,
а ошибки чтения сопровождаются неприятны-
ми завываниями.
-----
ПРОГРАММИРОВАНИЕ КЭША.
(С) 2000 Макс/Compu-Studio Ltd
-----------------------------------------
Хотел я здесь рассказать о методах ра-
боты с кэшем, но такая лень напала... Ко-
роче, принцип известен, как добраться до
кэша, а дальше пишите кто на что гаразд.
Мне же только следует напомнить кое-что
тем, кто делает программы для взлома или
системные утилиты, которые находятся в
кэше - делайте корректный выход из кэша,
если порча основного ОЗУ может сказаться
на программе, в нём размещённой.
Суть проблемы такова: есть программа,
которая по нажатию magic или reset-2 (это
когда аппаратно "влетаешь" в кэш на адрес
ноль) что-либо делает, а потом подразуме-
вает возврат или переход в основную прог-
рамму, но работа которой может быть нару-
шена какими-либо изменениями в ОЗУ. А из-
менения делаются кодерами то ли по незна-
нию, то ли из-за лени... Короче, для "за-
крытия" кэша надо сделать команду
IN A,(#7В)
и она должна находиться в ОЗУ, а не в кэ-
ше. Оказывается, что это условие вовсе не
обязательно! Достаточно просмотреть про-
шивку ПЗУ в 128 и 48 бейсике и найти ко-
манды
РОР AF
RET
для реализации нормального выхода. У меня
эти команды прошиты по следующим адресам:
48 BASIC - #0554
128 BASIC - #007D.
В кэше надо за два байта до этих адре-
сов подставить команду IN A,(#7В) и про-
блема решится сама собой. Естественно на-
до предварительно сделать PUSH AF или же
подразумевать его снятие со стека. Выгля-
дит это примерно так:
PUSH AF ;адрес ещё кэша
IN A,(#7В);после этой команды
;подключается ПЗУ.
РОР AF ;а это уже ПЗУ!
RET ;continue program
И всё. Теперь любая программа, которая
критична к содержанию ОЗУ (считает его КС
или ещё что-нибудь, как в "Чёрном Вороне"
Медноногова) и может дать сбой в работе,
не заметит, что её кто-то тормозил. Можно
писать свой дебаггер или искатель музы-
кальных сонгов без риска вывалиться неиз-
вестно куда при возврате...
Но это ещё не всё! Сейчас много рас-
плодилось всяких там операционок, коман-
деров и прочей ерунды, которая рекоменду-
ется для прошивки в ПЗУ. Обычно предлага-
ют стереть 128-й бейсик и записать туда,
ну например NEOS или Real Commander vXX.
В этом случае придётся искать вышеуказан-
ную последовательность байт (команд) са-
мому и если повезло (нашёл), то переинс-
таллироваться на другие адреса безболез-
ненного выхода из кэша. Вот тут-то и ждёт
вас самый что ни есть пиздец - нарушение
стандарта чревато последствиями... :`(
Примечание: это больше касается желез-
ной темы, чем программистской, но скажу и
здесь - если будет глючить с выходом, то
надо обратить внимание на серии микросхем
в листалке страниц ОЗУ, а также тех, ко-
торые задействованы в кэше. Желательно,
чтобы там была "шустрая" серия 1533. Это
обезопасит от состояния, когда процессор
уже отработал команду отключения кэша, а
"железо" ещё не сделало подстановку ПЗУ и
тем самым получается состояние, именуемое
"немного беременная". Последствия, конеч-
но же, не роды, но сброс гарантирован!
Other articles: