Как попасть в файлы игры?
Такой подход упрощает установку игр и программ, но усложняет поиск apk или папки с приложением для удаления остаточных файлов. Какая папка .
Как зайти в файл игры?
Порядок действийЗайдите в раздел «Библиотека» и найдите в списке нужную вам игру.Щёлкните на игре правой кнопкой мыши и выберите «Свойства».В открывшемся окошке перейдите на вкладку «Локальные файлы»На указанной вкладке нажмите на кнопку «Просмотреть локальные файлы».Откроется папка с файлами игры.
Где хранятся файлы игр стим?
2.2 Далее в папке steamapps, вам нужно перейти в папку «common». 3. Когда вы откроете папку common, то вы увидите все установленные игры от стим, вот именно в эту папку устанавливаются все игры от стим.
Программы для распаковки игр
Программы для распаковки игр, речь о которых пойдет в данной статье, рекомендуется использовать в тех случаях, когда требуется извлечь игровые ресурсы, доступ к которым не получается организовать через “Проводник”. В случае, если файлы для установки игры или другой программы находятся в RAR или ISO архиве, то рассматриваемые программы вам не подойдут.

Какие есть программы для распаковки игр
Рассматриваемые программы поддерживают специальные скрипты и алгоритмы поиска, благодаря чему они способны обнаружить и корректно извлечь даже элементы, не отображающиеся при обычном просмотре. В рамках статьи рассмотрим 5 наиболее подходящих для нашей задачи программ.
Программа 1: MultiEx Commander
Данное решение совместимо с тысячами разных игр и некоторыми прикладными программами. С помощью этой программы можно не только найти “нужные” файлы, но и ознакомиться с их содержимым. Благодаря данной особенности пользователь может просмотреть все, что находится внутри объемных объектов и извлечь их для дальнейшего использования или редактирования.

Взаимодействие с искомыми объектами производится с помощью удобного графического интерфейса. Пользователю совершенно необязательно прописывать команды и скрипты. Просмотр содержимого найденных файлов возможно с помощью встроенного в приложение “Проводника”. С его же помощью производится извлечение требуемых данных.
Дополнительно расширить возможности MultiEx Commander можно через добавление EasyMod. С его помощью можно быстро интегрировать моды и различные дополнения в игровые ресурсы пользователя. Программа позволяет не только получать игровые файлы, но и заменять их, плюс, сразу же просматривать влияние изменений на игровой процесс.
Если у вас возникают сложности при использовании MultiEx Commander, то можно ознакомиться с технической документацией на сайте разработчика, а также видеоуроками. Они имеются в том числе и на русском языке.
Программа 2: Game Extractor
Имеет схожие возможности с предыдущей программой, но правда, со своими особенностями. Они касаются списка поддерживаемых игр и возможности редактирования их содержимого. Извлекаемые из каталогов игры ресурсы доступны для редактирования, а это значит, что вы можете вносить необходимые правки в работу игры, а возможно и делать некоторые расширения с помощью сторонних модификаций. Данный функционал подойдет для любителей разных модификаций, особенно, если вы хотели бы себя попробовать в роли мододела. Правда, рассмотренный функционал доступен только для тех игр, в которых не требуется постоянное соединение с интернетом.

Из дополнительных возможностей Game Extractor можно отметить наличие встроенного конвертера для изображений, использующихся в игре. Картинки, использующиеся в играх, имеют собственное расширение, не стандартные JPG и PNG, следовательно, открыть их для просмотра и редактирования в большинстве редакторов не представляется возможным.
Программа распространяется на условно-бесплатной основе, поэтому некоторый функционал, рассмотренный нами становится доступным только после приобретения полноценной подписки. На момент написания статьи платная подписка стоит около 10 долларов. Такой функционал, как просмотр и редактирование внутриигровых изображений разблокирован только после приобретения платной подписки.
Программа 3: Dragon UnPACKer
Программа позволяет просматривать корневые файлы выбранной игры в удобном графическом режиме. Внешне ее интерфейс похож на обычный “Проводник”, который присутствует в Windows. Встроенное средство предпросмотра корректно работает с большинством основных шаблонов. Программа официально поддерживает более 200 игр и этот перечень постоянно растет. Однако, если вашей игры нет в этом перечне, то это не значит, что она точно не будет поддерживаться. Возможно, что просто не были проведены соответствующие тесты.
С помощью Dragon UnPACKer удобно извлекать медиа-контент из игр — видео, музыку, картинки, текстуры, звуки, 3D-модели и некоторые другие составляющие. Если имеющегося в программе функционала вам будет недостаточно, то его можно расширить за счет дополнительных подключаемых модулей (плагинов). Всего их три:
- Driver plugins. Позволяет программе напрямую открывать игровые файлы для просмотра, плюс, увеличивает перечень поддерживаемых расширений.
- Convert plugins. Позволяет конвертировать форматы внутриигровых файлов в более популярные аналоги. Это может быть необходимо, например, для преобразования текстур, если у вас не получается открыть их и обработать в графическом редакторе. Обычно текстуры игр хранятся в RAW-формате и с ним умеет работать Photoshop и GIMP, но бывают и более экзотические форматы.
- HyperRipper plugins. Является расширенной версией первого плагина. Позволяет открывать программе наименее известные форматы игровых файлов, например, файлов в старых играх.

