|
Move
#05
18 мая 1997 |
|
XOR'em ALL - Алгоритмы защиты програмного обеспечения: ALKATRAZ , SPEEDLOCK.

XOR'EM ALL (Продолжение)
──────────────────────────────────────────
(c) Ars MDM 249-9753
Одним из наиболее извращенных способов
защиты загрузчиков являются мультиксорки.
Они появились достаточно давно, когда ши-
роко использовались различные ленточные
протекты, типа Alcatraz'а и SpeedLock'а.
Основное их назначение состояло в том,
чтобы получше упрятать какой-либо нестан-
дартный loader, не позволявший осуществить
копирование программы обычными средствами.
Защита дисковых программ также не обошлась
без вложенных ксорок. Так в 1995 году фир-
мой SoftLand был выпущен хит сезона - игра
"Поле Чудес". Поскольку он был написан на
языке Basic и, учитывая большой спрос на
столь популярную продукцию, игрушка была
сурово защищена - "размазана" по всему
диску и слегка заксорена. Это самое "слег-
ка" занимало порядка 40(!) секторов. Дру-
гим ярким примером подобного кодирования
является всеми (особенно Sanalex'ом) горя-
чо любимая штучка под названием Multi-
Protect (автор-MastSoft). Защита ставилась
поверху MicroProtect'а и включала в себя
стартовый Basic-блок и мультиксорку на 11
секторов. Следует сказать, что DeadLock
(так назывался MultiProtect MastSoft'a),
выполнил свою задачу - воровство программ
для многих было остановлено на достаточ-
но большой срок - до того момента, когда
стали распространены дисковые копировщики
типа McDonald'а. Интересно отметить, что
данная защита видимо понравилась не только
trader'ам Минска, но и других городов. На-
пример, в игрушке SquareHead от OutLand'а
использован данный протект.
Что же представляет собой мультипротект ?
Это последовательность примитивных ксорок
типа:
DI
LD A,par1
LD R,A
LD HL,address-1
LD DE,par2
LD BC,length
cycle LD A,R
XOR (HL)
XOR D
XOR E
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,cycle
address ...
Последующие ксорки могут иметь точно та-
кой же вид (с другими значениями парамет-
ров) либо немного отличаться, например:
использовать для организации цикла коман-
ду DJNZ, не использовать регистров DE,
и т.п. Отдельные ксорки сами по себе эле-
ментарны, однако их огромное количество,
измеряемое секторами, вынуждает сразу от-
казаться от мысли раскрутить их вручную.
Тем более, что на момент появления подоб-
ных защит еще не существовало STS и от-
лавливать изменение регистра R приходи-
лось самостоятельно. Большим недостатком
мультипротекта (в отличие от того же
Alcatraz'а) являлось то, что он был очень
уж примитивен в том плане, что состоял из
практически одинаковых ксорок, в которых
не было ничего оригинального. Т.е. защита
должна была по задумке авторов, попросту
говоря, взять измором незадачливого хаке-
ра. Несложно было предполжить, что уста-
новка защиты осуществлялась с помощью не-
которой програмки, а следовательно, и
процесс взлома возможно легко автоматизи-
ровать. Для этого необходимо было учесть
следующие обстоятельства:
1. на первом шаге цикла ксорка восстанав-
ливает адрес условного перехода (ячейка
address-1);
2. значение регистра R, заданное в ксор-
ке, может использоваться в качестве на-
чального параметра в последующих ксорках;
3. размер ксорок последовательно изменя-
ется в зависимости от их типа;
4. ксорка может быть неперемещаемой.
Предлагаю свой способ решения данной
задачки:
;DEXORING SYSTEM
;Written by Ars 1995
st_code EQU #9EC1 ;начало ксорки
len_code EQU #14E7 ;длина ксорки
zapas EQU #0500
;нужен "на всякий случай", чтобы послед-
;няя ксорка не запортила кусок кода
dopusk EQU #0020
;max возможный размер ксорки: именно по
;этому признаку осуществляется останов, то
;есть на том месте где кончаются ксорки и
;начинается loader, ради которого все и
;делалось...
double EQU st_code+len_code+zapas
;копия исходного кода ксорки
START EQU double+len_code
;адрес начала рабочей области
ORG #9C40
DI
LD HL,st_code ;Текущий адрес-
LD (curr),HL ;начало ксорки
LD BC,len_code ;Делаем копию кода
LD DE,double ;всей ксорки
LDIR
NEWXOR LD A,#77 ;Поиск LD (HL),A
CALL SEAR_B ;см. замечание 1
CALL WORK
CALL COPY
CALL START ;Расксориваем 1
LD (dexor),A ;байт - для JR NZ
LD A,#20 ;Поиск JR NZ
CALL SEAR_B
INC DE
LD A,(dexor) ;Записываем верный
LD (DE),A ;адрес перехода
INC DE
LD (curr),DE ;Теперь раскручи-
CALL WORK ;ваем всю ксорку
CALL COPY
CALL START
JR NEWXOR ;и т.д.
SEAR_B LD (byte+1),A
LD HL,(curr)
PUSH HL
CP #20
JR Z,metka
LD DE,#0006 ;Отступ для того
JR plus ;чтобы пропустить
metka LD DE,#0001 ;возможную коман-
plus ADD HL,DE ;ду LD DE,par
EX DE,HL ;где в par может
POP HL ;быть код #77
BNF LD A,(DE)
byte CP 0 ;Выход, если ко-
RET Z ;манда найдена
INC DE
PUSH HL
PUSH DE
EX DE,HL
XOR A
SBC HL,DE
XOR A
LD BC,dopusk
SBC HL,BC
POP DE
POP HL ;Цикл, если ко-
JR C,BNF ;манда не найдена
POP HL ;Полный выход,
EI ;ли код не найден
RET ;на длине dopusk
WORK XOR A ;Копируем код
EX DE,HL ;ксорок в буффер
SBC HL,DE
PUSH HL
POP BC
EX DE,HL
LD DE,(buffer)
LDIR
LD (buffer),DE
LD A,#C9 ;Установка точки
LD (DE),A ;останова
LD (curr),HL ;Сохраняем теку-
RET ;щий адрес
COPY LD HL,double
LD DE,st_code ;Восстанавливаем
LD BC,len_code ;"оригинал"
LDIR
RET
curr DW 0
buffer DW START
dexor DB 0
Не могу гарантировать, что это оптималь-
ное решение, однако, идея, по-моему, ясна.
Другие статьи номера:
Похожие статьи:
В этот день... 19 ноября