Chief-NET

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Chief-NET » Экстрим хакинг » Blue Marline(Nes)


Blue Marline(Nes)

Сообщений 1 страница 20 из 45

1

Гайвер писал:

Привет собратьям по разуму!!! Эмуляторы форевер!!! Вот мой жалкий
недоделанный перевод хорошей дендевской игрушки...

Перевод ещё очень сырой - я его не проверял на совместимость со
смыслом игры - просто посмотрел, как он отображается - и всё...

Те слова, которые я не могу найти, написаны теми же буквами, что и
остальные... Поэтому я английский алфавит не менял - обошёлся знаками
припинания и цифрами, благо их было много... Вот собственно говоря и
всё...

Не могу найти: Текст на заставке игры, Enter your name, Enter
password, press start button, fising area, weather, temperature,
текст при выборе места ловли в начале игры, надписи при ловле рыбы
(vitality, LINE, TIME) и другие аналогичные надписи... Посмотрите -
может (да точно так и будет) у вас выйдет лучше...

Вставляю всё это добро в ром ПОКПЕРЕВОДОМ... (так как до другого я
ещё пока не дорос)...--
Guyver(X.B.M.)

Я нашел слово VITALY
http://chief-net.fatal.ru/images/guyver/screenguy1.jpg
Другие слова тоже почти нашел :)

2

Ccылка на РОМ и таблицы

3

Есть еще один шрифт на заставке:
таблица к нему
http://www.chief-net.fatal.ru/images/guyver/screenguy2.jpg

4

Шэф, таблицы - дело понятное, я сам текст в роме не нахожу... Ни так, ни релатив сёрчем - не получается что-то... Может у меня софт не тот? Взять хотя бы пресс старт баттон - я могу бкувы поменять, но вот где это слово находится в роме - не знаю...

5

пробуй искать через 4байта

Код:
s???t???a???r???t

6

Я таким способом нашёл только слово noname - это когда имя игроку не писать, то оно будет таким по умолчанию... А как ещё ищут подобный текст? По каким признакам его определяют?

7

Мы с алексом ищем в дебагере, пока получается плохо.

8

Предложение перенести форум, в открытые форумы.

9

Я перенес тему, в открытый форум.
Также ссылка на тему

Отредактировано chiefexb (2005-11-22 11:27:16)

10

Общими усилиями было выяснено, что в надписи на заставке используется пожатая карта тайлов, и без знания асма туда не стоит соваться.

Отредактировано Alex_231 (2005-11-24 09:46:54)

11

Да уж! Мне пока некогда а то можно было бы попробовать.

12

Я так и знал, что тут всё не так просто! Спасибо вам за ваш труд... Ничего..... Поумнею и лет через ...дцать её допереведу :о)

13

Не горячись я еще в поиске: глубоком debug'е, думаю можно сломать. Только править это все надо не PokePerevod'ом, а hexEditоr'ом

14

Вот что прислал мне griever:
http://chief-net.fatal.ru/images/guyver/marlinang_01.jpg

ссылка

Отредактировано Guyver (2009-07-11 13:54:52)

15

Круто!

16

Долгожданное объяснение от griever

"Задача:
Довольно часто в играх NES встречаются запакованные тайловые карты. Основной симптом этого - ненаходимость отдельных
надписей в РОМе. Один из тысяч примеров - игра The Blue Marlin на NES. На титульном экране есть множество надписей,
но та что мерцает(PUSH START BUTTON) не находится в РОМе.
Здесь я собираюсь привести пример того как лично я нашел
ее. Т.е. я не утверждаю, что это оптимальный вариант (я почти уверен, что можно это сделать если не легче, то уж
точно быстрее), но для примера, я думаю, сойдёт и так.

Тулзы:Я лично пользовался модифицированным эмулем FCEU под названием FCEUXD SP 1.04, но подойдет любой эмулятор с отладчиком
[бряки они и в Африке бряки =)], ну еще можно хексредактор, хотя просмотрщик хекса в РОМе есть и в FCEUXD SP.
Знания: Глубокое знание асма не обязательно [у меня самого его нет =)], но без азов можно ничего не понять.
Желательно, конечно, чтоб вы знали еще и что такое тайловые карты и работу процессора M6502 и т.д., но думаю,
это не является критичным требованием.
Всю необходимую инфу можно получить из доки Cah4e3'a, которую можно найти на его сайте и док Parasyt'a, которую можно
найти соответственно на его =)

Решение:
В первую очередь закрадывается подозрение, что надпись действительно спрайтовая(раз не находится сразу в такой простой
игре, где даже таблички стандартные). Чтобы убедиться  - нужно посмотреть в спрайтовый буфер - специальная область
памяти приставки, куда записываются индексы и аттрибуты спрайтов (в том числе и координаты). Вся теоретическая
база по этой теме содержится в супердоке Cah4e3'a. Я не стану описывать, как искать этот буфер - более понятно
и теоретически обоснованно это описано в доке Cah4e3'a. Плюс, во всех играх, с которыми я имел дело, буферы находились
в памяти по адресу 200h... Blue Marlin не исключение. Откроем клавишей F6 HexEditor, найдём адрес 200h.
Как мы видим, спрайты постоянно изменяются - оно и понятно - пузырьки воздуха на титульнике постоянно
поднимаются (ясно, что изменяют координату), плюс, возможно, тут есть перемешивание спрайтового
буфера (угадай, в какой доке это явление описано ;) ) Чтобы точно убедиться, что наша надпись составлена не из
спрайтов - можно взять мощный , но абсолютно не функциональный дебаггер с простеньким эмулем No$Nes
и нажать на F5 появится окно VRam viewer'a  откроем вкладочку OAM Data - и увидим табличку всех спрайтов, которые
есть на экране в данную секунду. Да, No$Nes бесполезен с точки зрения бряков, но этой функции я больше нигде не видел -
главное - наглядно. Красный квадрат отслеживает изменяющиеся спрайты, как видим нижняя часть экрана, где содержится
интересующая нас надпись не выделяется никогда, плюс в таблице спрайтов только графика пузырьков и никаких букв.
Кому интересно - могут заглянуть VRam viewer'ом в игру Teenage Mutant Ninja Turtles - Tournament Fightersв Options сразу видно, какая надпись составлена из спрайтов.
Итак - надпись не спрайтовая. Значит, поиск нужных процедур будет вестись по несколько иному пути...
берем нажимаем Ctrl+F1 появляетя  PPU viewer находим буквы, из которых составлено предложение press start button
Видим что-то вроде PRESTABU...буквы, конечно, не повторяются, т.к. в коде будут использоваться одна буква, загруженная
несколько раз.
Вот тут нам впервые повезло, да еще как! буквы полностью загружены в память PPU, без всяких изврашений, в читаемом
виде, самое главное теперь мы можем узнать индекс тайлов букв, которые загружены в  PPU
так, например P= $70, R=$71 и так далее. Это для нас означает, что обязательно при загрузке этого экрана, вызывается
процедура, загружающая эти значения в память PPU. Можно смело ставить BreakPointWrite на адрес $2368 в PPUсрабатывает бряк вначале, когда в PPU сохраняется ноль - это нас не интересует, жмем RUN и

Код:
$C330:B9 00 03  LDA $0300,Y @ $030D = #$70
>$C333:8D 07 20  STA $2007 = #$00

чуть выше видим команду, которая загрузила в аккумулятор число $70
как мы видим $70 содержалось в ячейке $030D в RAM'e нас интересует, кто записал это значение туда, ставим бряк уже на RАМ
и вновь загружаем наш титульник. Как мы видим, вначале эту ячейку активно используют для заполнения каких-то других
ячеек(может быть для вычисления значений и т.д.) нас это не интересует, т.к. все время код останавливается на команде

Код:
>$8031:9D 00 03  STA $0300,X @ $030D = #$A4 [В регистре А сейчас $40]
 $8034:E8        INX
 $8035:C6 02     DEC $0002 = #$18

.............................
Нас же интересует команда, которая загрузит $70, жмём RUN и замечаем, что это $40 грузится очень много число раз
пока дойдем до заветной команды можно поседеть. Можно заняться глубокой трассировкой кода (или Condition breakpoints),
как бы сделали опытные
хакеры, но я, к сожалению, к таковым не отношусь... Я выбрал более долгий, зато намного более понятный способ :
использовал прикольную функцию Trace Logger. ..что она делает? Просто записывает команды, выполненные процессором
в порядке их выполнения на экран или в файл - я предпочитаю последнее, т.к. можно пользоваться функцией поиска в любом
редакторе. Так вот просто берем и перед загрузкой нашего экрана жмем Start Logging, предварительно назвав файл, в который
будет записываться команды процессора вместе со значениями всех регистров и, для особых извращенцев, с состоянием всех
флагов =). прекращаем запись, как только на экране появится наш титульник(буквы уже загружены, а в файл пишутся не
интересующие нас команды). У меня получился файл размером 40 мегабайт( неплохо за 2-то секунды =) )
открываем текстовым редактором, ищем команду, аналогичную STA $0300,X @ $030D = #$A4, только меняем A4 на 70
конечно, мы уже перепрыгнем на один цикл интересующую нас команду, т.е. сохраняться будет уже другое число
в аккумуляторе уже $40),
а в ячейке  $030D  УЖЕ содержится наше заветное $70. Необходимо от команды, которую мы только что
нашли отлистать вверх до предыдущей записи в ячейку $030D .Просто вводим в поиск "STA $0300,X @ $030D = #$" и ищем
в обратном направлении [вверх]. После "#$" не стоит никакого числа, т.к. мы не знаем какое число содержалось в нашей ячейке
до того как в него было записано $70. Итак, через наносекунду в ячейке будет $70, если вы не забыли, это индекс буквы
'P' в слове  'PRESS' и мы, наконец, внутри той процедуры, к которой так рвались. Она уже у нас на крючке - осталась малость - только разузнать, что она делает, а
дальше дело техники... Строго говоря, процедура началась еще раньше - когда фактически начинала заполнять тайловую карту
в память - зрячие люди могут видеть, что до этого писался индекс $40, который, очевидно, означает пробел (ведь перед
словом 'PRESS' стоит пробел и даже не один...)
Итак, разрешите представить, наша процедура:
....................................................................

