News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Hi, I'm new to rom hacking and I have a question  (Read 2923 times)

Anilk

  • Newbie
  • *
  • Posts: 3
    • View Profile
Hi, I'm new to rom hacking and I have a question
« on: August 20, 2013, 05:11:38 am »
Hello

I tried searching for this, but I couldn't really find any good answers.  Sorry if there is a guide or a thread out there already.

I picked super mario 64 as a rom to start hacking because it was one of the few games that I actually owned that had tools out there for.  Anyways, I got most of what I needed to learn off this website and off of youtube, but I can't quite get the hang of hacking MIPS assembly. 

I've completely followed this awesome guide, but sadly, it isn't complete.

http://www.orbitaldecay.com/N64/

Through trial and error I've been able to do a lot of cool (and strange) stuff.  What I'm struggling with is finding the specific addresses I need.  Are there any better ways to find addresses other than using cheat engine? 

FAST6191

  • Hero Member
  • *****
  • Posts: 2962
    • View Profile
Re: Hi, I'm new to rom hacking and I have a question
« Reply #1 on: August 20, 2013, 06:09:44 am »
Arguably you have jumped in at the proverbial deep end, if only because the tools are not half as developed as the NES, SNES, GBA and a lot of other things. That document is not bad but it has a very odd way of looking at things, not inaccurate but not really the way I would expect things to be taught (others reading it teaches cheat making through the lens of the underlying OS memory model, though I guess with such an emulator happy crowd working on it that is not such a bad thing).

"Finding addresses"
In what regards?
Are you trying to find the address of a variable in RAM? If so then cheats are usually the way, there are more refined methods which are variations on what is to come in a little bit so I will hang back until then. I am not sure how much the N64 has in the way of dynamic allocation of memory aka the reason for pointer cheats -- quite famously the N64 was programmed extensively with C hence the dynamic recompilation method of emulation and C does afford pointers and programmers are encouraged to make use of such functionality (indeed one usually tells a bad programmer by the lack of understanding of them). If you want to find where it is in the RAM but take it deeper so you can find where it sits in the ROM and edit that ("I might have seven bullets but I want to know where in the game it says this gun can only hold seven bullets") then carry on reading.

Are you trying to find the address of a given piece of data in the ROM image itself? If so you want a method call tracing though this is where the rather underdeveloped nature of N64 emulation, debug devices and homebrew programming will come back to bite you. This is also why you are using a cheat engine as they are a crude alternative.

Are you trying to find the data that points to the data you want (possibly in the ROM itself)? For the most part the methods will resemble the previous two but there are slightly easier ways if you know where something is found. Typically if you find something in the ROM image and know the addressing of the system (where the ROM is found at, possibly also the commands of the DMA) you can try to search the ROM for such things.

On the ROM image, alas the N64 devs did not see the wisdom of the filesystem and as such have ROMs composed of giant binary blobs which you have to break down/map out manually. Pretty much everything that comes from an optical disc or is the DS or newer will have this but not here, at least outside some homebrew.
This means you are left with five methods
1) Tracing. Might be kind of hard owing to said lack of developed emulation though I have certainly seen and dealt with worse. The flow of things is the same anywhere in that you find where something is at runtime (or indeed if you know where something is in the ROM and find it at runtime) and follow its path as it gets copied to there, reset and follow that along......
2) Manual disassembly. Here you find your favourite MIPS R4300 disassembler and look at the text files it spits out, ponder what each instruction means and eventually get where you want to go. Tracing does much the same but cuts out 90% of the junk as you can watch it run and tell it to stop when something is read/written to, do the next so many instructions and other niceties. Many disassemblers will give you a guess as to what the value is referring to which can be useful but it is still not as nice as prodding it as it runs. That LEM asm program that guide suggests looks a bit crude (setting a virtual memory address seems like something it can not do and is about the second thing I would write into such a program after I had the instructions decoding properly) but will hopefully get the job done.
3) Function watching. The N64 has DMA and such like. Watch where it is pointing at and you can get a lot of info. It is not quite so nice as the likes of the GBA though which have far more specific functions that are almost always worth watching.
4) Blind luck. Many times have we simple scanned across the ROM in a tile editor or some other program and things popped out at us.
5) Fingerprinting and related methods. This is your traditional relative searching, pointer scanning, fingerprint detection (even if the developers did not have a filesystem many of the formats contained within would contain the hallmarks of the system-- things like files always starting with a given run of hex, even ASCII text)