Dragon UnPACKer распространяется бесплатно в виде версии, которой требуется установка, а также портативной, которой установка не требуется. Также на официальной странице разработчиков предоставлен исходный код программы. Он может быть полезен для разработчиков игр, а также любителей мододелов. Дополнительно на сайте разработчика находятся файлы для локализации программы, в том числе и на русский язык.
Программа 4: Game File Explorer
Это решение больше подойдет любителям старых игр, так как новинки оно поддерживает с трудом. Функционал в целом похож на предыдущие решения, так как он нацелен на просмотр и редактирование содержимого исходных файлов. Примечательно, что поддержка Game File Explorer давно прекращена и корректно она работает только на Windows 95, 98 и XP. Ее можно установить и на более поздние версии ОС, даже на “десятку”, проблем с этим не будет. Однако извлечь содержимое игр, которые не разрабатывались для Windows 95 или XP у вас вряд ли корректно получится.

Программа 5: QuickBMS/QuickBMS GUI
У этой программы есть особенность — вы можете выбрать интерфейс, с которым будете работать. Например, допускается запуск не только стандартного графического интерфейса, но и текстового в виде консоли. Более профессиональным разработчикам может быть удобно работать как раз в текстовом интерфейсе, так как некоторые операции там будут выполняться быстрее. Примечательно, что сама по себе QuickBMS/QuickBMS GUI не является средством распаковки игровых файлов, а служит лишь для запуска, исполнения и отладки BMS-скриптов. Однако расширить функционал программы можно за счет дополнительных плагинов, разработанных энтузиастами.

Из-за своих особенностей QuickBMS/QuickBMS GUI вряд ли подойдет начинающим пользователям, так как ее потребуется настроить, а это требует наличие определенных навыков. Однако тем, кто уже разбирается в подобных программах или готов потратить время на то, чтобы разобраться мы можем рекомендовать ознакомиться с ней. Те, кто увлекаются программированием могут также расширить функционал как самой программы, так и некоторых игр за счет скриптов в BMS-формате.
С помощью этих 5 программы вы сможете не только извлечь и просмотреть внутриигровые файлы, но и расширить игры за счет возможность редактировать их файлы и встраивать посторонние. Однако для работы с данными программами потребуется наличие хотя бы каких-нибудь умений и навыков.
Как у меня получилось взломать и распаковать ресурсы старой игры для PSX
«Вот бы распаковать эти игровые архивы и посмотреть что там внутри!», — наверное думал про себя, хотя бы раз, каждый геймер, который хотел понять, как устроена его любимая игра.
К счастью, сегодня большинство разработчиков не только не препятствуют изучению своих игр, но даже наоборот, делают всё, для того, чтобы игроки изменяли и дополняли игры сами. Но даже если официальной документации нет, то для 99% игр можно найти уже готовые программы для распаковки.
Я решил написать эту статью для того чтобы показать, что даже если вы столкнулись с очень редкой, старой или никому не нужной игрой, архивы которой не берет ни один «распаковщик», то даже с минимальными знаниями какого-нибудь языка программирования, вполне возможно вам удастся справится самому и стать первым, кто сможет распотрошить эту игру до косточек.
Так как само по себе, описание устройства игровых архивов вряд ли принесет какую-нибудь пользу, я опишу весь путь, который я проделал в ходе изучения игровых архивов, ход своих мыслей, а также ошибки, которые привели меня в тупики.
Завязка
Все началось с того, что будучи в детстве фанатом игр «SquareSoft», и маясь от безделья 1-го января, я заинтересовался информацией о ранних прототипах Final Fantasy и с удивлением узнал что у японской версии Final Fantasy VII для PlayStation был «бонусный» диск со всякими доп-материалами, и в том числе скетчами и скриншотами игры на ранних этапах разработки.
Немедленно скачав его образ с «торрентов» и запустив на эмуляторе я с некоторым разочарованием обнаружил, что во-первых диск жутко тормозит в эмуляторе(несмотря на новое железо), а во-вторых весь интерфейс на японском и черт ногу сломит в нем копаться через это меню.

