If you monetize Android automation scripts, one of the biggest headaches is scripts getting cracked: hard-earned code ripped off, licenses bypassed, logic tampered with and spread around. In the previous article we covered network license verification — that is the door lock. Code obfuscation is the armor that makes the lock hard to pick — even if the code is dragged away, reverse engineers face a pile of unreadable “gibberish”.
This article explains the complete obfuscation configuration: how to install it, what each parameter does, and when to turn it on.
1. What Obfuscation Is: Dressing the Code in Camouflage
Obfuscation applies trick instructions, control-flow changes, and other transformations to code during js compilation, in order to protect it.
In plain words: the code is still the same code, functionality unchanged, but the reading difficulty is maxed out. Common techniques include:
- Control flow flattening: breaks sequential execution into state-machine jumps, making it hard for reverse engineers to reconstruct the execution path;
- String arrays: extracts plain-text strings into arrays and retrieves them at runtime, preventing keyword searches from locating critical code;
- Dead code injection: inserts lots of realistic-looking code that never executes, as noise;
- RC4 encoding: encrypts the string-array contents with RC4, so static analysis only sees ciphertext.
2. Installing the Obfuscator: Node.js + javascript-obfuscator
Only two pieces are needed:
- Node.js: javascript-obfuscator runs on the Node runtime;
- javascript-obfuscator: the obfuscation library installed globally via npm.
Run in cmd or PowerShell:
npm install -g javascript-obfuscator
npm install -g class-validator
After installation, run npm root -g to find the global install path — you will need it for the config.
3. Core Config: obfuscator.json Field by Field
Since EC IDEA 9.4.0, an obfuscator.json file is auto-created under the project module. Obfuscation is off by default — it works only after you correctly configure the binPath (i.e., obfuscatorBinPath) in the JSON.
The official default config (tested and runnable):
{
"nodeBinPath": "D:\\programe\\nodejs\\node.exe",
"obfuscatorBinPath": "C:\\Users\\Administrator\\AppData\\Roaming\\npm\\node_modules\\javascript-obfuscator\\bin\\javascript-obfuscator",
"target": "node",
"compact": false,
"log": true,
"optionsPreset": "high-obfuscation",
"deadCodeInjection": false,
"simplify": false,
"seed": 10,
"controlFlowFlattening": true,
"controlFlowFlatteningThreshold": 1,
"unicodeEscapeSequence": false,
"stringArray": true,
"stringArrayRotate": false,
"stringArrayShuffle": false,
"stringArrayThreshold": 1,
"stringArrayWrappersCount": 5,
"stringArrayEncoding": ["rc4"],
"stringArrayCallsTransform": false,
"selfDefending": false,
"splitStrings": false,
"splitStringsChunkLength": 1
}
Note: the
//comments in the config are for explanation — remove them when actually using the file, or it will error out.
3.1 Path configuration (required)
| Property | Purpose |
|---|---|
nodeBinPath |
Path to node.exe |
obfuscatorBinPath |
Path to the javascript-obfuscator executable |
After installing Node.js, the global install path is typically C:\Users\<username>\AppData\Roaming\npm\node_modules; find the full path of javascript-obfuscator inside node_modules and copy it over.
3.2 Obfuscation strength (important)
| Property | Default | Purpose |
|---|---|---|
optionsPreset |
high-obfuscation |
Obfuscation-level preset |
controlFlowFlattening |
true |
Control flow flattening, scrambles execution order |
controlFlowFlatteningThreshold |
1 |
Flattening ratio; 1 = all code |
deadCodeInjection |
false |
Dead code injection, on or off |
simplify |
false |
Code simplification (opposite of obfuscation; keep false) |
3.3 String protection (important)
| Property | Default | Purpose |
|---|---|---|
stringArray |
true |
Extracts strings into an array |
stringArrayEncoding |
["rc4"] |
String-array encoding; after RC4, static analysis only sees ciphertext |
stringArrayThreshold |
1 |
Ratio of strings moved into the array; 1 = all |
stringArrayWrappersCount |
5 |
Number of wrapper functions; more = harder to reverse |
stringArrayRotate / stringArrayShuffle |
false |
Whether to rotate / shuffle the array |
3.4 Other controls
| Property | Default | Purpose |
|---|---|---|
compact |
false |
Whether to compact the code |
log |
true |
Prints detailed obfuscation info during compilation, to confirm obfuscation ran |
seed |
10 |
Random seed; a fixed seed makes obfuscation reproducible |
unicodeEscapeSequence |
false |
Whether to escape as unicode |
selfDefending |
false |
Self-defense: code breaks when beautified (use with care — can hurt you too) |
splitStrings |
false |
Split long strings |
4. When Obfuscation Runs: Off During Dev, On for Release
4.1 How obfuscation triggers
obfuscatorBinPathconfigured and the file exists in obfuscator.json → compilation obfuscates by default, covering both js mode and dex mode;- Remove the
obfuscatorBinPathvalue, or delete obfuscator.json → no obfuscation during compilation.
4.2 When to turn it on
The official advice is clear: obfuscation is resource-intensive; keep it off while debugging and developing, and turn it on when publishing or packaging.
The reasons are practical:
- During development, obfuscation slows every compile and makes debugging painful — pure self-torture;
- For release, obfuscation delivers the “hardened” build users actually receive, dramatically raising the cost of cracking.
5. Anti-Crack Done Right: Obfuscation Is Just One Layer
Used alone, obfuscation is limited. The official anti-crack recommendations form a layered playbook:
- Use network license verification: the core defense — licenses bind to devices with heartbeat checks; no card, no run;
- Obfuscate critical code only: protection-heavy targets like license checks and core algorithms; full obfuscation is not necessary;
- Enable package name, APK, and script fingerprint verification: slightly tedious — record each upload at packaging time — but prevents “re-shelling” and tampering;
- Put key business logic in remote variables and remote js code: when a crack is discovered, replace the remote code and stop the script for “one-click damage control”;
- Capable authors may embed destructive code (e.g., formatting the sdcard, deleting contacts) triggered remotely when a crack is found — a heavy hammer, use with care.
6. Summary
Code obfuscation is a lesson every script seller must learn:
- Simple principle: compile-time trick instructions and control-flow changes — same functionality, maxed-out reading difficulty;
- Core config: nodeBinPath + obfuscatorBinPath get it working; tune the rest as needed;
- Strength is adjustable: control flow flattening + string arrays + RC4 encoding is the default high-obfuscation plan, enough for most reverse-engineering attempts;
- Timing matters: off during development, on for release — balance efficiency and security;
- Layering wins: obfuscation + network verification + fingerprint checks + cloud variables form the complete anti-crack system.
Remember one sentence: no script is uncrackable, but there is always protection with a good cost-benefit ratio. The point of obfuscation is not to make scripts never cracked — it is to push the cracking cost high enough that nobody bothers.
Ready to build it for real?
Every approach in this article can be built on the EasyClick phone automation platform — full documentation, developer tools and cluster/cloud-control products, free to try.