Intro to ROM/RAM hacking: Building an SMS powered Game Genie with Lua and Python

Old video games are notorious for being insanely difficult. As a child I was astonished to discover a magical item appropriately named Game Genie that allowed me to beat certain games. “Cheating” to make games easier was great, but some Game Genie codes made things more fun rather than just providing infinite lives. Some of these codes manipulated the games in absurdly interesting ways such as making all enemies throw hammers in Super Mario Bros.

hammer_cheat.gif
As a hacker, I love doing crazy things with code not only because it’s fun but because it’s a great way to learn new things. I was ecstatic to discover that many video game emulators offer an API for the Lua programming language granting access to all sorts of functionality like saving states and editing the game’s memory. Imagine opening these classic games up to the power of the Internet. Today we are going to do just that by using the memory manipulation API to build a Game Genie that operates via text messaging with Twilio.

Power Ups that we will need

  • A version of the FCEUX Nintendo emulator that has Lua API access. We will be using the 2.2.2 Windows binary. You can also use other emulators as long as they have the same Lua API. The same code should work for Visual Boy Advance(gameboy games), SNES9X(SNES games) and others.
  • Wine to run Windows applications if you are a Linux or Mac user like me. Unfortunately right now, the Lua API and debugging tools are more commonly found on Windows versions of these emulators.
  • A free Twilio account and one Twilio phone number with SMS capabilities.
  • Python with the Flask and Twilio libraries installed. These can be installed with pip.
  • A ROM file for The Legend of Zelda that we will use for testing purposes. If you own the game there are devices you can buy online that allow you to use the ROM file from your cartridge.
  • An insatiable hunger for manipulating old school video games and bringing them to life with the power of the internet.

And so, our journey begins

Experienced adventurers know that the first step on a quest is stocking up for dangers that lie ahead. This is true whether you are item shopping in Corneria before heading out to battle Garland or if you are a hacker trying to setup your environment for a new project.

The first item in our inventory will be our emulator of choice, FCEUX. Download FCEUX and extract the files to a directory of your choosing where our project will live. If you are a Windows user then you’re good to go. Linux or Mac uses will need to install Wine. If you are a Mac user with Homebrew installed, then you can also use your terminal to get Wine (you also need to install XQuartz as a dependency as shown below). You may need to run brew update before installation.

Now that we are well-equipped, let’s sling some Lua code to fend off our enemies. Open a new file called “nesms.lua” in your favorite text editor. Let’s write some code to take over the emulator’s execution.

emu.frameadvance() tells the emulator to advance exactly one frame which is the basic unit of time on an NES. The emulator usually does this itself, but allows our script to do whatever we want before each frame is rendered.

Now it’s time to open up FCEUX with Wine. If you installed it with brew or another package manager, you can navigate to the directory where fceux.exe is sitting and run wine fceux.exe otherwise you can double click the file itself. You need to be playing a game for code to run. So open up your Legend of Zelda ROM and run your code by clicking “File -> Lua -> New Lua Script Window” and navigating to the script.

HelloWorld.gif

Victory.gif

Cue the famous victory fanfare as we have won our first battle. These experience points will be useful. Now that we know how to get Lua code to execute let’s cut to the chase and get to the real hacking.

Jump higher, punch harder, live forever

gamegenie.gif
Our Hello World script is nice but it’s hardly as magical as my childhood experiences with the Game Genie. Let’s dig into some of the basic tools we’ll need to emulate Game Genie’s functionality. FCEUX comes with a host of awesome debugging utilities. One of the most important things in this toolbox is a hex editor. With this we can look at the contents of the game’s memory in the form of hexadecimal addresses and values.

The hex editor is the main tool that ROM hackers use to open up a game’s Read Only Memory and edit the hex values to change what is in the game. Cleverly editing memory addresses can result in some crazy gameplay modifications or even completely new games. Let’s open the hex editor and see what we can do with it.

All of the two digit hex numbers you see represent a value in the game’s RAM at a specific location. You can change any value to see what happens in-game. You can also search for specific consecutive values. Check out this example to see the hex editor in action to find the bytes corresponding to the timer in Super Mario Bros and then changing the time to zero to kill Mario.

hexediting.gif

ROM hacking can be a pretty daunting task. We are about to discover that you don’t need to be an expert to do some really cool stuff.