Тут у меня и появилась идея, распотрошить диск и изучить его контент напрямую, а не использовать предложенный разработчиками интерфейс.
Первичный investigation
Первым делом я решил изучить какие файлы вообще содержаться на диске.
Первое что бросилось в глаза — расширение файлов NPK и LPK, что косвенно указывало на то, что это архивы.
Поэтому одной из первых идей, которая пришла мне в голову, было воспользоваться всевозможными универсальными анализаторами и распаковщиками. Я скачал все что смог найти для PSX и на всякий случай, даже Dragon UnPACKer, для ПК.
Но улов был незначительным, файлы в папке STR оказались видеороликами в стандартном для PSX формате STR, а три файла в папке S1G, оказались картинками, в опять таки стандартном, как мне позже удалось нагуглить, для «соньки» формате TIM. только с другим расширением.
Архивы NPK и LPK, которые, как я предполагал, содержали основной контент диска, так и не удалось взять ни одной программе, в том числе, софту ориентированному на «Final Fantasy VII».
Пришло время чуть усерднее поискать хоть какую-то информацию об этих NPK архивах, так как, скорее всего, я не первый, кто за них взялся, и хоть какое-то упоминание найтись было должно.
Результат оказался весьма занятным, пробуя и так и сяк составлять запросы и продираясь через кучи поискового мусора, я смог найти только два упоминания этих архивов в контексте это диска.

Причем оба упоминания были на одном и том же форуме, относившемся к, находящемуся в дауне, на момент написания этой статьи, сайту, посвященному софту для моддинга к играм серии FF.
Один из тредов был праздным обсуждением на тему «ах как хорошо было бы выдрать модельки» с кучей заглушек вместо скриншотов, которые были давно удалены хостером.
А вот второй тред, относящийся к 2005 году дал очень хорошие зацепки. В нем какой-то юзер предложил челендж(ох «люблю» я таких халявщиков, которые хотят всё чужим трудом заполучить) взломать этот самый диск, дабы выдрать из него ресурсы.
Qhimm(владелец форума и автор многих программ распаковщиков для FF) подорвался было изучать эти архивы, но закончилось все несколько внезапно…
Оказалось, что еще один разработчик софта для потрошения ресурсов PSX(snailrush) уже сделал утилиту для распаковки этих архивов. Казалось бы «Ура», переходим по ссылке и качаем утилиту, но если бы все было так хорошо, то этой статьи бы не было. В общем, ссылка была мертвой, и не помог даже archive.org. Сайт snailrush’а ушел в многолетний down практически через несколько дней после того, как он сделал эту чертову утилиту, и никаких снапшотов той страницы не сохранилось.

Таким образом, у меня был только пост Qhimm’а(который уже много лет не появлялся на своем форуме), о том, что ему удалось разобраться в устройстве этих архивов. А это значило, что ничего особо сложного в них не должно было быть.
Начинаем копать самостоятельно
Пришло время открыть файлы в HEX-редакторе. Сразу бросились в глаза какие-то числа в самом начале, которые указывали на то, что у файла есть что-то типа заголовка.
Тут я хотел бы сделать небольшое отступление. Не смотря на то, что в самом начале я сказал, что особых знаний для копания в ресурсах не нужно. Есть одно «небольшое» исключение. Нужно иметь хотя бы базовое представление о том, как именно в памяти или на диске могут хранится какие-нибудь данные, в самом простом виде — числа. Другими словами нужно знать что такое Big Endian и Little Endian.
Я попробую объяснить суть максимально кратко:
Очень часто числа или символы хранятся в памяти в обратном порядке. Например число «16830», которое в HEX выглядит как «41 BE», а будучи переменной типа int как «00 00 41 BE» в самой памяти может хранится как «BE 41 00 00», не буду объяснять почему так(вы можете погуглить сами), скажу просто что «компьютеру так удобнее». И соответственно, таким же образом, в обратном порядке, данные могут хранится в файле на диске.
Причем на первый взгляд, почти все файлы, независимо от расширения и LPK и ТЗЛ и FFD, имели очень схожую структуру в самом начале.
Несколько чисел типа int или short, потом последовательность «DF 10 00 00 00 09», потом уже какая-то мешанина байт, который были по всей видимостью данными.


