js-confuser 2.0.0-alpha.5 → 2.0.1
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/.github/ISSUE_TEMPLATE/bug_report.md +43 -43
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
- package/.github/workflows/node.js.yml +28 -28
- package/.prettierrc +4 -4
- package/CHANGELOG.md +1015 -989
- package/CODE_OF_CONDUCT.md +131 -131
- package/CONTRIBUTING.md +52 -52
- package/LICENSE +21 -21
- package/Migration.md +72 -71
- package/README.md +86 -78
- package/dist/constants.js +43 -43
- package/dist/index.js +14 -23
- package/dist/obfuscator.js +31 -25
- package/dist/order.js +4 -4
- package/dist/presets.js +31 -31
- package/dist/templates/integrityTemplate.js +4 -4
- package/dist/templates/template.js +1 -2
- package/dist/transforms/astScrambler.js +1 -2
- package/dist/transforms/calculator.js +1 -2
- package/dist/transforms/controlFlowFlattening.js +93 -63
- package/dist/transforms/deadCode.js +1 -2
- package/dist/transforms/dispatcher.js +4 -5
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +1 -2
- package/dist/transforms/extraction/objectExtraction.js +1 -2
- package/dist/transforms/finalizer.js +1 -2
- package/dist/transforms/flatten.js +1 -2
- package/dist/transforms/identifier/globalConcealing.js +15 -2
- package/dist/transforms/identifier/movedDeclarations.js +8 -7
- package/dist/transforms/identifier/renameVariables.js +7 -7
- package/dist/transforms/lock/integrity.js +11 -10
- package/dist/transforms/lock/lock.js +2 -3
- package/dist/transforms/minify.js +11 -29
- package/dist/transforms/opaquePredicates.js +1 -2
- package/dist/transforms/pack.js +5 -2
- package/dist/transforms/plugin.js +18 -19
- package/dist/transforms/preparation.js +16 -16
- package/dist/transforms/renameLabels.js +1 -2
- package/dist/transforms/rgf.js +8 -9
- package/dist/transforms/shuffle.js +1 -2
- package/dist/transforms/string/encoding.js +1 -2
- package/dist/transforms/string/stringCompression.js +3 -4
- package/dist/transforms/string/stringConcealing.js +8 -3
- package/dist/transforms/string/stringEncoding.js +1 -2
- package/dist/transforms/variableMasking.js +1 -2
- package/dist/utils/NameGen.js +2 -2
- package/dist/utils/PredicateGen.js +1 -2
- package/dist/utils/ast-utils.js +87 -88
- package/dist/utils/function-utils.js +8 -8
- package/dist/utils/node.js +5 -6
- package/dist/utils/object-utils.js +4 -4
- package/dist/utils/random-utils.js +20 -20
- package/dist/utils/static-utils.js +1 -2
- package/dist/validateOptions.js +4 -7
- package/index.d.ts +17 -17
- package/package.json +61 -59
- package/src/constants.ts +168 -168
- package/src/index.ts +118 -118
- package/src/obfuscationResult.ts +49 -49
- package/src/obfuscator.ts +501 -497
- package/src/options.ts +407 -407
- package/src/order.ts +54 -54
- package/src/presets.ts +125 -125
- package/src/templates/bufferToStringTemplate.ts +57 -57
- package/src/templates/deadCodeTemplates.ts +1185 -1185
- package/src/templates/getGlobalTemplate.ts +76 -76
- package/src/templates/integrityTemplate.ts +64 -64
- package/src/templates/setFunctionLengthTemplate.ts +11 -11
- package/src/templates/stringCompressionTemplate.ts +20 -20
- package/src/templates/tamperProtectionTemplates.ts +120 -120
- package/src/templates/template.ts +224 -224
- package/src/transforms/astScrambler.ts +99 -99
- package/src/transforms/calculator.ts +99 -99
- package/src/transforms/controlFlowFlattening.ts +1716 -1664
- package/src/transforms/deadCode.ts +82 -82
- package/src/transforms/dispatcher.ts +450 -450
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +156 -158
- package/src/transforms/extraction/objectExtraction.ts +186 -186
- package/src/transforms/finalizer.ts +74 -74
- package/src/transforms/flatten.ts +421 -420
- package/src/transforms/identifier/globalConcealing.ts +315 -295
- package/src/transforms/identifier/movedDeclarations.ts +252 -251
- package/src/transforms/identifier/renameVariables.ts +328 -321
- package/src/transforms/lock/integrity.ts +117 -114
- package/src/transforms/lock/lock.ts +418 -425
- package/src/transforms/minify.ts +615 -629
- package/src/transforms/opaquePredicates.ts +100 -100
- package/src/transforms/pack.ts +239 -231
- package/src/transforms/plugin.ts +173 -173
- package/src/transforms/preparation.ts +349 -347
- package/src/transforms/renameLabels.ts +175 -175
- package/src/transforms/rgf.ts +322 -322
- package/src/transforms/shuffle.ts +82 -82
- package/src/transforms/string/encoding.ts +144 -144
- package/src/transforms/string/stringCompression.ts +128 -128
- package/src/transforms/string/stringConcealing.ts +312 -298
- package/src/transforms/string/stringEncoding.ts +80 -80
- package/src/transforms/string/stringSplitting.ts +77 -77
- package/src/transforms/variableMasking.ts +257 -257
- package/src/utils/IntGen.ts +33 -33
- package/src/utils/NameGen.ts +116 -116
- package/src/utils/PredicateGen.ts +61 -61
- package/src/utils/ast-utils.ts +663 -663
- package/src/utils/function-utils.ts +50 -50
- package/src/utils/gen-utils.ts +48 -48
- package/src/utils/node.ts +78 -78
- package/src/utils/object-utils.ts +21 -21
- package/src/utils/random-utils.ts +93 -93
- package/src/utils/static-utils.ts +66 -66
- package/src/validateOptions.ts +256 -259
- package/tsconfig.json +13 -14
- package/dist/probability.js +0 -1
- package/dist/transforms/functionOutlining.js +0 -230
- package/dist/utils/ControlObject.js +0 -125
package/src/utils/NameGen.ts
CHANGED
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
import { ok } from "assert";
|
|
2
|
-
import { ObfuscateOptions } from "../options";
|
|
3
|
-
import { alphabeticalGenerator, createZeroWidthGenerator } from "./gen-utils";
|
|
4
|
-
import {
|
|
5
|
-
choice,
|
|
6
|
-
getRandomChineseString,
|
|
7
|
-
getRandomHexString,
|
|
8
|
-
getRandomInteger,
|
|
9
|
-
} from "./random-utils";
|
|
10
|
-
import { reservedKeywords, reservedObjectPrototype } from "../constants";
|
|
11
|
-
import Obfuscator from "../obfuscator";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Generate random names for variables and properties.
|
|
15
|
-
*/
|
|
16
|
-
export class NameGen {
|
|
17
|
-
public generatedNames = new Set<string>();
|
|
18
|
-
public notSafeForReuseNames = new Set<string>();
|
|
19
|
-
|
|
20
|
-
private counter = 1;
|
|
21
|
-
private zeroWidthGenerator = createZeroWidthGenerator();
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
24
|
-
private identifierGenerator: ObfuscateOptions["identifierGenerator"] = "randomized",
|
|
25
|
-
public options = {
|
|
26
|
-
avoidReserved: false,
|
|
27
|
-
avoidObjectPrototype: false,
|
|
28
|
-
}
|
|
29
|
-
) {}
|
|
30
|
-
|
|
31
|
-
private attemptGenerate() {
|
|
32
|
-
if (typeof this.identifierGenerator === "function") {
|
|
33
|
-
var value = this.identifierGenerator();
|
|
34
|
-
ok(
|
|
35
|
-
typeof value === "string",
|
|
36
|
-
"Custom identifier generator must return a string"
|
|
37
|
-
);
|
|
38
|
-
return value;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
var mode = Obfuscator.prototype.computeProbabilityMap(
|
|
42
|
-
this.identifierGenerator
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
const randomizedLength = getRandomInteger(6, 8);
|
|
46
|
-
|
|
47
|
-
switch (mode) {
|
|
48
|
-
case "randomized":
|
|
49
|
-
var characters =
|
|
50
|
-
"_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
|
|
51
|
-
var numbers = "0123456789".split("");
|
|
52
|
-
|
|
53
|
-
var combined = [...characters, ...numbers];
|
|
54
|
-
|
|
55
|
-
var result = "";
|
|
56
|
-
for (var i = 0; i < randomizedLength; i++) {
|
|
57
|
-
result += choice(i == 0 ? characters : combined);
|
|
58
|
-
}
|
|
59
|
-
return result;
|
|
60
|
-
|
|
61
|
-
case "hexadecimal":
|
|
62
|
-
return "_0x" + getRandomHexString(randomizedLength);
|
|
63
|
-
|
|
64
|
-
case "mangled":
|
|
65
|
-
var mangledName = "";
|
|
66
|
-
do {
|
|
67
|
-
mangledName = alphabeticalGenerator(this.counter++);
|
|
68
|
-
} while (reservedKeywords.includes(mangledName));
|
|
69
|
-
|
|
70
|
-
return mangledName;
|
|
71
|
-
|
|
72
|
-
case "number":
|
|
73
|
-
return "var_" + this.counter++;
|
|
74
|
-
|
|
75
|
-
case "zeroWidth":
|
|
76
|
-
return this.zeroWidthGenerator.generate();
|
|
77
|
-
|
|
78
|
-
case "chinese":
|
|
79
|
-
return getRandomChineseString(randomizedLength);
|
|
80
|
-
|
|
81
|
-
default:
|
|
82
|
-
throw new Error(
|
|
83
|
-
"Invalid identifier generator mode: " + this.identifierGenerator
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
generate(isSafeForReuse = true): string {
|
|
89
|
-
let name: string;
|
|
90
|
-
|
|
91
|
-
do {
|
|
92
|
-
name = this.attemptGenerate();
|
|
93
|
-
|
|
94
|
-
// Avoid reserved keywords
|
|
95
|
-
if (this.options.avoidReserved && reservedKeywords.includes(name)) {
|
|
96
|
-
name = "";
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Avoid reserved object prototype properties
|
|
101
|
-
if (
|
|
102
|
-
this.options.avoidObjectPrototype &&
|
|
103
|
-
reservedObjectPrototype.has(name)
|
|
104
|
-
) {
|
|
105
|
-
name = "";
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
} while (!name || this.generatedNames.has(name));
|
|
109
|
-
|
|
110
|
-
this.generatedNames.add(name);
|
|
111
|
-
if (!isSafeForReuse) {
|
|
112
|
-
this.notSafeForReuseNames.add(name);
|
|
113
|
-
}
|
|
114
|
-
return name;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
1
|
+
import { ok } from "assert";
|
|
2
|
+
import { ObfuscateOptions } from "../options";
|
|
3
|
+
import { alphabeticalGenerator, createZeroWidthGenerator } from "./gen-utils";
|
|
4
|
+
import {
|
|
5
|
+
choice,
|
|
6
|
+
getRandomChineseString,
|
|
7
|
+
getRandomHexString,
|
|
8
|
+
getRandomInteger,
|
|
9
|
+
} from "./random-utils";
|
|
10
|
+
import { reservedKeywords, reservedObjectPrototype } from "../constants";
|
|
11
|
+
import Obfuscator from "../obfuscator";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generate random names for variables and properties.
|
|
15
|
+
*/
|
|
16
|
+
export class NameGen {
|
|
17
|
+
public generatedNames = new Set<string>();
|
|
18
|
+
public notSafeForReuseNames = new Set<string>();
|
|
19
|
+
|
|
20
|
+
private counter = 1;
|
|
21
|
+
private zeroWidthGenerator = createZeroWidthGenerator();
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
private identifierGenerator: ObfuscateOptions["identifierGenerator"] = "randomized",
|
|
25
|
+
public options = {
|
|
26
|
+
avoidReserved: false,
|
|
27
|
+
avoidObjectPrototype: false,
|
|
28
|
+
}
|
|
29
|
+
) {}
|
|
30
|
+
|
|
31
|
+
private attemptGenerate() {
|
|
32
|
+
if (typeof this.identifierGenerator === "function") {
|
|
33
|
+
var value = this.identifierGenerator();
|
|
34
|
+
ok(
|
|
35
|
+
typeof value === "string",
|
|
36
|
+
"Custom identifier generator must return a string"
|
|
37
|
+
);
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var mode = Obfuscator.prototype.computeProbabilityMap(
|
|
42
|
+
this.identifierGenerator
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const randomizedLength = getRandomInteger(6, 8);
|
|
46
|
+
|
|
47
|
+
switch (mode) {
|
|
48
|
+
case "randomized":
|
|
49
|
+
var characters =
|
|
50
|
+
"_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
|
|
51
|
+
var numbers = "0123456789".split("");
|
|
52
|
+
|
|
53
|
+
var combined = [...characters, ...numbers];
|
|
54
|
+
|
|
55
|
+
var result = "";
|
|
56
|
+
for (var i = 0; i < randomizedLength; i++) {
|
|
57
|
+
result += choice(i == 0 ? characters : combined);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
|
|
61
|
+
case "hexadecimal":
|
|
62
|
+
return "_0x" + getRandomHexString(randomizedLength);
|
|
63
|
+
|
|
64
|
+
case "mangled":
|
|
65
|
+
var mangledName = "";
|
|
66
|
+
do {
|
|
67
|
+
mangledName = alphabeticalGenerator(this.counter++);
|
|
68
|
+
} while (reservedKeywords.includes(mangledName));
|
|
69
|
+
|
|
70
|
+
return mangledName;
|
|
71
|
+
|
|
72
|
+
case "number":
|
|
73
|
+
return "var_" + this.counter++;
|
|
74
|
+
|
|
75
|
+
case "zeroWidth":
|
|
76
|
+
return this.zeroWidthGenerator.generate();
|
|
77
|
+
|
|
78
|
+
case "chinese":
|
|
79
|
+
return getRandomChineseString(randomizedLength);
|
|
80
|
+
|
|
81
|
+
default:
|
|
82
|
+
throw new Error(
|
|
83
|
+
"Invalid identifier generator mode: " + this.identifierGenerator
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
generate(isSafeForReuse = true): string {
|
|
89
|
+
let name: string;
|
|
90
|
+
|
|
91
|
+
do {
|
|
92
|
+
name = this.attemptGenerate();
|
|
93
|
+
|
|
94
|
+
// Avoid reserved keywords
|
|
95
|
+
if (this.options.avoidReserved && reservedKeywords.includes(name)) {
|
|
96
|
+
name = "";
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Avoid reserved object prototype properties
|
|
101
|
+
if (
|
|
102
|
+
this.options.avoidObjectPrototype &&
|
|
103
|
+
reservedObjectPrototype.has(name)
|
|
104
|
+
) {
|
|
105
|
+
name = "";
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
} while (!name || this.generatedNames.has(name));
|
|
109
|
+
|
|
110
|
+
this.generatedNames.add(name);
|
|
111
|
+
if (!isSafeForReuse) {
|
|
112
|
+
this.notSafeForReuseNames.add(name);
|
|
113
|
+
}
|
|
114
|
+
return name;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import { NodePath } from "@babel/traverse";
|
|
2
|
-
import { PluginInstance } from "../transforms/plugin";
|
|
3
|
-
import * as t from "@babel/types";
|
|
4
|
-
import { prepend } from "./ast-utils";
|
|
5
|
-
import { NameGen } from "./NameGen";
|
|
6
|
-
import Template from "../templates/template";
|
|
7
|
-
|
|
8
|
-
export default class PredicateGen {
|
|
9
|
-
constructor(public plugin: PluginInstance) {}
|
|
10
|
-
|
|
11
|
-
dummyFunctionName: string | null = null;
|
|
12
|
-
programPath: NodePath<t.Program> | null = null;
|
|
13
|
-
|
|
14
|
-
ensureCreated() {
|
|
15
|
-
if (this.dummyFunctionName) return;
|
|
16
|
-
|
|
17
|
-
this.dummyFunctionName = this.plugin.getPlaceholder("dummyFunction");
|
|
18
|
-
|
|
19
|
-
// Insert dummy function
|
|
20
|
-
prepend(
|
|
21
|
-
this.programPath,
|
|
22
|
-
|
|
23
|
-
this.plugin.skip(
|
|
24
|
-
t.functionDeclaration(
|
|
25
|
-
t.identifier(this.dummyFunctionName),
|
|
26
|
-
[],
|
|
27
|
-
t.blockStatement([])
|
|
28
|
-
)
|
|
29
|
-
)
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
generateTrueExpression(path: NodePath): t.Expression {
|
|
34
|
-
return t.unaryExpression("!", this.generateFalseExpression(path));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
generateFalseExpression(path: NodePath): t.Expression {
|
|
38
|
-
this.programPath = path.find((p) => p.isProgram()) as NodePath<t.Program>;
|
|
39
|
-
this.ensureCreated();
|
|
40
|
-
|
|
41
|
-
// Overcomplicated way to get a random property name that doesn't exist on the Function
|
|
42
|
-
var randomProperty: string;
|
|
43
|
-
var nameGen = new NameGen("randomized");
|
|
44
|
-
|
|
45
|
-
function PrototypeCollision() {}
|
|
46
|
-
PrototypeCollision(); // Call it for code coverage :D
|
|
47
|
-
|
|
48
|
-
do {
|
|
49
|
-
randomProperty = nameGen.generate();
|
|
50
|
-
} while (
|
|
51
|
-
!randomProperty ||
|
|
52
|
-
PrototypeCollision[randomProperty] !== undefined
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
return this.plugin.skip(
|
|
56
|
-
new Template(
|
|
57
|
-
`"${randomProperty}" in ${this.dummyFunctionName}`
|
|
58
|
-
).expression()
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
1
|
+
import { NodePath } from "@babel/traverse";
|
|
2
|
+
import { PluginInstance } from "../transforms/plugin";
|
|
3
|
+
import * as t from "@babel/types";
|
|
4
|
+
import { prepend } from "./ast-utils";
|
|
5
|
+
import { NameGen } from "./NameGen";
|
|
6
|
+
import Template from "../templates/template";
|
|
7
|
+
|
|
8
|
+
export default class PredicateGen {
|
|
9
|
+
constructor(public plugin: PluginInstance) {}
|
|
10
|
+
|
|
11
|
+
dummyFunctionName: string | null = null;
|
|
12
|
+
programPath: NodePath<t.Program> | null = null;
|
|
13
|
+
|
|
14
|
+
ensureCreated() {
|
|
15
|
+
if (this.dummyFunctionName) return;
|
|
16
|
+
|
|
17
|
+
this.dummyFunctionName = this.plugin.getPlaceholder("dummyFunction");
|
|
18
|
+
|
|
19
|
+
// Insert dummy function
|
|
20
|
+
prepend(
|
|
21
|
+
this.programPath,
|
|
22
|
+
|
|
23
|
+
this.plugin.skip(
|
|
24
|
+
t.functionDeclaration(
|
|
25
|
+
t.identifier(this.dummyFunctionName),
|
|
26
|
+
[],
|
|
27
|
+
t.blockStatement([])
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
generateTrueExpression(path: NodePath): t.Expression {
|
|
34
|
+
return t.unaryExpression("!", this.generateFalseExpression(path));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
generateFalseExpression(path: NodePath): t.Expression {
|
|
38
|
+
this.programPath = path.find((p) => p.isProgram()) as NodePath<t.Program>;
|
|
39
|
+
this.ensureCreated();
|
|
40
|
+
|
|
41
|
+
// Overcomplicated way to get a random property name that doesn't exist on the Function
|
|
42
|
+
var randomProperty: string;
|
|
43
|
+
var nameGen = new NameGen("randomized");
|
|
44
|
+
|
|
45
|
+
function PrototypeCollision() {}
|
|
46
|
+
PrototypeCollision(); // Call it for code coverage :D
|
|
47
|
+
|
|
48
|
+
do {
|
|
49
|
+
randomProperty = nameGen.generate();
|
|
50
|
+
} while (
|
|
51
|
+
!randomProperty ||
|
|
52
|
+
PrototypeCollision[randomProperty] !== undefined
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return this.plugin.skip(
|
|
56
|
+
new Template(
|
|
57
|
+
`"${randomProperty}" in ${this.dummyFunctionName}`
|
|
58
|
+
).expression()
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|