image

Вот так теперь выглядит игра Laser Squad, которую я увидел очень давно. Тогда она была во всех смыслах проще и выглядела так:

image

При этом принципиально игра не изменилась. Просто стала сложнее: куча типов ресурсов, множество вариантов их применения плюс «инфляция»: каждая следующая мастерская, лаборатория или спутниковый канал стоят больше, чем предыдущие. С одной стороны, это все дает возможность играть разными стратегиями развития, но иногда так хочется поиграть просто в Laser Squad! Поэтому…

Поэтому я пошел на App Store и за каких-то 29$ купил XCOM. Метода хака ресурсов в играх не изменился с момента появления Первого Сейва: сохраняемся, меняем количество целевого ресурса, сохраняемся еще раз, запускаем hex-редактор, находим место, в котором первое контрольное значение изменилось на второе контрольное значение, пишем туда знаковое целое (что-то типа 0x7FFF) — и наслаждаемся резко упрощенным геймплеем.

Но тут меня ждал облом. Даже два: во-первых, последовательно сохраненные файлы отличались размером. Во-вторых, в той части файла, которая относилась к условному заголовку, соответствующие значения были, но их изменение приводило к тому, что XCOM жаловался на битые файлы: очевидно, в формате предусмотрены какие-то контрольные суммы, которые не совпадают после такого грубого внесения изменений.

Ну что-же. Значит, время взять в руки дебаггер: не получается править файлы, то будем править сразу память. Здесь метода немного другая:

  1. запустили игру;
  2. прицепились отладчиком;
  3. посмотрели количество целевого ресурса;
  4. нашли в памяти процесса множество адресов с этим значением и сохранили;
  5. поменяли количество целевого ресурса;
  6. нашли в памяти новое множество адресов и пересекли (set intersection) с предыдущим;
  7. повторили пп. 5 и 6 пока не остался один-единственный адрес;
  8. записали в этот адрес желаемое количество целевого ресурса.

Но здесь есть сложности. Первая в том, что в общем случае виртуальная память процесса во всех современных ОС не является непрерывной, а перебирать все пространство возможных адресов — слишком долго. К счастью, в 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 ядро сначала убеждается, что код, сделавший этот вызов, подписан надлежащим сертификатом. А потому, для того чтобы наш подход заработал, необходимо:

  1. создать локальный самоподписанный сертификат для подписи кода с максимальным уровнем доверия;
  2. поставить новый GDB;
  3. подписать запускаемый файл gdb свежесозданным сертификатом.


В случае, если-бы мне захотелось уйти от использования gdb и писать в адресное пространство XCOM'а из своего процеса, то мне понадобился-бы дополнительный Info.plist, который нужно вкомпилировать в исполняемый файл. За подробным описанием подхода отправляю к статье, из которой я всю эту механику и подчерпнул. Еще одна годная статья, в которой хорошо прописана механика подписи кода и нарезки прав процессу, лежит прямо на Хабре.

После всех этих танцевальных па GDB наконец смог присоединиться к процессу игры и я смог протестировать поиск вручную. Поскольку данных было очень много (списки даже из нескольких десятков адресов могут сильно утомить, если сравнивать их глазами), то поверх vmmap и GDB была написана обвязка, которая автоматизировала процесс поиска и правки значений в памяти.

До сих пор не уверен, от чего было получено больше удовлетворения: от игры в старый добрый Laser Squad или от процесса превращения в него XCOM.

Комментарии (19)


  1. crmMaster
    15.04.2015 12:37

    Artmoney разве не то что вам было нужно изначально?


    1. Newbilius
      15.04.2015 13:07

      Artmoney вроде же только под Windows?


      1. fsmorygo
        15.04.2015 13:11
        +1

        Посмотрите на The Cheat и iHaxGamez


      1. crmMaster
        15.04.2015 14:04

        Открою секрет — Boot Camp, и многие игры станут идти даже лучше чем на макосе.

        Все-так кто бы что не говорил, никсы на данные момент значительно уступают винде по скорости работы с играми


        1. 4umak
          15.04.2015 14:20
          +2

          > Все-так кто бы что не говорил, никсы на данные момент значительно уступают винде по скорости работы с играми

          потому что грязные хаки с видеодрайверами и ленивые программисты, не желающие заниматься оптимизацией портов?:)


          1. crmMaster
            15.04.2015 15:56
            -1

            Тут скорее нежелание некоторых производителей железа делиться кодом драйверов и попыткой спрятать компетенцию некоторых программистов под словами «проприетарные драйвера»

            Поддерживали бы opensource сообщество, проблем бы не было подобных, давно бы уже запилили оптимизированные и функциональные драйвера.


        1. Adnako
          15.04.2015 22:52
          +1

          blogs.valvesoftware.com/linux/faster-zombies

          After this work, Left 4 Dead 2 is running at 315 FPS on Linux. That the Linux version runs faster than the Windows version (270.6) seems a little counter-intuitive, given the greater amount of time we have spent on the Windows version. However, it does speak to the underlying efficiency of the kernel and OpenGL. Interestingly, in the process of working with hardware vendors we also sped up the OpenGL implementation on Windows. Left 4 Dead 2 is now running at 303.4 FPS with that configuration.


          Подумаешь, какой-то вальв тим что-то сказал.


      1. icCE
        15.04.2015 14:39

        Нет. Artmoney был и под DOS. По крайне мере первые версии.
        Под DOS были и другие программы, только вот сейчас название не вспомню.


    1. zbroyar Автор
      15.04.2015 21:23

      Во-первых, я не знаю, что это такое. А во-вторых artmoney наверняка не дает столько-же удовольствия от процесса, сколько gdb :-)


  1. Newbilius
    15.04.2015 13:08
    +5

    Хоть бы объяснили, что вы хотели получить… сделать из игры жанра «стратегия+пошаговая тактика» игру «пошаговая тактика без стратегии»?


    1. zbroyar Автор
      15.04.2015 21:21

      Именно.


  1. dshinin
    15.04.2015 13:42
    +1

    Тогда она была во всех смыслах проще
    Не согласен. Геймплей у тактической части нового XCOM'а значительно проще, чем в Laser Squad, не говоря уже про оригинальные игры серии XCOM.


  1. lorc
    15.04.2015 13:47
    +3

    Ммм, статья о том как запустить gdb в MacOS X?


    1. zbroyar Автор
      15.04.2015 21:20

      Не совсем, скорее о том, как с его помощью получить удовольствие :-)


  1. seyfer
    15.04.2015 14:22
    +3

    О чем статья? Какого результата добился автор?

    Я ничего не понял
    image


  1. Gorthauer87
    15.04.2015 15:36

    А что мешает взять lldb и наваять скрипт на питоне? К тому же lldb уже надлежащим образом подписан.


  1. lolmaus
    15.04.2015 18:57
    +1

    Эх, из вступительного текста я решил, что статья о том, как взять игровую механику из LaserSquad и натянуть на нее графический движок от XCOM: Enemy Unknown.

    А тут всего лишь ковыряние в сэйвах. :(

    PS Плюсанул.


    1. zbroyar Автор
      15.04.2015 21:03
      +1

      К сожалению, это за пределами моей компетенции :-)


  1. Adnako
    15.04.2015 22:47

    Эх, было время!
    Незаметно пролетавшие часы копания в оперативке загруженной игры сторицей окупились найденным блоком ресурсов где закапывали оружие и патроны, не изменяя поверхностного вида почвы. При старте игры с другом на все деньги закупались броники, а снайперки, гранаты и рпг выкапывались по известным координатам.
    Было круто.