Anilk

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Hi, I'm new to rom hacking and I have a question
« Reply #2 on: August 20, 2013, 07:11:29 am »
I should have been more specific.  When I meant finding addresses, I mean locating the address within the rom of a specific command using LemASM like it is done in this video

http://www.youtube.com/watch?v=jS-w20Dbnd8

Anyways, thank you for taking your time to post such a comprehensive response.  It's pretty late for me so I'll probably get working tomorrow, but I will post again if I have any success and/or questions.  Thanks again!

Also, on a side note, is this a good resource for getting familiar with MIPS? 

http://www.federaljack.com/ebooks/Computers%20-%20Informatin%20Technology/Assembly%20,%20reverse%20engeniering%20and%20Computer%20Architecture%20books/Assembly/Before/Prentice%20Hall/MIPS%20Assembly%20Language%20Programming%202003.pdf

I have some experience with programming with more mainstream languages, but assembly is new territory for me. 



FAST6191

  • Hero Member
  • *****
  • Posts: 2962
    • View Profile
Re: Hi, I'm new to rom hacking and I have a question
« Reply #3 on: August 20, 2013, 09:53:33 am »
Hmm. Had we been discussing most other systems and most other tutorials I would have say "so you want to find either injection/hooking points, the position of functions/sections of functions or space for your new code". Having now seen the cheat making and oddities there I am not so sure this is what you seek but in the absence of much else I will go with the above. If that is the standard tool than N64 hacking was more... agricultural than I feared. My main dalliances with MIPS tend to come when I am doing single instruction things on the playstation or compiling whatever which means I get to play with nice tools like http://www.romhacking.net/utilities/635/ . Unlike say the ARM7 and ARM9 instruction sets (differences but similar enough that you can use one on the other and it will work) I have no idea about the extent of the differences between R3000 of the PS1 and the R4200 of the N64 and it could be quite large.

Anyway you are pretty much then looking at tracing.
Going back to bullets in a gun.
You do the usual cheat thing and find that the number of bullets in a gun is stored at memory location [a]
Hurrah you can make a cheat for infinite ammo (assuming that is always the location of the bullets in a gun).
Being an assembly hacker you decide you want to take it a step further. You set what is called a breakpoint (maybe a watchpoint if you prefer that style of things) and when you next shoot a bullet the emulation will halt (at just shy of 94MHz that is still probably in the millions of operations per second) and up will pop a screen saying this instruction was either trying to subtract a value or set it depending upon certain things and where that instruction was found.
This instruction will either be in memory (fair enough, you get to repeat things) or in the ROM itself (always nice though maybe not the end of your road).
Now being an assembly hacker you have many paths available to you at all points, we often find this scares those new to assembly but not to programming but it is a fact of life and you get to deal with it. If you wanted infinite ammo you could then either break the set value or more likely go back a step or two and find the subtract number and change it to a set (though there is typically no such thing as set and to do that you use the MOV command). A warning at this stage -- though programs and programmers are taught to love functions sometimes it is not worth the penalty (though MIPS is quite odd here and where most other programmers are getting to be fast friends with the push and pop commands MIPS deals slightly differently if you want it to) and there can be many different sub commands and set value methods working on a given value, the traditional example given is to think of all the ways you can die in Mario (pit, enemy, time, poison mushroom, crushed behind a moving level....) and though the value may be a single location the amount of things that can and are designed to touch it may be higher. On the flip side and my favourite example is drawn from the N64 in the case of Goldeneye. Find a gameshark cheat for infinite life and turn it on. You can be shot all day but proper explosions might still kill you -- this is as the cheat can not hold your life high enough against as much damage as a proper explosion will do. Your assembly hack that negates the initial change has truly rendered you invincible though.
If your value was in the memory you get to repeat the trace until you find where that code came from in the ROM (though the promise of self modifying code is of great power it is still too dangerous for most people to use in practice so they do not). Though I guess you could make a cheat to change an instruction in memory, this is what many of the better DS cheats do as the binary is loaded into memory to even run.
Being an assembly hacker, and as such counted among the best of ROM hackers, you aspire to greater things still. Going back through the function you will see all sorts of things that deal with the firing of the weapon like recoil, damage, fire rate, accuracy.... congratulations you now have a recoilless, nuclear missile launching, rapid fire, sniper rifle. You may also notice that the values for those are loaded into memory from a table in the game (far better than having such a thing all in code) and you now have the basis for a weapons mod. Going back to the being shot part though you might also be able to negate the knockback/screen blurring effect.
Trace it even further back and you get to where it jumps to when it detects the button has been pressed and it only goes deeper.

