I was playing around with some code that uses Frida to intercept il2cpp calls that are used by the Unity framework. The project is called frida-il2cpp-bridge (https://github.com/vfsfitvnm/frida-il2cpp-bridge) and it uses Typescript and node js (npm) to create the javascript that is then loaded into Frida. The reason for the post is also to document how to get started using this frida-il2cpp-bridge framework. 


Keep in mind we will make use of virtual environments for both Python and npm. 


Install virtualenv for Python and node.js on your Linux system (etc, Ubuntu):

pip3 install virtualenv 

Navigate to the directory that you want to store your virtualenv (maybe cd ~). Then create the Python virtual environment:

virtualenv pyvenv

To activate the virtual environment 

source pyvenv/bin/activate

Within that virtual environment, install nodeenv and create the npm virtual environment:

pip3 install nodeenv

nodeenv nodevenv

source nodevenv/bin/activate

And you should have something like this now (use exit or deactivate to exit it):

(nodevenv) (pyvenv) user:~$

Create a folder for your il2cpp scripts, lets call it 'fri-il2cpp': 

mkdir fri-il2cpp; cd fri-il2cpp

Within fri-il2cpp we will create 3 files, index.ts, package.json and tsconfig.json.

Let's start with a simple example of printing the version of Unity. Edit index.ts and add the following example code:

import "frida-il2cpp-bridge";

Il2Cpp.perform(() => {

    console.log(Unity.version);

});

Next we will create tsconfig.json: 

{

  "compilerOptions": {

    "target": "esnext",

    "lib": [

      "es2020"

    ],

    "allowJs": true,

    "noEmit": true,

    "strict": true,

    "esModuleInterop": true,

    "experimentalDecorators": true,

    "moduleResolution": "node"

  }

}

And finally the package.json file (don't forget to configure the different settings, frida server ip and port, target application, target process are all options you can set) :

{

  "name": "project",

  "main": "index.ts",

  "version": "1.0.0",

  "private": true,

  "config": {

    "ip": "192.168.1.254",

    "rport": "27042",

    "application": "com.Company.Game",

    "process": "game-name"

  },

  "scripts": {

    "build": "frida-compile -o _.js -w index.ts",

    "attach_usb": "run() { frida.exe -U $npm_package_config_application -l _.js --runtime=v8; }; run",

    "attach_remote": "run() { frida.exe -H $npm_package_config_ip:$npm_package_config_rport -l _.js --runtime=v8 $npm_package_config_application; }; run",

    "spawn_usb": "run() { frida.exe -U -f $npm_package_config_application -l _.js --no-pause --runtime=v8; }; run",

    "spawn_remote": "run() { frida.exe -H $npm_package_config_ip:$npm_package_config_rport -l _.js --no-pause --runtime=v8 $npm_package_config_application; }; run"

  },

  "devDependencies": {

    "@types/frida-gum": "^17.1.0",

    "@types/node": "^16.11.7",

    "frida-compile": "^10.2.4",

    "frida-il2cpp-bridge": "^0.5.8"

  }

}

First we need to install the required npm packages (remember these are stored in the virtualenv, you will need to load it again in the future to be able to use the environments):

npm install

Next we will build the _.js file that will be loaded into Frida. We will call npm build. 

npm run build

You should get something like the following output on a successful build:

 > project@1.0.0 build

> frida-compile -o _.js -w index.ts

Compiled 45 files (xxx ms)

This will run the build command found in package.json. Likewise we will execute the connection to the remote frida system as follows:

npm run attach_remote

You might see the following:

Frida logo etc... (removed for brevity)

Attaching...

2020.3.0f1 

Now you are free to configure index.ts with all the examples and your own code to get il2cpp working with Frida. All you have to do is run build and attach_remote (assuming the Frida server is remote), check the package.json for other options(e.g.,attach_usb, attach_remote,  spawn_usb, spawn_remote or add a custom one) .