Как работать с защищёнными программами (тайники спектрума) 1990 г.

Глава 9. - декодирование закодированных блоков типа "bytes".


9. ДЕКОДИРОВАНИЕ ЗАКОДИРОВАННЫХ БЛОКОВ ТИПА "BYTES"

Кодирование программы - это род достаточно простого
шифра, делающего невозможным правильную работу программы.
Для ее запуска служит специальная декодирующая процедура.
которая находится в той же программе, и, что самое важное-
не закодирована. Кодирование просто затрудняет доступ к
тексту программы,после того как все предшествующие зашиты
устранены и программа считана без самозапуска. В этом слу-
чае в памяти лежит "полуфабрикат" программы, который только
после обработки декодирующей процедурой становится програм-
мой. Кодирование может быть основано на инверсии всех
байтов в программе. Хорошим примером является программа
"ART STUDIO ".Ее бейсиковая часть практически не защищена
никак, но главный блок программы ("STUDIO-MC" CODE 76000,

30672) частично закодирован. По адресу 26000 находится
инструкция JP 26024, которая осуществляет переход к деко-
дирующей процедуре:

26024

21С154

LD HL,26049:

запись адреса

26027

ES

PUSH HL;

26049 в стек

26028

21С165

LD HL,26049;

адрес начала

26031

11476С

LD DE,2 6719;

адрес конца

26034

LD A, (HL) ;

выбор байта из

26035

D622

SUB 34;

памяти, переко-

26037

07

RLCA:

дирование его с

26038

ЕЕСС

XOR #CC

помощью SUB, RLCA,

26040

77

LD(HL);

XOR и запись .

26041

23

INC HL;

следующий адрес

26042

В7

OR A;

проверка признака

26043

ED52

SBC HL-DE:

конца, возврат в

26045

19

ADD HL.DE:

цикл или выход

26046

2 0F2

JP NZ,26034;

по адресу, записан

26048

С9

RET;

ному е стеке

26049

B2EDF1

или 26049

сначала процедура помещает в стек адрес 26049.Теперь
собственно, начинается декодирование : в регистр HL заново
загружается адрес 26049 - как начало декодированного блока,
в DE - 27719. как адрес последнего декодированного блока.
Затем в цикле декодируются последовательно байты-инструкция
SUB 34, RLCA, и XOR #CC являются ключом, с помощью которого
расшифровывается эта часть программы. Наконец, проверяется
условие достижения адреса 27719. как последнего декодируемого
(содержится в DE) . Выполняется инструкция RET, но последним
записсанным в стек является не адрес возврата в бейсик, а
записанный в начале с помощью PUSH HL адрес 26049 или адрес
только что раскодированного блока, следовательно происходит
его запуск.

Обратим внимание, какие инструкции осуществляют дешифра-
цию - никакая из них не теряет ни одного бита. Вычитание
производится по модулю 256 и для двух разных входных данных
результаты тоже различны. RLCA заменяет значения битов 7,6,
3 и 2 на противоположные. Другими инструкциями, имеющими те
же самые свойства яеляются. например. ADD, ING, DEC, RRCA,
NEG, CPL но не OR или AND. Как раскодировать этот блок?
Проще всего - вводя в бейсике:

РОКЕ 26027,0 (код инструкции NOR)

Тем самым ликвидируя инструкцию PUSH (RET в конце программы
перейдет в бейсик). и выполнить RANDOMIZE USR 2 6000. Однако
помнить о том. что декодирующая программа может проверяться
другим фрагментом программы. Вот дальнейшая часть программы
в "ART STUDIO" :

26283

67

LD H, A;

в А уже находится

26264

6F

LD L, A;

значение 0

26285

E5

PUSH HL;

запись его в стек

26292

3AA8 6 5

LD A, (26024) ;

и проверка

26295

FE21

CP #21

содержимого ячеек

26297

C0

RET NZ;

с адресами

26298

2AA9 6 5

LD HL.(26025);

26024..27027

26301

B7

OR A;

и если оно другое-

26302

11C165

LD DE26049;

то стирание

26302

ED52

SBC HL,DE;

памяти с помощью

263 07

C0

RET NZ;

RET NZ

26308

3AAB6 5

LD A, (2 6027) ;

(под адрес 0)

26311

FEE5

CP #E5;

