Работа с ZX-Spectrum 1993 г.

Тайники. Глава 7. - декодирование закодированных блоков типа «bytes».


ГЛАВА 7

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

«BYTES»

Что означает то, что программа или блок закодированы? Кодирование
это род весьма простого шифра, делающего невозможной правильную рабо-
ту программы. Для её запуска служит специальная декодирующая процедура,

которая находится в этой же программе, а также, что самое важное, не за-
кодирована. Так для чего же служит кодирование? Это просто очередное за-
труднение доступа к тексту программы после того, как все предшествующие
предохранители взломаны и программа считана без запуска. В этом случае в
памяти лежит «полуфабрикат», который только после переработки де-
кодирующей процедурой становится программой. Кодирование может быть
основано, например, на инверсии всех байтов в программе. Хорошим приме-
ром является программа «ART STUDIO». Её Basic-чэсть практически не
защищена никак, но главный блок программы ("STUDIO-MC CODE
26000.30672) частично закодирован. Что сделать, чтобы раскодировать его?
Просто найти адрес, с которого этот блок запускается. В случае «ART
STUDIO» этот адрес - 26000. Там находится инструкция JP 26024, которая
осуществляет переход к декодирующей процедуре. Вот её текст:

26024

21С165 LDHL,26049;

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

26027

Е5

PUSH HL;

26049 в стек

26028

21С165 LD HL,26049;

адрес начала

26031

11476С LD DE,27719;

адрес конца

26034

IE

LD A,(HL);

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

26035

D622

SUB 34;

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

26037

07

RLCA; t

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

26038

EECC

XOR #CC;

помощью SUB,RLCA,

26040

77

LD (HL),A;

XOR и запись

26041

23

INC HL;

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

26042

B7

OR A;

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

26043

ED52

SBC HL,DE;

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

26045

19

ADD HL,DE;

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

26046

20F2

JP NZ,26034;

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

26048

C9

RET;

ному в стеке

26049

B2EDF1

или 26049

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

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

INC, DEC, RRCA, NEG, CPL, но не OR или AND. Как раскодировать этот блок:
Проще всего - вводя в BASIC'e:

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

тем самым ликвидируя инструкцию £USH HL (RET в конце программы
перейдет в BASIC), и выполнить RANDOMIZE USR 26000. Стоит, однако,
помнить о том, что декодирующвая программа может проверяться другим
фрагментом программы. В «ART STUDIO» так и есть. Вот дальнейшая часть
программы:

26283 67 LD Н,А; в А уже находится

26284 6F LDUA; -значение 0

26285 Е5 PUSH HL; запись его в стек
26292 ЗАА865 LD А,(26024); и проверка

26295 FE21 CP #21; содержимого ячеек

26297 СО . RET NZ; с адресами

26298 2АА965 LD HL,(26025); 26024 ...26027

26301 В7 OR А; и если оно другое,

26302 11С165 LDDE,26049; то стирание
26305 ED52 SBC HL,DE; памяти с помощью

26307 СО RET NZ; RET NZ

26308 3AAB65 LD A,(26027); (под адрес 0)

26311 FEE5 CP #E5; если все нормально

26313 CO RET NZ; то снятие адреса 0

26314 El POP NZ; и «нормальный»

26315 C9 RET; выход

Этот фрагмент проверяет: наверняка ли декодирующая процедура за-
пустила всю программу, и если нет, то с помощью RET NZ стирает память
(так как на стеке записан адрес 0).

Что делать в этом случае? Можно ликвидировать и эти меры защиты, но
в некоторых программах это не поможет. Тогда остается другой выход: снова
закодировать программу, т.е. сделать обратное, чем декодирующая програм-
ма. В нашем случае следовало бы выполнить:
XOR #СС
RRCA
ADD 34

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

26003 21С1165 LD HL,26049; адрес начала
26006 11476С LD DE,27719; адрес конца

26009 7Е LD AA,(HL); выборка байта из

26010 ЕЕСС XOR #СС; памяти, кодирование
26012 OF RRCA; его с помощью XOR,

26013 С622

ADD

34;

RRCA, ADD и его

26015 77

LD

<HL),A

запись

26016 23

INC

HL;

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

26017 В7

OR

A;

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

26018 ED52

SBC

HLtDE;

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

26020 19

ADD

HL,DE;

возврат

26021 20F2

JR

NZ,26009;

в BASIC

26022 С9

RET;

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

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

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

; КОД :