Так как первые числа у всех файлов были разные, я предположил, что это скорее всего какие-то смещения или размеры внутренних блоков.
Для более подробного изучения я решил сконцентрироваться на одном файле и выбрал NPK_WEP.NPK, так как из треда было ясно что во-первых именно его удалось распаковать, а во-вторых было известно, что в нем хранятся картинки в формате TIM.
Настало время поближе присмотреться к формату TIM который я и собирался искать внутри.
К счастью на данный момент TIM хорошо документирован, в том числе потому что утекла официальная документация сони.
И сразу хорошие новости, у TIM есть стандартный заголовок «10 00 00 00

Открываю заодно в HEX тем 3 файла, который уже были у меня в наличии в открытом виде.

Вау, тут во всех них „10 00 00 00 09“ в самом начале, прямо как в моем архиве.
Кажется это не может быть совпадением, вот оно! Tim файл прямо внутри, но почему его тогда не обнаружили автоматические анализаторы? и почему сразу после „10 00 00 00 09“ мешанина?
Пробую искать „10 00 00 00 09“ по файлу и обнаруживаю 127 совпадений. Более того все места с „10 00 00 00 09“ похожи друг на друга.
Вот например второе место в NPK_WEP.NPK где обнаружилась последовательность „10 00 00 00 09“:

После кучи нолей, я увидел точно такую же структуру как и в самом начале файла.
Так, теперь можно сделать кое-какие предварительные предположения и выводы:
- Если „10 00 00 00 09“ — действительно сигнатура говорящая о начале TIM файлы, то таких файлов в архиве 127, что в общем-то логично и похоже на правду.
- Архив NPK_WEP.NPK как таковой собственных заголовков(которые бы описывали именно его структуру) не имеет и скорее всего является нагромождением как-то структурированных данных.
- TIM файлы(если это все же они) в архиве как-то сжаты, так как данные после заголовка „10 00 00 00 09“ на реальные файлы ну никак не похожи.
Самым первым числом было:
37 00 00 00 > 00 00 00 37(HEX) > 55(DEC) Не похоже чтобы это было смещением, так как смещение 37 находится уже внутри того, что я пока считают сжатыми данными, так что пропустим его.
Второе число было short F7 03 > 03 F7(HEX) > 1015 (DEC)
Третье тоже short F6 04 > 04 F6(HEX) > 1270 (DEC)
Вот эти два уже похожи на смещения, попробуем найти что-то в районе этих мест.

И бинго! Походу именно тут кончается блок данных, так как начиная с этого места идут нули.
А что тут строкой ниже? 36 00 00 00 FD 03 2F 08 — Не похоже на сжатые данные, зато очень похоже на такой же заголовок как и в начале.
Тогда чем было третье смещение? так как оно указывает на середину следующего блока, я пока что предположу, что это размер данных после распаковки.
Зато теперь появляется предположение, что означало самое первое число 37(HEX) или 55(DEC)
По всей видимости, -это количество суб-блоков до конца запакованного файла, у каждого следующего блока оно будет уменьшаться на 1. Проверка подтвердила это предположение.
Одно только осталось непонятным, если у нас есть смещения, говорящие о длине блока, то почему бы не начинать следующий блок сразу после конца предыдущего, зачем вся эта куча нолей? К тому, на начало второго блока 0х0400 ничего не указывает, как тогда понять, где начинается следующий блок? С другой стороны 0400 уж очень подозрительное смещение, слишком ровное. Интересно сколько это в DEC?

Ух ты! ровно 1024, вряд ли это совпадение. посмотрим что у нас через еще 1024 байта по смещению 0х800:

Теперь все ясно, размер каждого суб-блока — 1 килобайт.
Итак, структура NPK_WEP.NPK практически полностью расшифрована.
Весь файл разбит на блоки по 1024 байта.
Первые 4 байта каждого блока — число суб-блоков до конца одного содержащегося в архиве файла.
Следующие 2 байта — смещение от начала суб-блока до конца полезных данных
Еще два байта — скорее всего размер данных после распаковки(видимо для выделения места под них в памяти).
Вроде похоже на правду, осталось только понять, чем сжаты или зашифрованы сами данные.
Разбираемся с сжатием
До этого я никогда не сталкивался с сжатием или шифрованием и не имел вообще никакого ни представления, ни опыта.
Поэтому я стал искать информацию сразу в двух направлениях:
Во-первых, как на глаз понять какое сжатие используется в файле, если это неизвестно.
И во-вторых, какое сжатие используется чаще всего для PlayStation в целом, или для игр SquareSoft и серии FF в частности. Зацепкой было то, что Qhimm довольно быстро разобрался с файлом, значит это было что-то знакомое для него.
Начав с общего поиска „как на глаз определить чем сжат файл“, самое полезное что я обнаружил — это вот этот список:
zenhax.com/viewtopic.php?t=27, в котором глаз зацепился за
что в общем-то походило на то, что было у меня.
А во-вторых можно было исключить сразу всякие zip-related и прочие методы имеющие какие-то стандартные заголовки, так как ничего похожего на заголовок у сжатых данных не наблюдалось.
Поиск по сжатию используемому в Final Fantasy VII привел на упавший сайт wiki.qhimm.com, снапшоты которого к счастью были доступны через Wayback Machine.
Там говорилось что в FF VII к примеру используется два типа сжатия GZIP и LZS (какой-то специфический подвид LZSS). GZip я сразу отмел, так как у него должен был быть хидер, а вот на LZSS я решил остановится поподробнее, так как все указывало на него.
Но тут я совершил, можно сказать ошибку и полез в »википедию»(при редактировании статьи заметил, что это не википедия, а другой вики-сайт ) читать про LZSS. А проблема была в том, что одно дело — принцип сжатия 80х описанный в учебнике, а другое — его конкретное реализация. Я совсем не учел, что сохраняя принцип сжатия, реализовать его можно кучей разных способов, но в учебниках и в том числе в большинстве статей где оно описывается в интернете, оно описано следующим способом: читается 1 бит, если это 0, то читаются следующие 8 бит и заносятся как есть в буфер (вывод), а если это 1, то читаются следующие 7 бит, часть из которых офсет в буфере, а часть длина данных, которые нужно считать из буфера и занести в вывод.
Т.е. как бы все понятно и логично, но ни черта не похоже на то, что есть у меня, и уж тем более не соотносится с идеей, что начало данных должно выглядеть так, как будто они «не сжаты». (Ну просто потому, что при такой реализации все данные выглядели бы как каша, так как первый байт содержал бы 1 сигнальный бит и 7 бит несжатых данных, 8-ой бит которых был бы первым битом второго байта.)
Я не сразу понял, что конкретная реализация алгоритма очень сильно зависит от размера буфера, и то, что описано в учебниках, подходит для буфера ничтожно малой длины.
В общем, потеряв впустую несколько часов на попытки сложить 2+2, я решил зайти с другой стороны и поискать какие-нить реализации «в коде» сжатия используемого именно в FF VII.
И сразу наткнулся на github.com/cebix/ff7tools — набор утилит на питоне для перевода ff7, в состав которых входили lzss и unlzss. Для проверки я решил натравить lzss на один из имеющихся у меня tim файлов. Получилось как-то так:

