[HN Gopher] So, you want to be a ROMhacker? (2006)
___________________________________________________________________
So, you want to be a ROMhacker? (2006)
Author : mkl95
Score : 34 points
Date : 2021-02-24 12:22 UTC (1 days ago)
(HTM) web link (www.romhacking.net)
(TXT) w3m dump (www.romhacking.net)
| derefr wrote:
| In the modern era, I feel like ROMhacking is almost "obsolete" as
| a pursuit. By bit-twiddling a ROM image file, you're effectively
| forced to work within the constraints of an arbitrary static-
| linked memory-map generated by a linker decades ago to suit the
| precise needs of the particular assembler source fed in at the
| time (and the needs of the ROM chip that said source would be
| burned onto.)
|
| IMHO, with the tools we have available today, it makes much more
| sense to not directly hack _on ROM images_ themselves, but rather
| to first _disassemble_ the ROM; to factor the produced assembly
| into modules; to reverse the assembler data constant sections
| into separate named resource files, with a Makefile that converts
| them back; and so forth. At each step, with each change to
| increase legibility, you ensure that typing `make` continues to
| reproduce the original ROM image byte for byte.
|
| We've done this enough times now (e.g.
| https://github.com/pret/pokered et al) that the process is now as
| well-documented and tooling-supported as the process of hacking
| directly on ROMs is. With these tools, this reversing process is
| effectively no additional work over that required to develop a
| complete understanding of what the original game's ROM "says" --
| which you'd need to do either way. (Just, in the case of
| ROMhacking, the output of that understanding process are messy
| rambling docs, rather than an annotated ASM codebase under
| version control.)
|
| Once you have a source repo containing a clean, original-ROM-
| reproducing disassembly, you can then _fork_ that repo, and
| develop any "hacks" you like on top of it, with a regular IDE
| and cross-compile toolchain. At this level, you don't have to
| worry about overrunning allocated strings-sections, rewriting
| pointers, patching subroutines with jumps because there's no room
| left at the call-site, etc. The assembler and linker handle all
| that, and sort+fixup all the symbols and entries _after_ knowing
| how big they are. (There 's also nothing+ stopping you from just
| bumping up your target ROM image size if you run out of
| headroom.)
|
| If you do go through this reversing process on your way to
| producing a hack, then as a side-benefit, you'll have also
| produced an artifact (the clean disassembly) that documents the
| original game for anyone who wants it, e.g. people who want to
| know how the game's algorithms work to build speedrunning tools;
| people who want to learn old programming techniques lost to time;
| people who want to conserve the game by porting it to new
| platforms; etc.
|
| _And_ , of course, you make it _far_ easier for anyone who comes
| after you to _also_ produce hacks. They don 't have to go through
| the reversing process; they can just start with your clean
| disassembly code. (That "anyone else" also includes "future you
| who might want to come back and finish a years-old hack, and has
| forgotten how this all worked!")
|
| If you're a programmer, and you feel drawn to make ROMhacks, you
| _should_ reverse-engineer the source game first, if it hasn 't
| been already. It benefits you now; it benefits you later; it
| benefits the community. When you reverse an old game, everybody
| wins.
|
| -----
|
| + Well, okay, maybe you'll be limited by the fact that the system
| architecture only has an address-space so large, and the original
| game as written was small enough that it didn't use banking, but
| upon expanding it you now need to use banking. That's a hurdle,
| but not an insurmountable one... unless the system didn't even
| support banking. (Are there any systems that didn't?)
| grawprog wrote:
| I'm not sure rom hackers and people who can entirely
| dissassemble a rom always overlap.
|
| You don't need full knowledge of assembly or your target
| system's architecture to open a rom in a hex editor and play
| with some values.
|
| The skills and tools needed to dissassemble a rom, reprogram it
| and recompile it are a bit more involved.
|
| Saying, nobody should bother hacking roms unless they have the
| skills to dissassemble and recompile the game is going to
| discount a lot of the people that have brought the state of rom
| hacking and modification to what it is today.
| milesvp wrote:
| Yeah, while I agree with the parent about taking the time to
| disassemble a rom for larger projects, I feel he may be
| ignoring how low a barrier to entry it is to just modify some
| hex values and see them effect the rom you're playing. It
| used to be a common first thing budding programmers did was
| write trainers for games, which often amounted to little more
| than changing a hex value from 0x03 to 0xff. Now you have 255
| lives instead of the stock 3! Very heady stuff for someone in
| grade school, especially if those 3 lives cost a quarter in
| the arcade. There are a lot of people out there with little
| computer chops who would get a real thrill just replacing
| some of the sprites in their favorite game too.
| kmeisthax wrote:
| I spent about a year doing this to the Telefang translation
| patch itself. No, not Telefang, the _patch_ to Telefang. It was
| made with a version control system of "hex edit the last
| patched ROM to do what you want and post an IPS on the
| forums"... even though we were also writing tools to compress
| graphics and reinsert scripts (from MediaWiki, no less); as
| well as hand-assembled patches to get VWF text going. Needless
| to say this made fixing certain bugs or revising old work
| extremely difficult. For example, there were multiple versions
| of useful custom functions sitting in bank 0 (which had around
| 200 bytes free); developers had recreated certain utilities
| independently and assembled them separately into the HOME.
|
| Also, this was a multi-version game, because late-90s mongames
| demanded it. We only had worked on Power Version, so anyone who
| wanted to play Speed Version in English was SOL. Fortunately,
| both versions were similar enough that once I had disassembled
| our own patch, and modified the title screen a bit, Speed
| Version just "worked". Such is the power of having source code.
| jsmith45 wrote:
| Clean disassembly can be extremely hard for some games, and not
| always do what you want anyway.
|
| I mean sure, it is always possible to dump out "something" that
| can reassemble to the original if you don't change anything. It
| is less easy to get everything correct such that if you change
| the length of a code block or some data array the rom still
| fully works. This potentially requires having properly
| identified all the code vs data, and all data that contains
| static pointers to other data (including immediate instruction
| operands) and replacing them with labels. But on some systems
| that is still not too hard.
|
| On others it is terrible. For example the SNES where
| instruction sizes vary depending on the accumulator or index
| register mode sizes. This along with occasional use of non-
| standard flow control (like subroutine calls that never return,
| but instead pop the return address off the stack, and use it to
| find a jump table that occurs right afterwards), makes most
| attempts at automated disassembly fail. Semi-automated
| disassembly guided by information about instruction widths from
| an emulated playthrough helps, but getting such traces for all
| the code in a game can be really difficult.
|
| Even if you do end up with a completely accurate disassembly,
| significant changes are not always easy. SNES ROMs code banks
| may have little room remaining. Subroutines that can be called
| cross bank are different from those that can be called in the
| same bank, and there is very much visible differences to the
| assembly for cross bank data access vs "current bank" (which is
| not always the same as the current code bank). Assemblers that
| do the right thing here don't really seem to exist, and would
| be based on fallible heuristics that will silently misassemble
| in some cases leaving you with a crash.
|
| While obviously nothing is insurmountable here, it does mean
| that using ROM Hacking style techniques to avoid disturbing the
| bank layout can sometimes be easier than making the change you
| want, and then trying to shuffle things so that your new code
| will still fit.
|
| Things get even worse if you want to maintain glitch level
| compatibility with the original game (as is common for things
| like practice hacks for games that have glitch speedrun
| categories). Some glitches very much depend on out of bounds
| data accesses returning a specific value which happens to be
| some code, or a specific value in some later table. It can be
| difficult to preserve those while allowing code and data to be
| relocated. (Other glitches don't always require these sorts of
| things, and Nintendo has accidentally preserved many glitches
| in some games while porting from assembly to C.)
|
| I will admit that the SNES is MUCH, MUCH worse than most other
| consoles in the sort of headaches I describe above. Most other
| consoles tend to have an unambiguous disassembly that can be
| far more automated, newer console tend to avoid having near/far
| pointers and near/far subroutines, etc. The glitch
| compatibility considerations still apply though.
|
| I'm not arguing against full reverse engineered assembly of
| games, that can be wonderful. And starting from those can be a
| great way to develop a hack on some systems. But it hardly
| obsoletes traditional rom hacking, which can require much much
| less effort to get started with, and for some scenarios may be
| the better fit even with a complete disassembly available.
___________________________________________________________________
(page generated 2021-02-25 23:03 UTC)