если все нормально

26313

C0

RET NZ:

то снятие адреса 0

26314

E1

POR NZ;

и нормальный

26315

C9

RET:

выход

Этот фрагмент проверяет : наверняка ли декодирующая проце-
дура запустила всю программу, и если нет. то с помощью RET
NZ стирает память (т.к. на стеке записан адрес 0) .
Что делать в этом случае? Ножно ликвидировать и эти меры
защиты; но в некоторых программах это не поможет. Тогда
остается другой выход : снова закодировать программу т.е.
сделать обратное, чем декодирующая программа. В нашем
случае следовало бы выполнить:

XOR #СС

RRCA

ADD 34

В "ART STUDIO" неизвестно для чего была помещена кодирующая
программа. Она находится под адресом 2 6003 и выглядит так:

26003

21С165

LD

HL.2 6;

адрес начала

26006

1147 6С

LD

DE,27719;

адрес конца

26009

LD

A, (HL) ;

выборка байта из

26010

ЕЕСС

XOR

#CC;

памяти, кодирование

26012

OF

RRCA;

его с помощью XOR

26013

С622

ADD

34;

RRCA, ADD и его

26015

77

LD

(HL).A:

запись

26016

23

ING

HL;

следующий адрес

26017

В7

OR

A;

проверка окончания

26018

ED52

SBC

HL,DE;

переход в цикл или

26020

19

ADD

HL, DE;

возврат в

26021

20F2

JR

NZ,26009;

бейсик

Как видно, она построена аналогично декодирующей
процедуре. Если такой нет, то ее можно быстро и просто
написать на основе декодирующей процедуры (например ATIS
АТАС, NIGHT SHADE, THE WORD).

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

Наиболее часто встречаемыми не опубликованными
инструкциями являются команды, оперирующие на половинках
индексных регистров IX и IY в группе команд, которым не
предшествует никакой иной префикс (т.е. SBH или EDH) .
Основываются они на префиксации кодом DDH или FDH команды,
касающейся регистра Н или L. В этом случае вместо этого
регистра берется соответствующая половина индексного
регистра. Через НХ обозначается старшая часть регистра НХ,
через IX - младшая. Аналогично HY и IY. Вот пример:

Это верно для всех команд однобайтовых пересылок
между регистрами и восьмибитовых операций AND, OR, ADD,
ADC, SUB, ВС, СР - выполняемых в аккумуляторе.

Префикс FDH или DDN относится ко всем регистрам Н^
или HL, присутствующим в команде, следовательно, в одной
инструкции невозможно использование ячейки адресованной
как (HL) , регистра HL. H или L одновременно с НХ, HY, IX,
IY (в дальнейшем ограничимся регистром IX, но все это
относит:" и к регистру IY I. например:

Несколько иначе представляется ротация ячейки, адресуе-
мой индексным регистрам, т.е. инструкцией начинающейся
кодом DDCB. Инструкция типа RR ( IX+* **) и им подобные подроб-
но описаны во всех доступных материалах о микропроцессорах
Z80, но мало кто знает об инструкциях типа RR ( IX + * * * ) ,% и
им подобных, где % обозначает любой регистр микропроцессора,
они основываются на префиксировании кодом DDH или FDH
инструкции типа RR%, также обстоит дело с инструкциями
SET N, ( IX+*),%, а также RES N, (IX + *),%. ( но для BIT -
уже нет). Выполнение такой инструкции основано на выполнении
нормальной команды RR(IX + *) (или. подобной) , SET N, ( IX + *)

или RES N, (IX + *) , а затем пересылки результата как
в ячейку (IX + * ) , так и в соответствующий внутренний регистр
микропроцессора . Например:

СВ13 RL Е

DDCB0113 RL (IX + 1) , Е

DDSB0116 RL (IX+1)

DDSE01 LD Е, ( IX+1)

В конце рассмотрения инструкции этого типа следует вспомнить
что команд EX DE, IX или EX DE. IY нет. Префиксирование
команды EX DE, HL не дает никаких результатов. Также и
префиксирование команд, коды которых начинаются с EDH, а
также тех, в которых не присутствует ни один из регистров
И, L или пары HL ( например LD В, Н RRCA и т.д.).

Еще одной интересной командой является SLI (SHIFT
LEFT AND INCREMENT), выполнение которой аналогично SLA с
той разницей, что самый младший бит устанавливается в 1.
Признаки устанавливаются идентично SLA и другим сдвигам:

СС3 7 SLI A

СВЗб SLI (HL)

DDCB«*3 6 SLI (IX+*)

DDCB«* 5 7 SLI (IX + * ) ,A

Временами некоторые проблемы вызывают построение
Флажкового регистра, особенно тогда, когда он используется
достаточно нетипично. Например:

PUSH AF

POP ВС

RL С

JP NC,...

Его вид представлен на рисунке

Дополнительной особенностью регистра Е является то. что
биты 3 и 5 ( обозначенные как F3 и F5 ) точно отражают
состояние восьмибитовой арифметической или логической
операции IN%, (C) и IN F, (С) . Например:

XOR А; запись значения 0

ADD A, 15; результат - 00001111

указатели будут : F5 = 0 : F3=1

Еще одна возможность построения зашиты основана
на использовании регистра обновления памяти Р, а точнее того,
что когда после очередного машинного цикла микропроцессора
инкрементируется значение этого регистра, то его старший бит
остается неизменным, следовательно, может быть использован
для хранения любой, естественно однобитовой информации. Важно
так же то, что инструкция LD A,R с помощью которой может
быть получена эта информация, устанавливает также указатель
S и, следовательно, не требуется дополнительная инструкция,
проверяющая значение этого бита.

Б конце несколько коротких, но часто применяемых
мер защиты. Их ликвидация основывается обычно на действиях
обратных защитным. Например, переменная (DF SZ (23659) опре-
деляет число строк в нижней части экрана, требуемое для
вывода сообщения об ошибке или для ввода данных. Во время
работы программы это значение равно двум, но достаточно
занести туда 0, чтобы программа зависла при попытке
прерывания (т.к. выводится сообщение, для которого нет
места) . Если в программе находится инструкция INPUT или CLS,
то она имеет подобный результат.

Распостраненным способом защиты является также
изменение значений переменной BORDER (23624), которая
определяет цвет рамки и атрибутов нижней части экрана.
Значение отдельных битов следующее:

7 бит - FLASH

6 бит - BRIGHT

5,4,3 биты - BORDER

2,1,0 биты - INK

Способ защиты основывается на том, что цвет чернил тот же
самый, что и у рамки, следовательно, при остановке програм-
мы, можно подумать, что она зависла (Т.к. не видно сообще-
ния) . Разблокировать программу можно вписав BORDER 0 (или
другой цвет).

Еше одним способом защиты может быть изменение
переменной ERRSP (23613-23614) , или дна машинного стека, (эта
переменная указывает дно стека), где обычно находится адрес
процедуры обрабатывающей ошибки языка BASIC ( вызываемой с
помощью RST 8 ) . Уменьшение значения ERRSP на 2 вызывает
защиту программы от "BREAK" и любой другой ошибки-программа
заново запускается с того места в котором произошла ошибка.
Смена содержимого дна машинного стека или другая замена
значений ERRSP может вызвать зависание или даже рестарт
компьютера.

Известным способом защиты является также занесение
значения больше 9999 в ячейки памяти, обозначающие номер
строки бейснка (первый байт - старший). Если он размешается
в границах 10000 - 16383. то на листинге это выглядит,
например, 0000 (вместо 10000) и строки невозможно скорректи-
ровать (EDIT). если же превышает 16384 - дальнейшая часть

программы считается несуществующей. Можно также встретить
защиту основывающуюся на занесении минимальных значений
(т.е.1) в переменные REPDEL (23561) и REPPER (23562), что
затрудняет работу с компьютером, но для ее ликвидации
требуется всего лишь быстрая реакция компьютера (запишите
с помощью РОКЕ нормальные значения : 3 5 и 5 -
соответственно).




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

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



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

Похожие статьи:
Ликбез - Аккумуляторы. Практическое применение различных типов.
черная собака - да, чёрная собака...
AMANDAS ALL NEW X-RATED DIARY
Разное - Байки из склепа.
Проект Зомби - В самый разгар "перестройки" редактор ташкентской газеты, в которой я сотрудничал, заказал мне очерк с первого конгресса Aссоциации экстрасенсов CCCP...

В этот день...   25 апреля