Modding electron apps on macOS.
Also reverse engineering to bypass the license activation logic (for fun..)
Step 1. Prepare the environment :
Extract the .app from dmg file to your project’s folder.
Right click the .app file and click show package contents.
There you’ll find a couple of files and folders. Copy the ‘Resources‘ folder to the parent project directory
We are gonna need the following tools :
asar CLI : its basically a packaging program for electron apps which can be also be used for unpacking apps
webcrack CLI : Really Good JS deobfuscator. Works well on common obfuscation techniques. I’ll show what they are later.
A faster text editor : Obfuscated and packaged js code is reeeally ugly and the LOC can extend upto 100k+ per file. So no, your electron based editor (cough.. vs code) won’t cut it. You need something performant to perform static analysis without ripping your hair out.
I recommend using vim or any other cli based IDE. You can also try ZED if you are used to the UI. It’s written in RUST and is really performant.
Step 2. Unpack the asar file : Use the asar CLI to unpack the asar file: Make sure the supporting directories (eg. app.asar.unpacked) and modules are present in the folder where app.asar is present.
npx asar extract resources/app.asar extracted-app/
This will extract out all the app data to a separate folder for static analysis.
Step 3. Find and deobfuscate all the {{required}} js files in the dist directories …
Obfuscated js looks like this :
And this is the result after deobfuscation :
Makes the code much more readable..
Obfuscation is a facinating topic overall. You can read more about it here.
Step 4. Static Analysis: Find the code that is responsible for your desired functionality.
I will take an example of bypassing licence activation.
Note: I already own the app I am demonstrating this for. I don’t condone piracy. Just fkin pay for good software.
This is the license activation screen.
Use search to find the exact phrase in the codebase..
Use this to find out what function is getting called when you press the activate button. then back-track to find out the function where network call is being made. That is made typically to a licensing server.
Other ways to find out the code responsible for activation is :
Network monitor. Start the electron app connect to postman’s proxy and intercept all the request: this may or may not work because the developers may not use simple protocalls to make requests.
Dev console. Use electron’s inbuilt dev-console to find out the request. This may also not work deu to the same reason above.
Wireshark/Burpsuite. Can work, have’t tried yet.. Wireshark support a large variety of protocols so you may find out server endpoint using it.
Search for https:// in the codebase. This is tricky and time consuming.
After you’ve found out what part of code is responsible for making the request. Modify it so that it always returns a success. Also check all the downstream functions of that piece of code to bypass all of those checks too..
In my case I found out this part of code :
It can simply be replaced by this to bypass all checks:
Another part was the the function which persists the licence key across sessions :
This can also be simple bypassed:
Similarly you can find out all the places licence key is being fetched/stored/verified and mod out the functions.
Step 5. Repackaging and assembling a new .app file.
Now after you’ve made all the changes. Repackage the app to an asar file using the asar cli again.
npx asar pack extracted-app/ app.asar
Now go to the original .app of your application, right click > show package contents > delete the original app.asar from the Resources folder and copy the modified newly packaged app.asar into it.
Reopen the app and see if your mods had any effect.
Note: Open the app without mods first just for macOS to pass package verification. Subsequent modifications will pass through just fine.
Reverse engineering apps, especially obfuscated ones is really fun. It’s like solving an interesting math problem.
Will post more about the interesting/challenging techniques I encounter while reverse-engineering random apps in the future.
Adios till then 🙌