Updates:

Fans are welcome!

Мысли по дизассемблированию

Started by teremochek, June 10, 2014, 11:08:07 AM

Previous topic - Next topic

teremochek

У кого есть идеи, как можно дизассемблировать TGL. И вообще мысли по этому поводу.
Есть вариант использовать "IDA". Сложность состоит в том, как потом определить, какая рутина за что отвечает.
Еще вопрос, как именовать память т.е. какая память за что отвечает. Для этого вероятно нужно использовать FCEUX. Может у кого есть опыт в этом...

arseniy

на английском бы спросить, optomon может что-то подсказать.

Anegorami

У FCEUX есть целый набор инструментов - во время написания MaPs (который, по идее, нужно переписать с нуля, чтобы уменьшить концентрацию плохого кода) я пользовался именованием ячеек\участков памяти.
Quote
FCEUX allows you to label any address of RAM or ROM with a human-readable symbolic name.

For example, when you've figured out that at the address $C022 there's a subroutine which refills player HP, you can right-click the address and type a name like "AddHealthpoints". You can also add a comment, which will be seen while browsing the code near this address. From now on, the address will be substituted by the name everywhere - in all instructions referencing this address, in Hex Editor window, in the log produced by Trace Logger. E.g., JSR $C022 will look like JSR AddHealthpoints.

When entering the name, you can use any symbols except #. It's also recommended to avoid whitespaces in names.

To rename an address, just right-click the name.

The data for Symbolic Debugging is stored in NL files in the same folder as the ROM. You can edit the files in any text editor (to reload all NL files of the currently active ROM file press the "Reload Symbols" button), but it's more convenient to use right-clicks.

You can enable and disable symbolic debugging by clicking the checkbox "Symbolic debug" in the lower right corner. In general, there's no need to disable this feature. If you need to see the actual address which got substituted by a name, you can simply left-click the name and watch its address in the "Seek To" text field. This also works when clicking a name in the Trace Logger window.
А насчет дизассемблирования - я пользовался только FCEUX'овым Debugger'ом.

teremochek

Пока покажу что получается при дизассемблере IDA'ой.


; =============== S U B R O U T I N E =======================================


sub_60D12: ; CODE XREF: sub_63282+177p
; BANK7:F62Dp ...
LDY #0
STY $11
STA $10
LDA $518,X
CMP $668,X
BEQ locret_60D0E
BCS loc_60D34
LDA $5C0,X
CLC
ADC $10
STA $5C0,X
LDA $5D8,X
ADC $11
STA $5D8,X
RTS


Давайте покумекаем что к чему.
Во первых почему субрутина называется sub_60D12: ?
Я надеюсь что все-таки это адрес в роме.
Только адрес 4'ех значный. Может первая цифра номер банка?
Только нет. Написано же что банк 7.


CODE XREF: sub_63282+177p

Возможно адрес другой субрутины из которой вызывается эта.

Насколько мне кажется у FCEUX дебаггера некоторые трудности с распознаванием Даты.
Хотя возможно я им плохо умею пользоваться...

Anegorami

Я, возможно, чего-то не понимаю, но в ROM'е этот код расположился по адресу 0x01CD22:

A0 00
84 11
85 10
BD 18 05
DD 68 06
...

FCEUX Debugger выдает следующее:

07:CD12:A0 00     LDY #$00
07:CD14:84 11     STY $0011
07:CD16:85 10     STA $0010
07:CD18:BD 18 05  LDA $0518,X
07:CD1B:DD 68 06  CMP $0668,X
07:CD1E:F0 EE     BEQ $CD0E
07:CD20:B0 12     BCS $CD34
07:CD22:BD C0 05  LDA $05C0,X
07:CD25:18        CLC
07:CD26:65 10     ADC $0010
07:CD28:9D C0 05  STA $05C0,X
07:CD2B:BD D8 05  LDA $05D8,X
07:CD2E:65 11     ADC $0011
07:CD30:9D D8 05  STA $05D8,X
07:CD33:60        RTS


07:CD12:A0 00     LDY #$00       LDY #0
07:CD14:84 11     STY $0011      STY $11
07:CD16:85 10     STA $0010      STA $10
07:CD18:BD 18 05  LDA $0518,X    LDA $518,X
07:CD1B:DD 68 06  CMP $0668,X    CMP $668,X
07:CD1E:F0 EE     BEQ $CD0E      BEQ locret_60D0E
07:CD20:B0 12     BCS $CD34      BCS loc_60D34
07:CD22:BD C0 05  LDA $05C0,X    LDA $5C0,X
07:CD25:18        CLC            CLC
07:CD26:65 10     ADC $0010      ADC $10
07:CD28:9D C0 05  STA $05C0,X    STA $5C0,X
07:CD2B:BD D8 05  LDA $05D8,X    LDA $5D8,X
07:CD2E:65 11     ADC $0011      ADC $11
07:CD30:9D D8 05  STA $05D8,X    STA $5D8,X
07:CD33:60        RTS            RTS