КОМАНДА I

код

КОМАНДА

код

КОМАНДА

! 24 •

INC Н

DD24

NC НХ

FD24

INC HY

! 2D ■

DEC L

DD2D

DEC IX

FD2D

INC IY

1 i

| LD С,Н

DD4C

LD С,НХ

FD4C

LD C.HY

I 64

LD Н.Н

DD64

LD НХ,НХ

FD64

LD HY.HY

1 2601

LD Н,1

DD2601

LD НХ,1

FD2601

LD HY,1

В5

OR L

DDB5

OR IX

FDB5

OR IY

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

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

66 LD H,(HL> DD66" LD НХ,ЦХ+*)
75 LD (HL),L DD75** LD <IX+*),IX
65 LD H,L DD65 LD HX.IX
Несколько иначе представляется ротация ячейки, адресуемой индекс-
ным регистром, т.е. инструкций, начинающихся кодом DDCB. Инструкция
типа RR (IX+**) и ей подобные подробно описаны во всех доступных ма-

териалах о микропроцессорах 280, но мало кто знает об инструкциях типа RR
(1Х+**), % и им подобных, где % обозначает любой регистр микропроцессо-
ра. Они основываются на префиксовании кодом DuH или FDH инструкции
типа RR %.

Также обстоит дело с инструкциями SET N,(lX+*)r%, 3 также RES
N,(IX+*), % (но для BIT - уже нет). Выполнение такой инструкции основано на
выполнении нормальной команды RR (1Х+*) (или подобной), SET N,(tX+*) или
RES N»(IX+*), а затем пересылки результата как в ячейку (1Х+*), так и соответ-
ствующий внутренний регистр микропроцессора. Например:
СВ13 RL Е

DDCB0113 RL <1X41 )tE
вызывает сдвиг ячейки с адресом IX-H влево на 1 бит и пересылку
результата в регистр Е, что обычным способом следовало бы сделать так:
DDCB0116 RL UX+1)
DD5E01 LD ЕД1X4-1)
В конце рассмотрения инструкции данного типа следует вспомнить, что
команд EX DEJX или EX OE,IY нет. Префиксование команды EX DE,HL не
дает никаких результатов. Также - префиксирэвание команд, коды которых
начинаются с EDH, а также тех, в которых не присутствует ни один из
регистров Н, L или пары HL (например. LD B,N , RRCA и т.дА Очередной лю-
бопытной командой является SU (SHIFT LEFT AND INCREMENT), выпол-
нение которой аналогично SLA с той разницей, что самый младший бит
устанавливается в 1. Признаки устанавливаются идентично SLA и другим
сдвигам:

СВ37 SL1 А
СВ36 SLI (HL)
DDCB**36 SLI <IX+*)
DDCB**57 SU (IX-^УЛ
Временами некоторые проблемы вызывает построение флажкового
регистра, особенно тогда, когда он используется достаточно нетипично,
например:

PUSH AF
POP ВС
RL С
JP NC,...
Его вид представ/ген на рис. 1:

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

XOR А; запись значения 0
ADD А, 15; результат - 00001111
указатели будут: F5-0; F3-1

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

В конце несколько коротких, но часто применяемых мер защиты. Их
ликвидация основывается обычно на действиях обратных защитным. Чаще
всего с этой точки зрения эксплуатируются системные переменные.
Например, переменная DFSZ (23659) определяет число строк в нижней части
экрана, требуемое для вывода сообщения об ошибке или для ввода данных.
Во время работы программы это значение обычно равно 2, но достаточно за-
нести туда 0. чтобы программа зависла при попытке прерывания (так как туда
выводится сообщение, для которого нет места).

Если в программе находится инструкция INPUT или CLS, то она имеет
подобный результат.

Распространенным способом защиты является также изменение зна-
чения переменной BORDCR (23624), которая определяет цвет рамки, и
атрибутов нижней части экрана. Значение отдельных битов следующее:
7 бит - FLASH
6 бит-BRIGHT
5.4,3 биты - BORDER
2,1,0 биты-INK

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

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




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
B.B.S. Новости - Почему на IBM все пучком , или что нам не хватает ?
Форум - По поводу релоцируемых программ.
Demoscene - Deja Vu #04: Oбзoр демoсцены (продолжение).
Литературная страничка - И.БАРКОВ "ЛУКА МУДИЩЕВ", ПОЭМА.
Happy 2 - законы невезения и юмористическая реклама.

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