https://github.com/evex-dev/expose-kit
A universal toolkit for deobfuscating JavaScript
https://github.com/evex-dev/expose-kit
deobfuscation deobfuscator javascript obfuscator
Last synced: 5 months ago
JSON representation
A universal toolkit for deobfuscating JavaScript
- Host: GitHub
- URL: https://github.com/evex-dev/expose-kit
- Owner: evex-dev
- License: mit
- Created: 2026-01-04T16:17:00.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-01-07T19:29:50.000Z (5 months ago)
- Last Synced: 2026-01-13T19:57:41.506Z (5 months ago)
- Topics: deobfuscation, deobfuscator, javascript, obfuscator
- Language: TypeScript
- Homepage: https://evex.land
- Size: 193 KB
- Stars: 12
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# Expose Kit

[](https://discord.gg/evex)
> A universal toolkit for JavaScript deobfuscation
---
## What is this?
JavaScript deobfuscation tools are everywhere.
But many of them are **too aggressive**, rewriting code until it breaks.
Expose Kit takes a **different approach**.
- No brute force
- Step-by-step, verifiable transforms
- Designed to *not* break your code silently
Each transformation is meant to be **checked and validated**, so you always know *when* something goes wrong.
Alongside deobfuscation, Expose Kit also provides a set of **practical utilities** for working with obfuscated JavaScript.
---
## Installation
Just one step:
```bash
npm i -g expose-kit
# or
bun i -g expose-kit
```
```bash
expose --help
expose parsable sample.js
```
---
## Usage Notes
### Default arguments
- The first argument is the input file
(`--file` / `--input` can also be used)
- If required options are missing, Expose Kit will **prompt you**
- A timeout is enabled by default to avoid hangs
Use `--unlimited` for long-running execution
---
## Recommended Workflow
First, an important premise:
> It is **impossible** to create a static deobfuscation tool that *never* breaks.
Reasons include:
- Unpredictable execution (`eval`, dynamic code)
- Bugs or edge cases in AST manipulation
Because of this, you should **verify the code at every step**.
### 1. Always verify with `parsable`
After each transformation, run:
```bash
expose parsable file.js
```
This ensures the syntax is still valid.
---
### 2. Make scopes safe first
One of the most common causes of breakage is **variable name confusion**.
If you try to write your own deobfuscation logic (e.g. in Python), you’ll quickly realize how painful it is to track scopes correctly.
That’s why you should **always start with**:
```bash
expose safe-scope input.js
```
This renames bindings per scope, producing code like:
```js
Before: var x = 810;((x) => console.log(x))(114514);
After: var x = 810;((_x) => console.log(_x))(114514);
```
With this alone:
- The code becomes far more resistant to breakage
- Writing custom deobfuscation logic becomes much easier
- You no longer need to worry about scope collisions
---
### 3. Apply transforms step by step
After `safe-scope`, combine common techniques like:
- `expand-array`, `expand-object` and more
After **each step**, run `parsable` and `remove-unused` again.
(even if it's not frequent, we might overlook something broken)
The more you do it, the clearer it becomes.
Expose Kit will also clearly indicate whether a **diff** exists, making inspection easy.
Repeat this process, and the original code will gradually reveal itself.
---
## Commands
### `expose parsable`
Check whether a file is syntactically valid.
```js
parsable: const x = 810;
not parsable: const ;x; == 810;
```
```bash
expose parsable path/to/file.js
```
Args:
- Default args only
---
### `expose safe-scope`
Rename bindings per scope for safer transformations.
```bash
expose safe-scope path/to/file.js --output path/to/file.safe-scope.js
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/safe-scope/mocks).
Args:
- `--o, --output `
Output file path
- No extension → `file.safe-scope.js`
- With extension → `file.safe-scope.`
---
### `expose pre-evaluate`
Pre-evaluate const numeric/string expressions. (Safe evaluate)
```js
const a = 1 + 2 * 3; // => 7
const c = "aaaa";
const b = "a" + c; // => "aaaaa"
```
```bash
expose pre-evaluate path/to/file.js --output path/to/file.pre-evaluate.js
```
Args:
- `--o, --output `
Output file path
- No extension → `file.pre-evaluate.js`
- With extension → `file.pre-evaluate.`
Notes:
- Inlines zero-arg functions that return safe array literals by hoisting them to a var.
---
### `expose expand-array`
Expand array index access for primitive values.
```js
var a = [1, 1, 4, 5, 1, 4];
// before
console.log(a[0], a[2], a[3]);
// after
console.log(1, 4, 5);
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-array/mocks).
```bash
expose expand-array path/to/file.js --target arrayName --output path/to/file.expand-array.js
```
Args:
- `--target `
Target array variable name
- `--o, --output `
Output file path
Notes:
- Each replacement is validated by reparsing; unsafe replacements are skipped.
(This array is intended to be immutable, so caution is required)
---
### `expose expand-object`
Expand object property access for primitive values.
```js
const obj = { a: 1, b: 2 };
// before
console.log(obj.a, obj["b"]);
// after
console.log(1, 2);
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-object/mocks).
```bash
expose expand-object path/to/file.js --target objectName --output path/to/file.expand-object.js
```
Args:
- `--target `
Target object variable name
- `--o, --output `
Output file path
Notes:
- Each replacement is validated by reparsing; unsafe replacements are skipped.
(This object is intended to be immutable, so caution is required)
---
### `expose object-packer`
Pack consecutive object property assignments into literals.
```js
const obj = {};
// before
obj.a = 0;
obj["b"] = 1;
// after
const obj = { a: 0, b: 1 };
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/object-packer/mocks).
```bash
expose object-packer path/to/file.js --output path/to/file.object-packer.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Packs only consecutive assignments following an empty object literal.
- Stops when a property value references the object itself.
---
### `expose key-simplify`
Replace safe string literal property accesses (`obj["foo"]`) with dot-style access (`obj.foo`).
```js
const obj = { foo: 1, bar_baz: 2 };
obj["foo"] = obj['bar'];
console.log(obj["foo"], obj["bar_baz"]);
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/key-simplify/mocks).
```bash
expose key-simplify path/to/file.js --output path/to/file.key-simplify.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Only rewrites computed keys that are plain identifiers.
- Leaves invalid identifier keys untouched so the output stays parseable.
---
### `expose remove-updater`
Replace safe update expressions with += or -=.
```js
// before
a++;
--b;
// after
a += 1;
b -= 1;
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-updater/mocks).
```bash
expose remove-updater path/to/file.js --output path/to/file.remove-updater.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Only replaces update expressions whose value is not used.
- Safe for expression statements and for-loop update clauses.
---
### `expose remove-reassign`
Inline safe alias assignments and wrapper calls.
```js
const a = 0;
const b = a;
const c = b;
console.log(c); // => console.log(a);
```
```js
function a(arg) {
return b(arg);
}
function c(arg) {
return d[arg];
}
a(0); // => b(0)
c(0); // => d[0]
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-reassign/mocks).
```bash
expose remove-reassign path/to/file.js --output path/to/file.remove-reassign.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Only inlines const/immutable alias chains.
- Skips object shorthand replacements and shadowed bindings.
- Wrapper inlining is limited to single-return passthroughs.
---
### `expose remove-deadcode`
Remove unreachable branches and simplify conditional expressions.
```js
if (true) {
a();
} else {
b();
}
// after
a();
const x = cond ? true : false;
// after
const x = !!cond;
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-deadcode/mocks).
```bash
expose remove-deadcode path/to/file.js --output path/to/file.remove-deadcode.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Only removes branches with literal/array/object tests.
- Simplifies ternaries when both branches are booleans.
---
### `expose remove-anti-tamper`
Drop the self-defending wrapper, debug guards, and console hijacks generated by anti-tamper scripts.
```js
var wrapper = (function () {
var guard = true;
return function (ctx, fn) {
var thunk = guard ? function () {
if (fn) {
fn.apply(ctx, arguments);
fn = null;
}
} : function () {};
guard = false;
return thunk;
};
})();
wrapper(this, function () {
console.log("tamper");
});
console.log("safe");
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-anti-tamper/mocks).
```bash
expose remove-anti-tamper path/to/file.js --output path/to/file.remove-anti-tamper.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Targets wrappers that return guarded helper functions and removes their invocations.
- Cleans up debug/console helper functions before removing the wrapper.
---
### `expose control-flow-packer`
Inline control-flow flattening loops generated by string-based state machines.
```js
const _0x1 = "a|b|c".split("|");
let _0x2 = 0;
while (true) {
switch (_0x1[_0x2++]) {
case "a":
console.log("a");
continue;
case "b":
console.log("b");
continue;
case "c":
console.log("c");
return;
}
break;
}
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/control-flow-packer/mocks).
```bash
expose control-flow-packer path/to/file.js --output path/to/file.control-flow-packer.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Only flattens loops whose state array comes from a literal `split`.
- Stops when a branch returns or a state token is missing.
---
### `expose fn-inliner`
Inline proxy function calls into expressions.
```js
const add = (a, b) => a + b;
const sum = add(1, 2);
// after
const sum = 1 + 2;
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/fn-inliner/mocks).
```bash
expose fn-inliner path/to/file.js --output path/to/file.fn-inliner.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Only inlines functions that return a single expression.
- Skips return expressions with assignments, functions, blocks, or sequences.
---
### `expose sequence-split`
Split sequence expressions into statements.
```js
// before
a, b, c;
// after
a;
b;
c;
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/sequence-split/mocks).
```bash
expose sequence-split path/to/file.js --output path/to/file.sequence-split.js
```
Args:
- `--o, --output `
Output file path
Notes:
- Splits safe sequence expressions into standalone statements.
- Also normalizes single-statement control flow blocks.
---
### `expose remove-unused`
Remove unused variabless.
```js
// before
var a = 0, b = 1;
console.log(a);
// after
var a = 0;
console.log(a);
```
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-unused/mocks).
```bash
expose remove-unused path/to/file.js --output path/to/file.remove-unused.js
```
Args:
- `--o, --output `
Output file path
## Community & Support
- Missing a feature? → [Create an issue](https://github.com/EdamAme-x/expose-kit/issues)
- Not sure which command to use? → Join our [Discord](https://evex.land)
---
## Author
- [EdamAme-x](https://github.com/EdamAme-x)
Built for research, not abuse.
Want stronger obfuscation? Then build something this tool can’t reverse.