Адрес 0x60D12 указывает на начало кода.

teremochek

#5
Спасибо.
Это хорошо. Единственное не понимаю почему "60" а не С ?
В принципе не важно, главное что это понятно.

IDA кажется не подходит. В ней нет автоматического определения Даты от Ассемблера.
В ручную это делать, я не знаю как. Придется сначала учить IDA.. Легче воспользоваться FCEUX дебаггером, о чем и упомянуто в этом документе.
http://griever.magicteam.net/doc/?doc=NES_IDA

Кроме того есть еще такой дизассемблер - "Smart Renes"
Но в случает TGL он выдает ошибку. Хотя большая часть рома вроде дизассемблирована. Вот для сравнения, та же рутина.

Lbl_cd12:
   ldy #$00
   sty $11
   sta $10
   lda $0518,x
   cmp $0668,x
   beq Lbl_cd0e
   bcs Lbl_cd34
   lda $05c0,x
   clc
   adc $10
   sta $05c0,x
   lda $05d8,x
   adc $11
   sta $05d8,x
   rts


Какие есть доки, или лучше в двух словах может объяснишь, как работать в FCEUX дебаггере.
Предлагаю взять и дизассемблировать один простой Метод.(Например метод стрельбы основного оружия.)

Anegorami

#6
Документы можно откопать здесь: http://www.romhacking.net/?page=documents&category=11&platform=1&game=&author=&perpage=20&level=&title=&desc=&docsearch=Go.

Насчет отделения кода от данных:
Quote
The Code/Data Logger makes it much easier to reverse-engineer NES ROMs. The basic idea behind it is that a normal NES disassembler cannot distinguish between code (which is executed) and data (which is read). The Code/Data Logger keeps track of what is executed and what is read while the game is played, and then you can save this information into a .cdl file, which is essentially a mask that tells which bytes in the ROM are code and which are data. The file can be used in conjunction with a suitable disassembler to disassemble only the actual game code, resulting in a much cleaner source code where code and data are properly separated.
Сам ни разу не пользовался, потому ничего о производительности сказать не могу. К тому же, чтобы получить результат, нужно ПОЛНОСТЬЮ ПРОЙТИ ИГРУ, ИСПОЛЬЗОВАВ ВСЕ ВОЗМОЖНЫЕ ВАРИАНТЫ.
Quote
The Code/Data Logger can also be used to generate a stripped NES ROM.
"Stripped" NES ROM is a ROM in which everything that was not logged by the Code/Data Logger is removed. It can be useful in many ways, for example, you can view the ROM in an external Hex Editor or a Tile Viewer, and you'll see only the parts that were used while playing. Furthermore, you could use it to create a demo ROM by only playing through the parts you would like others to see.

Example of such usage:
1. Open the Code/Data Logger, and press Start to begin logging.
2. Perform a soft and a hard reset while logging, in order to capture the ROM's startup sequence. If you don't do so, you can distribute a save-state file so they will start from within the game.
3. If the game has Save-RAM (e.g. Zelda), you will need to capture the game's Save-RAM initialization routines; you can try to do so by deleting the game's *.sav file and then perform a soft and hard reset again while logging.
4. Play through whatever levels you want present in the demo ROM. Be sure to perform every move, get every item, etc., so that the code and data necessary for those things are logged. If, for example, you fail to perform some special move, and then someone plays the stripped ROM and attempts to perform that move, the game may very well crash or glitch up, because there are zeros in the stripped ROM instead of the code responsible for handling this special move.
5. Save the stripped NES ROM.
Впрочем:
Quote
When you "Load" another .cdl file, it does not clear the current log; instead, it combines ("arithmetical OR") it with the information in the file. This can be useful if you're trying to obtain a complete log of certain game, as multiple people can play through the game and keep own code/data logs, and then the results can be combined into an all-encompassing log. But if you would like to actually clear the code/data log, press the "Reset Log" button.
Так что, похоже, придется всем заняться очередным прохождением любимой игры.

А насчет работы в Debugger'е - есть справка, в которой описано гораздо больше фишек, чем я когда-либо использовал.

UPD:
Все чуть более радостно, чем я думал. Дойдя до первого сохранения (по дороге провернув мягкий и жесткий сбросы и посмотрев демки) спустил *PRG not logged* до 36.93%.

UPD2:
Зачистил первый сектор - 32.21%. Архив с сохранением и маской: https://dl.dropboxusercontent.com/u/79803223/Forum/TGL/CDL.zip.

UPD3:
Получил второй ключ - 26.61%. https://dl.dropboxusercontent.com/u/79803223/Forum/TGL/CDL2.zip.

teremochek

#7
Большой респект!

В папку с игрой нужно добавить файлы:

имярома.nes.ram.nl - для именования памяти [0x7FF]
имярома.nes.0.nl     - для именования рутин и переходов( цифра кажись номер банка )
имярома.nes.1.nl
имярома.nes.2.nl
имярома.nes.3.nl
имярома.nes.4.nl
имярома.nes.5.nl
имярома.nes.6.nl
имярома.nes.7.nl    - (не сменный банк)

Затем нажав кнопку Reload Symbols все это добро будет добавляться в деббагер.

Будет хорошо собрать информацию о памяти в отдельном топике.(как это сделано в Eng разделе.)

Anegorami

Пока приостановил прохождение. Так что не стесняемся - подхватываем сохранение и продолжаем.

teremochek

Своими словами напишу как именовать памать во FCEUX.
Запускаем игру в эмуляторе, затем DEBUG -> HEX EDITOR.
В Хекс Эдиторе проверяем VIEW -> NES MEMORY.

Память состоит из:
$FF                 ZEROPAGE       Нулевая страница (256 адресов)
$FF - $1FF      STACK             Стэк (256 адресов. Не именуется)
$1FF - $7FF    3 to 8 PAGES   Оставшиеся шесть страниц (256*6=1536 адресов)

Затем вся эта память повторяется 4 раза до адреса $1FFF. И это не имеет для нас значения.

Замораживаем интересующие адреса. Проверяем результат. Если понято за что этот адрес(а) отвечают.
Придумывает и вписываем ему имя. Таким образом эти имена появятся в Дебаггере, в дизассемблере.

teremochek

Интересно-бы сделать ХАК, в котором увеличить Максимальную силу оружий с 3 до 5, скажем.
Еще идея такая, если узнаем лучше как устроена карта, и где она хранится, то идея сделать мод - только ходьба по лабиринтам.

Более грандиозная идея, это увеличить кол-во спрайтов. Для этого надо понять как все это работает в РОМЕ и эмуляторе. (Должно быть) в памяти хранятся 64*4 ячейки зарезервированные под спрайты. Затем в каких-то рутинах, эти спрайты передаются в память графического процессора.
Так-что сначала придется память спрайтов в роме перенести, и увеличить. А потом наверно увеличивать память в GPU эмулятора.
В идеале, реализовав это, можно будет вызывать несколько больших боссов без мерцания спрайтов.

arseniy

Лютая идея. Как мне кажется, проще и доступнее твой проект доработать и там всё это реализовать.

Anegorami

Quote from: teremochek on June 19, 2014, 06:52:19 AM
Интересно-бы сделать ХАК, в котором увеличить Максимальную силу оружий с 3 до 5, скажем.
Тогда придется разобрать формат бонусов, разбросанных по карте - ЕМНИП в игре оружия положено ровно столько, чтобы его хватило на три ступени.

Quote from: teremochek on June 19, 2014, 06:52:19 AM
Еще идея такая, если узнаем лучше как устроена карта, и где она хранится, то идея сделать мод - только ходьба по лабиринтам.
Не стоит вырывать из контекста один из жанров. TGL тем и хороша, что чередует исследование и битвы.

Quote from: teremochek on June 19, 2014, 06:52:19 AM
Более грандиозная идея, это увеличить кол-во спрайтов. Для этого надо понять как все это работает в РОМЕ и эмуляторе. (Должно быть) в памяти хранятся 64*4 ячейки зарезервированные под спрайты. Затем в каких-то рутинах, эти спрайты передаются в память графического процессора.
Так-что сначала придется память спрайтов в роме перенести, и увеличить. А потом наверно увеличивать память в GPU эмулятора.
В идеале, реализовав это, можно будет вызывать несколько больших боссов без мерцания спрайтов.
Quote from: arseniy on June 19, 2014, 10:14:20 AM
Лютая идея. Как мне кажется, проще и доступнее твой проект доработать и там всё это реализовать.
Соглашусь. Зачем переписывать графическую систему, когда можно извлечь логику поведения и адаптировать ее под новую графическую систему?..

arseniy

Quote from: Anegorami on June 19, 2014, 07:11:24 PM
Не стоит вырывать из контекста один из жанров. TGL тем и хороша, что чередует исследование и битвы.

Мне кажется тут большой минус в том, что пропадает смысл способности героя трансформироваться.

teremochek

Quote from: arseniy on June 20, 2014, 10:46:09 PM
Мне кажется тут большой минус в том, что пропадает смысл способности героя трансформироваться.
Речь идет о простоте хакинга, а не о том что лучше.
Поэтому для начала можно потренироваться, и попробовать что-то одно. Тем более у некоторых уже есть опыт работы с картой.

Quote from: anegorami on June 20, 2014, 10:46:09 PM
Тогда придется разобрать формат бонусов, разбросанных по карте - ЕМНИП в игре оружия положено ровно столько, чтобы его хватило на три ступени.
Формат карты и бонусов придется разобрать.
Оружия в игре по разному. Голубой шар можно взять пять раз, если память мне не изменяет.

Quote from: anegorami on June 20, 2014, 10:46:09 PM
Соглашусь. Зачем переписывать графическую систему, когда можно извлечь логику поведения и адаптировать ее под новую графическую систему?..
Скорее всего писать много не придется.. Сложность в том, где конкретно и что писать.