Мож­но ли модифи­циро­вать любимую игру без дизас­сем­бле­ра? Зап­росто. Тебе понадо­бят­ся лишь HEX-редак­тор и нес­коль­ко хит­рых при­емов, которы­ми я поделюсь в этой статье. Мы рас­смот­рим, как лег­ко лома­ются неиз­вес­тные фор­маты фай­лов на при­мере все­мир­но приз­нанно­го шедев­ра — игры «Ядер­ный тит­бит».

Во мно­гих играх ресур­сы упа­кова­ны в спе­циаль­ный файл — игро­вой архив. Здесь могут лежать модели, тек­сту­ры, скрип­ты, ани­мация, зву­ки и про­чее. Некото­рые раз­работ­чики не запари­вают­ся и исполь­зуют ZIP, раз­ве что для минималь­ной мас­киров­ки меня­ют рас­ширение на какой‑нибудь про­изволь­ный набор букв.

Сей­час поч­ти все игры дела­ются на одном из популяр­ных движ­ков, но в начале двух­тысяч­ных раз­работ­чики еще час­тень­ко делали всё с нуля. У мно­гих фирм были свои уни­каль­ные наработ­ки, которые ложились в осно­ву одной или нес­коль­ких игр. Пот­рошить игры на таких движ­ках нам­ного инте­рес­нее, чем ковырять ассе­ты популяр­ных движ­ков, для которых пол­но готово­го инс­тру­мен­тария.

SweetScape 010 Editor

Кто‑то ска­жет, что глав­ный инс­тру­мент хакера — его моз­ги. И будет прав. Но на вто­ром мес­те — удоб­ный HEX-редак­тор. Я горячо рекомен­дую SweetScape 010 Editor. Редак­тор кросс‑плат­формен­ный: есть вер­сии для Windows, Linux и macOS.

Даль­ше в статье я буду активно исполь­зовать встро­енный Inspector, который интер­пре­тиру­ет бай­ты как чис­ла, даты или ассем­блер­ные опко­ды. Кли­каешь на инте­ресу­ющий тебя байт и видишь, чем он может быть. Так­же час­то быва­ет нуж­на «линей­ка» — выделя­ешь мыш­кой дан­ные и узна­ёшь рас­сто­яние меж­ду струк­турами.

 

Формат с кислотным привкусом

Се­год­ня про­дегус­тиру­ем «Ядер­ный тит­бит», игру 2003 года, соз­данную при учас­тии Дани Шепова­лова.

До­гадать­ся, какой из фай­лов в пап­ке игры — это архив с ресур­сами, мож­но, прос­то гля­нув на раз­меры. QUEST.ezd самый боль­шой и занима­ет 216 Мбайт. Это явно наш кли­ент. Откры­ваем его в HEX-редак­торе:

0000h: 65 7A 64 FF 4D 08 00 00 3D 75 02 00 D6 9A 82 0D ezd.M...=u..Öš‚.
0010h: 64 6F 6F 72 5F 30 31 2E 6D 65 61 74 00 00 02 00 door_01.meat....
0020h: 00 00 3D 75 02 00 E1 1C 00 00 09 0A 00 00 64 6F ..=u..á.......do
0030h: 6F 72 5F 30 32 2E 6D 65 61 74 00 00 02 00 00 00 or_02.meat......
0040h: 46 7F 02 00 95 21 00 00 53 0B 00 00 64 6F 6F 72 F...•!..S...door
0050h: 5F 30 33 2E 6D 65 61 74 00 00 02 00 00 00 99 8A _03.meat......™Š
0060h: 02 00 71 20 00 00 0F 0B 00 00 64 6F 6F 72 5F 30 ..q ......door_0

Обыч­но пер­вые четыре бай­та содер­жат сиг­натуру фор­мата. Здесь мы видим стро­ку ezd., что сов­пада­ет с рас­ширени­ем фай­ла. Зна­чит, это сиг­натура. Если нет явных про­тиво­речий, про­дол­жаем раз­бор с шагом в четыре бай­та. Струк­туры час­то вырав­нива­ются по INT32.

Сле­дующие четыре бай­та: 0x4D080000. Прог­рамма соб­рана для x86, поэто­му чис­ла записа­ны в обратном поряд­ке бай­тов. Таким обра­зом, 0x4D080000 интер­пре­тиру­ется как 0x0000084D, что в десятич­ной сис­теме рав­но 2125. Что это может быть? Воз­можно, заголо­вок архи­ва содер­жит чис­ло фай­лов. Две тысячи — впол­не адек­ватное чис­ло. Про­верим эту гипоте­зу поз­же.

Да­лее идет 0x3D750200, это декоди­рует­ся в чис­ло 161 085, что сос­тавля­ет 157 Кбайт. Это может быть раз­мер текущей струк­туры или сме­щение начала сле­дующей. Дей­стви­тель­но, по адре­су 161 085 закан­чива­ется спи­сок строк, похожих на име­на фай­лов.

Сле­дующий DWORD — 0xD69A820D, что экви­вален­тно 226 663 126. Это точ­но раз­мер фай­ла — 226 663 126 байт.

0x00 657A64FF ezd. Сигнатура формата
0x04 4D080000 2125 Возможно, количество файлов
0x08 3D750200 161085 Неизвестное смещение
0x0C D69A820D 226663126 Размер файла

Опыт под­ска­зыва­ет, что на 16-м бай­те фай­ловый заголо­вок закан­чива­ется. Даль­ше сле­дуют стро­ки, переме­шан­ные с неиз­вес­тны­ми чис­лами. Ско­рее все­го, это мас­сив струк­тур, опи­сыва­ющих кон­крет­ные фай­лы. Поп­робу­ем опре­делить раз­мер и наз­начение всех полей.

Пер­вая струк­тура начина­ется с ASCII-строч­ки door_01.meat. Если раз­мер стро­ки заранее не ука­зан, зна­чит, она чита­ется до нулево­го бай­та. До начала сле­дующей стро­ки 18 байт. Рас­сто­яние меж­ду слу­чай­ными стро­ками не меня­ется, сле­дова­тель­но, это зна­чимые поля.

Срав­нивая пред­полага­емые струк­туры, замеча­ем пос­ле каж­дой стро­ки шесть неиз­менных зна­чений 0x000002000000. Счи­таем их кон­стан­той. Оста­ется понять наз­начение 12 изме­няемых бай­тов.

0x10 646F6F725F30312E6D656174 door_01.meat
0x1C 000002000000 const
0x22 3D750200 161085
0x26 E11C0000 7393
0x2A 090A0000 2569

Что сра­зу бро­сает­ся в гла­за? Во‑пер­вых, чис­ло 161 085 сов­пада­ет со сме­щени­ем из фай­лового заголов­ка. Веро­ятно, это адрес с дан­ными пер­вого фай­ла. Сле­дующие два чис­ла могут быть раз­мером и кон­троль­ной сум­мой. Сме­щение вто­рого фай­ла — 163 654. Вычитая сме­щение пер­вого, получа­ем 2569. Зна­чит, это поле с раз­мером дан­ных.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    1 Комментарий
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии