ZX Format #03
29 февраля 1996

Программистам - адаптцация игр: бессмертия.

Пособие для мелкого пакостника
              или

     КАК СТАТЬ БЕССМЕРТНЫМ


(C) Ржавельщик (А.А.М.)  1996

________________________________


   Итак,  Вы  успешно переписали
игру на диск. Однако порубившись
в  нее  часа четыре, сделали вы-
вод, что если бы попыток было бы
побольше,  то, несомненно, джой-
стик  остался  бы еще жив, а Га-
лактика  уже спасена. Отсюда де-
лается  простой,  как  кассетная
нейтронная   боеголовка,  вывод:
Ваша черная работа еще не закон-
чена. Придется снова грузить мо-
нитор и шарить голодными глазами
по килобайтам программы.
   Здесь глобальное преимущество
имеют владельцы Скорпионов, т.к.
они могут оперировать по живому,
сразу видя результат. Для прочих
требуется  преодолеть барьер де-
компрессии  и ксорки (т.е. прос-
матривать  игру нужно такой, ка-
кой она является во время ее ра-
боты). Для этого можно использо-
вать  сброс MAGIC'ом и программу
@-CRACK (возможно, что полученый
файл не будет работать как игра,
но  этого  и  не требуется, - он
нужен только для просмотра). Ес-
ли LOADER бейсиковый, то следует
вместо  последнего RANDOMIZE USR
поставить выход в монитор. Тяже-
лее  всего  будет владельцам 48К
(неужели  еще есть 48 с дисково-
дом?),  им  советую пользоваться
MONS - подобным монитором, кото-
рый помещается в экранной облас-
ти.
   Итак приступим. Первое: опре-

делим  диагноз. Допустим, мы ус-
тановили,   что   игра  страдает
острой   жизненной   недостаточ-
ностью.  Тогда  надо  определить
метод  лечения - прибавление на-
чальных  ресурсов, либо удаление
процедуры вычитания (чтобы знать
когда  остановиться, иначе можно
переборщить и вместо бесконечной
энергии получить,например,BATTLE
COMMAND, в котором танк спокойно
проходит сквозь все объекты, за-
кончить игру за 5 минут и выбро-
сить).
   Кстати,  поиск  бессмертия  -
лучший способ освоить ассемблер,
однако если Вы совсем не знакомы
с  данным предметом, то придется
трудновато.  Посему  запишите  и
запомните  основные  команды, на
которые  Вам  придется  обращать
внимание.

код:       мнемоника:


#3E,#DD:  LD A,#DD регистр А=#DD
(под #DD и #DDDD подразумевается
любое число одно- и двубайтное )

#32,#DD,#DD: LD (#DDDD),A
эквивалент POKE adr,A

#3A,#DD,#DD: LD A,(#DDDD)
LET A=PEEK adr

#21,#DD,#DD: LD HL,#DDDD
----

#D6 #DD: SUB #DD   A=A-#DD

#3D: DEC A   декремент А:  А=А-1

#3C: INC A   инкремент А:  А=А+1

#35: DEC (HL)  Соответственно
#34: INC (HL)  dec и inc содер-
жимого ячейки памяти по  адресу,
который находится в HL.

   Далее  -  команды  ассемблера
CALL adr, JP adr и JR adr. Соот-
ветственно  - GO SUB adr и GO TO
adr.  Последние две команды раз-
личаются  способом задачи адреса
-  в JP он пишется напрямую, а в
JR - по смещению на определенное
кол-во  байт. Это команды безус-
ловного  перехода.  Есть команды
условного  перехода - т.е. пере-
ход  произойдет,  если соблюдено
определенное  условие.  Условием
является состояние соответствую-
щего  бита  регистра F -"флага".
Наиболее  часто  используют  два
флага:  Z  - флаг "0" и C - флаг
переноса. Флаг нуля поднимается,
если  в ходе расчета был получен
результат = 0.  Флаг  переноса -
если,  например,  большее  число
вычитается  из  меньшего  (0-1).
Команды  выглядят соответственно
так:  JP  Z adr, JP C adr - если
переход  происходит при поднятом
флаге  и  JP NZ adr, JP NC adr -
при сброшенном. Флаг определяет-
ся  по результату последней опе-
рации,  которая  на него влияла.
Команды  переходов  на  флаги не
влияют.
   Запомнили? Тогда идем дальше.
   Допустим,  Вы  хотите заморо-
