| Разработка и ромхакинг > Ромхакинг и программирование |
| [Статья] Как найти процедуру вывода текста и собственно текст на SMD |
| (1/1) |
| DrMefistO:
Всем привет. В этой статье я расскажу, как найти процедуру вывода текста в любой или почти любой игре на SMD. Инструментарий: * Gensida - дебагер-плагин для IDA, позволяющий отлаживать ромы Sega Genesis / Mega Drive, унаследовавший некоторые фичи Gens Rerecordings, Gens KMod, Gens r57shell mod; * Smd Ida Tools - набор из загрузчика ромов Sega в IDA и подсказчика по отправляемым в VDP-регистры значениям; * Ром игры (возьмем, например, Caliber .50).Приступаем: Для начала, устанавливаем весь необходимый инструментарий (инструкции есть на репозиториях каждой из утилит). Далее открываем IDA, кидаем в нее ром игры: В качестве загрузчика у нас выбран smd_loader.ldw. Так и оставляем. Жмем ОК. Теперь нужно указать дебагер-плагин: Выбираем "GensIDA debugger plugin". Запуск процесса отладки и установка бряков: Жмем клавишу F9 (или меню Debugger->Start process). После запуска процесса мы тут же прерываемся на самом старте эмуляции: Далее заходим в меню Tools->Plane Explorer. Откроется окно гляделки: Теперь давайте выберем текст, который мы хотим найти. Для этого снова нажмем в IDA клавишу F9. Мне понравился текст "20 YEARS LATER." (Вы можете выбрать совершенно другой текст. Принцип останется тем же.): Жмем кнопку Pause на клавиатуре, либо на значок паузы в IDA. Переключаемся на окно Plane Explorer'а. Видим, что на Plane A черный экран. Пробуем Plane B - ага, вот и текст! Наводим на первую букву курсор: И на последнюю букву: Красными рамками я выделил информацию о тайлах. Нам нужны значения ADDRESS, запомним их. Теперь самое интересное и муторное: установка бряков и анализ каждого из срабатываний. Алгоритм такой: * Перезапустить эмуляцию; * Дать игре дойти до места, которое как можно ближе к месту, где текст уже отображен, нажать Pause; * В IDA перейти на первое значение ADDRESS (клавиша G), которое мы взяли из Plane Explorer'а; * Установить брейкпоинт (клавиша F2) на запись в VRAM; * Продолжить эмуляцию (клавиша F9); * Проанализировать место остановки.Итак, с первым пунктом понятно. Далее, нужно дойти до места, где чуть далее будет показан искомый текст. У меня получилась такая вот картинка: Установим бряк на адрес 0xE69A (у Вас адрес может быть другим): Это окно можно просто пропустить нажатием OK. Зато на следующем окошке - собственно установка брейкпоинта: Обратите внимание на строку диапазона. Это те самые два значения ADDRESS из Plane Explorer'а. Жмем OK, и отпускаем эмуляцию дальше... И вот, первое срабатывание: Судя по диапазону сработавшего бряка, и по коду, на котором остановилась IDA, это всего лишь очистка VRAM. Отпускаем эмуляцию дальше... А вот это уже интереснее: (Я тут закрыл лишние окна, и оставил самые важные.) Знающие люди сразу поймут, что этот код именно тот, что нужно. Для менее знающих поясню немного: --- Код: ---ROM:00000A36 movea.l $10(sp),a0 --- Конец кода --- Здесь в a0 заносится адрес чего-то, что идет сразу за адресом вызова процедуры. В Вашем случае передача адреса может выглядеть по другому. Главное найти регистр с адресом, откуда читаются символы, которые потом пишутся в VRAM. Какой именно регистр нужен, станет понятно далее по коду. --- Код: ---ROM:00000A3A move.w (a0)+,d0 ROM:00000A3C tst.b d0 ROM:00000A3E beq.s loc_A50 ROM:00000A40 ROM:00000A40 loc_A40: ; CODE XREF: sub_A2C+22j ROM:00000A40 move.w d0,(a6) ROM:00000A42 move.b (a0)+,d0 ROM:00000A44 move.b (a0)+,d1 ROM:00000A46 tst.b d0 ROM:00000A48 beq.s loc_A50 ROM:00000A4A move.w d0,(a6) ROM:00000A4C move.b d1,d0 ROM:00000A4E bne.s loc_A40 --- Конец кода --- Весь этот код просто читает из a0 по два байта (word) и пишет их в VDP_DATA. Запись прекращается, когда обнаруживается нулевой байт ($00). Теперь посмотрим на места вызовов процедуры, чтобы узнать, какие там данные. Становимся на имя процедуры в IDA, жмем клавишу X, и видим три ссылки. Переходим по любой, и видим: --- Код: ---ROM:000040BA jsr sub_A2C ROM:000040BE or.b $20(a2,d3.w),d0 ROM:000040C2 subq.w #4,d5 ROM:000040C2 ; --------------------------------------------------------------------------- ROM:000040C4 dc.b $41 ; A ROM:000040C5 dc.b $52 ; R ROM:000040C6 dc.b $53 ; S --- Конец кода --- IDA коряво распознала данные, идущие за вызовом процедуры (оно и понятно, т.к. при jsr ожидается, что возврат будет выполнен на последующий код. Поправим это. Становимся на следующую за вызовом инструкцию, жмем U. --- Код: ---ROM:000040BA jsr sub_A2C ROM:000040BA ; --------------------------------------------------------------------------- ROM:000040BE dc.b $80 ; А ROM:000040BF dc.b $32 ; 2 ROM:000040C0 dc.b $30 ; 0 ROM:000040C1 dc.b $20 ROM:000040C2 dc.b $59 ; Y ROM:000040C3 dc.b $45 ; E ROM:000040C4 dc.b $41 ; A ROM:000040C5 dc.b $52 ; R ROM:000040C6 dc.b $53 ; S ROM:000040C7 dc.b $20 ROM:000040C8 dc.b $4C ; L ROM:000040C9 dc.b $41 ; A ROM:000040CA dc.b $54 ; T ROM:000040CB dc.b $45 ; E ROM:000040CC dc.b $52 ; R ROM:000040CD dc.b $2E ; . ROM:000040CE dc.b 0 --- Конец кода --- Ага, вот и текст!=) На этом все... Всем спасибо за внимание!=) © Dr. MefistO [Lab 313] |
| Ermac_oo:
DrMefistO, а собственно перевести предложение в итоге надо в другой проге (то есть выдрать этот текст из рома или как)? |
| DrMefistO:
Ermac_oo, открыть в хекс-редакторе, если буквы в ASCII кодировке, и переписывать прямо так. Или же, если буквы имеют символы, отличные от ASCII (используется таблица перекодировки), то юзать редакторы типа Translhextion. |
| Ermac_oo:
--- Цитата: DrMefistO от 10 Ноябрь 2015, 17:07:54 ---Ermac_oo, открыть в хекс-редакторе, если буквы в ASCII кодировке, и переписывать прямо так. Или же, если буквы имеют символы, отличные от ASCII (используется таблица перекодировки), то юзать редакторы типа Translhextion. --- Конец цитаты --- Спасибо. |
| Навигация |
| Главная страница сообщений |