Вот так теперь выглядит игра Laser Squad, которую я увидел очень давно. Тогда она была во всех смыслах проще и выглядела так:
При этом принципиально игра не изменилась. Просто стала сложнее: куча типов ресурсов, множество вариантов их применения плюс «инфляция»: каждая следующая мастерская, лаборатория или спутниковый канал стоят больше, чем предыдущие. С одной стороны, это все дает возможность играть разными стратегиями развития, но иногда так хочется поиграть просто в Laser Squad! Поэтому…
Поэтому я пошел на App Store и за каких-то 29$ купил XCOM. Метода хака ресурсов в играх не изменился с момента появления Первого Сейва: сохраняемся, меняем количество целевого ресурса, сохраняемся еще раз, запускаем hex-редактор, находим место, в котором первое контрольное значение изменилось на второе контрольное значение, пишем туда знаковое целое (что-то типа 0x7FFF) — и наслаждаемся резко упрощенным геймплеем.
Но тут меня ждал облом. Даже два: во-первых, последовательно сохраненные файлы отличались размером. Во-вторых, в той части файла, которая относилась к условному заголовку, соответствующие значения были, но их изменение приводило к тому, что XCOM жаловался на битые файлы: очевидно, в формате предусмотрены какие-то контрольные суммы, которые не совпадают после такого грубого внесения изменений.
Ну что-же. Значит, время взять в руки дебаггер: не получается править файлы, то будем править сразу память. Здесь метода немного другая:
- запустили игру;
- прицепились отладчиком;
- посмотрели количество целевого ресурса;
- нашли в памяти процесса множество адресов с этим значением и сохранили;
- поменяли количество целевого ресурса;
- нашли в памяти новое множество адресов и пересекли (set intersection) с предыдущим;
- повторили пп. 5 и 6 пока не остался один-единственный адрес;
- записали в этот адрес желаемое количество целевого ресурса.
Но здесь есть сложности. Первая в том, что в общем случае виртуальная память процесса во всех современных ОС не является непрерывной, а перебирать все пространство возможных адресов — слишком долго. К счастью, в OS X есть замечательный утиль vmmap, который на выходе отдает подробную карту памяти процесса в виде:
% vmmap 15552
…
shared memory 3afff000-3b000000 [4K] rw- / rw- SM = SHM
MALLOC_SMALL 3b000000-3b800000 [8192K] rw- / rwx SM = PRV DefaultMallocZone_0x4816000
MALLOC_LARGE 3b800000-3b84c000 [304K] rw- / rwx SM = PRV DefaultMallocZone_0x4816000
shared memory 3b84c000-3b854000 [32K] rw- / rw- SM = SHM
IOKit 3b85d000-3b866000 [36K] rw- / rw- SM = ALI
MALLOC_LARGE 3b866000-3b891000 [172K] rw- / rwx SM = PRV DefaultMallocZone_0x4816000
shared memory 3b891000-3b899000 [32K] rw- / rw- SM = SHM
MALLOC_LARGE 3b8a2000-3b8ee000 [304K] rw- / rwx SM = PRV DefaultMallocZone_0x4816000
…
Вторая сложность заключается в том, что таких сегментов памяти, как в примере выше, может быть очень много. Например, в моем случае их было более двух с половиной тысяч, поэтому вручную просканировать их все не получится.
С точки зрения задачи и имеющихся сложностей GDB идеален: он скриптуется. Это означает, что его можно запускать в пакетном режиме и скармливать ему списки команд или из файла или из командной строки.
Вообще, с помощью GDB делаются две вещи: поиск адреса(ов), и запись нужного значения по заданному адресу. Поиск адресов нужного значения делается в GDB командой find (сюрприз!). Для одного из приведенных выше диапазонов и значение 100 команда будет выглядеть так: find / w 0x3b800000, 0x3b84c000 100. Если нужной нам адресу окажется 0x3b800004, то командой записи значения 200 в этот адрес будет: set {int} 0x3b800000 = 200.
В теории все прозрачно. Но уже на попытке присоединиться к процессу у меня возник очередной облом: GDB получал в лоб segfault'ом и падал в корку. Проверил права: id эффективного пользователя для дебаггера и игры совпадают — мои. Попробовал присоединиться к top'у, запущенному в соседнем шелле — получилось только от рута. Присоединиться к процесу XCOM, даже от рута — не получается, segfault…
Дальнейшее разбирательство прояснило две вещи:
- GDB, который идет в комплекте с XCode, очень старый
- Система безопасности процессов в OS X на голову выше, чем в Microsoft Windows Vista и Windows 7 не потому, что «оно там внутри UNIX», а «Винда мастдай».
Лирическое отступление: различные вредоносные программы пытаются или вовсе не иметь собственного отдельного процесса, или маскироваться под системный, или прятать свой процесс. Первые два подхода сводятся к возможности «запрыгнуть» в процесс честной программы и дальше творить черные дела от ее доброго имени. Третий обычно требует «запрыгивание» в ядро ??операционной системы. Так вот, в OS X даже присоединиться к соседнему процессу, запущенному с моими-же правами, у меня получилось только после прочтения статьи, в которой этот процесс подробно расписан. Вкратце, при вызове определенных API ядро сначала убеждается, что код, сделавший этот вызов, подписан надлежащим сертификатом. А потому, для того чтобы наш подход заработал, необходимо:
- создать локальный самоподписанный сертификат для подписи кода с максимальным уровнем доверия;
- поставить новый GDB;
- подписать запускаемый файл gdb свежесозданным сертификатом.
В случае, если-бы мне захотелось уйти от использования gdb и писать в адресное пространство XCOM'а из своего процеса, то мне понадобился-бы дополнительный Info.plist, который нужно вкомпилировать в исполняемый файл. За подробным описанием подхода отправляю к статье, из которой я всю эту механику и подчерпнул. Еще одна годная статья, в которой хорошо прописана механика подписи кода и нарезки прав процессу, лежит прямо на Хабре.
После всех этих танцевальных па GDB наконец смог присоединиться к процессу игры и я смог протестировать поиск вручную. Поскольку данных было очень много (списки даже из нескольких десятков адресов могут сильно утомить, если сравнивать их глазами), то поверх vmmap и GDB была написана обвязка, которая автоматизировала процесс поиска и правки значений в памяти.
До сих пор не уверен, от чего было получено больше удовлетворения: от игры в старый добрый Laser Squad или от процесса превращения в него XCOM.
Комментарии (19)
dshinin
15.04.2015 13:42+1Тогда она была во всех смыслах проще
Не согласен. Геймплей у тактической части нового XCOM'а значительно проще, чем в Laser Squad, не говоря уже про оригинальные игры серии XCOM.
seyfer
15.04.2015 14:22+3О чем статья? Какого результата добился автор?
Я ничего не понялGorthauer87
15.04.2015 15:36А что мешает взять lldb и наваять скрипт на питоне? К тому же lldb уже надлежащим образом подписан.
lolmaus
15.04.2015 18:57+1Эх, из вступительного текста я решил, что статья о том, как взять игровую механику из LaserSquad и натянуть на нее графический движок от XCOM: Enemy Unknown.
А тут всего лишь ковыряние в сэйвах. :(
PS Плюсанул.
Adnako
15.04.2015 22:47Эх, было время!
Незаметно пролетавшие часы копания в оперативке загруженной игры сторицей окупились найденным блоком ресурсов где закапывали оружие и патроны, не изменяя поверхностного вида почвы. При старте игры с другом на все деньги закупались броники, а снайперки, гранаты и рпг выкапывались по известным координатам.
Было круто.
crmMaster
Artmoney разве не то что вам было нужно изначально?
Newbilius
Artmoney вроде же только под Windows?
fsmorygo
Посмотрите на The Cheat и iHaxGamez
crmMaster
Открою секрет — Boot Camp, и многие игры станут идти даже лучше чем на макосе.
Все-так кто бы что не говорил, никсы на данные момент значительно уступают винде по скорости работы с играми
4umak
> Все-так кто бы что не говорил, никсы на данные момент значительно уступают винде по скорости работы с играми
потому что грязные хаки с видеодрайверами и ленивые программисты, не желающие заниматься оптимизацией портов?:)
crmMaster
Тут скорее нежелание некоторых производителей железа делиться кодом драйверов и попыткой спрятать компетенцию некоторых программистов под словами «проприетарные драйвера»
Поддерживали бы opensource сообщество, проблем бы не было подобных, давно бы уже запилили оптимизированные и функциональные драйвера.
Adnako
blogs.valvesoftware.com/linux/faster-zombies
Подумаешь, какой-то вальв тим что-то сказал.
icCE
Нет. Artmoney был и под DOS. По крайне мере первые версии.
Под DOS были и другие программы, только вот сейчас название не вспомню.
zbroyar Автор
Во-первых, я не знаю, что это такое. А во-вторых artmoney наверняка не дает столько-же удовольствия от процесса, сколько gdb :-)