Скриншот собственно той самой игры LHX
Скриншот собственно той самой игры LHX

Интро

Про что здесь

В этом цикле статей я расскажу о том, как занимался реверсом данных из DOS-игры LHX Attack Chopper - симулятора боевых вертолетов от EA и одной из самых любимых игр моего детства (как оказалось, не я один такой - вот современный оммаж играм такого жанра той эпохи).

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

Как вы понимаете - это было долгое путешествие, которое я проделал из чистого любопытства и прямо-таки импринтинга к этой игре. Не будь у меня такой мотивации - я бы бросил это все на полдороге. 

Мотивация

Компьютер, который у меня был в детстве (девяностые), отнюдь не блистал техническими характеристиками - процессор NEC V20 (слегка улучшенный клон 8088), 640 кБ памяти, 20 МБ диска, дисковод 5.25 на 360 кБ, CGA-адаптер. Всё. Не Байт и не Спектрум, но и дум на ней не запустишь. Да и много чего не запустишь. И LHX была одной из немногих игр, которые можно запустить, и которые при этом выглядели на этом компе впечатляюще, на мой взгляд. И после, когда я сменил железо (неоднократно), LHX все равно осталась в моем сердечке. И много лет я хотел покопаться в ее внутренностях, как бы двусмысленно это ни звучало.

Бэкграунд

Знания, которыми я пользовался в процессе описываемого - практически все они из тех DOS-времен. Ограниченность того компьютера и отсутствие интернетов не дали (увы) мне утонуть в играх (по вышеозначенным причинам). Потому мне пришлось со скуки погрузиться в азы программирования в частности и айти в целом - но это были именно азы и именно программирования, а не реверса. Я знал Турбо Паскаль и писал на нем игры (2 штуки, обе затерялись в годах), я слышал краем уха про ассемблер (но это казалось мне чем-то запредельным), я даже знал о том, что DOS - это нереентерабельная ОС (и это меня не очень сильно волновало). Я отличал байт от бита, знал об упаковке экзешников как явлении и бесился от 4-цветности CGA. Но это все было довольно стандартным набором знаний для подростка, который более-менее интересовался компьютерами в то время.

По наклонной

Единственная вещь, которую вряд ли можно считать прям стандартной - это то, что я успешно расковырял (ну частично) данные в одной игре уже тогда, в девяностые. Это была игра Goody (с совершенно дурацким управлением - q, a, o, p, space, enter). И сделал я это от скуки и любопытства (то еще сочетание), еще не имея ни малейшего представления о программировании вообще.

Goody. Главный герой - вор, алкоголик, махинатор, лестниценосец (об этом узнаешь совершенно случайно) - сидит на табуретке возле табуретки и скучает.
Goody. Главный герой - вор, алкоголик, махинатор, лестниценосец (об этом узнаешь совершенно случайно) - сидит на табуретке возле табуретки и скучает.

Как я уже написал, игр у меня на том компе было немного, интернетов тогда не было, а развлекаться с компьютером хотелось. Одним из развлечений были встроенные функции просмотра и редактирования файлов в Volkov Commander (клавиши F3 и F4). Причем любых файлов - и текстовых, и бинарных. И вот в попытке понять, как же устроены игры, я просматривал содержимое их экзешников - и ничего не понимал. Потому что не там смотрел.

Я пытался понять, глядя на такую картинку (ASCII-view)
Я пытался понять, глядя на такую картинку (ASCII-view)
А надо было пытаться понять, глядя на такую (Hex-view). Но про оба способа просмотра (и редактирования) я знал.
А надо было пытаться понять, глядя на такую (Hex-view).
Но про оба способа просмотра (и редактирования) я знал.

А потом как поня однажды просто по наитию в режиме просмотра байтов взял да и вбил в совершенно рандомное место несколько повторяющихся значений (типа 999999999999999), сохранил и запустил. И где-то в игре вместо нормального спрайта появилось что типа такого:

Типа такого.
Типа такого.

Не видно? Это потому что тогда экраны были с разрешением в 6-10 раз меньше, а диагональ - меньше только в 2, а то порой и почти такая же ?. Ну вот же, на лампочке: 

Лампочка с нюансами
Лампочка с нюансами

То, что мне очень повезло и почему полоска двоится - я понял почти сразу. То, что одной цифре “9” из введенной последовательности соответствуют сразу 2 пикселя (красный и зеленый) - тоже. А вот почему их 2 и почему они именно красный и зеленый - я до конца понял только некоторое время назад, когда собственно реверсил LHX (не то, чтобы это занимало меня все эти годы, да). 