ROM represents the unchanging contents of what you’d find on a game’s cartridge whereas RAM represents the actual memory of the game as the program is running. Changes made to RAM appear immediately allowing you to make real time changes. There are NES RAM maps here and here that will tell you which memory addresses correspond to specific things in-game.

Let’s try to mimic the Game Genie by “enhancing” games with Lua scripts. As an example, let’s mess around with one of my all time favorites, the original Legend of Zelda. Using this RAM map we will edit certain values to make some funky stuff happen.

Open up a new file in your text editor and add some of these one liner example scripts to change RAM values and see what happens. You will need to have your Legend of Zelda ROM running in FCEUX have a new game started for these scripts to work.

It’s dangerous to go alone…

You’ve seen what we can do with a bit of Lua. But it is getting lonely in here so let’s equip ourselves. Instead of a sword, our weapon will be the power to communicate with other programming languages. I am not a very good Lua developer, but I love me some Python. Wouldn’t it be rad to manipulate the game’s memory with Python instead?

Our Lua scripts run in an environment provided by the emulator but we can open them to the outside world in a couple of different ways. We could use sockets or implement an HTTP server, but let’s just use text files for now.

Hop back to “nesms.lua” and add a function for reading text files:

We’ll use this function in our frame loop to listen for changes in two text files: “address.txt” and “value.txt” On every frame advance we will read a hexadecimal string from each of these files and write the contents of value.txt to the memory location in address.txt. Let’s add this to nesms.lua as well.

Let’s see if this code works. Run the new version of our script in your emulator and throw some hex numbers in them using the previously linked RAM maps for your game of choice. Let’s try another Zelda example:

  1. Load your Zelda ROM if it was not already open. Get past the file select screen and make sure you have Link on the overworld.
  2. Open “address.txt” and write “0600” (and nothing else) in the text file.
  3. Open “value.txt” and write “40” (and nothing else) in the text file.
  4. Save both files and run “nesms.lua” in FCEUX.
  5. Listen to the music change to the dungeon tune.

“Get equipped” with Twilio and FlaskGetEquippedWithTwilioMegaman2.png

Now we can receive input from other programs including the terminal output from Dr. Wily’s robots. The idea is to leave our nesms.lua script running and manipulate the game’s memory whenever those text files change. Let’s make this way cooler by setting up a Twilio phone number that will receive text messages with memory addresses and values to write to these text files.

First you need to create a Twilio account if you haven’t before and purchase a phone number. We will set up a Flask app to receive requests from Twilio once we configure our number. Here’s how you buy a phone number:

buy-a-twilio-number.gif

In order to receive messages, let’s make a web app on our local machine that will respond to HTTP requests. We will use the Flask web framework for Python because it’s lightweight and easy to get running. First install Flask and Twilio using pip. We’ll do it in a virtualenv to avoid messing with anything else on your machine. If you’re unfamiliar with pip and virtualenv you can check out this awesome guide to setting up your Python environment.

Navigate to your project’s directory, create a virtualenv and activate it.

Then install Flask and Twilio so we can write some code.

Open a file called “app.py” in the same directory as your Lua script and try this out:

Now that we have a hello world Flask app, lets run it:

Visit http://localhost:5000 on a web browser to make sure things are working.

Let’s make a route in our app to respond to the webhook Twilio sends when messages are received. We will expect messages in the form of a four digit hex address and a two digit hex value separated by a space. This will involve using Twilio’s Python library to generate some TwiML to respond to the message.

Now we need to expose our local environment to the Internet so Twilio can see our web app. Ngrok is a great tool for this. I would explain how ngrok works, but my buddy Kevin already wrote an awesome (and thematically relevant) post detailing this process. Once you have ngrok set up, you can run it to listen to the port that your Flask application is running on, which in our case is the default 5000.

You should see a screen that looks like this with a generated link that we can visit to access our Flask app:

ngrok.png

We need to add this URL to our Twilio phone number in the account phone numbers dashboard so Twilio knows to send us an HTTP request when a text is received.

twilio_dashboard.png

Your phone number is configured, your Flask server is listening for text messages and your emulator is running with our Lua script listening to these text files. We can finally shoot a message to this Twilio number to make some real time changes to the game you are playing.

To keep with our example from earlier open up your Zelda ROM in the emulator and make sure all of your code is running. Text “0600 10” to your Twilio number and this should change the music to the ending credits theme.

