Как правильно дизассемблировать игры ZX Spectrum для изучения на современных ПК из под WIN или Linux :)
Кто какие способы использует, очень интересен данный вопрос.
Как правильно дизассемблировать игры ZX Spectrum для изучения на современных ПК из под WIN или Linux :)
Кто какие способы использует, очень интересен данный вопрос.
для статического анализа выбор удобных "способов" небольшой - IDA Pro или Ghidra
меня сейчас в основном интересуют только графпроцедуры
ломаю в своём же эмуле, где наглядно видно, какая что рисует
форматированный дизасм выгоняю в txt из отладчика zxspin
структуру буферов и спрайты смотрю в xpeccy
там же иногда немножечко трассирую
Highway Encounter разбирал с помощью Skoolkit https://skoolkit.ca/
Он хорош для случая когда хочется потом поделиться результатом - получается куча HTML на выходе.
Но у меня была цель портирования на другую платформу, для этого этот инструмент не очень хорош.
1. Получаем карту использования памяти (обычно взяв и прогнав готовый rzx, где ещё нужно дополнительно поумирать по-всякому, потыкать в меню разные редефайны клавиш, и прочее)
2. Карту и снап (можно выгрузить из rzx, или вручную из оригинальной тапки чистый бинарник получить) кормим в SkoolKit, на выходе получаем достаточно приличный дизасм, где уже определены блоки кода/данных.
3. Далее этот файл можно править по-всякому и компилить.
4. Полученный в результате компиляции бинарник (или снап) сверяется с эталоном на предмет различий. Если найдены - то править косяк, и снова компилить.
Очень удобно для исследования IDA, но прямого метода выгрузить оттуда текст для компиляции, да ещё и с нужными комментариями не нашёл.
И как его тем же SjASM компилить?
Кроме этого, я делаю различные IFDEF и макросы к примеру.
Позволяет сильно упростить исходник, и сделать повторное использование блоков.
Типа как тут
https://github.com/Bedazzle/EATF/blo..._main_menu.asm
Интересно, где эмуляторы или реальный zx в файлах .tap .tzx и.т.д читают "точку входа" стартовый адрес для запуска игры. ?? Если в загрузчике нет ничего подобного RANDOMIZE USR ....
В Eric & the floaters какой стартовый адрес ?
Я попробовал дизассемблировать простенькую игру SIEGE .. одна из любимых в детстве :) Получилось с лету скомпилировать при помощи sjasm в .sna
Немного проанализировав исходник, добавил управление через kemston джойстик :)
Использовал дизассемблер yazd запускать через .bat файл.
yazd.exe --addr:32722 --entry:37178 -xref 1111.z80 eric.asm
pause 0
Только надо правильно указать точку входа, начальный адрес и длину блока можно посмотреть в эмуляторе при загрузке.
Не всегда. :)
Вот пример
https://www.worldofspectrum.org/info...cgi?id=0001639
А, уже сказали, ага. :)
В смысле? Берёшь и компилишь тот asm, который она тебе нагенерила. Только масс реплейс .ascii на db предварительно сделай. Макросы можно делать уже в конце, когда все работы по дизассму закончены и в иду больше не пойдёшь.
Поглядел твой исходник, ад какой-то :) У нас разное понимание слова "упростить".
Да, забыл про этот способ. Некоторые игры вообще грузятся через LOAD "" CODE таким макаром. Ещё могут подменяться адреса процедур вывода каналов/потоков в системных переменных, и вывод "OK" приведет к старту программы.
- - - Добавлено - - -
Или адрес процедуры обработки ошибок в системных переменных.
- - - Добавлено - - -
Забыл, потому что привык к машкодовым загрузчикам после REM)
приблизительно так
https://www.youtube.com/watch?v=IBUNEZLlQYk
вот так
https://www.youtube.com/watch?v=aNJtvdeVllA
или так
https://www.youtube.com/watch?v=p8K8B5_P7Wc
на выхлопе эти ребята получают компилябельный исходный код, и что самое главное, идентифицированные переменные и структуры игры.
в данных видео идёт работа с кодом 6502 или M68000, в случае Z80 процесс будет тот же только сбоку.
IDA – лучше нет (прибывал те что тут упоминали, и д.р.). Разобрали. Далее скриптами – самописными из коробки.
Тут проблема не оформить, а осознать что там происходит. Если старые игрушки, то все более менее понятно (условно).
А вот если какой хитрый код к примеру, HI-TECH Z80 C Compiler. То в начале все очень просто. Cишная структура компилятора восстанавливается на 99% (это где-то 50% кода), а далее начинается мрак (надо не одну умную книгу прочитать).
- - - Добавлено - - -
Да, скрипты очень полезны еще на пред разборке (при загрузке исходника). Как загрузишь, так и поплывешь (требуются некие знания о объекте интереса).
что именно, результаты работы или инструменты ?
если первое - у обоих авторов роликов есть репозитории на жидхабе, там всё добро и выкладывается.
если второе - IDA от известного рассового татарина стоит слишком денег, потому придется пиратить, то ли дело халявная Ghidra от злобного американского АНБ, правда жителям РФ напрямую скачать не дают, придется искать зеркала или через прокси.
Мог бы линки дать на репы тогда, их в описании нету. Попытки угадать вида https://github.com/eduardbeluha ни к чему не привели. Так что ждем от тебя ссылок все же.
У линуксоедов типа меня гидра прямо в репозитории :) yaourt ghidra и вот она уже стоит.
Но гидра мне показалась сильно неудобнее для именно асм-z80 реверсинга. Она хорошо под декомпилятор, там почти отлично.
блин, а в описании разве нету ? CaH4e3 - https://github.com/g0me3 , Мефисто - https://github.com/lab313ru
Ребятки вот новость=)
Да гидра, прикольное творение. Но я чую задней пяткой, оно не заработает. Как и любое творонение с накрученным счетчиком, как KiCad. Ждем коммерциализации.
По делу. Для ламеров ZX скрипты там написали? Есть там прикольные скрипты?
Здравствуйте у меня возникло несколько вопросов про дизассемблеры. Как правильно и на чем сделать hobeta для Spediz и чтобы он выводил не только код но и цифры и текст. Как на skoolkit правильно разметить блоки данных текста и кода. Как правильно дизассемблировать игру на ida pro что нужно делать для этого.
- - - Добавлено - - -
И ещё hobeta надо сделать из файла tap tzx.
zxlogin, hobeta - это устаревший тип файла, который на сегодняшний день практически не используется. Ему на смену пришли SCL и TRD. К тому же hobeta - это некий контейнер для одиночного файла с дискеты TR-DOS. Между тем TAP и TZX - это образы ленты. Они могут содержать, и почти всегда содержат, более одного блока (файла). Можно сделать, например, переходник с USB на RJ-45 (LAN). Но разве будет прок от такого переходника? Вот так же и с конвертером tap -> hobeta. Сделать можно, и я думаю, что даже такие конвертеры существуют, но большого прока от них не будет. Ну разве что в образе TAP/TZX будет только одна картинка или какой-то другой одинокий кодовый блок. Это я к тому, что прежде чем заниматься дизассемблированием, нужно получить понимание о форматах и прочих базовых вещах.
А как правильно дизассемблировать на ida pro?
Успешного опыта дизассемблирования в IDA у меня нет, хотя я и пробовал. Однако есть успешный опыт работы со skoolkit. Я не буду писать подробную инструкцию, а поясню лишь суть.
Любая игра или программа на Спектруме, да и не только на нём, состоит не только из исполняемого кода, но также содержит текстовые сообщения, таблицы, графику и другие данные. Дизассемблеру неведомо где что находится и он пытается дизассеблировать всё подряд, включая текстовые сообщения и т.д. Поэтому, чтобы произошло корректное дизассемблирование поддающееся анализу, дизассемблеру необходимо указать где находится код, а где всё остальное. А как это сделать? А довольно просто! С помощь эмулятора, поддерживающего функцию профайлинга, например FUSE, мы запускаем исследуемую программу и начинаем активно её гонять, стараясь сделать так, чтобы весь код, хотя бы раз выполнился. То есть в случае игры, проходим её до конца, тратим жизни, получаем Game Over, зарабатываем бонусы и т.д. В этот момент эмулятор создаёт некий лог - профайл, в котором помечает все участки программы, которые выполнялись. Далее этот файл и снепшот программы, который мы гоняли, скармливаем пакету skoolkit и на выходе получаем исходный текст, который и начинаем анализировать. Профайл представляет из себя текстовый файл, который можно править руками, указывая вручную какой участок является программой, а какой данными. Очень важно скармливать пакету skoolkit не исходный блок, а именно снепшот работающей программы. Дело в том, что исходный загружаемый блок может быть изначально пожат, закодировал или как-то иначе изменён. Если пытаться дизассемблировать такой блок, то на выходе мы получим белиберду.
хобетные файлы очень удобно доставать из образов trd и scl напрямую в Far Manager с соотв. плугинами (by HalfElf кажется)
а из tap достается какой-то давней утилиткой с названием ZART
в Spediz, в текстовичке к нему указано, что нажимать, чтобы дизасмило не только код
(цифры надо жамкать, разъезжая по памяти :) )
В скулките когда делаешь АСМ выводит предупреждения что warning no label for address x.
У скулкита хорошая документация, как раз для начального старта подробно расписано
Если коротко, то можно так:
1) Если игрушка не denied, берём rzx игры с https://www.rzxarchive.co.uk/
2) Открываем файл в эмуле, умеющем проигрывать rzx, и писать карту памяти например SpecEmu
3) Tools->Memory map->Clear (очищаем)
4) Запускаем проигрывание rzx на максимальной скорости Z80->CPU speed->50MHz
5) Ждём, пока будет проиграно до самого конца, возвращаем скорость к обычной
6) В записях часто отсутствуют смерть и тыканье по главному меню игры, где выбор управления и прочее - проходим этот функционал ручками
7) Сохраняем карту памяти Tools->Memory map->Save (файл вида хххххх.map)
8) Сохраняем снапшот игры File->Save snapshot (скулкит умеет работать с Z80 и SNA, не помню чем именно, но сна глючил, поэтому использую Z80)
9) Далее используем SkoolKit
10)
получаем контрольный файл с разметкой где что в памяти
sna2ctl.py -h -m GAME.map GAME.z80 > GAME.ctl
получаем скул файл
sna2skool.py -H -c GAME.ctl GAME.z80 > GAME.skool
конвертим во что-то асмоподобное
skool2asm.py --lower --hex --create-labels GAME.skool > GAME.asm
11) пробуем обернуть полученный дизасм для компиляции, как описано в доках
сохраняем файлик game_new.asm с таким содержимым:
device zxspectrum48
include game.asm
savebin "game_new.bin",ORG,LENGTH
или для тестовых экспериментов можно
savesna "game_new.sna",GAME_START
12) берём SjAsmPlus (достаточно только бинарника)
13) компилим наш обёрнутый исходник
sjasmplus.exe --syntax=abF --nologo --msg=err game_new.asm
14) Если вываливаются ошибки, смотрим по месту где что нужно поправить
15) Желательно во время экспериментов производить сверку с оригинальным файлом (который мы сохраняли в пункте 8), и по которому делался дизасм)
Делать это можно при помощи утилиты, которая умеет побайтовый diff. Мне удобно использовать скрипт на питоне (к примеру, чтобы пропускать сверку экранной области)
Для начала, нужно купить иду :) Либо взять старенькую версию, которую вроде как можно использовать бесплатно. Но придётся найти модуль для Z80.
В ней по шагам примерно так:
- новый проект
- загрузить бинарный файл
- если это снапшот, то не забыть указать количество байт, которые нужно отрезать в начале файла (для SNA это 49179 - 49152 = 27 байт)
- выбрать адрес загрузки файла, процессор поменять на Z80, убрать лишние галочки про DLL и сегменты
- когда файл будет загружен в память, перейти на адрес с которого начинается запуск игрушки, и начать дизассемблирование
Ида сохраняет проект в файл своего формата, но в добавок можно периодически делать выгрузку в асм, который просто так в SjAsm не засунешь. Но можно конвертить до более-менее сносного состояния, вырезая лишнее.
P.S.
Касательно исходников: кому-то нравится один монолитный файл, я в процессе обработки разбиваю на большое количество мелких, по процедурам, типа такого:
https://i.imgur.com/q6CXyMD.png
Основной файл в итоге состоит из пачки инклудов:
INCLUDE "code/_8021-8087___prepare_static_creature.a80"
INCLUDE "code/_8088-80BA___work_with_room.a80"
INCLUDE "code/_80BB-8141___draw_console.a80"
INCLUDE "code/_8142-8150___init_axil.a80"
INCLUDE "code/_8151-8184___scroll_axil_attributes.a80"
INCLUDE "code/_8185-81EF___axil_attr_roller.a80"
INCLUDE "code/_81F0-8246___process_pouch.a80"
INCLUDE "code/_8247-82B6___reset_obj_monst_axil.a80"
INCLUDE "code/_82B7-82ED___game_round_init.a80"
INCLUDE "code/_82EE-8359___process_exits.a80"
INCLUDE "code/_835A-8376___console_beep.a80"
INCLUDE "code/_8377-8383___focus_console.a80"
INCLUDE "code/_8384-83D2___animate_axil.a80"
INCLUDE "code/_83D3-841D___walk.a80"
INCLUDE "code/_841E-8438___loop_axil_anim.a80"
INCLUDE "code/_8439-8453___check_for_halt.a80"
INCLUDE "data/anims/_8454-845A___ani_what_xxx.a80"
INCLUDE "code/_845B-8494___say_what.a80"
INCLUDE "code/_8495-84D5___test_exit.a80"
это ненадёжно и утомительно, давно вроде есть утилитка для быстрой прогонки снапа (без ввода-вывода, но по ВСЕМ возможным ветвлениям), только я не помню, как называется :(
- - - Добавлено - - -
а себе я недавно написал спецобработчик полных дизасмов, который помечает подозрительно бессмысленные участки, чтобы можно было быстро почистить ручками
А поклянчить можно?
- - - Добавлено - - -
Это? https://github.com/simonowen/snaptrace
Надо тестить. Вангую, что будет ряд случаев, когда либо большие блоки не будет определять (SMC, или переход по таблицам, или рассчитываемые джампы), или будет тупо лезть в данные, принимая за код.
вряд ли оно будет тебе полезно, понимает только текст в формате выхлопа zxspin
правила весьма примитивные - помечает nop, rst, запись в пзу, фигню типа cp+popaf итд
смотрит только две последних строки
9 лет... может, и оно... хотя мне казалось, код таки выполнялся, то есть эти джампы считались бы... но тут по описанию не похоже