Skip to content

Reverse engineering

Владислав edited this page Sep 5, 2026 · 1 revision

Как это восстанавливалось

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

Два модуля, два диапазона адресов

Модуль Что там Адреса в цитатах
JumpyBall.exe вся игра: окно, кадр, физика, меню, трасса код 0x00011xxx..0x00024xxx, данные 0x00026xxx, 0x0003xxxx, 0x0006xxxx
hss.dll Hekkus Sound System: звук и MOD-плеер 0x0010xxxx

Поэтому в комментариях порта модуль назван всегда: JumpyBall.exe Blit 0x00023b78 - это игра, а hssSpeaker::updateModSFX 0x00104370 - это библиотека. У hss.dll сохранились C++-имена, отсюда цитаты вида hssSpeaker:: / hssMusic::; у игры имён нет вообще - только адреса.

В коде порта 292 ссылки на JumpyBall.exe, 45 упоминаний классов hss и 704 упоминания адресов вида 0x000xxxxx. Это не украшение, а правило проекта: комментарий либо называет внешний источник истины, либо его нет. Никаких «тут умножаем на два, потому что так ровнее».

Имя - соглашение, адрес - факт

Level_Begin, Blit_TileHV_Core, Menu_DrawFrame, Player_Respawn - не оригинальные символы. Исполняемый файл стрипнут; это имена, которые мы дали функциям при разборе. Твёрдый факт в цитате один - адрес. Если открыть JumpyBall.exe самостоятельно и назвать функцию по адресу 0x0001376c иначе - это не ошибка; сойтись обязательно только на адресе.

Отсюда практическое правило чтения вики: где рядом с описанием стоит адрес, там поведение сверено с дизассемблером. Где адреса нет - это либо следствие описанного выше, либо решение порта, и тогда сказано прямо (см. Deviations).

Ресурсы остались номерами

Оригинал грузил картинки как ресурсы: LoadBitmapW(g_hInstance, id) в Game_Init 0x000113bc. Порт читает те же картинки из файлов BITMAP/<id>.bmp - тот же номер, только в десятичном виде. Поэтому папка ассетов выглядит как склад безымянных чисел, и это не лень, а прямое следствие: у картинок в оригинале не было имён.

В дизассемблере Файл Что это
0xcc 204.bmp панель мастера переназначения клавиш
0xf7..0xfb 247..251 полоска, градиент, заголовок, две кнопки
0xfd 253.bmp логотип PocketNew
0xfe 254.bmp шрифт HUD
0x133 307.bmp первая текстура в порядке загрузки
0x14c 332.bmp крупный шрифт (Font_Load 0x0001f4d8, ветка g_fontSize == 2)
0x14e 334.bmp последняя - карта третьего уровня

Полный список - в jb_consts.h, каждый номер с цитатой на место загрузки. Четыре файла - 222.bmp, 252.bmp, 302.bmp, 303.bmp - лежат в репозитории, но кодом не используются: они были в поставке, а разбор не нашёл ни одного места, где игра их грузит.

Числа берутся байтами, а не на слух

ARM не загружает double одной инструкцией - он читает его из литерального пула рядом с кодом. Значит, константу можно не угадывать, а прочитать. Пример из Physics: проверка тайла под мячом использует + 0.58, и это не «примерно половина», а восемь байт по адресам 0x0021119c / 0x000211a4:

0x3fe28f5c 0x28f5c28f  ->  0.58

Так же добыты 7.0 (ускорение), 10.0 (импульс прыжка), 20.0 (гравитация), 0.08 (параллакс), 70 / 60 / 100 / 163 (проекция) - каждое лежит отдельным float в .data, и у каждого в цитате свой адрес.

Чем проверялось, что порт ведёт себя так же

  • Строгий C89 - tools/c89check.cmd и та же проверка в CI: код обязан собираться не только MSVC, см. Build-and-CI.
  • Дамп кадра - jumpyball 1 frame.raw выгружает бекбуфер и выходит; кадры можно сравнивать побайтово между сборками.
  • Быстрый доступ к состоянию - ключи --level=, --screen=, --index=, --unlocked= появились именно для проверки: попасть в нужный экран одной командой, а не проходить игру заново.
  • Музыка отдельно от игры - tools/modtest.c рендерит .tkm в WAV и печатает peak/RMS/длительность без звуковой карты, см. Audio-and-TKM.

Clone this wiki locally