To take it right back on topic though at each of those breakpoints it will tell you what instruction said to do it and where it is found. If it is memory you can try to see what put that in memory or try to grab that part of the memory and do a search in the ROM for it and if it is in the ROM you have your answer (give or take working a few steps forward or back to change exactly what you want). This sort of thing is also why they might have tried to teach you assembly when you learned programming as it does well when it comes to demonstrating why nested functions are often not ideal, why you may want to tone it down when it comes to storing everything in floats and other such things.

That covered injection/hooking after I say find the jump to that function or a part of the path and add your own jump, locating it comes as part of tracing and a place to put your own code is simply anywhere that has space. Finding said space may be easier said than done and you may have to trash something else, do your function, jump back and restore the original code, optimise later code to make it smaller to fit your instructions in or you might well simply get lucky and have a static section of memory that was never allocated or is never used.

Again your main problem is that the N64 debuggers fall far short of the really nice things we see with other systems or even the "everything is there but it might be a pain to use". n64js and Nemu seem to be your best bets but the main threads I found on the subject seem to be either quite outdated or from those are only skirted the peripheries of the N64 emulation world and there might be some as yet not widely known emulator with a debugger, I doubt it but I have seen stranger things happen.

That PDF... as far as primers on a non X86 architecture go it is one of the better ones I have seen, I do not know enough of the various flavours of MIPS and how it plays out across the consoles to say how relevant it would be to N64 vs some other MIPS device (it being geared more towards R2000 and R3000). For my taste it is a bit inclined towards the hand holding which I am not a fan of in programming tutorials but it is not unjustified, the appendices look quite nice as well.
I would still suggest http://www.plantation-productions.com/Webster/www.artofasm.com/index.html and http://stuff.pypt.lt/ggt80x86a/asm1.htm along with whatever else I usually link (usually http://www.coranac.com/tonc/text/asm.htm and finding a processor and/or hardware doc but I mainly deal in ARM stuff anyway). I usually prefer to go from various levels of electronics to general assembly, to general computer architecture, maybe a dash of FPGA type things and then lock it down/adapt it for the device (OK so this is basic assembly with fixed register size, I am not dealing with nested registers, I have no divide instruction on CPU but..., hardware floating point is single precision only, it is RISC so instructions tend not to exceed ? cycles, I have no SIMD stuff, immediate values are either a psuedo instruction or I have to generate them, memory access is only via a few commands rather than every instruction and on and on and on). I find this quite similar to learning a language mechanically (this is a verb, this is typical order of a sentence/noun-adjective....) in that you will often end up fairly proficient but you will miss many of the nuances until you encounter them for the first time and scratch your head for a while. on the flip side it does tend to allow you to transition between architectures somewhat more easily and if you are going to do something as backwards/esoteric as learning assembly in 2013 I figure you might as well have that. That said I have mad respect for those that do truly know an architecture and a system inside and out (I can make things work, they can make them sing).

Anilk

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Hi, I'm new to rom hacking and I have a question
« Reply #4 on: August 21, 2013, 03:33:12 am »
Thanks again for taking your time to answer my questions.  I've run into another issue though. 

I've been playing around with cheat engine and LemASM pretty much all day, and while I can do some neat stuff with it, I wanted to do a little bit more than edit single command lines.

Is it possible to add new lines using LemASM?  What I attempted to do was insert a bunch of commands into 00000514-000000530 (which all contain NOP) with LemASM and use

JAL 000000514

in order to reach these lines.  The problem is whenever I calculate the new CRC and attempt to run it on NEMU64, it says my boot code is wrong. 


Edit:  As luck would have it, I figured out the problem not too long after I posted this.  Anyways the problem was that I didn't pick a good spot.  Once I found a place right after a return statement to insert my code, I can run it on nemu just fine.
« Last Edit: August 21, 2013, 04:05:43 am by Anilk »