Infinite Coins in a Single-Player Tower Defense Game: A First CE + x64dbg Walkthrough

About the author. I’m Colin Xiao — an independent reverse engineer, mostly working solo on contract jobs. I dig into compiled code of every kind, including but not limited to: Android and iOS apps, x86/x64/ARM native binaries, packers and obfuscators, DRM and license checks, network protocols and APIs, crypto and signature algorithms, malware, game binaries, and embedded/IoT firmware. I also handle large-scale data collection and vulnerability research. If you have any project in mind, I’d be glad to take it on — whatever it is, as long as it’s within my wheelhouse. Just reach out. You can reach me on X at @colinxiao_lab or on Telegram at https://t.me/ColinXiao666.

This research is published for educational and defensive purposes. The target sample is anonymized throughout.


Infinite Coins in a Single-Player Tower Defense Game: A First CE + x64dbg Walkthrough

There’s a game about a bunch of little monkeys popping balloons — it’s on its 6th installment now, and I like it too. I’m new to reverse engineering, so I figured I’d practice on a game I actually play. My skills are still limited, so be gentle.

In a tower-defense game, the towers you place each round are limited by in-round coins. You start with an initial amount, place towers, earn coins from popping enemies, then place or upgrade more. When the round ends, the in-round coins are discarded, and the next round starts back at the initial amount.

So let’s do a reverse-engineering pass around those coins and see how to make the in-round coins infinite.

Back in the day I’d have used a memory editor for single-player games. Now that I’m learning reverse engineering, I’ll do it properly with Cheat Engine and x64dbg.

Step 1 — Find the coin value in Cheat Engine

First, use the classic memory-search approach: search for the coin value in CE and find memory address A.

Searching for the coin address in CE

Editing the value at address A doesn’t actually change the coins in game — but the value does reflect the current coin count. In other words, address A only displays the current coins; it isn’t the real storage location, and the real location can’t be found with a direct CE search.

Hypothesis: the real coin value isn’t written to memory directly. When the real value changes, the game separately updates address A. So let’s find the code that writes address A and see what it reveals.

In CE, right-click address A and choose “Find out what writes to this address”:

Find out what writes to this address

Then spend some coins in the game, and this code shows up:

The write instruction

movsd [rbx+28], xmm6

This copies the low 64 bits of xmm6 into [rbx+28] — the address A we just found. The instruction sits at 0x7FF9A2BB797D, which is the base of GameAssembly.dll plus offset 0xA1797D.

Step 2 — Find it in x64dbg

Use x64dbg to reach 0x7FF9A2BB797D. Close CE first to release its attachment to the game process, then open x64dbg and attach to the game. Navigate to 0x7FF9A2BB797D. Don’t close the game during this — if you do, the base address it’s loaded at will change.

The surrounding code looks like this:

Context around 0x7FF9A2BB797D

From the code you can see that before xmm6 is copied to [rbx+28], it’s copied from xmm1. So now we need to find where xmm1’s value comes from. Click the function head and look at who calls this function:

Looking at the callers

Too many callers — hard to narrow down, and with my limited experience I hit a dead end here.

So I started over, looking for another angle. Search for address A in CE again, “find out what writes to this address”, double-click the record — and I can see the base rbx in [rbx+28] is 0x1F8AAD604B0:

Finding the rbx base

Now search for the hex value 1F8AAD604B0 in memory — two addresses store it:

Two addresses holding the value

Track both (find out what accesses these addresses). When coins change in game, only the second address, B, is accessed:

Tracking the accesses

Three places access address B. By placing and selling towers over and over, I worked out:

  1. When a tower is clicked, the first instruction’s count jumps, by a lot each time.
  2. When a tower is placed (coins decrease), the second instruction’s count goes up by 1.
  3. When a tower is sold (coins increase), the third instruction’s count goes up by 1.

So the second instruction is the interesting one. If I can work out what that code does, I might get infinite coins. Here’s where it lives:

The second instruction’s location

Locate it in x64dbg:

The coin-subtraction code

This is the code that subtracts coins. The yellow box shows the call that updates address A. The white box shows that xmm1, before being copied to xmm6, came from xmm0; and xmm0, before that, was computed by subtracting xmm6 from itself. Setting a breakpoint and watching the register values confirmed it: xmm0 holds the current coin value.

So I changed:

subsd xmm0, xmm6

to:

addsd xmm0, xmm6

Running it — every time I place a tower, instead of losing coins, I gain coins. That effectively gives infinite coins.

Finally, use x64dbg to make a patch and replace the original file. Note this code isn’t in the main executable but in a DLL, so the patch has to be a DLL too.

And that’s a wrap!

(P.S. Don’t cheat like this in games — once you crack it, the fun evaporates instantly. This is for technical discussion only.)


Colin Xiao — I take on contract reverse-engineering work, and writeups like this are how I show what I can do. If you need help with anything in this space — including but not limited to the areas I cover above — I’m available. No project is too big or too small — if it’s reverse engineering and I can do it, I’ll take it. DM me on X (@colinxiao_lab) or Telegram (@ColinXiao666).

Get in touch