На первый взгляд — ничего хорошего, но я уцепился за 09 и последовательность за ней, которая уж больно напоминала то, как выглядели мои файлы в архивах. Тут я уже практически полностью уверился, что картинки сжаты какой-то из реализаций LZSS, осталось только разобраться какой именно.
Для этого я вернулся на wiki.qhimm.com и решил повнимательнее прочитать про «этот их LZS».
После внимательного прочтения и пере-прочтения — пазл сложился! БИНГО!
Формат устроен следующим образом:
Вся дата разбита на блоки, длина которых может варьироваться от 9 байт до 17 байт.
Первый байт блока указывает на то, чем будут все остальные байты блока. Закодировано это на уровне бит. 1 — значит что байт отправляется как есть в буфер и на вывод. 0 — означает что нужно прочитать 2 байта и они будут ссылкой на буфер. Причем чтение бит идет с конца.
Таким образом, если первый байт блока — FF, (11111111)- это значит, что следующие 8 байт нужно просто прочитать как есть и записать в вывод(буфер).
А, ставший для меня уже родным, байт DF, стоящий перед 10 00 00 00 09, в битовом виде выглядит как 11011111, что означает, что 5 идущих за ним байт нужно прочитать как есть(те самые 10 00 00 00 09), потом идет 2х-байтная ссылка(EF F0), и опять 2 байта нужно прочитать как есть (0C 02).
Дальше уже интереснее. Формат ссылки сильно зависит от размера буфера. В данной реализации буфер равен 4 килобайтам, а ссылка в битах выглядит следующим образом(опять гребаные биты, ненавижу уже их!)
OOOO OOOO OOOO LLLL (O = Offset, L = Length)
Ну или можно без бит, тогда так OO OL(на уровне байтов), причем первые 4 бита второго байта — это первый байт офсета, потому что читать опять нужно с конца. Но и это не все, к длине нужно прибавить три, просто такой вот хардкод. Потому что длины 0, 1 и 2 не имеют смысла, так как в таком случае ссылка будет занимать больше места чем считанные по ней данные. Так что 0 — это 3, 1 — это 4, и тд…
Понимаю что понять сложно, поэтому объясню на реальном примере:
Байт DF говорит нам о том, что 6-й и 7-й байт за ним — это офсет, у нас это EF F0.
Отсекаем последние 4 бита(длина) и переворачиваем, получаем 0хFEF — офсет в буфере, а оставшийся 0+3 = 3 — длина.
Таким образом, ссылка говорит нам прочитать 3 байта по офсету 0хFEF из буфера. Если вы проскролите выше и посмотрите как выглядит нормальный TIM файл, то там сразу после 09 — три нулевых байта, вот именно они и копируются из буфера.(по видимому это те 3 нулевых байта, которые были туда, буквально «только что», записаны предыдущими действиями).
Так же, в той статье, была описана сложная формула по вычислению реального офсета, по которому нужно читать из буфера. Объяснялось это тем что автор предполагал для записи и чтения использовать обычные потоки ввода-вывода, а формат сжатия подразумевал использование кольцевого буфера, и нужно было как-то хитро преобразовывать офсет.
Но я был отважен, и решил что «ну его нафиг», лучше я реализуют у себя кольцевой буфер, чем буду разбираться в этих странных формулах. Конечно я пожалел, но в тоже время, когда стал разбираться почему оно «не работает», нашел куда более красивое решение, чем автор той статьи.
Кроме того, в статье писалось о двух «фишках», которые нужно иметь ввиду, ссылки на буфер могут идти как в прошлое так и в будущее, обойти это предлагалось всякими хаками.
Как я потом выяснил при правильной реализации буфера, никакие «хаки» не нужны.
Пишем Код
Ну, а пока что, я расчехлил Eclipse(писать решил в JAVA, так как мне так удобнее)
Сначала надо определится с тем как реализовать кольцевой буфер. Дело в том что мне сразу было понятно, что реализовать его можно очень разными способами, так что я решил просто попытать счастье и выбрал подобную реализацию из более менее стандартной библиотеки CircularFifoQueue из apache.commons.collections. Это был FIFO буфер позволяющий читать по офсету внутри себя. Другие реализации из коробки чаще всего по офсету читать не позволяли.
В итоге код получился примерно такой(я выкинул всякий мусор для упрощения чтения и сокращения):
Описать его работу можно следующим образом:
1) Файл нарезается на куски по 1024 байта,
2) Для каждого считывается int, short, short
3) Остаток передается в цикл с распаковщиком(readLZSBlock)
4) Он читает первый байт, выясняет что делать с остальными, и либо записывает их как есть, либо, если это ссылка, то отдает его в обработчик ссылок на буфер(getFromCBuffer), который читает из буфера.
5) Когда один файл внутри архива прочтен — он сливается на диск
Результат выполнения был такой:

