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

January 17, 2021 Leave a comment

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 1 comment

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…
Categories: IL2CPP, Reverse Engineering Tags:

Il2CppInspector Tutorial: Working with code in IL2CPP DLL injection projects

January 14, 2021 1 comment

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:

IL2CPP Reverse Engineering Part 2: Structural Overview & Finding the Metadata

December 27, 2020 3 comments

[You can use Il2CppInspector to help automate the techniques outlined in this series]

In part 1 of this series we learned what IL2CPP is, how to setup a build environment, and compared the C#, IL, C++ and disassembly of a simple function.

In this article, you will learn:

  • an overview of the key files in an IL2CPP application from a reverse-engineering perspective
  • how an IL2CPP application loads the metadata we are interested in
  • how to find the application binary’s metadata by hand in a disassembler (x64 and ARM)
  • beginner-level disassembly navigation and tidying in IDA
  • how to interpret C++ function calls in assembly language

Pre-requisites:

  • Basic knowledge of high-level programming
  • Basic knowledge of disassembly (the article uses IDA but Ghidra works equally well)
  • Basic knowledge of what IL2CPP is – I recommend that you read part 1 first if you’re new to IL2CPP
Read more…
Categories: IL2CPP Tags:

Il2CppInspector Tutorial: How to create, use and debug IL2CPP DLL injection projects

November 27, 2020 5 comments

Il2CppInspector allows you to automatically create a Visual Studio solution containing a C++ DLL project targeted at the application you are reverse-engineering, which – when compiled – can be injected into the running application process to monitor or modify the application’s behaviour.

In the bad old days, you used to have to find every type, function, field etc. yourself. An excellent tutorial on this from an unknown author can be found here. Il2CppInspector’s C++ scaffolding projects render the need to perform this work obsolete. These projects give you complete access to all of the C#-equivalent types and methods in the IL2CPP application, plus all available IL2CPP APIs and exports. There is no need to determine any function pointers or add any type declarations.

In this article, we’ll briefly walk through how to create, edit, inject and debug these projects. Details on how to actually write useful code using the framework provided can be found in this tutorial.

Read more…
Categories: IL2CPP Tags:

Practical IL2CPP Reverse Engineering: Extracting Protobuf definitions from applications using protobuf-net (Case Study: Fall Guys)

August 10, 2020 Leave a comment

DISCLAIMER: The following information and source code is provided for educational purposes only. I do not condone cheating in online multiplayer games and expressly discourage this behaviour. This tutorial is intended to demonstrate the thought processes and techniques involved in reverse engineering. It is not intended to enable cheating, the modification of gameplay or any interference or alteration of any server-side components of the analysed product in any way whatsoever. Check your local laws before using this software. At the time of writing I have never connected to a Fall Guys network endpoint or launched the client.

You can download the full source code for this tutorial from the Il2CppProtoExtractor-FallGuys GitHub repo.

[Updated 7th December 2020: added instructions for using Il2CppInspector’s NuGet package in preference to creating a git clone; added link to commit with an example showing how to find attribute values automatically with a disassembly framework]

Introduction

Il2CppInspector provides several powerful tools to interact with IL2CPP application code and data via static analysis:

  • A low-level binary representation (Il2CppInspector) which allows you to query the IL2CPP metadata in its original format
  • A .NET type model (TypeModel) which provides a Reflection-style API to all of the types in the application
  • An application model (AppModel) which provides an API to query the compiled C++ types, methods and other symbols in the binary, including those not represented by .NET types

In this article, we will leverage the .NET type model to inspect a game and derive a Google Protobuf .proto file encapsulating its network protocol.

Pre-requisites:

  • Knowledge of .NET, C# and LINQ
  • Basic awareness with what IL2CPP is and what it does (no in-depth knowledge needed)
  • Basic awareness of what Google Protobuf is
  • Basic knowledge of how to use a disassembler such as IDA and how to read basic x86-64 assembly code
  • An inquisitive mind

In this article, you will learn:

  • How to set up a new Visual Studio project which uses Il2CppInspector
  • How to load an IL2CPP application and create a type model
  • How to use LINQ to query .NET types, interfaces, fields, properties, generic type arguments, arrays and attributes in an IL2CPP application
  • How to extract constructor arguments to custom attributes not retained by IL2CPP in the metadata
  • How to transform all of the combined data into a .proto file

The game at hand today is Fall Guys published by Devolver Digital, a Battle Royale-style party game where 60 players race around in bright colorful maps vying for victory. The game requires an upfront purchase and then has microtransactions on top. Being asked to pay more for the rest of the content when I’ve already purchased a game makes me very cantankerous, and Fall Guys also happens to be compiled with IL2CPP, which makes it the perfect target for some reverse engineering fun!

Although I’m using Fall Guys for this example, many of the techniques described below are applicable to any game deployed with IL2CPP and using Protobuf.

Read more…
Categories: IL2CPP Tags:

IL2CPP Reverse Engineering Part 1: Hello World and the IL2CPP Toolchain

June 24, 2020 4 comments

[You can use Il2CppInspector to help automate the techniques outlined in this series]

[Updated 27th November 2020: the command-line build instructions were updated to be compatible with Il2CppInspector 2020.2.1]

In this article, you will learn:

  • what IL2CPP is and why it exists
  • what the generated C++ source code and binary disassembly of a simple function looks like compared to native C#, IL and C++ code
  • how to setup your environment to generate C++ source code and IL2CPP binaries from your own C# code so that you can examine and compare them with your original code
  • how to use IL2CPP at the command-line on arbitrary code without Unity

Introduction to IL2CPP

IL2CPP is an alternative application deployment model introduced into Unity in 2015 which is designed to bring significant performance improvements to Unity games. It’s a beautiful mess, and today we’re going to start picking it apart.

A standard Unity game is distributed as a series of .NET assemblies which are executed by the managed runtime (CLR) on the target platform of choice as per the norm for any .NET application. The premise of IL2CPP is to take these assemblies, parse the IL, generate C++ equivalent source code from it, then compile this C++ into machine code for faster, unmanaged execution. This is described quite well on this page of the Unity manual with this diagram:

A diagram of the automatic steps taken when building a project using IL2CPP

There are several excellent guides about how IL2CPP generates code such as Unity’s own IL2CPP Internals blog series and Jackson Dunstan’s exquisitely detailed musings, so I’m not going to repeat that work here. Instead, I want to focus on the opposite perspective: how do we reverse engineer compiled IL2CPP binaries?

Unity games have traditionally been exceptionally easy to reverse engineer, generally requiring nothing more than a copy of ILSpy (or my preferred tool Telerik JustDecompile) and a dream. IL2CPP changes all that: we go from neat assemblies – often with all of the function and variable names intact – to straight up machine code that we have to wade through in a disassembler. Suddenly, even finding the areas of interest becomes magnitudes tougher. How can we make this task easier?

To answer that question, we’re going to need to develop a deep understanding of how IL2CPP manages types and data under the hood, and that’s what this series is all about. Buckle up!

Read more…
Categories: IL2CPP Tags:

Change to Twitter account

July 27, 2015 3 comments

Please note I have created a new Twitter account specifically for following my coding activities and blog updates/articles, separate from my personal and gaming life 🙂 If you are currently following @TheLittlestKaty or @KatyHearthstone on Twitter, please follow @KatysCode instead for code stuff!

Katy.

Categories: Blog Updates
%d bloggers like this: