CHEAT и POKES в игровых программах. Александр Десятниченко, г.Сумы _________________________________________ Первая публикация - журнал "ZX РЕВЮУКРАИНА", 1996г. Новая, значительно до-полненная и исправленная версия - специ-ально для журнала "ZX POWER", 1997г. 1. История методов "нечестной" игры. Самые первые игровые программы для ZXSPECTRUM были достаточно примитивными и,соответственно, сравнительно легкими вигре. Наверное, любой из вас cможет часа-ми играть в RIVER RAID, залетая очень да-леко и обходясь при этом тем скудным за-пасом дополнительных жизней, которым былнаделен пилот создателями программы. Но по мере того, как совершенствовалась тех- ника программирования, усложнялись и сами игры. Уже в 1985 году появились програм- мы, игровое пространство которых насчиты- вало от нескольких десятков до нескольких сотен экранов. Это такие хорошо известные вам игры как STARQUAKE, FIRELORD, ROBIN in the WOOD и многие другие. Значительно увеличилось количество противников в игре и заметно возросла их агрессивность, на- чались вводиться ограничения по времени выполнения поставленной задачи и амуниции главного персонажа. Возросли требования и к мозгам играющего, - теперь приходилось держать в голове карту лабиринта, раскладку предметов по локациям и при этом еще подбирать ключи к дверям или, параллельно со стрельбой по врагам, раз- мышлять над применением предметов. Безус- ловно, все эти факторы сильно повлияли на темпы прохождения игр, которых начало по- являться все больше и больше. Сами же иг- ры становились все красочнее, начали соз- даваться так называемые FINAL CUT, - это когда в самом конце игры при ее успешном прохождении демонстрировалось что-то типа мультфильма с поздравлениями и теперь иг- рающего,после каждого успешно пройденного экрана, начал мучить самый актуальный из всех вопросов, - а что же там, дальше? Вот примерно в это время и появились пер- вые методы "нечестной" игры. В чем они заключались? Конечно же, в устранении причин, усложняющих игру, и, в первую очередь, это касалось лимита жизней, - ведь мало кому удавалось пройти огромное игровое пространство с пятью жизнями в условиях, когда на тебя все время бросают камни, да еще и выполнить при этом пос- тавленную задачу. Тот, кто хоть немножко разбирался в машинном коде, просматривал листинг программы с целью найти в ней ад- реса ячеек памяти, в которых хранилось количество жизней, а также адреса, в ко- торых это самое количество уменьшалось с каждой гибелью персонажа, и вносил изме- нения в текст программы то ли непос- редственно, то ли с помощью оператора PO- KE в бейсик-загрузчике. Позже списки та- ких POKES начали публиковаться в компью- терных журналах и у каждого пользователя появилась возможность самому задавать в игре количество жизней, необходимое для ее прохождения или же просто ликвидиро- вать уменьшение числа дополнительных жиз- ней, установленного самой программой. К тому времени загрузчики уже достаточно хорошо защищались, поэтому некоторые игры "обессмерчивались" внесением жестких из- менений непосредственно в тело игры с по- мощью копировщика COPY-COPY (Pirate 02), который позволяет это делать. Именно в таком виде и дошли до нас такие игры как ALIEN 8, NODES of YESOD, INDIANA JONES и DIZZY. Фирмы-производители игр мгновенно отреагировали на такую наглость и наказа- ли пользователя кодированием основного блока игры. Теперь уже, прежде чем "за- циклить" программу, ее требовалось взло- мать и раскодировать. Жестко обессмерчи- вать игры стали реже, все чаще это стало делаться из загрузчика. Начали учиты- ваться и интересы играющих "по-честному", - в хаккерских загрузчиках перед POKE ставилось REM, чтобы в обычном режиме иг- ра работала нормально, а те, кто не укла- дывается в лимиты, установленные програм- мой, мог убрать оператор REM и играть с бесконечной жизнью. Некоторые загрузчики, перед тем, как запустить игру, задавали вопрос: "INFINITE LIVES (Y/N) ?", и, в случае утвердительного ответа, вносили соответствующие изменения. Новым словом было меню выбора режима игры. Впервые это можно было наблюдать в программе NEBULUS, позже - в загрузчиках Билла Гилберта к играм KRAKOUT 2 и ROBOCOP. Появились и первые мегатрейнеры, - так называют меню из нескольких, от трех до десятка пунктов, воспользовавшись которыми, можно полностью настроить все лимиты в игре по своему вкусу, начиная от бесконечной жиз- ни и заканчивая входом сразу же в любой уровень игры. Первые такие мегатрейнеры вы могли увидеть в играх SLAP FIGHT и NORTH STAR, особого же развития "инфини- тизация" программ нашла в нашей стране благодаря отсутствию закона об авторских правах. Сейчас практически каждая прог- рамма, адаптированная к работе в TR-DOS, снабжается если не мегатрейнером, то хотя бы единичным POKE. А ведь есть еще огром- ная масса игр прошлых лет, так ни кем до конца и не пройденных, а сколько есть но- вых игр, пока до нас еще не дошедших.. Многие из вас могут сказать, что все уже до нас дошло и ничего нового больше не будет. А где же FLYING SHARK 2 (from FI- REBIRDS'91), SAVAGE 4 (from PROBE' 91), MONSTRLAND (from ROLLINGSOFT'91), SATURN 2 (from OCEAN'91), CHANGE TO NINJA (from ULTIMATE'92),DEUCE (from DURELL'92), DARK INSIDE (from DINAMIC'92),GRABER (from CEPPELIN'92), HAND TO HAND (from U.S.GOLD' 92), LETIFEROUS (from IMAGI- NE'92), LITTLE ELEPH (from GOLD WIN'92), NINJA IN FUTURE (from HIT PAC'92), SAVAGE BARBARIAN (from MASTERTRONIC'92), TWILS (from CODEMASTERS' 92), THE GEGG (from KONAMI'92), THE ISLAND (from MIKRO- GEN'92), YAMAHA ISD (from ACTIVISION'92) и сотни других игр? Видели ли вы их, ведь достоверно известно, что эти игры су- ществуют, есть даже их описания! Неоднок- ратно на страницах различных изданий под- нимался вопрос о моральных аспектах бес- конечных жизней. Я же, являясь плохим иг- роком и поклонником всех методов не- честной игры, оставляю решение этого воп- роса на совести каждого и считаю своей задачей только просто ознакомить вас с методиками поиска адресов бессмертия, а как ими пользоваться, - то ли использо- вать только для себя, то ли встраивать в свои загрузчики и предлагать в таком виде широкому кругу пользователей, - пусть каждый из вас определится сам. 2. Фирменный CHEAT. В начале "синклеровской" эры ходили самые невероятные слухи о том, что в не- которых программах есть так называемые "горячие" клавиши, нажимая которые,можно вытворять такие вещи, как проходить сквозь стены, перескакивать через экраны и целые игровые уровни, обеспечить себе бессмертие и неограниченный боезапас. За- тем постепенно эти мошенничества (по-английски - CHEAT) становились пред- метом все большей огласки, и сейчас уже каждый школьник знает, что если в меню программы CYBERNOID 2 выбрать REDEFINE KEYS, а затем, на запрос переопределить клавиши влево, вправо и т.д., нажимать клавиши, которые в совокупности напишут на экране слово "ORGY", то можно запросто стать бессмертным. Очень интересные CHEAT в играх сериала DIZZY. Так, если после загрузки TREASURE ISLAND DIZZY (DIZZY 2), нажать одновременно клавиши Р, О и А, а затем ENTER, то запустится такой CHEAT. Теперь в любой момент в процессе игры можно нажать клавишу C (при этом сам Диз- зи исчезает) и клавишами Z, X, K и М пе- редвигать игровые экраны. Нажатие JUMP на джойстике возвращает Диззи в этот выбран- ный вами экран и можно продолжать игру уже с этого места. Еще круче устроен CHE- AT в SPELLBOUND DIZZY 128К (DIZZY 5). Ес- ли в титульной странице набрать "I WANT AN OMLETTE" (без пробелов, если не полу- чится с первого раза, то можно повторять до тех пор, пока бордюр не заморгает), то в процессе игры при нажатии на клавишу С на экран вызывается целое меню с выбором типа CHEAT, пользуясь которым можно не только двигать экранами, но и выбрать лю- бой предмет, добавить себе звезд и жиз- ней, даже сразу спасти всех членов се- мейства. Практически все программы фирмы OCEAN имеют встроенные фирменные CHEAT. Например, если в таблице рекордов игр NA- VY SEALS 1 & 2 набрать вместо своего име- ни фразу "CLUBBING SEASON", то, при зат- руднении в прохождении, можно нажать EN- TER и перейти сразу на следующий уровень. Практика показывает, что абсолютное большинство CHEAT активизируются тремя способами: переназначением клавиш управ- ления, набором кода в титульном листе, набором кода в таблице рекордов. Однако бывает, что программа на протяжении всей игры поддерживает CHEAT, - в игре IRON SOLDIER в любой момент можно сделаться бессмертным, нажав одновременно клавиши G,A,D. Что же это за CHEAT и откуда они там взялись? Дело в том, что программист, создающий игровую программу, должен про- верить ее работу и проверить не как-ни- будь, а обойти все экраны,пропрыгать по всем кочкам, поубиваться на каждом колыш- ке... Другими словами, он должен предус- мотреть все возможные и невозможные вари- анты игры в каждом игровом экране, чтобы программа везде правильно отработала и нигде не зависла, не говоря уже о том, что он должен пройти несколько раз всю игру от начала до конца полностью, убе- дившись в ее нормальной работе и в дости- жении поставленной цели. Конечно, от- дельные подпрограммы можно проверить и под наблюдением монитора-отладчика, а вот полностью игру - только в том виде,в ко- тором ее получит пользователь. Разумеет- ся, не каждый программист, даже если он является автором своей собственной игры, может быстро и легко пройти до конца, скажем, NARCOPOLICE со всеми уровнями. Поэтому, чисто для себя, программисты де- лали вот такие секретные CHEAT, набирали после загрузки пароль и проверяли свою игру от и до. Почему же они не убирали их после окончательной отладки? А вы представляете, что такое полностью гото- вая фирменная игра с кучами защит? Не так-то просто убрать из нее фрагмент программы, особенно если он сотни раз "перексорен" и упакован вместе с основным блоком игры. К тому же,спустя некоторое время можно опубликовать этот CHEAT и вызвать этим новый интерес к своей игре у тех, кто ее не смог пройти раньше. Если же вам очень хочется пройти до конца ка- кую-нибудь интересную, но тяжелую игру, а ни CHEAT, ни POKES к ней вам не известны, можно попытаться найти такой CHEAT само- му, для этого даже знания ассемблера по- началу не понадобятся, потребуется хоро- шая программа-монитор и немножко вашей интуиции. Проще всего это делается на диске, - декомпрессируется длинный кодо- вый блок игры, записывается на диск и просматривается монитором на предмет по- иска в нем текстовых сообщений. При рабо- те с лентой, после декомпрессии основного блока игры, загрузите любой дизассемблер и запустите его "на дамп". Просматривая содержимое памяти, особое внимание обра- тите на текстовые сообщения, которых во время игры вы никогда не видели на экра- не, и, если на глаза попадутся таковые, запишите или запомните их. Чаще всего это необычные слова или фразы, намекающие на CHEAT. Так, в игре MIDNIGHT RESISTANCE это будет предложение "I AM AN OCEAN TES- TER", сразу же за ним расположена целая подпрограмма, которую можно запустить ко- мандой RANDOMIZE USR 28749, и она предло- жит вам настроить игру по своему вкусу. Найдя такие необычные фразы, можно попы- таться набрать их в титульном листе или таблице счета. Если ничего не получится, а подозрение на эту фразу очень большое, то придется обратиться за помощью к ди- зассемблеру с целью найти, где в програм- ме идет обращение к этой фразе и что пос- ле этого должно произойти. И совсем уж надежно можно найти что-либо интересное, просматривая подпрограммы опроса клавиа- туры. Ведь переопределением клавиш, опро- сом горячих клавиш во время игры и контролем над одновременно нажатыми кла- вишами занимаются именно такие подпрог- раммы, и если вы найдете опрос клавиш, не участвующих в игре, то наверняка это CHE- AT. Я не привожу практических примеров того, как выглядит опрос клавиатуры на языке ассемблера, так как сам применяю 5-6 способов такого опроса. Что же каса- ется программистов-профессионалов, то всех пальцев на руках не хватит, чтобы просто только перечислить методы, с по- мощью которых можно контролировать нажа- тие нескольких клавиш, всего ряда или тем более единичной клавиши. К тому же,наде- юсь, каждый, кто собирается самостоя- тельно обессмерчивать игры, имеет представление об этом. Есть еще одна осо- бенность, которую тоже можно отнести к теме фирменных CHEAT, по крайней мере, в рамках этой статьи. Это касается кодов и паролей, которые выдают некоторые прог- раммы после прохождения определенного этапа игры, например, игрового уровня, и с помощью которых впоследствии можно бу- дет начать играть, пропустив уже пройден- ные ранее уровни игры. Такие коды и паро- ли неоднократно публиковались в печати, обнаружить их самому среди текстовых со- общений также не составляет особого тру- да, если они не закодированы, конечно. В некоторых программах, например, LORNA, вообще такие коды к уровням написаны с пояснениями: "CLAVE ACCESO FASE 2: LOLI", "CLAVE ACCESO FASE 3: PLANINGA" и т.д. Очень часто пользователи жалуются, что, зная код, они не могут его набрать, - клавиатура опрашивается настолько быстро, что стоит только коснуться первой клави- ши, как этой буквой мгновенно заполняется все пространство, выделенное для набора секретного слова. Извините, мои дорогие, но в этом виноват ваш компьютер, - он не "по-фирменному" опрашивает клавиатуру. Конечно, можно повозиться и переписать процедуру опроса, но если вы только хоти- те просто посмотреть, что там, в следую- щем уровне, а не выпускать эту игру для широкой аудитории, то я могу поделиться с вами секретом, как "по-варварски" бо- роться с непослушной клавиатурой. Принцип борьбы очень прост, - уж если ваш компью- тер так резво выбивает целую строку одной и той же буквы, так не препятствовать ему надо, а помочь в этом! Для этого снова запустите монитор, который позволяет не только просматривать, но и редактировать содержимое памяти, и поменяйте код. Нап- ример, если для второго уровня игры LORNA был код доступа LOLI, то вы его перебей- те, скажем, на 2222. Теперь, когда прог- рамма попросит вас ввести код для загруз- ки второго уровня, просто нажмите на кла- вишу 2. Послушная машина выбьет столько двоек, сколько поместится в отведенное для этого место на экране, после чего можно смело нажать на ENTER и загружать второй уровень. Еще раз хочу напомнить вам,что распространять программы с такими жестко внесенными изменениями ни в коем случае нельзя, ведь есть люди, которые из описания игры или из компьютерного журна- ла узнали коды доступа к уровням игры, а войти в них не смогут благодаря вашим, с позволения сказать, "модернизациям". И еще одно замечание. Код доступа может храниться в программе дважды, - в тексто- вом сообщении, выводимом на экран после успешно пройденного уровня, и просто само собой, - к нему и будет обращаться прог- рамма для сравнения с кодом, который наб- рали вы. 3. Использование опубликованных POKES. В многочисленных изданиях, посвященных ZX SPECTRUM, публиковались длинные списки POKES, была даже издана отдельная книга с POKES для 600 игр. Правда, большинство из них никто не проверял, во многих были до- пущены ошибки (об этом предупреждали и сами издатели),большое количество POKES подходило только для определенной версии игры, некоторые вообще предназначались только для жесткой установки с помощью копировщика. Неоднократно приходилось за- мечать и просто перепечатки из издания в издание с теми же самыми ошибками. И это еще ничего, гораздо хуже, когда некоторые ребята присылают в журнал POKES, взятые из других изданий или из чужих загрузчи- ков, делая ударения на том, что они их нашли сами. При испытаниях же оказывает- ся, что многие из них содержат явные ошибки и даже не проверялись. Определить, что эти POKES были найдены не их псев- до-авторами очень просто, - это сразу видно, если адрес бессмертия точно совпа- дает с необходимым, а значение,которое нужно занести в эту ячейку, не приводит к желанному результату. Например, для одной из игр было предложено для установки бес- конечной жизни по адресу 32132 занести 0. Оказалось же, что если занести в эту ячейку 0, то после первой же ошибки игра выдаст "GAME OVER", потому что в эту ячейку на самом деле нужно занести число 182. Можно смело делать вывод, что это POKE не только не принадлежит его мнимому автору, но даже не проверялось. В связи со всем этим, к опубликованным POKES нуж- но относиться с осторожностью, особенно если вы устанавливаете их жестко. В иде- альном случае POKES устанавливаются в загрузчики игр после загрузки длинного кодового блока и декомпрессии этого бло- ка, то есть перед последним RANDOMIZE USR. К сожалению, многие хакеры публикуют свои POKES, найденные в программах, заг- руженных под произвольный адрес или не- распакованных. Кстати, сейчас развелось очень много разных упаковщиков, которыми компрессируются длинные кодовые блоки. Естественно, POKES, найденные в програм- ме, упакованной одним компрессором, не подойдут для программы, откомпрессирован- ной другим. Очень хотелось бы, чтобы все, кто собирается обнародовать собственно- ручно найденные адреса бессмертия, указы- вал их для того случая, когда программа загружена на свое родное место в память машины и полностью распакована. Разумеет- ся, это должны быть безупречные POKES, правильно работающие и не дающие нежела- тельных побочных эффектов. А для тех, кто не смог найти в печати POKES для тяжелой игры или же просто не доверяет им, можно порекомендовать только одно, - загрузить дизассемблер и найти таковые самостоя- тельно. 4. Поиск адресов бессмертия. За период с 1991-го года с целью обессмерчивания мною было исследовано по- рядка 1000 игр, и я попытаюсь поделиться с вами своими методиками поиска и успеха- ми на этом поприще. Итак, с чего начать? Конечно же, в первую очередь нужно запус- тить саму игру и, убедившись в ее нор- мальной работе, немножко поиграть, обра- тив особое внимание на такие вещи, как: сколько дополнительных жизней дается программой, как это отображается на экра- не, как эти жизни отнимаются и что проис- ходит,когда лимит жизней исчерпался до конца. После этого нужно разобраться, заглянув в загрузчик, под какие адреса загружаются файлы программы и как они за- пускаются. Если с этим возникают затруд- нения, то сначала загрузчик придется взломать и привести всю игру к такому ви- ду, чтобы она легко загружалась и запус- калась из Бейсика командой RANDOMIZE USR. Как это делается, вы, надеюсь, понимаете, по крайней мере, это тема для отдельной статьи и таких статей и целых книг было немало. Пусть не обижаются на меня и зре- лые хакеры за то, что я так подробно "разжевываю" в своих статьях, по их мер- кам, порой элементарные вещи. Просто я ставлю себе целью написать так, чтобы да- же те, кто только вчера сел за компьютер, прочитал, попробовал и незаметно даже для себя перешагнул барьер между бейсиком и машинным кодом, потому что сам я начинал осваивать ассемблер именно таким образом, пытаясь обессмертить строптивые игрушки. Для первого примера наилучшим образом подходит какая-нибудь широко распростра- ненная и в то же время достаточно трудная игра, например, STAR BOWLS. Как вы заме- тили,первоначально игроку дается 8 жиз- ней, которые очень быстро впоследствии убывают. Из загрузчика следует, что длин- ный кодовый блок игры загружается под ад- рес 26000 и запускается с адреса 34620, предварительно распаковавшись запуском с начального адреса загрузки. Загружаем этот файл (не забывайте перед этим уста- новить CLEAR на единицу меньше, чем адрес загрузки, то есть 25999) и распаковываем командой RANDOMIZE USR 26000. Теперь нуж- но загрузить и запустить дизассемблер, но как же это сделать, ведь для этого нужно больше 6 кБ памяти, а у нас она вся заня- та загруженным и декомпрессированным длинным блоком игры? Но ведь не вся па- мять занята машинным кодом программы, ведь для игры требуется еще большое коли- чество графики, музыки, таблиц и т.д., которые нам сейчас не нужны. Если же из- вестно, что игра запускается с адреса 34620, то можно предположить, что от это- го адреса и ниже до 26000 и располагается вот эта ненужная нам пока информация, значит,сюда и загрузим дизассемблер. Ко- нечно, если вы работаете с диском, то можно сразу с помощью монитора опреде- литься,где в файле полезная информация, предварительно записав его в распакован- ном виде, и совсем нет проблем с 128к-ма- шинами, позволяющими без накладок загру- зить и исследовать код с помощью замеча- тельного STELTH STALKER MONITORа. Запус- тив дизассемблер, давайте попытаемся най- ти в программе то место, где задается ко- личество жизней. Классически количество жизней помещается в аккумулятор и зано- сится затем в ячейку памяти, постоянно его хранящую. Попросим дизассемблер найти нам мнемонику LD A,#08. Он мгновенно ос- тановится на адресе 47805: 47805 LD A,#08 47807 LD (48249),A Теперь становится понятным, что коли- чество жизней постоянно хранится в ячейке 48249. А что, если занести туда не 8, а, скажем, 100 жизней? Для этого можно пере- загрузить длинный блок, очистив память, декомпрессировать его (RANDOMIZE USR 26000) и дать POKE 47806,100. Теперь за- пустите саму игру (RANDOMIZE USR 34620) и вы собственными глазами увидите, что ко- личество жизней значительно возросло, правда, их стало почему-то не 100, а только 64... Дело в том, что эта игра распечатывает количество жизней в шестнадцатиричном представлении, и если вам понадобится 255 жизней, то на экране вместо привычного числа 255 появится #FF. Многие игры проверяют количество жизней и не печатают на экране, если их, скажем, больше 9. Игра BOSCONIAN, например, печа- тает количество жизней в десятичной фор- ме, но под это количество на экране выде- лено только два разряда и если вы задади- те ей больше 99 жизней, то после первого же столкновения получите GAME OVER. Есть игры, которые отображают количество жиз- ней не числом, а соответствующим коли- чеством предметов, например, количество жизней в игре ROBOCOP соответствует коли- честву голов Робокопа в нижней части эк- рана. Представляете, что будет, если за- дать их больше, чем предусмотрено? Конеч- но, если программа проверяет это, то от- секает лишние, а если нет? Тогда в LAST NINJA 2 программа при распечатке коли- чества оставшихся жизней попытается выстроить в одну шеренгу 255 ниндзей, а игра MURRAY MOUSE SUPER COP попробует разместить в пределах экрана 255 мышей. К тому же, даже такого огромного запаса жизней не всегда может хватить для успеш- ного завершения игры, - я, например, не уверен, что на двадцати семи уровнях игры SPACE HARRIER 2 меня убили меньше 255 раз. По всем этим причинам такой способ решения проблем с количеством жизней не только не нашел распространения, но он и нежелателен. Гораздо красивей и надежней работают POKES, устраняющие убавление жизней. Поскольку обычно за один раз от- нимается только одна жизнь, то наиболее вероятнее, по-видимому, применение коман- ды DEC для этой цели. Давайте вернемся снова к STAR BOWLS и проверим это предпо- ложение. Как мы уже знаем, для постоянно- го хранения количества жизней в этой программе выделена ячейка памяти по адре- су 48249. Попробуем отыскать фрагмент, где бы шло обращение к этой ячейки памя- ти, например, через аккумулятор. Дизас- семблер выдаст: 46275 LD A,(48249) 46278 DEC A 46279 DAA 46280 LD (48249),А Продолжение следует... _________________________________________