С одной стороны это хорошо, видны очертания меча, да и файл открылся во вьювере. С другой стороны очевидно, что буфер ничерта не работает, можно догадаться, что все данные которые читались из него — мусор, причем видно, как сначала мусором были нули и верх файла почти белый, а потом, по мере того, как буфер наполнялся, мусор стал цветным. При этом видны очертания меча, что радует.
Я не сильно расстроился, так как ожидал, что буфер придется допиливать. На всякий случай прогнал через программу все остальные архивы на диске и с удивлением обнаружил, что первый файл в архиве NPK_WEP.NPK был единственным который открылся в просмоторщике tim файлов. Так что мне очень повезло, что я начал именно с него.
Следующим шагом стала попытка понять, где именно произошел сбой. Для этого, я, вооружившись описанием формата TIM, вручную в HEX-редакторе начал проходить по своему файлу. Надежда была на то, что сбой обнаружится уже в заголовке и я смогу узнать какое именно значение должно было быть, а какое на самом деле записалось, и зная состояния буфера, внести какую-то коррекцию.
Заметная ошибка обнаружилась по офсету 0х214. в нормальном TIM файле там должен был int соответствующий размеру данных в нем, причем учитывая, что файлы TIM не сжаты по умолчанию и размер зависит от разрешения, а разрешение в свою очередь у картинок растянутых на весь экран телевизора у playstation — одно и тоже, я даже наверняка знал, какое именно число там должно быть.
Вот пример нормального файла:

Размер данных 00 01 E0 0C.

вместо нормального числа у меня там какой-то мусор.
Теперь изменив немного код, я получил данные относящиеся к обработке данного места.
Офсет считанный из файла был 4092, длина — 3 байта.
Вот как выглядел мой буфер в момент, когда из него нужно было получить 00 01 E0

(На самом деле это конец, так как весь буфер не влазил даже в мой экран, но в начале там просто еще больше нолей чем на картинке.)
Найдя в буфере нужные данные, я оказался в замешательстве.
В буфер было загнано 527 байт «полезной» даты. нужные данный находились по офсету 15 с начала ввода данных, и примерно по офсету 3569 с начала буфера. Каким образом их можно было считать по офсету 4092, выданному мне, я не мог понять. Еще, вспомнив что в статье упоминалось число 18, я попытался прибавлять и отнимать его от разных офсетов, но так ничего осмысленного и не получил.
В итого, почесав репу, и поняв что оригинальный буфер был устроен ну как-то совсем иначе, чем мой, я вернулся к статье и описанию того, как получить «реальный офсет» при использовании чтения из потоков. Формула выглядела настолько ужасно, что я просто скопировал ее как есть, не пытаясь вникнуть и еще прицепил к ней пару вагонов дополнений чтобы натянуть ее на мой буфер, в итоге получился вот такой ужас:
(realoffset и realoffset2 можно было конечно сократить, но так как я не был уверен что оно заработает, я оставил так как есть для дебага.)
И как ни странно, оно заработало!

