Most searches for game hacking will return with a plethora of articles about using CheatEngine to make alterations in memory. While this is a valid option, I wanted to challenge myself to use a different method to implement some common game cheat functionality. I decided to use a reverse engineering framework to implement patches to the game files. Not only does it avoid using the clunky CheatEngine UI, it’s also much more portable and repeatable to make permanent changes to the game file, rather than in memory.
As the never-ending battle between IDA and Ghidra rages, Binary Ninja has slowly been improving in reliability and performance. Behind the aesthetic UI and intuitive keybindings is a powerful scripting API. Gone are the days of writing Java or Jython (looking at you Ghidra) – Binary Ninja supports Python and C++ by default, with Rust binding available too. This article is essentially going to be a demo of how I use the scripting API to write patch automation.
The target for the article is going to be the PwnAdventure3 Windows Client. PwnAdventure is a deliberately vulnerable video game, written for the Ghost in a Shell 2015 event, so feel free to follow along, or dive in and create some cheats for yourself.
PwnAdventure can be hosted on a server or played entirely from the game client. For the purposes of this article the game will be played entirely from the game client (offline mode).
A Basic Patch
This sets the highest byte of the 4 bit (little endian) signed integer to the max possible positive value. Saving the newly patched DLL and running the PwnAdventure.exe file, we now observe our speed increases rapidly until we can cross the entire map in just a few seconds.
Improving the Reliability
So that’s a fair way to increase the reliability. We could also increase the portability by removing the reliance on the PBL file.
Improving the Portability
In PwnAdventure, a player can collect spells as the progress through the game. The first spell a player gets is called Great Balls of Fire, and it costs 4 mana to perform.
Being able to perform the spell without worrying about mana levels would be pretty cool, let’s patch it out. This can be done without the PBL file by dynamically locating interesting data that exists directly inside the DLL, rather than symbols imported from the PBL file. Strings are a useful place to start here.
A Binary Ninja plugin for something like this could look like the following. The code has been commented heavily to describe the functionality of the Binary Ninja specific functions:
The spell now costs no Mana. This works on dll files independently of the PBL file too making the script more portable. This could be extended further by reworking the script to work independently of the Binary Ninja, as a headless script.