Skip to Main Content
Grand Larceny Auto — Robbing a Vault That Won't Give You Six Stars Back to Top

Grand Larceny Auto — Robbing a Vault That Won't Give You Six Stars

By shadowe1ite
4 minutes

the setup

This was tagged as a game hacking challenge, so the first thing I did was just play it.

It’s a small GTA parody called Grand Larceny Auto. You drive around, steal cars, knock over traffic cones, and your wanted level goes up. There’s a big VAULT sign — walk up, press F, and it says you need six stars. The catch is the game stops you at five.

So the whole thing is: get six stars when the game won’t let you.


poking at it first

Unzip it and look around.

unzip -q GrandLarcenyAuto-windows-*.zip
cd GrandLarcenyAuto-windows
ls
GrandLarcenyAuto.exe                      ~105 MB
GrandLarcenyAuto.pck                      2.3 KB
data_GrandLarcenyAuto_windows_x86_64/     188 files

A huge exe with a tiny .pck is a Godot export. The data_/ folder is a bundled .NET runtime (coreclr.dll, GodotSharp.dll, and so on), so it’s Godot with C#. One file stands out from the 188:

data_.../GrandLarcenyAuto.dll     93 KB

That’s the game. Since it’s a .NET assembly, I decompiled it with ILSpy:

export DOTNET_ROOT="$HOME/.dotnet"
export PATH="$HOME/.dotnet:$HOME/.dotnet/tools:$PATH"
export DOTNET_ROLL_FORWARD=LatestMajor

ilspycmd -p -o ./decompiled \
  "data_GrandLarcenyAuto_windows_x86_64/GrandLarcenyAuto.dll"

The class names survived (WantedSystem, SafehouseVault, CryptoUtil, PlayerState), so it was easy to find the interesting stuff. But the method bodies are ConfuserEx-obfuscated — control-flow flattening, so every method is a while (true) { switch ((num ^ 0x...) % N) } state machine with a bunch of junk arithmetic. Readable, but annoying. Here’s the raw SafehouseVault:

public string TryOpen() {
    if (player.WantedStars >= 6) {
        while (true) {
            int num = -399529747;
            while (true) {
                switch ((uint)(num ^ 0xD4D51D3A) % 6) {
                case 1u: array = CryptoUtil.DeriveKey(player.WantedStars); num = ...; continue;
                case 3u: array2 = CryptoUtil.Xor(SealedBlob, array); ...   num = ...; continue;
                // ...more fake states...
                }
            }
        }
    }
    return "...shut...";
}

The num = lines are all dead — they just pick the next fake state. I fed the obfuscated dump to an LLM and asked it to strip the control-flow junk into plain pseudocode, which gave me this:

// WantedSystem — the cap
public void EscalateHeat(int amount) {
    int s = player.WantedStars + amount;
    if (s > 5) s = 5;          // you can never go past five
    player.WantedStars = s;
}

// SafehouseVault — the door
if (player.WantedStars < 6) return "The vault stays shut. (You need SIX stars.)";

WantedStars is just a normal int. The only thing keeping me at five is that if (s > 5). Normal play never puts a 6 in there, but nothing stops me from writing it myself while the game runs. No patching, no rebuilding — just change the number in memory. So, Cheat Engine.

There’s a cheat console in the game (press K) that spits out a THM{...} string. It’s a decoy — it ends in _4r3_f0r_t0ur1sts. Ignore it, the real flag comes from the vault.


opening the vault with Cheat Engine

Start the game, then attach Cheat Engine to it.

WantedStars is a 4-byte int and I don’t know its address, so I let the game find it for me by scanning for the number on the HUD and narrowing down.

1. Scan type 4 Bytes, Exact Value, type my current star count (0 at spawn), then First Scan. Thousands of hits — that’s fine.

2. Commit one crime, boot a traffic cone. Stars go to 1. Back in Cheat Engine, Next Scan for 1.

3. Do that a few more times. Each scan drops the addresses that didn’t move with my stars, so the list shrinks fast.

after a few rounds you’re down to one or two.

4. Double-click the one that’s left to add it to the table, then the only thing that really matters: set it to exactly 6.

I tick freeze too, so the game can’t drop it back down while I walk over.

5. Walk to the vault and press F.

THE VAULT SWINGS OPEN
Six stars. All you had to do was rob the dang vault.
FLAG: THM{...}

Done. The flag (hover to reveal):

THM{h0tf1x3d_my_0wn_w4nt3d_l3v3l}

I ran Cheat Engine itself under Wine. If you’d rather stay native on Linux, scanmem / GameConqueror does the exact same job against the wine process: 4 bytes, scan, next-scan on change, set to 6.


wrap up

I don’t have a Windows machine, so I ran the whole thing under Wine and cracked it with Cheat Engine. It was a good learning experience.

thanks for reading.


Buy Me a Coffee if you liked this one