На этом можно было бы остановится, но кривая реализация буфера не давала мне покоя. И самое главное, я хотел лучше понять как был устроен буфер на самом деле, ведь очевидно было, что у самих разработчиков никаких грязных хаков при чтении по офсету не было, и если они получили офсет 4092, то нужные данные действительно находились по адресу 4092.
Признаюсь, что думал я долго, много рисовал на бумаге и массивы и кольца, чтобы понять как именно, а главное, почему оно было реализовано именно так, как было.
В итоге получилось как-то так:
Проще говоря, буфером был обычный массив байтов. Чтение происходило с начала массива, и маркер чтения никогда не перемещался. Единственным хаком было то, что изначальной точкой начала записи в массив было не 0, а размер массива минус 18. И все заработало как нужно!
Т.е достаточно было сместить на 18 точку записи в самом начале и после этого можно было спокойно читать и записывать без всяких хаков. при таком раскладе 15-й записанный в массив байт, действительно оказывался по офсету 4092.
Ну и кроме того не нужны были никакие хаки связанные с чтением из «прошлого» или «будущего».
Причиной того, что смещение на 18 вообще было необходимо, скорее всего послужило то, что при заполнении буфера при сжатии, часть уже имеющихся в буфере данных будут перезаписаны. И возможна следующая ситуация:
1) Данные предназначенные для сжатия ищутся в буфере.
2) Обнаруживаются там.
3) Создается ссылка на них, и они записываются в буфер.
4) Но они перезаписывают, по сути, сами себя, причем частично
5) И в результате правильная распаковка теперь становится невозможной.
Но и на этом сюрпризы от бонусного диска не закончились. По мере того как я перешел к другим архивам, я обнаружил странную «аномалию».
Помните те блоки по 1024 байт, данные в которых занимали чуть меньше места? У меня был код, который проверял остаток блока и выдавал уведомление, если там были не только нули. На первом файле — NPK_WEP.NPK, этот участок кода ни разу не сработал, но уже на следующем и почти на всех остальных выскакивали постоянные предупреждения. Так как файлы при этом распаковывались корректно, я решил посмотреть что там за «лишние» данные в хвостах. И немного офигел. Не долго думая, я добавил код, которые весь «мусор» из архива дампит в отдельный файл и вот что среди этого мусора я обнаружил:
Скорее всего, незанятое полезной инфой место, в оперативке, было сдамплено на диск «как есть» из памяти, и содержало предыдущую информацию. Кроме исходного кода, там был обычный мусор, который ожидаешь увидеть в памяти компьютера, образы процессов(в том числе исполняемого файла самого диска) и тп.
Другие архивы на диске имели либо точно такую же структуру, либо похожую, так что разбирать их тут смысла нет.
Как залезть в файлы игры
![]()
Извлекаем и изучаем файлы игры самостоятельно «Способ #1»
Используя данный способ вы сможете:
1. Просматривать содержимое файлов игры
2. Скачивать картинки
3. Просматривать 3д модели
Как бонус, мы расскажем где стоит искать информацию о грядущих пассах и ивентах.
Что нам понадобиться?
- Прямые руки
- Пк или ноутбук под управлением Windows (для ребят с MacOS этот способ тоже подойдёт, но будует пара нюансов)
- Исходный файл игры
Приступаем
1.1 Для начала переходим по ссылке и проходим регистрацию на сайте (используйте временный почтовый ящик), чтобы получить возможность скачать программу и получить лицензионный ключ к демо-версии (при желании можно приобрести полную версию)
1.2 Запускаем программу и ждём пока у нас появится окно и потребует ввести лицензионный ключ, после чего перезапускаем программу. (Лицензионный ключ будет выслан вам на почту, а также доступен на сайте)
Вот ссылка на видео, как активировать лицензию. Link
Для пользователей с Windows стоит скачать версию DevXUnityUnpackerToolsDemoArchive.zip
Для пользователей с MacOS подойдёт только DevXUnityUnpackerDemo-MAC.zip
Продолжаем
После того, как мы установили необходимый софт на пк, нам необходимо извлечь исходный файл.
2.1 Для Android
Скачиваем из плей маркета приложение skit
Ссылка – Play Market | 4pda (требуется регистрация)
Изначально заходим в настройки приложения -> Приложения -> пункт Папка в разделе «Извлечение» и выбираем папку, куда будет сохранена игра.
Потом выбираем Critical Ops из списка приложений, нажимаем на шестерёнку в нижнем правом углу и выбираем пункт извлечь.
После данных манипуляций, в выбранной вами папке появится игра с расширением .apks если это так, то вы на правильном пути.
2.2 Для iOS
В данном случае нам необходимо достать .ipa файл, самый просто способ, это использовать утилиту iMazing. Подробную инструкцию по извлечению файла вы можете изучить перейдя по данной ссылке «Link»
Финишная прямая
Вот мы почти на финишной прямой.
Запускаем DevXUnity, нажимаем open и выбираем в зависимости от того какой у вас файл «Open as APK, OBB, XAPK file (android)» или «Open as IPA file (iOS)», не трогаем никакие галочки и нажимаем OK.
После чего необходимо ждать, время ожидания зависит только от вашего железа.
Как бонус, подскажем вам в каком файле искать информацию по поводу грядущих обновлений (для этого вы должны загрузить исходники бета-версии)
Через «Search form…» вбиваем item_definitions, после чего через ctrl+f ищем интересующий нас контент, например вводим название ивента или пасса и изучаем информацию.
Спасибо за прочтение данной статьи, также через поиск можно искать картинки и 3д модели, но извлечь можно только картинки и то с ограничениями по времени, если вам интересны и другие методы, то дайте нам про это знать.