Код:
$8031:9D 00 03  STA $0300,X @ $030D = #$40 A:70 X:0D Y:02 P:nvUbdizc
$8034:E8        INX                        A:70 X:0D Y:02 P:nvUbdizc
$8035:C6 02     DEC $0002 = #$18           A:70 X:0E Y:02 P:nvUbdizc
$8037:D0 F1     BNE $802A                  A:70 X:0E Y:02 P:nvUbdizc
$802A:20 E8 80  JSR $80E8                  A:70 X:0E Y:02 P:nvUbdizc
$80E8:A5 08     LDA $0008 = #$A0           A:70 X:0E Y:02 P:nvUbdizc
$80EA:0A        ASL                        A:A0 X:0E Y:02 P:NvUbdizc
$80EB:90 04     BCC $80F1                  A:40 X:0E Y:02 P:nvUbdizC
$80ED:06 09     ASL $0009 = #$10           A:40 X:0E Y:02 P:nvUbdizC
$80EF:B0 05     BCS $80F6                  A:40 X:0E Y:02 P:nvUbdizc
$80F1:B1 0E     LDA ($0E),Y @ $A433 = #$01 A:40 X:0E Y:02 P:nvUbdizc
$80F3:C8        INY                        A:01 X:0E Y:02 P:nvUbdizc
$80F4:D0 02     BNE $80F8                  A:01 X:0E Y:03 P:nvUbdizc
$80F8:48        PHA                        A:01 X:0E Y:03 P:nvUbdizc
$80F9:20 FE 80  JSR $80FE                  A:01 X:0E Y:03 P:nvUbdizc
$80FE:E6 05     INC $0005 = #$6B           A:01 X:0E Y:03 P:nvUbdizc
$8100:A5 05     LDA $0005 = #$6C           A:01 X:0E Y:03 P:nvUbdizc
$8102:29 3F     AND #$3F                   A:6C X:0E Y:03 P:nvUbdizc
$8104:D0 11     BNE $8117                  A:2C X:0E Y:03 P:nvUbdizc
$8117:29 07     AND #$07                   A:2C X:0E Y:03 P:nvUbdizc
$8119:D0 0C     BNE $8127                  A:04 X:0E Y:03 P:nvUbdizc
$8127:60        RTS                        A:04 X:0E Y:03 P:nvUbdizc
$80FC:68        PLA                        A:04 X:0E Y:03 P:nvUbdizc
$80FD:60        RTS                        A:01 X:0E Y:03 P:nvUbdizc
$802D:45 04     EOR $0004 = #$70           A:01 X:0E Y:03 P:nvUbdizc
$802F:85 04     STA $0004 = #$70           A:71 X:0E Y:03 P:nvUbdizc
$8031:9D 00 03  STA $0300,X @ $030E = #$40 A:71 X:0E Y:03 P:nvUbdizc
$8034:E8        INX                        A:71 X:0E Y:03 P:nvUbdizc
$8035:C6 02     DEC $0002 = #$17           A:71 X:0F Y:03 P:nvUbdizc

....................................................................