зить  параметр, который задается
конкретным  числом, - количество
жизней,  например (если параметр
показывается на экране полоской,
то  его численное значение опре-
делить  сложно).  Запишите коли-
чество  жизней  и  все остальные
числовые  параметры, а также все
надписи, сохранив шрифт (заглав-
ные буквы имеют иные коды, неже-
ли  строчные).  Теперь загрузите
игру  в ее рабочем виде и запус-
тите монитор. Все игры при стар-
те  устанавливают свои начальные
параметры,  т.е.  кол-во жизней,
энергии,  времени  и  т.д. Ввиду
этого  нужно для начала поискать
процедуры  стартовой  настройки.
Самое   простое:  введите  поиск
последовательности  типа  #3E NN
#32  -  это  переводится  как LD
A, NN:  LD (addr), A; здесь NN -
количество  жизней.  То  есть по
адресу   addr  помещается  коли-
чество  жизней.
   Возьмем для примера REX1. Там
имеется  4 жизни и 99 единиц за-
щитного  поля. Комбинация #3E 04
#32 встречается там не один раз.
Найдя  ее,  нужно  осмотреть ок-
рестности  на  предмет начальных
установок других параметров. Ос-
мотр  показывает,  что  наиболее
подозрительным  местом будет ад-
рес,  по   которому  расположено
следующее:

LD A,#04
LD (#A063),A
LD A,#02
LD (#A06C),A
CALL #BA49
LD A,#63      <-- #63=99 !
LD (#A04D),A

   Очевидно,  что  это начальная
установка,  т.к. здесь выставля-
ется не только кол-во жизней, но
и  энергия  защиты  (99 единиц).
Тогда задаем поиск ссылок на ад-
рес A063. Запомните один момент:
в  кодах младший байт числа идет
первым (если число двухбайтное),
т.е.   искать  нужно  комбинацию
#63,#A0.  Ссылки  на  означенную
комбинацию  встречаются  раз  5.
Для  нас  имеют  значение только
те,  которые изменяют содержимое
памяти  по  этому  адресу. Такой
фрагмент имеется только один:

LD A,(#A063)
DEC A        <-адрес #9C79=40057
LD (#A063),A
CP #FF
JP Z,9C..

   Здесь  мы видим, что если ко-
личество  запасных жизней станет
меньше  0, произойдет переход на
другой адрес. Это место уже нас-
только  подозрительно, что можно
попробовать этот адрес (например
поставить  в  загрузчике,  перед
последним RANDOMIZE USR, команду
POKE 40057,0). Для окончательно-
го  приговора  нужно посмотреть,
что находится там, куда идет пе-
реход под флагом Z. Там мы видим
такое:

LD HL,#AAED
LD B,1
CALL #A13E

   Запомните, что комбинации по-
добного  вида  обычно используют
для  печати  сообщений.  Смотрим
дамп  по адресу #AAED. А там на-
ходятся 3 байта служебных симво-
лов и текст: "GAME OVER". Вывод:
подозреваемая  процедура виновна
в  лишении жизней и приговарива-
ется  к  коррекции  путем замены
DEC A на NOP (т.е. 0).  Все.  Вы
бессмертны.
   На  эту  процедуру можно было
выйти  и  по  надписи GAME OVER.
Это  делается так: находим адрес
надписи  (т.е.  адрес в памяти с
которого  начинаются  ASCII коды
надписи),  затем ищем его упоми-
нания.  Если  ссылок на адрес не
найдено,  то ищем упоминание ад-
реса  на 1 меньше. В данном при-
мере  адрес сдвинут на три байта
назад.  Найдя  ссылку (осмыслен-
ную)  на адрес, ищем начало под-
программы,  в  которой  есть эта
ссылка,  затем  ищем  упоминание
адреса входа в эту подпрограмму.
Процедура    вычитания    жизней
должна иметь выход на печать со-
общения  о том, что вычитать уже
нечего  (для  данного  примера -
GAME OVER).
   Если  охота, то можно еще бо-
лее  облегчить  свою жизнь путем
установки   бесконечной  защиты.
Ищем упоминание адреса #A04D (4D
A0). Его упоминают также не еди-
ножды.   Процедура,  определенно
уменьшающая содержимое памяти по
данному адресу тоже только одна.

LD A,(#A04D)
SUB L
JP C,#99EF
LD (#A04D),A  <-#99E8=39400
CALL #99FA
RET

   SUB L - вычитание из А содер-
жимого  регистра L. Опыт показы-
вает,   что  в  данной  ситуации
удобнее  убрать занесение нового
значения в память - например за-
менить #32 на #3A (это не внесет
сбоев в работу программы). Тогда
по   адресу   #99E8   будет   LD
A,(#A040).  Либо  можно заменить
адрес  на  адрес в области ПЗУ -
для   этого  достаточно  стереть
старший байт адреса (POKE 39402,
0). Последнее займет меньше мес-
та  в  строке  загрузчика, ввиду
этого  оно предпочтительней. Для
наглядности  посмотрим  еще один
пример - ARCANOID-2. В этой игре
на первый взгляд дается три жиз-
ни,  однако поиски 3E 03 32 дают
один    подозрительный    адрес:
#9DE4.  Если поискать его упоми-
нания, то можно найти процедуры,
которые меняют содержимое ячейки
с  данным адресом, однако делают
это весьма странно:

LD A,(#9DE4)
SRL A
INC A
LD (#9DE4),A

   Это  явно не уменьшение на 1,
к  тому  же - нет проверки усло-
вий.  Остается предположить, что
количество жизней не 3. Рассмот-
рите   внимательно  игру:  перед
каждым вбрасыванием мячика вычи-
тается  одна попытка, а это зна-
чит,  что  так  происходит и при
старте игры - т.е. на самом деле
жизней 4. Ищем 3E 04 32 - имеет-
ся два упоминания, и оба они по-
хожи на начальные установки. Под
подозрение  попадают два адреса:
#7F86 и #7815. Далее ищем ссылки
на подозреваемых. #7F86 упомина-
ется 3 раза (начальное занесение
не  считается), в числе упомина-
ний:

LD HL,#7F86;INC(HL) - похоже  на
прибавление одной жизни.
LD HL,#7F86
DEC (HL)   <-#926C=37484
JP NZ #82DC
JP #FC7B

   Эта комбинация достаточно по-
дозрительна,  можно попробовать.
Когда  используется  команда DEC
(HL),  ее  нужно  заменять на OR
(HL) - код #B6=182. Проверка по-
казала,  что  адрес  верен (про-
верьте сами).
   Если  Вам уже все понятно, то
сбрасывайте  машину  и  - в бой.
Для  оставшихся  я дам несколько
практических советов:
   При  поиске ссылок на сообще-
ния  будьте  терпеливы  - иногда
отступать приходится очень дале-
ко,  например, в одной ленточной
версии   HERO   QUEST   пришлось
отступить  от  надписи  аж на 14
байт. Иногда сообщения печатают-
ся из таблицы - тогда при вызове
печати  задается начальный адрес
таблицы  и номер сообщения (пос-
мотрите  внимательно  REX1,  там
сделано именно так). Иногда над-
пись выводит программка, которая
стоит  прямо  перед текстом, - в
этом  случае  адрес сообщения не
указывается,   но   тогда  такая
программка  должна  стоять перед
любой  отдельной  фразой. Иногда
встречаются  такие  феноменально
безграмотные игры, которые имеют
множество  почти одинаковых про-
цедур   отъема   энергии  (STORM
HAWK, LICENSE TO KILL). Как пра-
вило,  здесь  одна  процедура  -
один вид опасности.
   Не  стесняйтесь  пользоваться
методом перебора, - если дело не
движется,  то отыщите все подоз-
рительные  места и заморозьте их
по очереди.
   Старайтесь искать легкий путь
- всегда просмотрите полный дамп
программы - так иногда попадают-
ся  секретные  коды и пароли. На
разных стадиях загрузки потыкай-
те  в клавиши, - бывает, что ха-
керы,   делавшие  данную  версию
ставят тайный CHEAT MODE, напри-
мер в 48 утюгов нужно при старте
нажать  и  держать до конца заг-
рузки клавиши, составляющие наз-
вание  одного из альбомов группы
SEPULTURA,  а  в  DIZZY  Y (free
copy)  - FCM при загрузке второй
части.
   Когда для вычитания применяют
DEC A, то стирать лучше его. Ес-
ли DEC (HL) - лучше заменить ад-
рес,  саму  команду можно менять
только на OR (HL) (код #B6=182),
иначе  будете получать GAME OVER
сразу. Когда используется SUB dd
(обычно  SUB  1), нужно заменить
аргумент на 0 (получить SUB 0).
   Если  Вы  не уверенны в коли-
честве  жизней  -  пробуйте  оба
числа.  Иногда в программах при-
меняются  защитные меры - напри-
мер  проверка состояния основных
процедур  или дублирующие проце-
дуры,  которые  выглядят  иногда
достаточно  мирно,  в  то время,
как  "пустая" - буквально кричит
о себе.
   Самое трудное - когда очевид-
ных процедур присвоения и печати
нет (например, Silk Worm). В та-
ком  случае  можно  скинуть игру
при  разных количествах жизней и
методом  сравнения  найти  адрес
счетчика.  Или, - только для ZS-
256, - использовать функции  мо-
нитора move и ch. (перенести ку-
сок  игры в дополнительное ОЗУ и
сравнивать значения в разных по-
ложениях).
   Когда значение показывают по-
лоской  на  экране (скажем, уро-
вень  топлива), то оно может из-
менятся  совсем  не так, как ка-
жется.  Так в TRANTOR энергия не
вычитается, а прибавляется.
   Пожалуй, последнее - помните,
что  в ассемблере есть множество
команд, и занести значение в па-
мять   можно  разными  способами
(это  делается  через  индексные
регистры, через LDIR, через стек
и т.д.).

   P.S.  Вышеизложенная информа-
ция отнюдь не претендует на пол-
ноту,  однако  очень поможет Вам
сделать первые шаги на хакерской
тропе. Заниматься этим вслепую -
чрезвычайно сложно, знаю по сво-
ему  опыту.
   Мне   не  приходилось  видеть
"Пособие для взломщиков", издан-
ное типографским способом, а это
-  единственная книжка на данную
тему,  которая  мне  попадалась.
Главный  совет  один:  учите ас-
семблер и тогда ни одна програм-
ма не устоит перед Вами.
   Кстати,  возьмите на вооруже-
ние:   игры  одной  фирмы  имеют
обычно почти идентичную структу-
ру.

   P.P.S.  Пожалуй,  самая инте-
ресная уловка сделана в XONIX (в
одном  из  наших),  -  там коли-
чество жизней определялось кодом
числа,напечатанного   на  экране
(ASCII код).
________________________________




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

Похожие статьи:
Мillennium Reрort - 5.6 мaя,в Минскe, в клубe "Тoннeль" прoшeл втoрoй фeстивaль кoмпьютeрнoгo исскуствa "Мillennium 1901".
Этюды - Е.Волчков. Улучшение подпрограммы вычисления адреса в дисплейном файле.
Джойстик - прохождение игры Inside Outing.

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