Hackerman's Hacking Tutorials

The knowledge of anything, since all things have causes, is not acquired or complete unless it is known by its causes. - Avicenna

Jan 29, 2019 - 4 minute read - Comments - Game Hacking

Cheating at Moonlighter - Part 3 - Enabling Debug HUD

In this part, I am going to use dnSpy to enable the Debug HUD. We will analyze how it's enabled and how it can be accessed.

Looking at StatsModificator.intelligence, I went down this rabbit hole to see how items are created.

Item creation call analysis Item creation call analysis

And I saw these two methods in a class named HUDDebug. They have curious names GiveItemToWill and GiveWeaponToWill. If my guess is correct, there's a debug UI somewhere in the game that allows spawning items.

HUDDebug Class HUDDebug Class

It has a Start() method, we can analyze it to see what calls it.

Seems like nothing calls it, same with Awake().

HUDDebug analysis HUDDebug analysis

These are unity methods. According to this video https://unity3d.com/learn/tutorials/topics/scripting/awake-and-start:

  1. Awake(): Called first even if the script is not enabled. Used for initialization.
  2. Start(): Called only once after awake and before update if the script is enabled.
  3. Update(): Called after the script is enabled and can be called multiple times.

These are called by the engine, so the Analyze tab will not have the chain.

Enabling Debug Mode

Inside Update() we can see:

HUDDebug.Update() HUDDebug.Update()

Pay attention to line 76. There's an if condition that enables everything. We can analyze IsDebugEnabled:

IsDebugEnabled analysis IsDebugEnabled analysis

Woot. It seems like we found it. Now we need to modify this to only return true.

IL instructions for get_IsDebugEnabled IL instructions for get_IsDebugEnabled

To return true, we need to return 1. We can delete lines 0 to 6 and only keep lines 7 and 8:

 7: ldc.i4.1    // push 1 to the stack
 8: ret         // return

Highlight lines 0 to 6 and press delete (or use the context menu) to remove them. Press Ok to get the modified C# code.

Modified get_IsDebugEnabled Modified get_IsDebugEnabled

This enables debug mode for every run. But what else is out there?

Debug Shortcuts

Let's go back to the analysis results for GameManager.IsDebugEnabled

IsDebugEnabled analysis IsDebugEnabled analysis

We have already looked at HUDDebug.Update, now we look at the other two.

HeroMerchant.Update() has some shortcuts.

HeroMerchant.Update() HeroMerchant.Update()

KeyCodes

Input.GetKeyDown detects when a key is pressed and released. The parameter to the method is an enum of type KeyCode or a string. It took me a while to find out the associated numbers.

I found it in the decompiled code at:

Here's a local copy, in case the repository is taken down.

It's based on ASCII-Hex decimal values with extra keys (e.g. gamepad) in the end.

Now we can decipher some debug shortcuts:

Potion Shortcut Potion Shortcut
  • 104: H
  • 304: LeftShift

Note we can also change the item granted with anything we want.

if (Input.GetKeyDown(98) && Input.GetKey(304))
{
    this.TeleportToFloorEnd();
}

We can teleport to the last room of any dungeon floor:

  • 98: B
  • 304: LeftShift

And so on.

Controller Shortcuts

HeroMerchantController.Update() defines controller shortcuts.

Controller shortcuts Controller shortcuts

Save/Reset Shortcuts

There are a couple of more shortcuts inside HUDDebug.Update():

Save/reset shortcuts Save/reset shortcuts
  • Save: LeftShift + S
  • Reset: LeftShift+ R

Enabling Debug HUD

We still need to enable the HUD. It must have a shortcut key. Searching the internet tells us it's Tab.

See this page about a CheatEngine trainer:

How can we find it ourselves? Back inside HUDDebug.Update() we can see a block that enables and disables consoleDebugPanel:

Enabling and disable consoleDebugPanel Enabling and disable consoleDebugPanel

Inside the if we can see that GameManager.Instance.consoleDebug is referenced. Let's analyze that.

consoleDebug  analysis consoleDebug analysis

Double-click on GameManager.Update():

GameManager.Update() GameManager.Update()

We can see it's triggered by holding the ButtonRightStick for a second (I think). A bit further up we can see the equivalent keyboard shortcut.

if (Input.GetKeyDown(9))

It's the Tab key which confirms what we found online. We can press Tab in the game to enable debug HUD.

Debug HUD Debug HUD

And it's quite extensive.

Lessons Learned

We learned:

  • How to use dnSpy's Analyze feature to track variables/methods/etc.
  • How to enable debug mode.
  • Shortcut keys for various things such as potions.
  • Shortcut key to enable the debug HUD.

My next plan was to use Cheat Engine to make cheats and enable debug HUD. But it's already done. In the next part, I will write my thoughts about some questions that I was asked about such cheating. Maybe after that, I will return and do the Cheat Engine part but I will need to re-learn the tool again.