Этого куска достаточно чтобы разобраться, что она делает: обратим внимание на то, что далее в ячейку  $030E грузится
число $71, т.е. уже следующим знаком будет буква с этим индексом. А это, ясное дело, буква 'R' ну и так далее, некоторые
буквы будут загружаться в ячейки несколько раз, как например буква 'S'. Теперь нам надо понять, как получают это число:
почти перед самой записью аккумулятор вытаскивают из стека и XOR'ят с $0004. Находим выше, что поднимаюм его в
стек командой '$80F8:48        PHA'  , а непосредственно перед поднятием в аккумулятор грузят значене из $A433
Это число можно рассматривать как некий своеобразный поинтер, из которого получают это число. Теплится слабая надежда,
что на этом трассировка кода закончена (т.е. уже число в ячейке $4A33 уже никак не вычисляют, и его можно будет
банально найти в РОМе). Чтобы найти это число в РОМе нам нужно знать, что по соседству - вновь ставим бряк на запись
в $030D и при загрузке титульного экрана, как только произойдет останов, открываем HexEditor, находим $4A33, как мы и
ожидали, там число $01, которое используется для расчета индекса второй буквы, т.к. первую мы к этому времени уже
загрузили и сейчас расчитываем вторую. Итак, запоминаем цифры по порядку - это $30 $01 $03 $01 $33 $33 $07 $01 $04
$05 $34 $36 $01 $47 $03 $0C $01 $39. Т.к. далее идут 'необычные' байты типа 'FF' можно сказать, что это конец
наших поинтеров, кроме того в фразе 'PRESS START BUTTON' вместе с пробелами ровно 8 знаков - как и цифр. Можно
ввести цифры поиском, можно перейти прямо так из FCEUXD SP, нажав правую кнопку, но факт в том, что все эти цифры есть
в РОМе[по адресу $a442] и их уже можно изменять в целях перевода!
Так, программой берется первое число($30) потом XOR'ится с предыдущим числом(было $40) получаем заветное $70!
[особо недоверчивые могут проверить в калькуляторе Windows =)]
Далее берется второй поинтер($01),XOR'ится с предыдущим числом(было $70) стало $71 и так далее...
теперь осталось только перерисовать буковки, расставить в нужном нам порядке поинтеры и закончатся наши мытарства
с этой надписью, а сколько их еще будет! =)

                                                                     -=#Griever's Stuff#=-                                                                       Н.Новгород 2005"

17

Ёклмн... Какой КОШМАР!!! А сколько их ещё будет ?!

18

Эх, сейчас пересмотрел то что написал давным-давно и пересмотрел алгоритм: выходит не всё так просто.
Есть приколы с тем как хранятся двойные буквы : preSS, buTTon и т.д. Что-то типа битового потока: если ноль, то буква одна, если единичка, то идут две одинаковых буквы, НО байт этого потока загружается не через
каждые восемь букв(что было бы естественно), а подчиняясь какому-то дикому алгоритму с тремя параметрами, который слишком крепок для моих мозгов.
Поэтому предлагаю Alex'y посмотреть что там на самом деле. В конце концов, это в интересах группы Chief-net.
А я бы с удовольствием узнал алгоритм.

19

Вот именно сегодня я решил вернуться к переводу этой игры - стал пробовать то, что не выходило раньше - а тут Griever со своим сообщением!!! Он что - мысли читает? Это же надо - выбрал тот же день ;о))) Вот и не верь после этого в совпадения ;о)

20

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

Код:
$80FE:E6 05     INC $0005 = #$6B           A:01 X:0E Y:03 P:nvUbdizc
$8100:A5 05     LDA $0005 = #$6C           A:01 X:0E Y:03 P:nvUbdizc
$8102:29 3F     AND #$3F                   A:6C X:0E Y:03 P:nvUbdizc
$8104:D0 11     BNE $8117                  A:2C X:0E Y:03 P:nvUbdizc
$8117:29 07     AND #$07                   A:2C X:0E Y:03 P:nvUbdizc
$8119:D0 0C     BNE $8127                  A:04 X:0E Y:03 P:nvUbdizc
$8127:60        RTS                        A:04 X:0E Y:03 P:nvUbdizc

Этот код, похоже, отвечает за копирование предыдущего символа, но проблема в том, что AND #$3F обнуляет только $40, $60, $80 и $С0, а у нас диапазон от $6А до $7С, значит, участок $8106-$8116 не сработает, так же и с AND #$07, который обнуляет (в нашем случае) $70 и $78, но $70 соответствует второму коду $33, кодирующему букву "S" в начале слова "START" (не там где нужно), а вот с буквами "Т" более-менее срабатывает: $78 соответствует коду $47 - который не вписывается в общий алгоритм работы и, по-видимому, организует копирование.

Мне бы посмотреть участки $8106-$8116 и $811B-$8126, тогда бы я мог сказать точнее.

Отредактировано Alex_231 (2006-09-04 05:53:19)


Вы здесь » Chief-NET » Экстрим хакинг » Blue Marline(Nes)