Here is an example of a message being received and making changes to Super Mario Bros to show that this works with any game.

mario_dies.gif

But our princess is in another castle

Here’s a twist: We didn’t just implement a Game Genie. You may have noticed that all of these arbitrary hex values don’t look like those beloved 8 character codes of days long past. All of this was just having fun hacking with low level memory manipulations.

With the actual Game Genie, the gamer enters a 6 or 8 digit code of seemingly arbitrary letters. This goes through a cipher and is translated to a hex address and value. The Game Genie hardware intercepts the memory reads from the game console and responds with the value that the code represents. Here is a pretty good explanation of this process with example bits of C code.

The Game Genie works by intercepting reads to the ROM. It actually isn’t messing with the RAM like we were. But idea is still the same: manipulating memory locations in the game and replacing the contents with different values to get the results we want. The Lua API actually gives us a way to bypass manually doing this. We can interact with Game Genie codes directly using emu.addgamegenie

Sure we can directly add Game Genie cheats to our emulator but aren’t you glad you learned the basics of hex editing and RAM manipulation first? The journey is satisfying in the same way that playing through every level of Mario is despite the princess only being in the last castle. But now let’s get through that final castle by adding the ability to accept Game Genie codes directly via SMS. Hop back into nesms.lua and make these changes:

Now our Lua script is checking cheat.txt to see if any new Game Genie codes have been added. Let’s take care of the rest by hopping back into our app.py and adding this to the Flask app:

And with this we should be done. Run our Flask app and our Lua script again and try texting “IZLZZZ” to your Twilio number while playing Zelda. This will make it so that when you walk into walls, enemies appear. This may not end well for Link.

gamegeniecheat.gif

The morning sun has vanquished the horrible night

When hacking old games I feel the excitement I felt in my younger days using Game Genie to have fun with my Nintendo cartridges. Now that we’ve went over the basics of ROM/RAM hacking, I hope you can derive this same enjoyment. Like Simon Belmont as the sun rises and his hostile enemies disappear, you are now able to equip yourself. With a small Lua script running in your emulator you can hack classic games using any programming language. There are endless possibilities now that we’ve hooked up old video games to the power of the Internet.

You can:

  • Have Mario send phone calls to your ex.
  • Exchange Bitcoin for rupees in Zelda.
  • Have Mike Tyson order you a pizza.

What crazy ideas can you think of?

a_winner_is_you.png

Check out the entire documentation for the FCEUX Lua API to get started on your own hacks. If you are curious about more of the hex editing stuff you can also see their hex editing guide.

I cannot wait to see what awesome emulator extensions you build. Drop me a line if you have any questions or if you just want to show off your hack.

  • digihaven

    Strange but cool rom hacking. But can it text high scores?

    • Sam Agnew

      You can modify this to text high scores with a little bit of tweaking. I think that sounds like an awesome idea.

      For reference, here are the RAM locations of the scores in Super Mario Bros for the NES:

      07DE – P1 Score: 9xxxx0
      07DF – P1 Score: x9xxx0
      07E0 – P1 Score: xx9xx0
      07E1 – P1 Score: xxx9x0
      07E2 – P1 Score: xxxx90
      07E4 – P2 Score: 9xxxx0
      07E5 – P2 Score: x9xxx0
      07E6 – P2 Score: xx9xx0
      07E7 – P2 Score: xxx9x0
      07E8 – P2 Score: xxxx90

      Taken from this RAM map: http://www.thealmightyguru.com/Games/Hacking/Wiki/index.php?title=Super_Mario_Bros.

      All you would need to do is write some code to read from those memory values and send the highest scores out as a text message :)

  • Ângelo Paulino

    haha! Great!

  • http://www.cregox.com/ caue

    Have you considered using https://github.com/bfirsh/jsnes ?

  • http://denilson.sa.nom.br/ Denilson Sá

    Regarding emulators with Lua support, I believe BizHawk (AKA EmuHawk) is the best one. It is a multi-system emulator with support for several consoles and handhelds, and has Lua support for all of them (or most of them).

    http://tasvideos.org/BizHawk.html

    It is widely used by the “tool-assisted speedrun” community.

    • Sam Agnew

      Wow that’s a really good resource! Thanks a bunch for showing this to me. I’m surprised I haven’t checked it out before. The TAS community never fails to impress me.