А на тот момент времени я просто составил таблицу цветов для каждой цифры и буквы (A-F). И, используя ее, нашел положения кусков спрайтов в файле. Ну то есть, посмотрел на исходный спрайт, сконвертил цвета пикселей в циферки согласно таблице, после чего поиском в файле нашел. Проблемой было то, что паузу поставить нельзя (а анимация с нужным спрайтом уже прокрутилась), скриншот сделать нечем, а фотики с циклом получения готовой фотки быстрее, чем через неделю, еще не придумали. Но так или иначе, для всех спрайтов главного героя я нашел их размеры и положение в файле. 

И, конечно же, нарисовал свои и вписал их в экзешник. Вручную. Так главный герой игры моими стараниями превратился в шагающего боевого робота. Я даже нашел свои тетрадки с тех времен, так что сейчас еще немного картинок.

Процесс замены спрайта в игре
Процесс замены спрайта в игре

Первая (палитра) и вторая (сочиненный мной спрайт с наложенной палитрой, пустые клетки - нули) картинки давали набор байт (типа 000555555550000 для предпоследней строки), который и мне надо было записать в экзешник по адресу с третьей картинки, чтобы получить четвертое изображение уже в игре - конкретно тут это “присевший робот”. Особый шарм придавало то, что указывать надо было не цвет пикселя, а сочетание цветов двух соседних пикселей. То еще упражнение. Для экономии пространства в тетрадке я придерживался принципа “одна клетка - одна цифра”, что, очевидно, давало в игре растягивание конечной картинки в 2 раза по горизонтали.

Сам факт вот такого перехода из “бессмысленно пялюсь в байтовый дамп” в “заменил все спрайты главного героя на собственноручно сделанные” я, собственно, и назвал “частично расковырял данные”.

Ну и еще, имея на руках упомянутую таблицу цветов стало возможным быстро найти спрайты в других досовских 2д-играх - повторюсь, надо просто посмотреть сквозь заземленный защитный экран на миллиметрового размера пиксели, списать последовательность цветов в одной из строк спрайта и составить строку значений по таблице цветов. Потом поискать эту строку значений в экзешнике. Нашлась - значит, здесь лежит описание спрайта. Не нашлась - отбросить у исходной последовательности цветов первый пиксель (помним про два цвета на одну цифру) и попробовать еще раз. Опять не нашлась - ну, значит, не судьба. Я помню, что я и находил, и исправлял, но уже без энтузиазма, первый раз - это все же первый раз.

Из этого всего я вынес для себя три вещи:

  1. модифицированный экзешник goody.exe (утерян)

  2. подход “чтоб понять непонятное - испорти его копию и сравни результат с оригиналом” (порой пригождался)

  3. и веру в то, что я норм такой хакер (была быстро утрачена)

Завязка

Действие первое

И вот с этой нерастраченной верой что я норм такой хакер я полез в экзешник lhx.exe (помимо него в папке игры хватало файлов, но я же хакер). Внутри его бинарного содержимого проскакивали строковые английские названия техники и окружения из игры - su25, bridge, camel и т.п. Даже тогда это как бы намекало мне, что внутри экзешника в этих местах есть что-то связанное с этими объектами. Но новообретенный подход не помогал - порченный экзешник тупо не запускался или вылетал в какой-то момент времени. Да и размеры (61 килобайт у Goody против 279 килобайт у LHX) тоже играли не в мою пользу. Дополнительно, как мне думается, не в мою пользу сыграл тот факт, что файл lhx.exe был, оказывается, упакован.

Действия со второго по n-ное

Несколько раз, с перерывами в несколько лет, я пытался делать подходы к разборке этой игры.

Я узнал-таки (сейчас это можно сделать при помощи, например, Detect It Easy), что экзешник упакован упаковщиком MS EXEPACK 4.06 - и распаковал его. 

Нашел описание распаковщика ресурсных файлов EA тех лет (.lib) на профильной вики, заимел откуда-то исходник утилитки распаковки на Nim (то ли сам по описанию написал, то ли скачал откуда то - это было так давно, что даже не помню - но на всякий случай выкладываю). Им распаковал ресурсные файлы. 

По итогу, у меня на руках оказалась полностью распакованная игра. 

Это я тогда так думал.

Действие очередное

Следующим шагом для себя я видел как-то подступиться к дизассемблированию всей этой распакованный красоты. Это были уже далеко не девяностые, а вполне себе 2010-ые. Я знал, что это будет непросто, потому что я абсолютный нубяра в ассемблере, а это 3D игра под DOS, выпущенная в 1990 году, и которая довольно шустро шевелилась даже на том архаичном моем компе. Все эти факты приводили к трем выводам - DOS наложит свою некислую специфику; скорее всего, не будет никаких стандартов/библиотек (слишком рано для них); но будет уйма хаков/хитрых телодвижений (потому что оно шустро шевелилось). Не сказать, что все это упростило бы дело для новичка в дизассемблировании. Я попытался подстелить соломки инструментами (ссылки скорее для историчности): 

  1. Ida (естественно) с плагинами к ней - snowman (реверс компилятор) и dosbox plugin. Мне это не сильно помогло. Потом были:

  2. Ghidra (дизассемблер от ЦРУ (шучу, от АНБ))

  3. Reco (декомпилятор общего пользования, по утверждению авторов)

  4. radare2 (целый тулчейн для реверса) 

  5. И даже SoftIce (мощный дизассемблер времен LHX). 

Всё, на что меня хватило со всем этим счастьем - это понять две вещи. Первая - одна из функций в файле lhx.exe предназначена для работы с Adlib Sound; вторая - скорее всего, при старте программа лезет патчить вектора прерываний и при этом досбокс плагин обламывается ее отследить и брейкпоинты не срабатывают (в этом я уверен примерно на 7%). Ну или у меня совсем уж кривые руки, этого совсем нельзя исключать.

Как вишенка торте - я нагуглил как-то пост от какого-то мастера реверса, в котором он вскрыл досовский самолетный симулятор F-19 и достал оттуда модельки. В треде не было особых подробностей, но сами картинки подогревали интерес. Который невозможно было удовлетворить.

В общем, я осознал довольно-таки очевидную вещь. Надо или вписываться в это вот все и начинать тратить очень много времени на изучение реверса в целом и DOS в частности, причем с бОльшим упором на DOS. Или решить для себя, что все же эпоха ушла (MS отказался от поддержки DOS в июне 1994 - это 30 лет назад на момент написания), и это уже не реверс, а палеонтология и поставить точку. 

И несколько лет назад я поставил, как мне казалось, точку.

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


  1. chernish2
    17.09.2024 11:26
    +2

    Первая цивилизация на таких машинах вполне себе работала. У меня правда монитор был EGA, а в остальном в точности Ваша конфигурация.


    1. unbalanced Автор
      17.09.2024 11:26
      +1

      Ну вот я как сейчас помню файл centurio.exe, который запускался и что-то пищало даже в динамик, но на экране было черным-черно. И это было не исключение)


  1. chernish2
    17.09.2024 11:26
    +2

    Вообще статья шикарная, жду продолжения! От DOS вряд ли всерьез отказались в 1994 году, не забываем про Windows Me который вышел в 2000.


    1. unbalanced Автор
      17.09.2024 11:26
      +1

      Спасибо за оценку, продолжение будет завтра)


  1. Vaitek
    17.09.2024 11:26
    +1

    Наиграл в этой игре десятки часов на 286) возможность переключать камеру на любой объект, даже на снаряд авиапушки, восхищала. Звуковой карты не было, но звук от pc speaker, выведенный на большую колонку до сих пор помню)


    1. unbalanced Автор
      17.09.2024 11:26
      +1

      Про авиапушку - я тоже налетал уже несколько сотен часов и только тогда узнал о том, как переключаться на ракеты. Узнал я после того, как в ярости (уже не помню из-за чего) начал стучать по клавиатуре.


  1. Quester
    17.09.2024 11:26
    +3

    Божечки-кошечки, как я обожаю всякие статьи про реверс. Много лет пытался отреверсить TestDrive III, но времени и терпения не хватает. А ещё тот факт, что HexRays только 32 бита декомпилирует, 16 игнорирует.
    Плагин досбокс-ида, кстати, по моей же просьбе пересобрал lab113, когда IDA обновилась. Изначально это был плагин от создателей Exult'а.
    Есть надежда, что эти ваши бесполезные ИИ когда-нибудь научатся выворачивать код наизнанку и без человека реверсить старые игры.


  1. Ulrih
    17.09.2024 11:26
    +1

    Сколько же несчетных часов налетал в LHX еще на Искре 1031 или 1034 уже и позабыл


    1. Bombus
      17.09.2024 11:26

      Как насчет Retal?


  1. pda0
    17.09.2024 11:26
    +1

    с совершенно дурацким управлением - q, a, o, p, space, enter

    О... Вайбы спектрума...