Ломать — не строить,
тут сноровка нужна.
(Любой взломщик)
Часто бывает так — вам попадается такая игра, что в нее хочется играть вечно. Но что делать, когда кампания пройдена, а сетевые баталии надоели? Возникает желание придумать что-нибудь новое, внести в игру изменения и еще разок поиграть. Хорошо, если разработчик вовремя озаботится написанием продолжений и дополнений. К сожалению, это происходит далеко не всегда.
А бывает иначе. В симпатичной игре с интересным сюжетом, чтобы продвинуться дальше по сценарию, приходится часами повторять однообразные механические действия — тренировать солдат, копить ресурсы, изучать заклинания и так далее... Особо усердные, конечно, добьются своего, а остальные плюнут на это гиблое дело, забросят диск с игрой в ящик стола — и так и не узнают, чем все закончилось.
Неоднократно сталкиваясь с такими ситуациями, я решил написать о способах борьбы с ними. Эти довольно простые приемы позволят вам взглянуть на игру изнутри, разгадать нехитрую головоломку и изменить ее по своему желанию.
Помните эпохальную киноленту «Матрица»? Тот кадр, когда раненный Нео неожиданно понимает, что непобедимые и вездесущие агенты — не более чем зеленые закорючки, суетливо бегущие по экрану? В этот момент он стал непобедимым, и остался им навсегда. Ведь порой достаточно подправить лишь пару цифр, чтобы сравняться с Богом в своем, отдельно взятом мире. Ощутить невиданную силу, вседозволенность и всемогущество. А может быть — развлечь друзей и прослыть матерым хакером? Ну, это уже вам виднее.
По понятиям
Давайте определимся, что же такое «взлом»? Речь ни в коем случае не идет о всевозможных рецептах, позволяющих отнять деньги у разработчика или помешать ему их заработать. Здесь вы не увидите технических советов, как «отучить» программу от компакт-диска, сгенерировать регистрационный номер или каким бы то ни было другим способом обойти защиту от несанкционированного копирования. Во-первых, подобные рецепты грозят «небом в клеточку», а во-вторых, как программист по профессии, я считаю неэтичным отбирать живую копеечку у братьев по клавиатуре.
Далее, следует четко различать взлом и так называемое «читерство». Одно дело, если вы подсмотрели где-то (да хоть в конце этого журнала!) коды бессмертия, а совсем другое — своими руками проделали сложную работу, не пользуясь никакими специальными «лазейками для ленивых». Это большая разница, как в глазах ваших товарищей по виртуальному оружию, так и в самоуважении.
Взломом мы будем называть такое вмешательство в работу игры (или в данные, ею созданные), которое влияет только на игровой мир и его обитателей. Иначе говоря, мы стараемся получить игровые преимущества своими, не предусмотренными в игре, способами.
По мере возможности, я буду иллюстрировать те или иные приемы конкретными примерами. Воспользовавшись ими, вы без труда сможете повторить мои эксперименты. Но не увлекайтесь повторением! Я намеренно делаю акцент не на рецептах взлома нескольких известных игр, а на общих принципах, позволяющих импровизировать в меру собственной фантазии.
Ликбез
И хотел бы я вас порадовать, что для взлома игр не потребуется никаких специальных знаний, но не выйдет. Базовые представления о битах, байтах и системах счисления все же необходимы, хоть бы на уровне школьного курса информатики.
Я сведу ликбез к минимуму и продемонстрирую основные принципы на довольно простых примерах. Если вдруг вас не пугают словосочетания «обратный порядок байт» или «знаковый бит», прошу простить меня за эти прописные истины и не судить слишком строго. Помните, что для многих персональный компьютер — всего лишь инструмент для решения определенных задач, а то и просто игрушка. И согласитесь, что большинство современных задач не требуют подобных знаний.
Системы счисления
Если вам кто-нибудь скажет, что позиционных систем счисления существует четыре: двоичная, восьмеричная, десятичная и шестнадцатеричная — можете смело задвинуть такого «специалиста» в угол, так как это в корне неверно. Ближе к истине будет следующее утверждение: систем счисления может быть бесконечное множество, какую бы вы ни придумали.
В двух словах: система счисления — это некий способ сделать число из цифр. К примеру, мы читаем последовательность рядом стоящих цифр 1, 2 и 3 как «сто двадцать три», используя десятичную систему счисления. Многие из нас никогда не задумывались, как она работает, хотя это весьма просто — рассмотрим это как раз на примере числа 123.
Предположим, мы начали записывать цифры справа налево, по ходу нумеруя их (начиная с нуля!). Тройка попадет на нулевую позицию, двойка — на первую и единица — на вторую. Чтобы сделать из этого набора цифр число, нужно сложить их между собой. Но не просто сложить, а сначала умножить: нулевую цифру — на единицу, первую — на десять, вторую — на сто (то есть, на 10 в той степени, на какой позиции стоит цифра).
Dec | Hex | Bin |
0 | 0 | 0000 |
1 | 1 | 0001 |
2 | 2 | 0010 |
3 | 3 | 0011 |
4 | 4 | 0100 |
5 | 5 | 0101 |
6 | 6 | 0110 |
7 | 7 | 0111 |
8 | 8 | 1000 |
9 | 9 | 1001 |
10 | A | 1010 |
11 | B | 1011 |
12 | C | 1100 |
13 | D | 1101 |
14 | E | 1110 |
15 | F | 1111 |
3*1 + 2*10 + 1*100 = 123
Это — десятичная система счисления. Улавливаете закономерность? Если нет, могу подсказать еще. В двоичной системе счисления мы будем умножать на двойку в разных степенях, в шестнадцатеричной — на шестнадцать.
Далее, система счисления требует достаточного «алфавита» цифр, чтобы при помощи него можно было записать любое число. В двоичной системе две цифры: 0 и 1. В десятичной — десять, в шестнадцатеричной — шестнадцать...
Стоп! Как вы понимаете, привычных обозначений цифр не хватает для 16-ричной записи — ну нет в нашем алфавите цифр «тринадцать» или «пятнадцать»... Что делать? Традиционно эта проблема решается так: для обозначения первых десяти цифр берутся арабские символы от 0 до 9, а для оставшихся — латинские буквы от A до F.
Как прочитать, к примеру, число 8F? Вспоминаем, что буква F условно обозначает цифру «пятнадцать». Далее, как и в случае с десятичной системой, умножаем нулевую цифру на 1, первую — на 16 (дальше было бы на 256, на 4096 и так далее, но цифры из примера закончились). Получаем:
15*1 + 8*16 = 143
Часто возникает иллюзия, что шестнадцатеричная система гораздо сложнее десятичной. Это не совсем правда. С математической точки зрения, они ничем между собой не отличаются, кроме основания (попросту говоря — кроме количества цифр). Просто наш язык развивался в мире, где господствовала десятичная система. Для других систем в нем не хватает ни слов, ни обозначений. Потому и неудобно.
Двоичная система нам, скорее всего, не понадобится, но для интереса можете попробовать перевести двоичное число 1101 в десятичную систему (степени двойки: 1, 2, 4, 8, 16, 32, 64 и т.д.). Если получилось 13, то вы еще не совсем потеряны для общества.
Байты и слова
Байт — это число от 0 до 255, которое обычно обозначают двумя шестнадцатеричными цифрами: от 00 до FF. Так сложилось, что именно байт взят за основную единицу измерения информации, а остальные величины: кило-, мега- и гигабайты — образованы от него. Кстати, килобайт это не 1000 байт, а 1024. Чтобы жизнь медом не казалась.
Анекдот: как отличить опытного программиста от начинающего? Начинающий программист считает, что в килобайте 1000 байт. Опытный уверен, что в километре 1024 метра.
Байт часто путают с символом — оно и понятно. Разработчики кодовой таблицы для DOS в свое время решили, что 256 символов хватит для любых нужд. Таблица, ими созданная, содержит именно такое количество знаков, пронумерованных от нуля и выше. Поэтому и оказывается, что для каждого значения байта есть специальный значок, его символизирующий.
Если вы откроете на просмотр любой файл, то увидите набор значков, каждый из которых представляет некий код в пределах от 0 до 255. Кстати, такую запись можно по праву считать 256-ричной системой счисления, если каждый значок считать цифрой. Но это уже лирика...
Еще один важный термин, от которого никуда не спрятаться начинающему взломщику — слово. Это число. Вопреки русским традициям, в программировании слово состоит всего из двух букв, а точнее — из двух байт. Два байта, поставленных рядом — это оно родимое и есть. Несложно посчитать, что одним словом можно записать числа от 0 до 65535, или от 00 00 до FF FF (привыкайте к 16-ричной системе!).
И все было бы ничего, если бы все программисты сразу договорились, в какой последовательности стоит делать слово из двух байт. Желая записать в виде слова число 255, одни пишут 00 FF, а другие — FF 00, и какого-то универсального стандарта здесь не существует. Просто запомните, что существует прямой и обратный порядки байт.
Dec | Hex | Bin | Примечание |
0 | 00 | 00000000 | Ноль — cамое великое число всех времен |
255 | FF | 11111111 | Максимальное значение байта без знака |
127 | 7F | 01111111 | То же самое, только для байта со знаком |
65535 | FF FF | 1111111111111111 | Максимальное значение слова без знака |
32767 | 7F FF | 0111111111111111 | То же самое, только для слова со знаком |
Наконец, двойное слово — это четыре байта подряд. Они тоже бывают записаны слева направо или справа налево (или если корректно — от младшего байта к старшему или от старшего к младшему). Именно в двойных словах сейчас чаще всего хранят целые числа — память уже давно экономить не принято.
Для справки: большинство игр используют прямой порядок байт. Это означает, что сначала идет младший байт, а затем старший. Если записать в виде двойного слова число 90000, то есть 15F90 в шестнадцатеричном представлении, получится 90 5F 01 00 (прямой порядок байт) или 00 01 5F 90 (обратный порядок байт).
Положительные и отрицательные числа
В десятичной системе мы настолько привыкли к знаку «минус», что навряд ли кто-нибудь отдает себе отчет в том, что это тоже своеобразная цифра, а для ее хранения тоже нужно место. Как поступают программисты, когда нужно хранить как положительные, так и отрицательные числа? Очень просто. Самый старший бит числа считается знаком. Если там стоит 0 — число положительное, если 1 — отрицательное. Если мы работаем в пределах одного байта со знаком, то для хранения самого числа остается уже 8 — 1 = 7 бит. Ведь первый бит слева — не значащая цифра, а знак «+» или «-». Соответственно, один байт со знаком может принимать значения от -128 до +127.
Это интересно: Обратите внимание на число -128. Почему не 127, как это по логике должно быть? Ведь 7 бит — это числа от 0 до 127... Все потому, что «плюс ноль» и «минус ноль» — это одно и то же число — «ноль». Чтобы две разные битовые комбинации не означали одно и то же число, отрицательные числа «сдвинули» на единицу. Очень разумно.
Для слова и двойного слова ситуация абсолютно аналогичная. Один бит для знака, остальные — для самого числа. Следовательно, слово со знаком изменяется в пределах от -32768 до +32767. Пятнадцать бит хранят модуль числа, а последний бит — знаковый.
В чем ценность этих сведений? Часто бывает так, что жадный взломщик радостно ставит себе FF FF денег в казне. Если деньги хранятся в виде слова со знаком, то результат неутешительный — после «взлома» в сокровищнице пылятся ровно 32768 золотых монет... долга. Если бы его познаний хватило на то, чтобы поставить 7F FF, он имел бы максимально допустимый в игре золотой запас.
Контрольные суммы
Контрольная сумма — это некое число, которое используют для проверки корректности данных. Предположим (только для примера), что программист решил записать где-то число 12, а также обеспечить себе способ выяснить, не менял ли кто-нибудь эти цифры вручную. Для этого его программа вычисляет сумму всех цифр числа, после чего гордо приписывает в конец цифру 3. Получаем что-то вроде 123, где 12 — значащие цифры, а 3 — так называемая контрольная сумма. Теперь, если взломщик поменяет 12, к примеру, на 25, программа сообщит ему об ошибке. Она посчитала контрольную сумму и получила 2 + 5 = 7, а это не сходится с последней цифрой. Значит, кто-то внес изменения в защищенные данные! Этого бы не произошло, если бы взломщик написал число 257, догадавшись о способе контроля.
Так выглядит при просмотре типичная контрольная сумма. |
К сожалению, такими простыми способы бывают только в сказках. Чаще всего контрольная сумма состоит из нескольких байт, а вычисляется отнюдь не при помощи суммирования. Думаю, что вы сами сходу сможете придумать какую-нибудь хитрую функцию для вычисления контрольной суммы, чтобы у взломщика волосы встали дыбом при попытке найти закономерность.
Радует только то, что обычно игровые данные никто не спешит защищать. Оно и понятно — какой резон разработчику заниматься теми вещами, от которых ему ни холодно, ни жарко? Какая разница фирме-производителю — пятьсот золотых у вас в игровой казне или пять миллиардов? Да никакой! Серьезные защиты делают там, где на карту поставлена прибыль предприятия, но эти защиты мы ломать не будем (тем более что создают их со звериной серьезностью).
Как определить, что данные защищены контрольной суммой? Иногда это видно по самой структуре файла — достаточно равномерная картинка нулевых, с мелкими вкраплениями, байт, вдруг заканчивается несколькими байтами «какой-то чуши» — двумя, четырьмя, восемью и т.д. Другой случай — после изменения данных программа сама сообщает об этом. Дескать, данные были изменены, «кина не будет». Рекомендую с ней согласиться. Обнаружив такую защиту, лучше поищите другой, более легкий путь.
Понемногу начинаем
Инструментарий
Я сознательно ограничиваюсь примерами, не требующими сложного программного (а тем более — аппаратного) обеспечения. Практически все программы, которыми мы будем пользоваться, входят в стандартную поставку операционной системы Windows или установлены почти на любом персональном компьютере.
Исключение составляет программа ArtMoney, без нее не обойтись при работе с оперативной памятью. Кроме того, потребуется любой шестнадцатиричный редактор файлов, но этого добра тоже везде хватает. Фактически, вот весь «хакерский» инструментарий, который как-то упоминается в статье:
ArtMoney — мощная программа для работы с оперативной (и не только) памятью.
Far manager — файловый менеджер текстового режима, со встроенным редактором.
Fc — стандартная системная утилита для сравнения файлов. Запускается из командной строки и не задает лишних вопросов.
Gzip — программа архивации и разархивации в формате Zip.
Hiew — hacker’s viewer, замечательный 16-ричный редактор.
Калькулятор — программа из стандартной поставки Windows.
Чуть не забыл. В качестве главной составляющей успешного взлома нам не обойтись без головы, способной мыслить, анализировать, обобщать и сопоставлять. Теперь точно все.
Способы
Каждая игра хранит свои данные либо в оперативной памяти, либо на жестком диске компьютера. Еще не изобретены программы, имеющие прямой доступ в астрал, поэтому все данные игры находятся в вашем распоряжении. Главное — уметь искать, смотреть и видеть.
Существует три принципиально разных способах взлома: изменение файлов самой игры, правка сохраненных игр (savegame) и редактирование значений в оперативной памяти. Вряд ли можно назвать абсолютный метод взлома — все зависит от каждой конкретной ситуации.
Файлы игры. Проще всего, если игра хранит свои данные в текстовом формате. С тех пор, как большинство игр стали делать на так называемых «движках» (engines), для описания особенностей мира программисты все чаще используют тексты. В них хранится практически вся служебная информация — виды войск, характеристики оружия, сценарии и даже алгоритмы поведения. Даже в весьма ранних играх уже встречалась эта технология (например — Duke Nukem или Tiberian Sun).
Если вы помните мою статью про Breed, там упоминался «рецепт долголетия». В двух словах: в игре было несколько уровней сложности, и каждый из них описан набором параметров в текстовом файле. Если свести к нулю коэффициент повреждений для выбранного нами уровня, все наши солдаты вообще не страдают в бою. Это типичный пример, когда исправлением служебных файлов игры можно добиться различных игровых преимуществ.
Сохраненные игры. Чаще всего взламывают сохраненные игры — самый удобный объект для хакерских изысканий. Размер savegame редко выходит за пределы нескольких сотен килобайт, поэтому ориентироваться в нем довольно просто. Потребуется простейший редактор, позволяющий переключаться в шестнадцатеричный формат, а также дающий возможность поиска и исправления данных.
Оперативная память. Один из самых надежных способов взломать игру — это найти и изменить нужные ячейки памяти. Без него не обойтись, если требуется не просто установить какое-то значение, но и постоянно поддерживать его. К примеру, в играх жанра action полезно сделать так, чтобы атаки противника не наносили повреждений, или чтобы здоровье мгновенно восстанавливалось. Кроме того, сохраненные игры временами защищены контрольной суммой. Тогда идем в обход — взламываем нужное состояние прямо в памяти, а уже потом спокойно сохраняем игру.
Недостаток этого способа очевиден. Современные игры редко церемонятся с выделением памяти, сразу «отхватывая» 200-300 мегабайт. Найти среди них несколько нужных байт — задача непростая, и уж точно — не быстрая.
Что ломать
Казалось бы, что тут думать? Если это action, обеспечиваем себе вечную жизнь, убойную силу патронов, неограниченный боекомплект и радуемся жизни, на горе местным монстрам. Если стратегия реального времени или RPG — объектом взлома должны стать деньги, различные прочие ресурсы, численность и состав войск, доступные знания и умения... В большинстве случаев оно так и есть, но не всегда.
Иногда возникают ситуации, когда вот так, напрямую, взять и сделать себе миллион золотых в кошельке — или просто невозможно, или на редкость утомительно. Зато, к примеру, можно изменить количество других, менее ценных ресурсов у вас на складе, а в игре их продать. Или, как альтернативный вариант, можно попробовать подправить цены на интересующие вас товары — в кармане остаются те же пять монет, но купить на них можно половину Вселенной. Согласитесь — это ведь то же самое?
Это главное: следует помнить, что взлом — это не пробивание стены лбом, а поиск двери, которая по недосмотру осталась незапертой.
Наконец, задумайтесь — может быть, в игре есть какой-нибудь оригинальный, необычный и интересный способ взлома? Может, удастся добиться какого-нибудь результата, который авторам и в страшном сне не снился? Или подшутить над друзьями, цинично сохраняя невозмутимое выражение лица и наблюдая за их нелепыми действиями? В конце концов, творческий подход еще никто не отменял.
Изучаем каталог игры
Перед тем, как приступать к сколько-нибудь осмысленному процессу взлома, с игрой следует немного познакомиться. Для этого давайте зайдем в каталог, куда установлена игра, и посмотрим на его содержимое. Наша цель — найти любые полезные данные в формате, который можно легко изменить при помощи текстового редактора. Грубо говоря, нужно посмотреть, можно ли взломать игру просто, без лишних хитростей.
Каталог Half-Life (правая панель) и вложенный каталог TFC (левая панель). |
Основное внимание следует уделять небольшим файлам с расширениями *.txt, *.cfg, *.ini. Не ищите их вручную, лучше воспользуйтесь автоматическим поиском файлового менеджера Far или стандартными средствами «Проводника».
Для примера возьмем Half-life. Что же показывает изучение каталога? Помимо исполняемых файлов *.exe, динамических библиотек *.dll и игровых ресурсов *.wad и *.pak, мы обнаруживаем интереснейший файл config.cfg в каталоге TFC. Заглянем внутрь...
Все эти параметры определяют настройки игры по умолчанию. Чувствительность мыши, яркость экрана и тому подобные значения записаны в простом текстовом виде. Но их исправлять неинтересно. Предположим, что есть другие, более интересные параметры, и их названия нужно узнать. Для этого поступаем следующим образом — ищем в каталоге с игрой все файлы, содержащие одно из известных названий параметров, например — «sv_aim». В нескольких dll-файлах такое значение есть. Открываем один из них и находим это название, а рядом видим великое множество других имен параметров. Например — «sv_gravity». Попробуем применить эти сведения на практике ...
Лаконичный опыт с Half-Life
Если мы добавим в config.cfg строчку «sv_gravity 50» и запустим игру, то увидим, что сила притяжения многократно ослабла. Все прыжки длятся несколько секунд, а то и десятков секунд, и к тому же стали намного безопаснее. Помните космонавтов на Луне? Примерно это и получится.
Если, напротив, поставить высокую гравитацию — что-то вроде «sv_gravity 100000», то даже высота одной ступеньки лестницы станет смертельной. Спускаетесь по лестнице... Один шаг — и покойник. Падение с высоты 15 сантиметров при такой гравитации — непозволительная роскошь.
Теперь давайте творчески воспользуемся этой находкой. Посмотрев, как настраивают в скриптах оптический прицел (который включается по нажатии клавиши и отключается при отпускании), сделаем аналогичный скрипт для гравитации. Получится что-то вроде этого:
alias + fall «sv_gravity 100000»
alias — fall «sv_gravity 800»
bind «SPACE» + fall
Как вы думаете, что произойдет в процессе сетевой игры, когда игрок, у которого установлен такой скрипт, нажмет на пробел? Правильно — гравитация в игровом мире скачкообразно возрастет, а сразу после отпускания клавиши вернется к прежнему уровню. Как только увидели подпрыгнувшего противника — нажимайте. Он даже не успеет понять, от чего умер.
Конечно, это примитивный пример. Может быть, он даже слегка «притянут за уши», так как консольные команды Half-Life многие знают наизусть. Тем не менее, данный пример показывает, что зачастую можно добиться нетривиальных результатов, не прибегая ко «взлому» в буквальном смысле слова.
Ломаем Heroes of Might and Magic IV
Постепенно продвигаясь от простого к сложному, остановимся на знаменитых «героях». Думаю, что обойти их стороной было бы непростительно.
Для начала, как полагается, ознакомимся с каталогом игры. В принципе, ничего особенно интересного там не видно. Нет ни файлов настройки, ни каких-либо других полезных текстовых файлов. Ну, раз так, сфокусируем внимание на каталоге Games, в котором, судя по всему, хранятся сохраненные игры. Если вы просмотрите содержимое любого из файлов в этом каталоге, то увидите чушь, редактировать которую абсолютно бессмысленно. Тем не менее, из структуры файла можно сделать вывод, что он содержит упакованные данные.
Для справки: сжатые данные сильно отличаются от несжатых внешним видом. Это связано с тем, что любой алгоритм архивирования стремится найти дублирующуюся информацию, чтобы заменить ее на уникальные, более короткие последовательности. Если вы видите хаотический набор байт, лишенных всякой визуальной закономерности — скорее всего, это заархивированный блок данных.
Шаг первый: распаковка
Итак, пробуем разархивировать файл сохраненной игры, исходя из предположения, что он упакован при помощи стандартного алгоритма zip. Для этого переименуем файл, изменив расширение на *.zip. Так, взятый мною для примера файл Stager.h4s я переименовываю в Stager.zip.
Открываем его при помощи программ WinZip или WinRar и убеждаемся, что это действительно архив, содержащий одноименный файл (в моем случае — «stager»). Распаковываем его и делаем резервную копию, чтобы дальше безопасно с ним экспериментировать. Помимо указанных программ, можно воспользоваться архиваторами pkunzip.exe или gzip.exe (в последнем случае файлы придется называть laquo;движкахне *.zip, а *.gz)
Это важно: вообще говоря, использование стандартного алгоритма упаковки — большое везение. Чаще данные пакуются при помощи специализированных алгоритмов, так что распаковать их не так просто. Впрочем, для многих форматов, используемых известными фирмами, народные умельцы уже давно написали редакторы и декомпрессоры. Ищите.
Шаг второй: анализ файла
С первого взгляда видно, что содержимое разархивированного файла более чем осмысленно. Основной массив составляют нулевые байты, среди которых то здесь, то там встречаются какие-то значащие величины. Кое-где можно обнаружить даже обрывки текста — реплики из диалогов, события сценария и т.п. Отдельное умиление вызывают обнаруженные названия объектов вроде «trees.Pine.CedrusDeodara02» или «Mountains.grass.07». Переводится приблизительно так: здесь посадим кедр, а вот тут пусть будет травка. Создатели игры об экономии дискового пространства явно задумывались в самую последнюю очередь, поэтому и решили архивировать файлы.
На всякий случай, сразу смотрим самые последние байты — нет, на контрольную сумму это не похоже. Прогноз оптимистичный.
Шаг третий: поиск денег и ресурсов
Давайте начнем с того, чтобы обеспечить себя ресурсами. Для этого понадобится найти в распакованном файле место, где они хранятся, и немного подправить цифры. Смотрим, сколько денег у нас есть сейчас. Предположим, ровно 15000 золотых. Запускаем стандартный системный калькулятор, переключаем его в расширенный (инженерный) режим и переводим число 15000 в шестнадцатеричную систему счисления. Если вы никогда не пользовались расширенным калькулятором — поясняю. Пишете число 15000 в поле ввода, а потом в группе радиокнопок «Hex-Dec-Oct-Bin» включаете Hex. Если получилось 3A98, значит, оба устройства — и калькулятор, и пользователь — работают исправно.
Предположим, что деньги хранятся в виде двойных слов с прямым порядком байт. Кстати, это предположение не взято «с потолка». Вы ведь видели в казне больше 65535 единиц золота? Я тоже видел. Значит, ни в байте, ни в одинарном слове это число не может быть записано — просто не поместится. Остается двойное слово. А прямой порядок байт — это правило, исключения из которого крайне редки.
Ищем, где игра хранит деньги. Что приятно — находим. |
Запишем ту сумму денег, что у нас в казне, в виде двойного слова с прямым порядком байт. В моем примере (15 тысяч золотых) эта последовательность будет выглядеть так: 98 3A 00 00. Открываем файл при помощи любого Hex-редактора (например — hiew.exe) и выполняем поиск этой комбинации. Только не забудьте указать, что вы ищете не последовательность символов «98 3A 00 00», а четыре байта с этими кодами.
Нашли. Но что самое интересное — сразу за этими четырьмя байтами идет пара двойных слов 0F 00 00 00, а затем еще четыре двойных слова 07 00 00 00. Смотрим на состояние наших ресурсов — так и есть. У нас по пятнадцать единиц дерева и камня, а также по 7 единиц серы, ртути, кристаллов и самоцветов. В общем, логично, что в файле все ресурсы записаны рядом.
Попробуем изменить. Думаю, что десяти миллионов золотых и по миллиону единиц каждого ресурса должно хватить. По крайней мере — на первое время... Еще раз воспользовавшись калькулятором, получаем набор кодов, которые требуется записать. Для денег — 80 96 98 00 (десять миллионов), для ресурсов — 40 42 0F 00 (один миллион). Вносим исправления и сохраняем файл.
Шаг четвертый: упаковка
Состояние складов: до и после изменений. Слева файл, справа — картинка из игры. |
Для того, чтобы изменения вступили в силу, придется проделать последнюю операцию — упаковать файл и поместить архив в каталог игры. Для этого архивируем его при помощи того же WinZip или gzip, меняем расширение файла на *.h4s и копируем в каталог games.
Настал миг торжества — запускаем Heroes of Might and Magic и загружаем игру. Действительно, денег у нас теперь куры не клюют, да и остальные ресурсы тоже не в дефиците. Кстати — обратите внимание на букву «k» справа от некоторых чисел. Имеется в виду, что число при показе не поместилось целиком, поэтому оно показано в тысячах.
Но это не конец — посмотрим, какие еще параметры можно взломать...
Численность войск
Найдем, где можно изменить численность войск. Для разнообразия сделаем это несколько другим способом — при помощи сравнения двух файлов.
Входим в игру и загружаем файл, который мы недавно редактировали. Берем одного героя — предположим, у него в отряде 25 арбалетчиков и 30 булавоносцев. Увольняем по одному бойцу (то есть — делим отряды на 24+1 и 29+1, после чего прогоняем одиночных солдат) и сохраняем игру под другим именем. Главное — больше ничего не делайте. Единственное отличие между сохраненными играми — численность войск.
Как и прежде, распаковываем оба файла сохраненных игр и складываем во временный каталог. Теперь воспользуемся стандартной системной утилитой fc.exe (File Compare — «Сравнение файлов»). Синтаксис команды такой: fc.exe /b имя1 имя2 > имя3.
Результаты сравнения файлов. Нужные строчки выделены синим. |
Имя1 и имя2 — это имена сравниваемых файлов, а имя3 — файл, в который будут записаны результаты сравнения. Ключ /b подразумевает, что файлы не текстовые и их нужно сравнивать побайтно, а не построчно.
Выполнив команду, мы получаем перечень всех отличий, записанный в самостоятельный файл. Откроем его. Если отличий между файлами все же окажется много, воспользуемся обычным текстовым поиском. Найти нужно две строчки. В одной — значение изменилось с 25 на 24 (арбалетчики), во второй — с 30 на 29 (булавоносцы). Вычислив шестнадцатеричные эквиваленты этих чисел и разделив их пробелами (так, как выдает результаты fc.exe) будем искать «19 18» и «1E 1D». Вот они — стоят рядом, а слева указаны адреса. Запомните эти адреса, а лучше — запишите.
Это важно: если в результате сравнения вы получаете огромный выходной файл, из которого следует, что практически все байты разные — возможно, вы забыли разархивировать сравниваемые файлы. Если все сделано верно, отличаться могут лишь одна-две сотни значений.
Мы уже близко. Открываем любой из распакованных savegame-файлов программой hiew.exe, переходим в Hex-формат и нажимаем клавишу F5 — переход по указанному адресу. Вводим один из адресов, которые мы только что запомнили (а то и записали). Переходим. Вот она — численность войск. Кстати, она тоже хранится в виде двойных слов — делайте хоть миллион, хоть миллиард солдат.
Виды войск
Более интересный взлом — поменять не численность, а состав войск. Это — задача посерьезнее. Требуется выяснить, по каким адресам хранятся виды войск. Главная проблема — мы не знаем, какой код искать. Каждому роду войск наверняка соответствует некий номер, но какой? Он ведь не пишется напротив отряда!
Поступим следующим образом. Зайдем в игру и возьмем героя, у которого в отряде два рода войск. Например — пресловутые арбалетчики и булавоносцы. Уволим часть из них так, чтобы количество тех и других стало равным (уже догадываетесь, зачем?). Сохраняем игру под каким-нибудь именем. Теперь меняем отряды местами — при этом изменяется только род войск на первой и второй позиции (ведь количество — равное!), а сразу после этого — сохраняем игру под другим именем.
Далее, уже привычным образом распаковываем оба файла и сравниваем их между собой, записывая результат сравнения в файл. В нем нужно найти два адреса. Их отличительная черта — содержимое, которое поменялось местами. Если по одному адресу мы видим что-то вроде 0B 36, а по другому — 36 0B, то именно эти адреса нам и нужны. Легко убедиться, что, проставив по обоим из них значение 36, мы получим два отряда булавоносцев, а проставив 0B — два отряда лучников.
Можете поэкспериментировать, проставляя на эти позиции любые другие числа, но помните, что видов войск не так уж и много. Весьма вероятно, что на какой-нибудь код игра выдаст ошибку, так как отряда с таким номером в ней не предусмотрено.
Для того чтобы поставить себе не случайные, а желаемые виды войск, нам по-прежнему не хватает информации. Конечно, можно подбирать наугад, запоминая коды, но это долго и утомительно. Подойдем к вопросу по-научному.
Прошу любить и жаловать — драконы и богомолы. |
Предположим, мы хотим поставить герою феерических драконов на первую позицию, а богомолов — на вторую. Для этого необходимо узнать, какие коды им соответствуют. Проанализируем ту информацию, что у нас уже есть. Мы знаем адреса, по которым располагается численность и род войск для первой и второй позиции — ведь мы вычислили их в ходе предыдущих экспериментов. Несложно заметить, что род войск следует сразу перед количеством. То есть, если мы сместимся на 4 байта влево от адреса, по которому записана численность отряда, то встанем точно на код, определяющий род войск в этом отряде. Для чего нам это нужно? Сейчас расскажу.
Давайте запустим редактор карт и сценариев. Возьмем какую-нибудь простую карту, и поставим на нее отряд драконов, а рядом — отряд богомолов. Каждому отряду вручную укажем количество, причем такое, которое легко потом будет найти и отличить от всех остальных. К примеру, численность драконов путь будет 12345, а численность богомолов — 23456. Сделав такую карту, запускаем Heroes и начинаем сценарий по этой карте. Как только игра началась, сохраняем ее в файле.
Теперь осталось привычным движением распаковать файл, открыть его в hiew.exe и найти ту «особую» численность, что мы им задавали. Разумеется, не забудьте перевести ее в 16-ричную систему. Нашли? Теперь смотрите левее — там указан код, который соответствует драконам (если я ничего не путаю, это код — 15). Аналогично находим количество богомолов, а слева от него — их код (24). Готово — коды известны. Подставим их в файл игры, где мы меняли арбалетчиков и булавоносцев местами. Получилось!
На этой оптимистической ноте я откладываю в сторону многострадальных «Героев». Надеюсь, что вы не ограничитесь простым повтором моих экспериментов — ведь я описал только ничтожную долю того, что с ними можно сделать.
Ломаем True Crime
Давайте вспомним, какие именно параметры в True Crime особенно заслуживают взлома? Во-первых, хотелось бы добиться неуязвимости для главного героя — где же это видано, чтобы герой погибал от десятка-другого пуль? Во-вторых, было бы полезно повысить рейтинг заслуг и рейтинг хорошего полицейского. А в качестве десерта — давайте остановим таймеры, ограничивающие время выполнения некоторых миссий и тренировочных упражнений.
Эта игра выбрана в качестве примера не случайно — типичный «тяжелый пациент». Сохраненные игры в True Crime защищены контрольной суммой — стоит изменить любой байт, и игра радостно сообщает об ошибке, отказываясь от дальнейшей работы. Оставим подбор контрольной суммы на долю истинных ценителей прекрасного, а сами поищем способ взлома поинтереснее. Лучше всего, на мой взгляд, подходит поиск и изменение значений в оперативной памяти.
Подход
Любая программа хранит основные рабочие значения в ячейках оперативной памяти, причем адреса этих ячеек практически никогда не изменяются в течение всего сеанса игры. Если мы узнаем адрес нужной ячейки, то сможем изменить хранимое значение. Чтобы определить адрес, воспользуемся специальной программой. Вообще говоря, программ такого класса существует множество, но лично мне больше всего по душе ArtMoney — на ней и остановимся.
Основной принцип работы програмы состоит в следующем. Мы ищем все адреса, содержащие искомое значение. Нетрудно предположить, что их будет очень много, так как вместе с нужным адресом мы найдем миллионы ячеек, значение в которых случайно совпало с искомым. Следующий шаг — отсеивание случайных значений. Раз за разом изменяя искомое значение в игре (и отражая изменения в поисковой программе!), мы сокращаем список, пока в нем не останется один-единственный адрес. Дальше остается только записать в найденную ячейку желаемое значение, или «заморозить» ее в определенном положении. Испробуем этот подход на True Crime.
Заслуги и репутация
Обратите внимание на правый нижний угол. |
Запускаем игру и программу ArtMoney, и в ней в качестве процесса выбираем «True Crime». Начнем с самого простого — репутации (число рядом с символом «дао»). Для этого загружаем сохраненную игру и выбираем одну из миссий, где можно вволю прогуляться по улицам. Например — «Driving for Chow» из первого эпизода.
Предположим, что изначальная репутация полицейского равна +3. Ищем в памяти все стандартные целые значения, равные 3. Возвращаемся в игру и убиваем одинокого прохожего. Репутация ухудшается до +2. Теперь нужно снова переключиться в ArtMoney и выполнить отсев значений с учетом того, что новое значение ячейки равно 2. Теперь можно обыскать пару человек и найти у кого-нибудь наркотики или оружие, чтобы поднять репутацию...
В общем, продолжайте изменять репутацию произвольным образом, и после каждого изменения выполняйте отсев лишних значений. Вскоре останется одна ячейка — она-то нам и нужна. Переносим ее в список и устанавливаем ей новое значение: +99. Для справки — у меня адрес этой ячейки был равен 006D5658. На вашем компьютере он может отличаться, но если вдруг совпадет — значит, вы совершенно точно все сделали правильно.
Переходим к заслугам. Скажу по секрету — это сразу три параметра: количество очков, обозначаемых цифрами, затем количество щитов, символизирующих сотни, и, наконец — их сумма. То есть, если у вас три щита и 26 единиц, то эти параметры будут равны 3, 26, 326. Во избежание казусов я советую найти и изменить все три. Адреса для справки: 006D5650, 006D5654 и 0DCDD384.
Бессмертие
На очереди святая святых (и при этом — самый неинтересный параметр) — бессмертие. Тут так просто не получится, ведь численное значение здоровья нам никто сообщать не спешит — вместо него есть только дугообразный индикатор в левом верхнем углу экрана. В этом случае следует искать неизвестное значение одного из стандартных типов.
Загружаем игру. Здоровье — на максимуме. Выполнили поиск — возвращаемся в игру и теряем немного жизни. Например — вступаем в драку или (что еще лучше) взрываем автомобиль и пробегаем через огонь. Возвращаемся в ArtMoney и выполняем отсев по критерию «Значение уменьшилось». Стратегия прежняя, только искать придется несколько дольше. Когда здоровье закончится и начнется новая жизнь — отсеивайте по критерию «Значение увеличилось» а потом снова продолжайте терять жизни.
Найдя нужный адрес, нужно будет его зафиксировать. Что толку, если вы единожды установите здоровье, а потом снова его потеряете? Для фиксации установите крестик в левой колонке таблицы — теперь ArtMoney будет восстанавливать старое значение, как только оно изменится.
Полностью доверять этому механизму не стоит. Если вы попадете в серьезную переделку, то можете лишиться здоровья и погибнуть раньше, чем программа успеет восстановить нужную величину. По этой причине лучше всего фиксировать максимальное здоровье — чтобы был хоть какой-то запас.
Таймер
Есть задания, на выполнение которых отводится фиксированное время. Не знаю, как для вас, но для меня лимит времени — самый неприятное из возможных препятствий. Причем во всех, без исключения, играх.
ArtMoney выполняет очередной отсев значений. |
Итак, задача — остановить эти мерзкие часы внизу экрана. Выбираем миссию, которая допускает вольные прогулки по улицам (например, ту же «Driving for Chow») и едем в тренировочный спортзал. В принципе, можно было бы выбрать одну из гоночных миссий, но там не представится возможность быстро повторить попытку.
Насколько я помню, на поиск таймера у меня ушло больше всего времени и сил. Искать советую неизвестное значение стандартного типа. Логично, что оно будет постоянно уменьшаться. Когда время выйдет — начинайте по новой (благо, заслуг у нас — хоть отбавляй, повторять попытки можно долго). Не забудьте сразу после начала новой попытки указать, что искомое значение увеличилось.
В конце концов, остается несколько ячеек, их можно перепробовать вручную. Зафиксируйте одну и посмотрите — не встали ли часы. Если вместо этого зависла игра или «заело» звуковую дорожку — делайте выводы. Адрес для справки: 0DCDD1E8.
После того, как часы остановлены, можете вздохнуть спокойно. Таймер общий на все случаи жизни, так что теперь все тренажерные залы, учебные трассы и миссии, проходящие под девизом «Успеть, пока не началось!» сложности не представляют. Можно расслабиться и на досуге подумать, что бы еще такое взломать.
Курьезы взломанных игр
В качестве небольшой разрядки, расскажу о паре случаев из собственной практики. Иногда можно получить намного более интересные результаты, чем богатство или бессмертие.
Disciples
Затеяли мы с другом состязание в Disciples, еще в первый. Компьютер у меня на тот момент был один, поэтому играли в режиме hot seat. Сражались долго, так что в какой-то момент моему оппоненту пришлось отлучиться на урок (он преподает английский) а я, тем временем, засел изучать файл сохраненной игры.
По сценарию, игра завершалась победой того, кто первым возьмет город Kazan. Все шло к тому, что мой соперник неминуемо меня опередит — уже и армия готова, и заклинания в полном объеме, и опыт приобретен. Но ведь у меня в руках — hiew.exe. Полчаса кропотливой работы, и злополучный город Казан отрывается от земли и переезжает на укромную полянку в другом конце карты.
И вот представьте — возобновляется партия, ликующий супостат выдвигает войска по направлению к цели. Но там — только зеленая лужайка: птички щебечут, травка колышется. Никакого города и в помине нет... Это выражение лица описать невозможно — только увидеть воочию.
Конечно, посмеявшись от души, мы продолжили партию с резервной, не исправленной копии «savegame». Надо ведь и честь знать.
UFO: Enemy unknown
Многие старые игроки помнят эту замечательную игрушку про инопланетных пришельцев, от которых надо усердно защищать родную планету. Уж сколько лет прошло, а я по прежнему с удовольствием вспоминаю большеголовых сектоидов и грозных мутонов, базу на Марсе и храброго Ника Завадски. «Никто не верит, что с самого начала нас было только восемь» — так начинается роман фантаста Васильева, посвященный UFO. В общем, много воды утекло с тех пор...
Стоит ли говорить, что мы ломали ее вдоль и поперек? Конечно, ломали. Тем более, что сохраненные игры состояли из набора файлов, где в идеальном порядке были разложены все необходимые данные. Старая школа, хороший тон.
Очень огорчало отсутствие многопользовательской игры. У каждого из нас уже были излюбленные тактики, поэтому безумно хотелось померяться силами друг с другом. Сказано — сделано. Для начала мы вылетали на задание с двумя комплектами одинаково вооруженных солдат — для равных условий. По прибытии их принудительно разводили в разные углы карты. Чтобы солдаты не паниковали от гибели своих сослуживцев (например — из группы солдат оппонента), пришлось подправить всем «мораль» — и бойцы обрели невозмутимость индейского вождя.
Но самое главное: найдя в файлах игры чертежи летающих тарелок, мы наглухо заварили в них все двери, чтобы эти назойливые пришельцы не путались под ногами и не мешали дружескому состязанию. Представляю, с каким чувством бедные сектоиды бродили по родной тарелке, бормоча под нос: «Ну ведь здесь же был выход... Он точно был где-то здесь...». А за иллюминаторами тем временем грохотали взрывы — это солдаты X-Com сводили личные счеты.
В конце концов, был даже написан специальный редактор оружия. Чего стоит, к примеру, винтовка, гарантированно пробивающая обшивку летающей тарелки? Или пушка, заряжаемая исключительно трупами пришельцев? Или пистолет, пуля из которого летит по заданной кривой траектории? Всего сейчас уже и не припомню.
Ни с чем не сравнимо чувство, когда сидишь над распечатками и вдруг понимаешь смысл той или иной колонки цифр. Меняешь, пробуешь — и происходит чудо! Игра поддается, начинает вести себя иначе и приобретает новый, еще никем не испробованный смысл.
Эпилог
Свою первую игру я взломал более десяти лет назад. Все началось с того, что один товарищ раскурочил ее у меня на глазах, а потом в двух словах объяснил, как он это сделал. Стоило один раз попробовать самостоятельно, чтобы понять, что ничего сложного в этом нет. Через какое-то время мне уже стало неинтересно обеспечивать себя бесконечными патронами и бессмертием — тогда я начал искать интересные возможности и оригинальные способы взлома.
Я надеюсь, что данная статья поможет вам сделать первый шаг и добиться успеха, чтобы вскоре перейти на «ты» почти с любой компьютерной игрой. А когда вы почувствуете, что миллион драконов — это не верх мастерства, а, в общем-то, банальность, то сами начнете охоту на различные «хитрости». Уверяю, в ход пойдет все — техника, фантазия, сумасбродные идеи и случайные находки.
Если они окажутся по-настоящему яркими и необычными, мы можем посвятить им отдельную статью. А пока — желаю удачи и отличного творческого настроения!