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 код). ________________________________
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября