Archive

Archive for the ‘IL2CPP’ Category

IL2CPP Tutorial: Finding loaders for obfuscated global-metadata.dat files

February 23, 2021 11 comments

Game publishers are loving it lately. Over the last few months I’m starting to see all kinds of weird and wacky obfuscation schemes designed to prevent Il2CppInspector from loading IL2CPP games.

While it’s quite amusing to see narrowly targeted attacks percolate, it does make the support tickets pile up on the issue tracker, and I unfortunately have neither the time nor the desire to sit and pick apart every file thrown at me. The old adage of giving a person a tool and they’ll hack for a day, but teach a person to write tools and they’ll hopefully stop spamming your social media seems pertinent here. At least I think that’s how the adage goes… or was it fish something? Either way, we all started off as plankton; hopefully you are thirsty to become a shark!

In this tutorial, I’ll walk (swim?) you through how to find the loader for global-metadata.dat in almost any IL2CPP application so that you can reverse engineer it yourself. This will include obfuscated metadata, encrypted metadata, and metadata embedded in the binary itself, plus light obfuscation of the code path to the loader. I’ll also throw in a couple of examples to whet your appetite.

Read more…
Categories: IL2CPP Tags:

Reverse Engineering Adventures: Brute-force function search, or how to crack Genshin Impact with PowerShell

January 24, 2021 6 comments

Today, I thought we’d have a bit of fun and show you a novel and unorthodox alternative way to find any function with known discrete inputs and an assumption about the possible outputs in a compiled application – specifically for this example, a decryption function in a game. We’re going to crack it with PowerShell.

Well, sort of… far be it from me to troll my dear readers with a clickbait title, but there is an element of truth in this. At the very least, to perform this attack your life will definitely be easier if you have some kind of scripting language on hand.

The technique I’m about to describe can be applied to any application which you know contains a specific function with particular arguments and return type, but don’t know where it is located in the binary file.

Read more…
Categories: IL2CPP, Reverse Engineering Tags:

Reverse Engineering Adventures: VMProtect Control Flow Obfuscation (Case study: string algorithm cryptanalysis in Honkai Impact 3rd)

January 23, 2021 3 comments

Recently, while reverse engineering Honkai Impact 3rd I came across some string decryption code that was obfuscated by VMProtect‘s implementation of control flow flattening. It takes an encrypted table of string data plus an index as an input, retrieves the encrypted string at the specified index in the table, decrypts it and returns it. IDA decompiles this function to almost 2000 lines of spaghetti code. In this article, I’ll show you how – in one caffeine-fueled all-nighter – I reverse engineered this function, and present a reimplementation of the algorithm in C#. Afterwards, we’ll briefly examine the algorithm’s cryptographic properties, showing alternate starting points for cryptanalysis without reverse engineering any code.

Code obfuscation

The purpose of code obfuscation is to make it more difficult to determine the behaviour of a function via static analysis in a disassembler or decompiler. There are many forms of obfuscation, but some of the most common – and ones we will encounter today – include:

  • Opaque predicates – these are conditions whose results are known at compile-time and never change; for example 1 == 1 will always evaluate to true. The conditions are used to determine which code paths to take and may be difficult to evaluate statically

  • Dead code insertion – code that is never executed is inserted into the compiled code to confuse the analyst

  • Do-nothing code – code that executes but has no semantic effect is inserted into the compiled code, again to confuse the analyst

  • Control flow obfuscation – spaghettification of the execution order of instructions to reduce the amount of sequential code blocks and make tracing the flow of execution in a function harder

Such code can be introduced by the compiler, operating at the source code level, or by a post-processing tool which introduces obfuscation at the assembly instruction level.

Read more…
Categories: IL2CPP, Reverse Engineering Tags:

Reverse Engineering Adventures: Honkai Impact 3rd (Part 3)

January 21, 2021 3 comments

This is a continuation of the Reverse Engineering Adventures: Honkai Impact 3rd mini-series – read part 1 and part 2 first!

Recap

So far, we have decrypted global-metadata.dat, and identified and resolved the data obfuscation of Il2CppGlobalMetadataHeader and the four obfuscated metadata tables. We have observed that the string data is still out of our reach, and we need this to be able to load Honkai Impact into Il2CppInspector. Today we’ll find out how to access this information and create a final working plugin that will enable us to fully deobfuscate the game and analyze it.

Read more…
Categories: IL2CPP Tags:

Reverse Engineering Adventures: Honkai Impact 3rd (IDA Decompiler Techniques) (Part 2)

January 19, 2021 3 comments

This is a continuation of the Reverse Engineering Adventures: Honkai Impact 3rd mini-series – read part 1 first! In this article, we’ll look at comparative data deobfuscation and how to work with the IDA decompiler.

Recap

When we left off our previous exploits, we had peeled off the first layer of encryption from global-metadata.dat and found the call site which calls the decryption function. This turned out to correspond to il2cpp::vm::MetadataLoader::LoadMetadataFile from the IL2CPP source code, with an added line of code to invoke the decryption.

We can’t load the metadata file into Il2CppInspector yet though, because the header does not conform to the expected format. Extra – potentially still encrypted – data is present, and the header length is 0x158 rather than 0x110 bytes, which means that the locations of some or all of the header fields has been changed. Additionally, while most of the rest of the file looks normal, there are no string literals – which are normally present in global-metadata.dat – and a large block of presumably encrypted data right after the header.

Read more…
Categories: IL2CPP Tags: ,

Reverse Engineering Adventures: Honkai Impact 3rd (Houkai 3) (IL2CPP) (Part 1)

January 17, 2021 9 comments

Of all the IL2CPP workloads that have landed on my office desk over the years, those published by miHoYo (web site in Chinese) are what I consider to be the current gold standard for IL2CPP obfuscation. miHoYo has taken aim at our beloved (and sometimes hated) IL2CPP tools and trashed them with customized metadata encryption and extensive struct reordering, encapsulated in an obfuscated UnityPlayer.dll built from a modified Unity source code base. We had a good chuckle together reverse engineering League of Legends: Wild Rift, but now it’s time to get serious.

People reverse engineer code for different reasons. If you’re a malware analyst, you don’t care how the payload is encrypted; you just want to understand what threat vectors the malware exploits, what its key behaviour is, and how to create a signature to detect it. If you’re the nefarious type who sells exploits for money, you probably don’t care how the target software works either, as long as you can sell your exploitative trash (shame on you).

Some people have a quite different motive: reverse engineering is a hobby for them; they don’t use or care about the product, they’re merely interested to learn about how different protections work – the reverse engineering is the game, so to speak. When I rewrote the disassembly of a Sky pay-TV smartcard in C in 1997 (I know, I was an unruly teenager who turned into an unruly adult, sorry) and the company who designed the smartcard (NDS – now merged with Cisco) wanted to “have a little chat” with me about this, one of the first questions they asked me was: if you wanted free TV, why didn’t you just run the smartcard code in a CPU emulator once you’d dumped the ROM instead of spending 8 months rewriting it in C? My answer was matter-of-fact: I already have a Sky subscription, I just wanted to know how the card worked and prove it could be done. They subsequently paid me to fix it for them (this is the smart play by the way: nobody can design security products as well as hackers; Sony would have done well to take this tip instead of suing GeoHot).

I’m sharing this humblebrag with you as a prelude to explaining my motivation regarding miHoYo’s games. Normally I make a point of learning how a particular protection works, but this time I had a bee in my bonnet: after going on a blitz adding various unpacking, decryption and deobfuscation functionality to Il2CppInspector, I was acutely aware that Honkai Impact was the only remaining title I knew about that my tool wouldn’t load. I also knew from earlier investigation how to make it load, that it was highly tailored to the one specific game, and so – unlike the other generalized deobfuscation code – had no place in a generic tool.

This failure to load every IL2CPP workload gnawed away at me, but as it happened I was also working on a plugin system, so by fortuitous confluence it seemed like the perfect subject material for a demo plugin. I was getting burned out on weeks of reverse engineering every day though, so I got lazy: the example we will present today demonstrates how to break protection in the “malware analyst” way: just get it to decrypt and don’t bother about the details of how it works beyond what’s necessary.

Today’s volunteer is Honkai Impact 3rd. Buckle up!

Tip: The walkthrough below uses version 4.3 but the process works in an identical fashion all the way back to 3.8, which is the earliest version I’ve tested. We demonstrate how to reverse engineer the Windows build of the game, however the algorithms used for the Android build are the same. The Android version can therefore be decrypted merely by substituting the PC build’s global-metadata.dat examined below with the Android version. How did we determine this is possible? Simply by trying it!

Info: You can view the complete, fully-commented source code of the miHoYo loader plugin here. This plugin is the result of the work described below and shows how to modify Il2CppInspector’s load pipeline to handle non-standard workloads without needing to fork or modify the original tool.

Read more…
Categories: IL2CPP Tags:

Reverse Engineering Adventures: League of Legends Wild Rift (IL2CPP)

January 15, 2021 8 comments

The most common issue I receive on the tracker for Il2CppInspector is “this file won’t load”. Oftentimes this is due to a bug in the tool, but sometimes it leads me down a reverse engineering rabbit hole. From the end-user’s perspective, there is no difference: they post the issue and wait, and some time later I post some commits and tell them it’s fixed. I am usually unaware of what the target workload (application) actually is, and it doesn’t really concern me. As a tool author, my job is to try to ensure a broad range of compatibility with different workloads.

I don’t like to add workload-specific customizations to Il2CppInspector as it’s meant to be a generic tool intended to be fed with “clean” IL2CPP files – although you can now code your own plugins to add workload-specific functionality – but from time to time I see files with the same obfuscation over and over again, and then I take a look. So it was with a series of files over the last few months, which after deobfuscation turned out to be Riot Games’ new mobile magnum opus League of Legends: Wild Rift.

In this article, I’m going to guide you through (an albeit highly abridged version of) the steps I took to deobfuscate Wild Rift. It’s not too complicated, but it will highlight the importance of developing intuition and leveraging on the variety of tools at the analyst’s disposal to achieve a quick turnaround. While Wild Rift’s obfuscation is not complex, it is enough to defeat the majority of casual hackers, so the idea here is to encourage newcomers to move beyond only using automated tooling and develop the skills and intuition needed to be able to progress when the automated tools break. If you don’t know what to do when your favourite tool (whatever it may be) doesn’t work on a particular workload, this article is for you!

Info: All of the steps described below are performed by Il2CppInspector automatically, and current versions can analyse Wild Rift without any problems. Nevertheless, the curious hacker should always want to learn more, so keep reading for an adventure!

Read more…

Il2CppInspector Tutorial: Working with code in IL2CPP DLL injection projects

January 14, 2021 18 comments

Once you have created a C++ scaffolding project for DLL injection with Il2CppInspector, you will likely be wondering how to interact with the injected IL2CPP application. In this article, we’ll look at how to perform common tasks such as accessing static and instance fields, creating new objects, working with strings, calling vtable functions and more.

The first part of this article is reference material covering how types, methods, properties and so on are represented, named and addressed in C++. The second part shows a number of concrete working examples, so if you want to skip the theory, feel free to jump forwards. Let’s dive in!

Note: C++ scaffolding is experimental and currently not for the faint-hearted. This document will be updated as the codebase matures and improves to reflect the current state of scaffolding projects.

Read more…
Categories: IL2CPP Tags: