obscura-js 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -0
- package/dist/bin/haze.d.ts +3 -0
- package/dist/bin/haze.d.ts.map +1 -0
- package/dist/bin/haze.js +54 -0
- package/dist/bin/haze.js.map +1 -0
- package/dist/src/antiDebug/index.d.ts +11 -0
- package/dist/src/antiDebug/index.d.ts.map +1 -0
- package/dist/src/antiDebug/index.js +23 -0
- package/dist/src/antiDebug/index.js.map +1 -0
- package/dist/src/antiDebug/integrityTag.d.ts +21 -0
- package/dist/src/antiDebug/integrityTag.d.ts.map +1 -0
- package/dist/src/antiDebug/integrityTag.js +100 -0
- package/dist/src/antiDebug/integrityTag.js.map +1 -0
- package/dist/src/antiDebug/nativeBinding.d.ts +15 -0
- package/dist/src/antiDebug/nativeBinding.d.ts.map +1 -0
- package/dist/src/antiDebug/nativeBinding.js +89 -0
- package/dist/src/antiDebug/nativeBinding.js.map +1 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +35 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/obfuscation/cff.d.ts +26 -0
- package/dist/src/obfuscation/cff.d.ts.map +1 -0
- package/dist/src/obfuscation/cff.js +129 -0
- package/dist/src/obfuscation/cff.js.map +1 -0
- package/dist/src/obfuscation/deadCode.d.ts +10 -0
- package/dist/src/obfuscation/deadCode.d.ts.map +1 -0
- package/dist/src/obfuscation/deadCode.js +70 -0
- package/dist/src/obfuscation/deadCode.js.map +1 -0
- package/dist/src/obfuscation/functionTable.d.ts +18 -0
- package/dist/src/obfuscation/functionTable.d.ts.map +1 -0
- package/dist/src/obfuscation/functionTable.js +105 -0
- package/dist/src/obfuscation/functionTable.js.map +1 -0
- package/dist/src/obfuscation/index.d.ts +15 -0
- package/dist/src/obfuscation/index.d.ts.map +1 -0
- package/dist/src/obfuscation/index.js +47 -0
- package/dist/src/obfuscation/index.js.map +1 -0
- package/dist/src/obfuscation/mba.d.ts +12 -0
- package/dist/src/obfuscation/mba.d.ts.map +1 -0
- package/dist/src/obfuscation/mba.js +91 -0
- package/dist/src/obfuscation/mba.js.map +1 -0
- package/dist/src/obfuscation/sequenceExpression.d.ts +16 -0
- package/dist/src/obfuscation/sequenceExpression.d.ts.map +1 -0
- package/dist/src/obfuscation/sequenceExpression.js +85 -0
- package/dist/src/obfuscation/sequenceExpression.js.map +1 -0
- package/dist/src/obfuscation/stringPool.d.ts +14 -0
- package/dist/src/obfuscation/stringPool.d.ts.map +1 -0
- package/dist/src/obfuscation/stringPool.js +142 -0
- package/dist/src/obfuscation/stringPool.js.map +1 -0
- package/dist/src/types.d.ts +65 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +3 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# obscura-js
|
|
2
|
+
|
|
3
|
+
A JavaScript code protection library inspired by the obfuscation and anti-debugging techniques used in Google reCAPTCHA.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/obscura-js)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](package.json)
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
| Category | Pass | Description |
|
|
12
|
+
| ----------- | ----------------------- | ------------------------------------------------------------------- |
|
|
13
|
+
| Obfuscation | `sequenceExpression` | Flatten `if` blocks into comma-sequence expressions |
|
|
14
|
+
| Obfuscation | `mba` | Expand arithmetic into Mixed Boolean Arithmetic (MBA) expressions |
|
|
15
|
+
| Obfuscation | `functionTable` | Move function declarations into an indirect table, call by index |
|
|
16
|
+
| Obfuscation | `stringPool` | Encrypt all string literals into an LCG-XOR pool |
|
|
17
|
+
| Obfuscation | `controlFlowFlattening` | Transform function bodies into flat state machines |
|
|
18
|
+
| Obfuscation | `deadCode` | Inject unreachable code blocks |
|
|
19
|
+
| Anti-debug | `nativeBinding` | Pre-bind native methods to defend against prototype pollution |
|
|
20
|
+
| Anti-debug | `integrityTag` | Attach Symbol-based integrity tags to detect object cloning/replace |
|
|
21
|
+
|
|
22
|
+
## Getting Started
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install
|
|
26
|
+
npm run build
|
|
27
|
+
npm test
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install obscura-js
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### API
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { protect } from "obscura-js";
|
|
42
|
+
import { readFileSync } from "fs";
|
|
43
|
+
|
|
44
|
+
const source = readFileSync("app.js", "utf-8");
|
|
45
|
+
|
|
46
|
+
const { code, appliedPasses } = protect(source);
|
|
47
|
+
// All 8 passes are enabled by default
|
|
48
|
+
|
|
49
|
+
console.log(appliedPasses);
|
|
50
|
+
// ['sequenceExpression', 'mba', 'functionTable', 'stringPool',
|
|
51
|
+
// 'controlFlowFlattening', 'deadCode', 'nativeBinding', 'integrityTag']
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### CLI
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Protect a file (output: app.obscura.js)
|
|
58
|
+
npx obscura-js protect app.js
|
|
59
|
+
|
|
60
|
+
# Specify output path
|
|
61
|
+
npx obscura-js protect app.js -o app.protected.js
|
|
62
|
+
|
|
63
|
+
# Minify output
|
|
64
|
+
npx obscura-js protect app.js --minify
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
### `protect(source, options?)`
|
|
70
|
+
|
|
71
|
+
| Parameter | Type | Description |
|
|
72
|
+
| --------- | ------------- | --------------------------------- |
|
|
73
|
+
| `source` | `string` | JavaScript source code to protect |
|
|
74
|
+
| `options` | `HazeOptions` | Optional configuration |
|
|
75
|
+
|
|
76
|
+
Returns `ProtectResult`:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
interface ProtectResult {
|
|
80
|
+
code: string; // Protected source code
|
|
81
|
+
appliedPasses: string[]; // Names of passes that were applied
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `HazeOptions`
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
interface HazeOptions {
|
|
89
|
+
obfuscation?: {
|
|
90
|
+
sequenceExpression?: { probability?: number } | false;
|
|
91
|
+
mba?: { rounds?: number } | false;
|
|
92
|
+
functionTable?: { minFunctions?: number } | false;
|
|
93
|
+
stringPool?: { seed?: number } | false;
|
|
94
|
+
controlFlowFlattening?: {} | false;
|
|
95
|
+
deadCode?: { targetLines?: number } | false;
|
|
96
|
+
};
|
|
97
|
+
antiDebug?: {
|
|
98
|
+
nativeBinding?: { methods?: string[] } | false;
|
|
99
|
+
integrityTag?: { tagDescription?: string } | false;
|
|
100
|
+
};
|
|
101
|
+
minify?: boolean; // Default: false
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Disable a specific pass by passing `false`:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
protect(source, {
|
|
109
|
+
obfuscation: { deadCode: false, mba: false },
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Custom options example:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
protect(source, {
|
|
117
|
+
obfuscation: {
|
|
118
|
+
mba: { rounds: 2 },
|
|
119
|
+
stringPool: { seed: 1234 },
|
|
120
|
+
deadCode: { targetLines: 100 },
|
|
121
|
+
},
|
|
122
|
+
antiDebug: {
|
|
123
|
+
nativeBinding: { methods: ["Math.floor", "Object.defineProperty"] },
|
|
124
|
+
integrityTag: { tagDescription: "myapp" },
|
|
125
|
+
},
|
|
126
|
+
minify: true,
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## CLI Reference
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
obscura-js protect <input> [options]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
| Option | Description |
|
|
137
|
+
| --------------------- | ---------------------------------------------------- |
|
|
138
|
+
| `-o, --output <file>` | Output file path (default: `<input>.obscura.js`) |
|
|
139
|
+
| `--no-seq` | Disable `sequenceExpression` pass |
|
|
140
|
+
| `--no-mba` | Disable `mba` pass |
|
|
141
|
+
| `--no-ft` | Disable `functionTable` pass |
|
|
142
|
+
| `--no-sp` | Disable `stringPool` pass |
|
|
143
|
+
| `--no-cff` | Disable `controlFlowFlattening` pass |
|
|
144
|
+
| `--no-dead` | Disable `deadCode` pass |
|
|
145
|
+
| `--no-native` | Disable `nativeBinding` pass |
|
|
146
|
+
| `--no-tag` | Disable `integrityTag` pass |
|
|
147
|
+
| `--sp-seed <number>` | XOR seed for the string pool cipher |
|
|
148
|
+
| `--minify` | Compact output (remove whitespace, shorten literals) |
|
|
149
|
+
|
|
150
|
+
## Requirements
|
|
151
|
+
|
|
152
|
+
- Node.js ≥ 18
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"haze.d.ts","sourceRoot":"","sources":["../../bin/haze.ts"],"names":[],"mappings":""}
|
package/dist/bin/haze.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const commander_1 = require("commander");
|
|
7
|
+
const index_1 = require("../src/index");
|
|
8
|
+
const program = new commander_1.Command();
|
|
9
|
+
program
|
|
10
|
+
.name("obscura-js")
|
|
11
|
+
.description("JavaScript code protection tool — obfuscation & anti-debugging")
|
|
12
|
+
.version("0.1.0");
|
|
13
|
+
program
|
|
14
|
+
.command("protect <input>")
|
|
15
|
+
.description("Protect a JavaScript file")
|
|
16
|
+
.option("-o, --output <file>", "Output file (default: <input>.obscura.js)")
|
|
17
|
+
.option("--no-seq", "Disable sequence expression pass")
|
|
18
|
+
.option("--no-mba", "Disable mixed boolean arithmetic pass")
|
|
19
|
+
.option("--no-ft", "Disable indirect function table pass")
|
|
20
|
+
.option("--no-sp", "Disable encrypted string pool pass")
|
|
21
|
+
.option("--no-cff", "Disable control flow flattening pass")
|
|
22
|
+
.option("--no-dead", "Disable dead code injection pass")
|
|
23
|
+
.option("--no-native", "Disable native method binding pass")
|
|
24
|
+
.option("--no-tag", "Disable symbol integrity tag pass")
|
|
25
|
+
.option("--sp-seed <number>", "Seed for the string pool XOR cipher", parseInt)
|
|
26
|
+
.option("--minify", "Minify output (compact whitespace, shorten literals)")
|
|
27
|
+
.action((input, opts) => {
|
|
28
|
+
const inputPath = (0, path_1.resolve)(process.cwd(), input);
|
|
29
|
+
const source = (0, fs_1.readFileSync)(inputPath, "utf-8");
|
|
30
|
+
const options = {
|
|
31
|
+
obfuscation: {
|
|
32
|
+
sequenceExpression: opts["seq"] === false ? false : {},
|
|
33
|
+
mba: opts["mba"] === false ? false : {},
|
|
34
|
+
functionTable: opts["ft"] === false ? false : {},
|
|
35
|
+
stringPool: opts["sp"] === false ? false : { seed: opts["spSeed"] },
|
|
36
|
+
controlFlowFlattening: opts["cff"] === false ? false : {},
|
|
37
|
+
deadCode: opts["dead"] === false ? false : {},
|
|
38
|
+
},
|
|
39
|
+
antiDebug: {
|
|
40
|
+
nativeBinding: opts["native"] === false ? false : {},
|
|
41
|
+
integrityTag: opts["tag"] === false ? false : {},
|
|
42
|
+
},
|
|
43
|
+
minify: opts["minify"] === true,
|
|
44
|
+
};
|
|
45
|
+
const { code, appliedPasses } = (0, index_1.protect)(source, options);
|
|
46
|
+
const outputPath = opts["output"]
|
|
47
|
+
? (0, path_1.resolve)(process.cwd(), opts["output"])
|
|
48
|
+
: inputPath.replace(/\.js$/, "") + ".obscura.js";
|
|
49
|
+
(0, fs_1.writeFileSync)(outputPath, code, "utf-8");
|
|
50
|
+
console.log(`✔ Protected: ${outputPath}`);
|
|
51
|
+
console.log(` Passes applied: ${appliedPasses.join(", ")}`);
|
|
52
|
+
});
|
|
53
|
+
program.parse(process.argv);
|
|
54
|
+
//# sourceMappingURL=haze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"haze.js","sourceRoot":"","sources":["../../bin/haze.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type * as t from "@babel/types";
|
|
2
|
+
import type { AntiDebugOptions } from "../types";
|
|
3
|
+
import { applyIntegrityTag } from "./integrityTag";
|
|
4
|
+
import { applyNativeBinding } from "./nativeBinding";
|
|
5
|
+
export { applyIntegrityTag, applyNativeBinding };
|
|
6
|
+
/**
|
|
7
|
+
* Run all enabled anti-debugging/tampering passes in order.
|
|
8
|
+
* Each pass is opt-in: pass `false` to skip it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyAntiDebug(ast: t.File, options: AntiDebugOptions | undefined, appliedPasses: string[]): void;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/antiDebug/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,CAAC,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,CAAC,CAAC,IAAI,EACX,OAAO,EAAE,gBAAgB,YAAK,EAC9B,aAAa,EAAE,MAAM,EAAE,GACtB,IAAI,CASN"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyNativeBinding = exports.applyIntegrityTag = void 0;
|
|
4
|
+
exports.applyAntiDebug = applyAntiDebug;
|
|
5
|
+
const integrityTag_1 = require("./integrityTag");
|
|
6
|
+
Object.defineProperty(exports, "applyIntegrityTag", { enumerable: true, get: function () { return integrityTag_1.applyIntegrityTag; } });
|
|
7
|
+
const nativeBinding_1 = require("./nativeBinding");
|
|
8
|
+
Object.defineProperty(exports, "applyNativeBinding", { enumerable: true, get: function () { return nativeBinding_1.applyNativeBinding; } });
|
|
9
|
+
/**
|
|
10
|
+
* Run all enabled anti-debugging/tampering passes in order.
|
|
11
|
+
* Each pass is opt-in: pass `false` to skip it.
|
|
12
|
+
*/
|
|
13
|
+
function applyAntiDebug(ast, options = {}, appliedPasses) {
|
|
14
|
+
if (options.nativeBinding !== false) {
|
|
15
|
+
(0, nativeBinding_1.applyNativeBinding)(ast, options.nativeBinding ?? {});
|
|
16
|
+
appliedPasses.push("nativeBinding");
|
|
17
|
+
}
|
|
18
|
+
if (options.integrityTag !== false) {
|
|
19
|
+
(0, integrityTag_1.applyIntegrityTag)(ast, options.integrityTag ?? {});
|
|
20
|
+
appliedPasses.push("integrityTag");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/antiDebug/index.ts"],"names":[],"mappings":";;;AAWA,wCAaC;AAtBD,iDAAmD;AAG1C,kGAHA,gCAAiB,OAGA;AAF1B,mDAAqD;AAEzB,mGAFnB,kCAAkB,OAEmB;AAE9C;;;GAGG;AACH,SAAgB,cAAc,CAC5B,GAAW,EACX,UAA4B,EAAE,EAC9B,aAAuB;IAEvB,IAAI,OAAO,CAAC,aAAa,KAAK,KAAK,EAAE,CAAC;QACpC,IAAA,kCAAkB,EAAC,GAAG,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QACrD,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;QACnC,IAAA,gCAAiB,EAAC,GAAG,EAAE,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QACnD,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import type { IntegrityTagOptions } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Pass: Symbol-based Integrity Tag
|
|
5
|
+
*
|
|
6
|
+
* Attaches a `Symbol(<description>)` integrity check value to every
|
|
7
|
+
* array/object literal in the AST. At runtime, code can verify the
|
|
8
|
+
* symbol is present to detect tampering (cloning, serialisation, etc.).
|
|
9
|
+
*
|
|
10
|
+
* The runtime helper `__haze_tag` is prepended to the output:
|
|
11
|
+
*
|
|
12
|
+
* const __haze_sym = Symbol('jas');
|
|
13
|
+
* function __haze_tag(v, checksum) {
|
|
14
|
+
* Object.defineProperty(v, __haze_sym, { value: checksum, enumerable: false });
|
|
15
|
+
* return v;
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* Arrays are replaced by: __haze_tag([...], <checksum>)
|
|
19
|
+
*/
|
|
20
|
+
export declare function applyIntegrityTag(ast: t.File, options?: IntegrityTagOptions): void;
|
|
21
|
+
//# sourceMappingURL=integrityTag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrityTag.d.ts","sourceRoot":"","sources":["../../../src/antiDebug/integrityTag.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI,CA2DtF"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.applyIntegrityTag = applyIntegrityTag;
|
|
40
|
+
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
41
|
+
const t = __importStar(require("@babel/types"));
|
|
42
|
+
/**
|
|
43
|
+
* Pass: Symbol-based Integrity Tag
|
|
44
|
+
*
|
|
45
|
+
* Attaches a `Symbol(<description>)` integrity check value to every
|
|
46
|
+
* array/object literal in the AST. At runtime, code can verify the
|
|
47
|
+
* symbol is present to detect tampering (cloning, serialisation, etc.).
|
|
48
|
+
*
|
|
49
|
+
* The runtime helper `__haze_tag` is prepended to the output:
|
|
50
|
+
*
|
|
51
|
+
* const __haze_sym = Symbol('jas');
|
|
52
|
+
* function __haze_tag(v, checksum) {
|
|
53
|
+
* Object.defineProperty(v, __haze_sym, { value: checksum, enumerable: false });
|
|
54
|
+
* return v;
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* Arrays are replaced by: __haze_tag([...], <checksum>)
|
|
58
|
+
*/
|
|
59
|
+
function applyIntegrityTag(ast, options = {}) {
|
|
60
|
+
const description = options.tagDescription ?? "jas";
|
|
61
|
+
const symVar = "__haze_sym";
|
|
62
|
+
const tagFn = "__haze_tag";
|
|
63
|
+
let hasArrays = false;
|
|
64
|
+
(0, traverse_1.default)(ast, {
|
|
65
|
+
ArrayExpression(path) {
|
|
66
|
+
// Skip if already tagged or inside the helper declarations
|
|
67
|
+
if (t.isCallExpression(path.parent))
|
|
68
|
+
return;
|
|
69
|
+
const checksum = path.node.elements.length ^ 0xdeadbeef;
|
|
70
|
+
path.replaceWith(t.callExpression(t.identifier(tagFn), [
|
|
71
|
+
t.cloneNode(path.node, true),
|
|
72
|
+
t.numericLiteral(checksum >>> 0),
|
|
73
|
+
]));
|
|
74
|
+
hasArrays = true;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
if (!hasArrays)
|
|
78
|
+
return;
|
|
79
|
+
// const __haze_sym = Symbol('jas');
|
|
80
|
+
const symDecl = t.variableDeclaration("const", [
|
|
81
|
+
t.variableDeclarator(t.identifier(symVar), t.callExpression(t.identifier("Symbol"), [t.stringLiteral(description)])),
|
|
82
|
+
]);
|
|
83
|
+
// function __haze_tag(v, checksum) {
|
|
84
|
+
// Object.defineProperty(v, __haze_sym, { value: checksum, enumerable: false });
|
|
85
|
+
// return v;
|
|
86
|
+
// }
|
|
87
|
+
const tagDecl = t.functionDeclaration(t.identifier(tagFn), [t.identifier("v"), t.identifier("checksum")], t.blockStatement([
|
|
88
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("defineProperty")), [
|
|
89
|
+
t.identifier("v"),
|
|
90
|
+
t.identifier(symVar),
|
|
91
|
+
t.objectExpression([
|
|
92
|
+
t.objectProperty(t.identifier("value"), t.identifier("checksum")),
|
|
93
|
+
t.objectProperty(t.identifier("enumerable"), t.booleanLiteral(false)),
|
|
94
|
+
]),
|
|
95
|
+
])),
|
|
96
|
+
t.returnStatement(t.identifier("v")),
|
|
97
|
+
]));
|
|
98
|
+
ast.program.body.unshift(tagDecl, symDecl);
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=integrityTag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrityTag.js","sourceRoot":"","sources":["../../../src/antiDebug/integrityTag.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,8CA2DC;AAhFD,+DAAuC;AACvC,gDAAkC;AAGlC;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,iBAAiB,CAAC,GAAW,EAAE,UAA+B,EAAE;IAC9E,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,IAAI,KAAK,CAAC;IACpD,MAAM,MAAM,GAAG,YAAY,CAAC;IAC5B,MAAM,KAAK,GAAG,YAAY,CAAC;IAE3B,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,IAAA,kBAAQ,EAAC,GAAG,EAAE;QACZ,eAAe,CAAC,IAAI;YAClB,2DAA2D;YAC3D,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAO;YAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC;YACxD,IAAI,CAAC,WAAW,CACd,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;gBACpC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;gBAC5B,CAAC,CAAC,cAAc,CAAC,QAAQ,KAAK,CAAC,CAAC;aACjC,CAAC,CACH,CAAC;YACF,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS;QAAE,OAAO;IAEvB,oCAAoC;IACpC,MAAM,OAAO,GAAG,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE;QAC7C,CAAC,CAAC,kBAAkB,CAClB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EACpB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CACzE;KACF,CAAC,CAAC;IAEH,qCAAqC;IACrC,kFAAkF;IAClF,cAAc;IACd,IAAI;IACJ,MAAM,OAAO,GAAG,CAAC,CAAC,mBAAmB,CACnC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EACnB,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAC7C,CAAC,CAAC,cAAc,CAAC;QACf,CAAC,CAAC,mBAAmB,CACnB,CAAC,CAAC,cAAc,CACd,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,EAC1E;YACE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YACjB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;YACpB,CAAC,CAAC,gBAAgB,CAAC;gBACjB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;gBACjE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;aACtE,CAAC;SACH,CACF,CACF;QACD,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;KACrC,CAAC,CACH,CAAC;IAED,GAAG,CAAC,OAAO,CAAC,IAAsB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import type { NativeBindingOptions } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Pass: Native Method Binding
|
|
5
|
+
*
|
|
6
|
+
* Pre-binds native browser/Node.js methods to their original receivers and
|
|
7
|
+
* stores them as constants. External scripts that monkey-patch prototypes
|
|
8
|
+
* cannot affect these captured references.
|
|
9
|
+
*
|
|
10
|
+
* Example output:
|
|
11
|
+
* const __haze_Math_floor = Math.floor.bind(Math);
|
|
12
|
+
* const __haze_Math_random = Math.random.bind(Math);
|
|
13
|
+
*/
|
|
14
|
+
export declare function applyNativeBinding(ast: t.File, options?: NativeBindingOptions): void;
|
|
15
|
+
//# sourceMappingURL=nativeBinding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeBinding.d.ts","sourceRoot":"","sources":["../../../src/antiDebug/nativeBinding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAcrD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,GAAE,oBAAyB,GAAG,IAAI,CAsCxF"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.applyNativeBinding = applyNativeBinding;
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
/** Default set of native methods to pre-bind */
|
|
39
|
+
const DEFAULT_METHODS = [
|
|
40
|
+
"Math.floor",
|
|
41
|
+
"Math.random",
|
|
42
|
+
"Math.ceil",
|
|
43
|
+
"Math.round",
|
|
44
|
+
"Object.defineProperty",
|
|
45
|
+
"Object.keys",
|
|
46
|
+
"Array.prototype.slice",
|
|
47
|
+
"Array.prototype.forEach",
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Pass: Native Method Binding
|
|
51
|
+
*
|
|
52
|
+
* Pre-binds native browser/Node.js methods to their original receivers and
|
|
53
|
+
* stores them as constants. External scripts that monkey-patch prototypes
|
|
54
|
+
* cannot affect these captured references.
|
|
55
|
+
*
|
|
56
|
+
* Example output:
|
|
57
|
+
* const __haze_Math_floor = Math.floor.bind(Math);
|
|
58
|
+
* const __haze_Math_random = Math.random.bind(Math);
|
|
59
|
+
*/
|
|
60
|
+
function applyNativeBinding(ast, options = {}) {
|
|
61
|
+
const methods = options.methods ?? DEFAULT_METHODS;
|
|
62
|
+
const declarations = methods.map((methodPath) => {
|
|
63
|
+
const parts = methodPath.split(".");
|
|
64
|
+
// receiver is the object before the last segment (e.g. Math for Math.floor)
|
|
65
|
+
const receiverPath = parts.slice(0, -1).join(".");
|
|
66
|
+
const constName = `__haze_${parts.join("_")}`;
|
|
67
|
+
// Build member expression: Math.floor
|
|
68
|
+
const memberExpr = parts.reduce((acc, part) => t.memberExpression(acc, t.identifier(part)), t.identifier(parts[0]));
|
|
69
|
+
// Actually rebuild correctly:
|
|
70
|
+
let obj = t.identifier(parts[0]);
|
|
71
|
+
for (let i = 1; i < parts.length; i++) {
|
|
72
|
+
obj = t.memberExpression(obj, t.identifier(parts[i]));
|
|
73
|
+
}
|
|
74
|
+
// receiver expression (e.g. Math, Array.prototype)
|
|
75
|
+
let receiver = t.identifier(parts[0]);
|
|
76
|
+
for (let i = 1; i < parts.length - 1; i++) {
|
|
77
|
+
receiver = t.memberExpression(receiver, t.identifier(parts[i]));
|
|
78
|
+
}
|
|
79
|
+
void memberExpr; // suppress unused warning — we use `obj` instead
|
|
80
|
+
void receiverPath;
|
|
81
|
+
// <method>.bind(<receiver>)
|
|
82
|
+
const bindCall = t.callExpression(t.memberExpression(obj, t.identifier("bind")), [receiver]);
|
|
83
|
+
return t.variableDeclaration("const", [
|
|
84
|
+
t.variableDeclarator(t.identifier(constName), bindCall),
|
|
85
|
+
]);
|
|
86
|
+
});
|
|
87
|
+
ast.program.body.unshift(...declarations);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=nativeBinding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeBinding.js","sourceRoot":"","sources":["../../../src/antiDebug/nativeBinding.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,gDAsCC;AAhED,gDAAkC;AAGlC,gDAAgD;AAChD,MAAM,eAAe,GAAG;IACtB,YAAY;IACZ,aAAa;IACb,WAAW;IACX,YAAY;IACZ,uBAAuB;IACvB,aAAa;IACb,uBAAuB;IACvB,yBAAyB;CAC1B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAAC,GAAW,EAAE,UAAgC,EAAE;IAChF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,CAAC;IAEnD,MAAM,YAAY,GAA4B,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QACvE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,4EAA4E;QAC5E,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,UAAU,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAE9C,sCAAsC;QACtC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAC7B,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAC1D,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACvB,CAAC;QACF,8BAA8B;QAC9B,IAAI,GAAG,GAAiB,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,GAAG,GAAG,CAAC,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC;QAED,mDAAmD;QACnD,IAAI,QAAQ,GAAiB,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,QAAQ,GAAG,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,CAAC;QAED,KAAK,UAAU,CAAC,CAAC,iDAAiD;QAClE,KAAK,YAAY,CAAC;QAElB,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QAE7F,OAAO,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE;YACpC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;SACxD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEF,GAAG,CAAC,OAAO,CAAC,IAAsB,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HazeOptions, ProtectResult } from "./types";
|
|
2
|
+
export type { HazeOptions, ProtectResult } from "./types";
|
|
3
|
+
export type { ObfuscationOptions, AntiDebugOptions, SequenceExpressionOptions, MbaOptions, FunctionTableOptions, StringPoolOptions, ControlFlowFlatteningOptions, DeadCodeOptions, IntegrityTagOptions, NativeBindingOptions, } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Protect JavaScript source code by running the configured passes.
|
|
6
|
+
*
|
|
7
|
+
* @param source - Original JavaScript source code
|
|
8
|
+
* @param options - Protection configuration
|
|
9
|
+
* @returns ProtectResult containing the protected code and applied pass names
|
|
10
|
+
*/
|
|
11
|
+
export declare function protect(source: string, options?: HazeOptions): ProtectResult;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE1D,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1D,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,4BAA4B,EAC5B,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,SAAS,CAAC;AAEjB;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,aAAa,CAqBhF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.protect = protect;
|
|
7
|
+
const parser_1 = require("@babel/parser");
|
|
8
|
+
const generator_1 = __importDefault(require("@babel/generator"));
|
|
9
|
+
const obfuscation_1 = require("./obfuscation");
|
|
10
|
+
const antiDebug_1 = require("./antiDebug");
|
|
11
|
+
/**
|
|
12
|
+
* Protect JavaScript source code by running the configured passes.
|
|
13
|
+
*
|
|
14
|
+
* @param source - Original JavaScript source code
|
|
15
|
+
* @param options - Protection configuration
|
|
16
|
+
* @returns ProtectResult containing the protected code and applied pass names
|
|
17
|
+
*/
|
|
18
|
+
function protect(source, options = {}) {
|
|
19
|
+
if (typeof source !== "string") {
|
|
20
|
+
throw new TypeError("source must be a string");
|
|
21
|
+
}
|
|
22
|
+
const ast = (0, parser_1.parse)(source, {
|
|
23
|
+
sourceType: "unambiguous",
|
|
24
|
+
plugins: ["jsx"],
|
|
25
|
+
});
|
|
26
|
+
const appliedPasses = [];
|
|
27
|
+
(0, obfuscation_1.applyObfuscation)(ast, options.obfuscation, appliedPasses);
|
|
28
|
+
(0, antiDebug_1.applyAntiDebug)(ast, options.antiDebug, appliedPasses);
|
|
29
|
+
const { code } = (0, generator_1.default)(ast, {
|
|
30
|
+
minified: options.minify ?? false,
|
|
31
|
+
compact: options.minify ?? false,
|
|
32
|
+
});
|
|
33
|
+
return { code, appliedPasses };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;AA2BA,0BAqBC;AAhDD,0CAAsC;AACtC,iEAAwC;AACxC,+CAAiD;AACjD,2CAA6C;AAiB7C;;;;;;GAMG;AACH,SAAgB,OAAO,CAAC,MAAc,EAAE,UAAuB,EAAE;IAC/D,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,cAAK,EAAC,MAAM,EAAE;QACxB,UAAU,EAAE,aAAa;QACzB,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,CAAC,CAAC;IAEH,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,IAAA,8BAAgB,EAAC,GAAG,EAAE,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1D,IAAA,0BAAc,EAAC,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAEtD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,mBAAQ,EAAC,GAAG,EAAE;QAC7B,QAAQ,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;QACjC,OAAO,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;KACjC,CAAC,CAAC;IAEH,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import type { ControlFlowFlatteningOptions } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Pass: Control Flow Flattening (CFF)
|
|
5
|
+
*
|
|
6
|
+
* Transforms a function body into a flat state machine with a central
|
|
7
|
+
* dispatcher loop, hiding the original execution order.
|
|
8
|
+
*
|
|
9
|
+
* Before:
|
|
10
|
+
* function f() { stmt0; stmt1; stmt2; }
|
|
11
|
+
*
|
|
12
|
+
* After:
|
|
13
|
+
* function f() {
|
|
14
|
+
* let __s = 0;
|
|
15
|
+
* while (true) {
|
|
16
|
+
* switch (__s) {
|
|
17
|
+
* case 0: stmt0; __s = 1; break;
|
|
18
|
+
* case 1: stmt1; __s = 2; break;
|
|
19
|
+
* case 2: stmt2; __s = -1; break;
|
|
20
|
+
* default: return;
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
*/
|
|
25
|
+
export declare function applyControlFlowFlattening(ast: t.File, options?: ControlFlowFlatteningOptions): void;
|
|
26
|
+
//# sourceMappingURL=cff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cff.d.ts","sourceRoot":"","sources":["../../../src/obfuscation/cff.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,CAAC,CAAC,IAAI,EACX,OAAO,GAAE,4BAAiC,GACzC,IAAI,CAmFN"}
|