Skip to content

Commit

Permalink
v0.5.1: #1 fixed, #26 fixed, Il2Cpp.Thread added, Il2Cpp.Domain c…
Browse files Browse the repository at this point in the history
…hanged to static, and few more
  • Loading branch information
ste committed Aug 25, 2021
1 parent ae774b5 commit 6e9944a
Show file tree
Hide file tree
Showing 25 changed files with 795 additions and 386 deletions.
84 changes: 68 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Frida](https://img.shields.io/badge/-frida-ef6456?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyAgIHZlcnNpb249IjEuMSIgICBpZD0iTGF5ZXJfMSIgICB4PSIwcHgiICAgeT0iMHB4IiAgIHZpZXdCb3g9IjAgMCA5LjcyOTk3OTkgMTAuOTM1NzEyIiAgIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIwNC40IDM5IiAgIHhtbDpzcGFjZT0icHJlc2VydmUiICAgc29kaXBvZGk6ZG9jbmFtZT0ibG9nby5zdmciICAgd2lkdGg9IjkuNzI5OTc5NSIgICBoZWlnaHQ9IjEwLjkzNTcxMiIgICBpbmtzY2FwZTp2ZXJzaW9uPSIxLjEgKGNlNjY2M2IzYjcsIDIwMjEtMDUtMjUpIiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIgICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnMgICBpZD0iZGVmczkiIC8+PHNvZGlwb2RpOm5hbWVkdmlldyAgIGlkPSJuYW1lZHZpZXc3IiAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIgICBib3JkZXJvcGFjaXR5PSIxLjAiICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIiAgIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiICAgc2hvd2dyaWQ9ImZhbHNlIiAgIGZpdC1tYXJnaW4tdG9wPSIwIiAgIGZpdC1tYXJnaW4tbGVmdD0iMCIgICBmaXQtbWFyZ2luLXJpZ2h0PSIwIiAgIGZpdC1tYXJnaW4tYm90dG9tPSIwIiAgIGlua3NjYXBlOnpvb209IjYuOTE3ODA4NCIgICBpbmtzY2FwZTpjeD0iLTAuMTQ0NTU0NDUiICAgaW5rc2NhcGU6Y3k9Ii04LjYwMDk4OTkiICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTIwIiAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwMDgiICAgaW5rc2NhcGU6d2luZG93LXg9IjAiICAgaW5rc2NhcGU6d2luZG93LXk9IjAiICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJMYXllcl8xIiAvPjxnICAgaWQ9Imc0IiAgIHN0eWxlPSJkaXNwbGF5OmlubGluZTtmaWxsOiNmZmZmZmYiICAgdHJhbnNmb3JtPSJtYXRyaXgoMC4yODA0MDI4NiwwLDAsMC4yODA0MDI4NiwtMTEuNTgwNjM4LDApIj48cGF0aCAgIGZpbGw9IiNmZmZmZmYiICAgZD0iTSA1MS40LDM5IEggNDEuMyBMIDQ5LjcsMjYuMSBDIDQ0LjksMjMuOCA0Mi4zLDE5LjYgNDIuMywxMy41IDQyLjMsNC44IDQ4LjIsMCA1OC41LDAgSCA3NiBWIDM5IEggNjcgViAyOCBIIDU4LjUgNTcuNyBaIE0gNjcsMjAgViA3IGggLTguNSBjIC00LjksMCAtNy43LDIgLTcuNyw2LjQgMCw0LjUgMi44LDYuNiA3LjcsNi42IHoiICAgaWQ9InBhdGgyIiAgIHN0eWxlPSJmaWxsOiNmZmZmZmYiIC8+PC9nPjwvc3ZnPg==)](https://frida.re)
[![NPM](https://img.shields.io/npm/v/frida-il2cpp-bridge?label=&logo=npm&style=for-the-badge)](https://npmjs.org/package/frida-il2cpp-bridge)

A Frida module to dump, trace or hijack any Il2Cpp application at runtime with a high level of abstraction, without needing the `global-metadata.dat` file.
A Frida module to dump, trace or hijack any Il2Cpp application at runtime, without needing the `global-metadata.dat` file.

![Screenshot_20210724_195807](https://user-images.githubusercontent.com/46219656/126877297-97529b9b-e74b-4130-9b6e-061b938a5737.png)
## Compatibility
Expand All @@ -15,13 +15,6 @@ It should work for any Unity version in the inclusive range **5.3.0** - **2021.1
**Android** is supported; **Linux** and **Windows** are not tested; **iOS** is not supported yet
([#15](https://github.com/vfsfitvnm/frida-il2cpp-bridge/issues/15)).


## Known limitations
A lot of aspects are still unknown to me.
- Absent generic classes or methods utilities
- Missing traceback system


## Acknowledgements
Thanks to [meme](https://github.com/meme) and [tryso](https://github.com/tryso) for helping and getting me into this,
and to [djkaty](https://github.com/djkaty) and [nneonneo](https://github.com/nneonneo) for providing the IL2CPP C
Expand All @@ -41,9 +34,11 @@ headers.
* [Heap scan](#heap-scan)
* [Methods](#methods)
* [Invocation](#invocation)
* [Replacement & Interception](#replacement-&-interception)
* [Replacement & Interception](#replacement--interception)
* [Generics handling](#generics-handling)
* [Miscellaneous](#miscellaneous)
* [How to handle overloading](#how-to-handle-overloading)
* [Ghidra script](#ghidra-script)

---

Expand Down Expand Up @@ -88,15 +83,15 @@ Learn more about `packages.json` [here](https://docs.npmjs.com/cli/v7/configurin
"scripts": {
"build": "frida-compile -o _.js -w index.ts",
"attach": "run() { frida -U \"$1\" -l _.js --runtime=v8; }; run",
"attach-with-spawn": "run() { frida -U -f \"$1\" -l _.js --no-pause --runtime=v8; }; run",
"app0-with-spawn": "npm run attach-with-spawn com.example.application0",
"spawn": "run() { frida -U -f \"$1\" -l _.js --no-pause --runtime=v8; }; run",
"app0-spawn": "npm run spawn com.example.application0",
"app1": "npm run \"Application1 Name\"",
"app1-with-spawn": "npm run attach-with-spawn com.example.application1"
"app1-spawn": "npm run spawn com.example.application1"
},
"devDependencies": {
"@types/frida-gum": "^17.1.0",
"frida-compile": "^10.2.4",
"frida-il2cpp-bridge": "^0.5.0"
"frida-il2cpp-bridge": "^0.5.1"
}
}
```
Expand Down Expand Up @@ -218,7 +213,7 @@ struct System.Int32 : System.ValueType, System.IFormattable, System.IConvertible
import "frida-il2cpp-bridge";

Il2Cpp.perform(() => {
const mscorlib = Il2Cpp.Domain.reference.assemblies.mscorlib.image;
const mscorlib = Il2Cpp.Domain.assemblies.mscorlib.image;
const SystemString = mscorlib.classes["System.String"];

// simple trace, it only traces method calls
Expand Down Expand Up @@ -327,7 +322,7 @@ words, however `Il2Cpp.Tracer` does not use `Interceptor.attach`, but a combinat
import "frida-il2cpp-bridge";

Il2Cpp.perform(() => {
const mscorlib = Il2Cpp.Domain.reference.assemblies.mscorlib.image;
const mscorlib = Il2Cpp.Domain.assemblies.mscorlib.image;
const SystemType = mscorlib.classes["System.Type"];

// it relies on classes gc descriptors
Expand Down Expand Up @@ -356,7 +351,7 @@ know how they internally work, I read enough uncommented C++ source code for my
import "frida-il2cpp-bridge";

Il2Cpp.perform(() => {
const mscorlib = Il2Cpp.Domain.reference.assemblies.mscorlib.image;
const mscorlib = Il2Cpp.Domain.assemblies.mscorlib.image;
const SystemString = mscorlib.classes["System.String"];

const IsNullOrEmpty = mscorlib.classes["System.String"].methods.IsNullOrEmpty;
Expand Down Expand Up @@ -410,6 +405,42 @@ Il2Cpp.perform(() => {
function (ch: number, chars: Il2Cpp.Reference<Il2Cpp.Pointer<number>>): boolean {}
```

### Generics handling

Dealing with generics is problematic when the `global-metadata.dat` file is ignored. You can
gather the inflated version (if any) via `Il2Cpp.Class.inflate` and `Il2Cpp.method.inflate`.
Reference types (aka objects) all shares the same code: it is easy to retrieve virtual address in this case. Value types (aka primitives and structs) does not share any code.
`inflate` will always return an inflated class or method (you must match the number of type arguments with the number of types you pass to `inflate`), but the returned value it's not
necessarely a class or method that has been implemented.
```ts
Il2Cpp.perform(() => {
const classes = Il2Cpp.Image.corlib.classes;

const SystemObject = classes["System.Object"];
const SystemInt32 = classes["System.Object"];


const GenericList = classes["System.Collections.Generic.List<T>"];

// This class is shared among all reference types
const SystemObjectList = GenericList.inflate(SystemObject);

// This class is specific to System.Int32, because it's a value type
const SystemInt32List = GenericList.inflate(SystemInt32);


// static T UnsafeCast(System.Object o);
const UnsafeCast = classes["System.Runtime.CompilerServices.JitHelpers"].methods.UnsafeCast;
// UnsafeCast is a generic method, its virtual address is null

// This is the UnsafeCast for every reference type
const SystemObjectUnsafeCast = UnsafeCast.inflate(SystemObject);

// This doesn't make sense, but this is the UnsafeCast specific to System.Int32, because it's a value type
const SystemInt32UnsafeCast = UnsafeCast.inflate(SystemInt32);
});
```

---

## Miscellaneous
Expand All @@ -427,3 +458,24 @@ System.Boolean Equals(System.String value, System.StringComparison comparisonTyp

Basically, an underscore is appended to the method name (key) until the key can be used.

### Ghidra script

The following script parses the file outputted by `Il2Cpp.Dumper` and looks for methods using regular expression.

```py
import re
from ghidra.program.model.address import AddressFactory
from ghidra.program.model.symbol.SourceType import USER_DEFINED

address_factory = getAddressFactory()

with open("/path/to/dump.cs", "r") as file:
content = file.read()

matches = re.findall("([^\s]+)(?:\(.+)(0x[0123456789abcdef]{8})", content)

for match in matches:
function = getFunctionAt(address_factory.getAddress(match[1]))
if function:
function.setName(match[0], USER_DEFINED)
```
32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
{
"name": "frida-il2cpp-bridge",
"version": "0.5.0",
"description": "A Frida module to dump, trace or hijack any Il2Cpp application at runtime with a high level of abstraction, without needing the global-metadata.dat file.",
"version": "0.5.1",
"description": "A Frida module to dump, trace or hijack any Il2Cpp application at runtime, without needing the global-metadata.dat file.",
"keywords": [
"frida",
"il2cpp",
"dump",
"trace",
"global-metadata"
],
"module": "./dist/index.js",
"repository": {
"type": "git",
"url": "https://github.com/vfsfitvnm/frida-il2cpp-bridge.git"
},
"license": "MIT",
"author": "vfsfitvnm",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"/dist/*"
],
"scripts": {
"build": "tsc"
},
"author": "vfsfitvnm",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/vfsfitvnm/frida-il2cpp-bridge.git"
},
"prettier": {
"tabWidth": 4,
"arrowParens": "avoid",
"trailingComma": "none",
"bracketSpacing": true,
"printWidth": 140,
"bracketSpacing": true
},
"devDependencies": {
"@types/frida-gum": "^17.1.0",
"prettier": "^2.3.2"
"tabWidth": 4,
"trailingComma": "none"
},
"dependencies": {
"decorator-cache-getter": "^1.0.0",
"fastest-levenshtein": "^1.0.12",
"kleur": "^4.1.4"
},
"devDependencies": {
"@types/frida-gum": "^17.1.0",
"prettier": "^2.3.2"
}
}
Loading

0 comments on commit 6e9944a

Please sign in to comment.