Decrypting Noita's files

After I got my hands on a game called Noita I couldn't help but get curious about how the game was implemented, so naturally I tried to take a look at its files.. But most interesting files were hidden away inside of a file named "data.wak". How could I gain access to these files?

Discovery

I tried to see if it was some kind of known file format by using the file tool inside of Linux. This tool contains a database of known file formats and will immediately give an indication of what the file-type of any file could be. But in this case file only gave the nondescript description 'data'.

This meant that it wasn't a known file format.. The next step was to analyse the file with ent, this tool measures the entropy of the file, in this case it told me that the entropy of the file was 7.999 bits per byte, this means that the file contained no detectable redundancy. That indicates that the file is either encrypted, compressed or both.

Misstep

Inside of the accessible game files there was a folder named licenses, after looking through it I found out that Noita used a compression library called "fastlz". I spent a lot of time trying to use this library to decompress the .wak file, with no success.

I decided to take a closer look at what the game was actually doing with the file data instead of trying things on a hunch.

Ghidra and GDB

My next step was to look at what the code was actually doing, for this I used Ghidra to look a the disassembled and decompiled code. With this I created theories about how the code worked.

To find out what code I needed to look at I used GDB to set breakpoints on standard Linux file loading functions. This way I eventually found out what code dealt with loading "data.wak".

After a lot of trail and error I found the exact point at which the file names got loaded from "data.wak". This was a great milestone for me, so I took a picture 😁.

Output of GDB where the same breakpoint gets hit multiple times.
file names such as materials.xml are printed to the console.

The file name secrets_secrets_secrets.png piqued my interest and kept me motivated!

After more experimentation I found out where the file contents got loaded, I also discovered the file's contents was loaded in-place of the unreadable version. This meant that unreadable and readable version of these files are the exact same size, so that rules out compression, it's only encrypted.

Misstep 2: Reimplementing AES by looking at assembly code

Noita used standard AES encryption.. I do not have enough experience with this kind of stuff to recognise that, so instead I went through the long and painful process of recreating the AES algorithm by looking at the disassembly/decompiled code in Ghidra & GDB.

This took a while, but eventually I managed to extract all files from "data.wak". Success! Secrets Secrets Secrets!

So what was the contents of secrets_secrets_secrets.png? Here it is:

Green text with a black background.
The text is: "Look at you, hacker, aren't you a clever one? We're really impressed.
Congrats! You now have access to all our secrets and while we cannot stop you,
maybe we can make a little deal? You can leak all the information if you want to.
or if you wait till 11.10.2019 before releasing them we will put you in the credits of the game."

This was a very cool surprise . After sending a couple emails and waiting a bit I got to see my name in the credits of the game!

A list of names under the section "Cryptic Highscores". A red arrow points at number 15 with the name Dexter Castor Döpping

I'm very proud of this accomplishment, I didn't have any reverse engineering experience so it took a lot of time and effort.

You can checkout the code I wrote to extract all of the files here: https://github.com/dextercd/Noita-Wak-Extractor/blob/master/src/enc.cpp

I hope this was interesting to you! :-)