js-confuser 1.7.2 → 2.0.0-alpha.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/.github/ISSUE_TEMPLATE/bug_report.md +6 -4
- package/.github/workflows/node.js.yml +1 -1
- package/CHANGELOG.md +105 -0
- package/Migration.md +57 -0
- package/README.md +23 -913
- package/dist/constants.js +69 -13
- package/dist/index.js +108 -152
- package/dist/obfuscator.js +316 -118
- package/dist/options.js +1 -109
- package/dist/order.js +30 -30
- package/dist/presets.js +47 -45
- package/dist/probability.js +25 -32
- package/dist/templates/bufferToStringTemplate.js +9 -0
- package/dist/templates/deadCodeTemplates.js +9 -0
- package/dist/templates/getGlobalTemplate.js +19 -0
- package/dist/templates/integrityTemplate.js +30 -0
- package/dist/templates/setFunctionLengthTemplate.js +9 -0
- package/dist/templates/stringCompressionTemplate.js +10 -0
- package/dist/templates/tamperProtectionTemplates.js +21 -0
- package/dist/templates/template.js +213 -93
- package/dist/transforms/astScrambler.js +100 -0
- package/dist/transforms/calculator.js +70 -127
- package/dist/transforms/controlFlowFlattening.js +1182 -0
- package/dist/transforms/deadCode.js +62 -577
- package/dist/transforms/dispatcher.js +300 -309
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +88 -189
- package/dist/transforms/extraction/objectExtraction.js +131 -215
- package/dist/transforms/finalizer.js +56 -59
- package/dist/transforms/flatten.js +275 -276
- package/dist/transforms/functionOutlining.js +230 -0
- package/dist/transforms/identifier/globalConcealing.js +217 -103
- package/dist/transforms/identifier/movedDeclarations.js +167 -91
- package/dist/transforms/identifier/renameVariables.js +240 -187
- package/dist/transforms/lock/integrity.js +61 -184
- package/dist/transforms/lock/lock.js +263 -303
- package/dist/transforms/minify.js +431 -436
- package/dist/transforms/opaquePredicates.js +65 -118
- package/dist/transforms/pack.js +160 -0
- package/dist/transforms/plugin.js +179 -0
- package/dist/transforms/preparation.js +263 -163
- package/dist/transforms/renameLabels.js +132 -56
- package/dist/transforms/rgf.js +142 -240
- package/dist/transforms/shuffle.js +52 -145
- package/dist/transforms/string/encoding.js +45 -173
- package/dist/transforms/string/stringCompression.js +81 -126
- package/dist/transforms/string/stringConcealing.js +189 -224
- package/dist/transforms/string/stringEncoding.js +32 -40
- package/dist/transforms/string/stringSplitting.js +54 -55
- package/dist/transforms/variableMasking.js +232 -0
- package/dist/utils/ControlObject.js +125 -0
- package/dist/utils/IntGen.js +46 -0
- package/dist/utils/NameGen.js +106 -0
- package/dist/utils/ast-utils.js +560 -0
- package/dist/utils/function-utils.js +56 -0
- package/dist/utils/gen-utils.js +48 -0
- package/dist/utils/node.js +77 -0
- package/dist/utils/object-utils.js +21 -0
- package/dist/utils/random-utils.js +91 -0
- package/dist/utils/static-utils.js +64 -0
- package/dist/validateOptions.js +122 -0
- package/index.d.ts +1 -17
- package/package.json +27 -22
- package/src/constants.ts +139 -77
- package/src/index.ts +70 -163
- package/src/obfuscationResult.ts +43 -0
- package/src/obfuscator.ts +328 -135
- package/src/options.ts +154 -623
- package/src/order.ts +14 -14
- package/src/presets.ts +39 -34
- package/src/probability.ts +21 -36
- package/src/templates/{bufferToString.ts → bufferToStringTemplate.ts} +5 -54
- package/src/templates/deadCodeTemplates.ts +1185 -0
- package/src/templates/getGlobalTemplate.ts +72 -0
- package/src/templates/integrityTemplate.ts +69 -0
- package/src/templates/setFunctionLengthTemplate.ts +11 -0
- package/src/templates/stringCompressionTemplate.ts +42 -0
- package/src/templates/tamperProtectionTemplates.ts +116 -0
- package/src/templates/template.ts +183 -92
- package/src/transforms/astScrambler.ts +99 -0
- package/src/transforms/calculator.ts +96 -224
- package/src/transforms/controlFlowFlattening.ts +1594 -0
- package/src/transforms/deadCode.ts +85 -628
- package/src/transforms/dispatcher.ts +431 -636
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +147 -299
- package/src/transforms/extraction/objectExtraction.ts +160 -333
- package/src/transforms/finalizer.ts +63 -64
- package/src/transforms/flatten.ts +439 -557
- package/src/transforms/functionOutlining.ts +225 -0
- package/src/transforms/identifier/globalConcealing.ts +261 -189
- package/src/transforms/identifier/movedDeclarations.ts +228 -142
- package/src/transforms/identifier/renameVariables.ts +252 -258
- package/src/transforms/lock/integrity.ts +84 -260
- package/src/transforms/lock/lock.ts +342 -491
- package/src/transforms/minify.ts +523 -663
- package/src/transforms/opaquePredicates.ts +90 -229
- package/src/transforms/pack.ts +195 -0
- package/src/transforms/plugin.ts +185 -0
- package/src/transforms/preparation.ts +337 -215
- package/src/transforms/renameLabels.ts +176 -77
- package/src/transforms/rgf.ts +293 -386
- package/src/transforms/shuffle.ts +80 -254
- package/src/transforms/string/encoding.ts +26 -129
- package/src/transforms/string/stringCompression.ts +118 -236
- package/src/transforms/string/stringConcealing.ts +255 -339
- package/src/transforms/string/stringEncoding.ts +28 -47
- package/src/transforms/string/stringSplitting.ts +61 -75
- package/src/transforms/variableMasking.ts +257 -0
- package/src/utils/ControlObject.ts +141 -0
- package/src/utils/IntGen.ts +33 -0
- package/src/utils/NameGen.ts +106 -0
- package/src/utils/ast-utils.ts +667 -0
- package/src/utils/function-utils.ts +50 -0
- package/src/utils/gen-utils.ts +48 -0
- package/src/utils/node.ts +78 -0
- package/src/utils/object-utils.ts +21 -0
- package/src/utils/random-utils.ts +79 -0
- package/src/utils/static-utils.ts +66 -0
- package/src/validateOptions.ts +256 -0
- package/tsconfig.json +13 -8
- package/babel.config.js +0 -12
- package/dev.js +0 -8
- package/dist/compiler.js +0 -34
- package/dist/parser.js +0 -59
- package/dist/precedence.js +0 -66
- package/dist/templates/bufferToString.js +0 -108
- package/dist/templates/crash.js +0 -59
- package/dist/templates/es5.js +0 -137
- package/dist/templates/functionLength.js +0 -34
- package/dist/templates/globals.js +0 -9
- package/dist/transforms/antiTooling.js +0 -88
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +0 -1281
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +0 -131
- package/dist/transforms/es5/antiClass.js +0 -164
- package/dist/transforms/es5/antiDestructuring.js +0 -193
- package/dist/transforms/es5/antiES6Object.js +0 -185
- package/dist/transforms/es5/antiSpreadOperator.js +0 -35
- package/dist/transforms/es5/antiTemplate.js +0 -66
- package/dist/transforms/es5/es5.js +0 -123
- package/dist/transforms/extraction/classExtraction.js +0 -83
- package/dist/transforms/identifier/globalAnalysis.js +0 -70
- package/dist/transforms/identifier/variableAnalysis.js +0 -104
- package/dist/transforms/lock/antiDebug.js +0 -76
- package/dist/transforms/stack.js +0 -343
- package/dist/transforms/transform.js +0 -350
- package/dist/traverse.js +0 -110
- package/dist/util/compare.js +0 -145
- package/dist/util/gen.js +0 -564
- package/dist/util/guard.js +0 -9
- package/dist/util/identifiers.js +0 -355
- package/dist/util/insert.js +0 -362
- package/dist/util/math.js +0 -19
- package/dist/util/object.js +0 -40
- package/dist/util/random.js +0 -130
- package/dist/util/scope.js +0 -20
- package/docs/ControlFlowFlattening.md +0 -595
- package/docs/Countermeasures.md +0 -63
- package/docs/ES5.md +0 -197
- package/docs/Integrity.md +0 -75
- package/docs/RGF.md +0 -419
- package/samples/example.js +0 -15
- package/samples/high.js +0 -1
- package/samples/input.js +0 -3
- package/samples/javascriptobfuscator.com.js +0 -8
- package/samples/jscrambler_advanced.js +0 -1894
- package/samples/jscrambler_light.js +0 -1134
- package/samples/low.js +0 -1
- package/samples/medium.js +0 -1
- package/samples/obfuscator.io.js +0 -1686
- package/samples/preemptive.com.js +0 -16
- package/src/compiler.ts +0 -35
- package/src/parser.ts +0 -49
- package/src/precedence.ts +0 -61
- package/src/templates/crash.ts +0 -55
- package/src/templates/es5.ts +0 -131
- package/src/templates/functionLength.ts +0 -32
- package/src/templates/globals.ts +0 -3
- package/src/transforms/antiTooling.ts +0 -102
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +0 -2146
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +0 -179
- package/src/transforms/es5/antiClass.ts +0 -272
- package/src/transforms/es5/antiDestructuring.ts +0 -294
- package/src/transforms/es5/antiES6Object.ts +0 -267
- package/src/transforms/es5/antiSpreadOperator.ts +0 -56
- package/src/transforms/es5/antiTemplate.ts +0 -98
- package/src/transforms/es5/es5.ts +0 -149
- package/src/transforms/extraction/classExtraction.ts +0 -168
- package/src/transforms/identifier/globalAnalysis.ts +0 -85
- package/src/transforms/identifier/variableAnalysis.ts +0 -118
- package/src/transforms/lock/antiDebug.ts +0 -112
- package/src/transforms/stack.ts +0 -551
- package/src/transforms/transform.ts +0 -453
- package/src/traverse.ts +0 -120
- package/src/types.ts +0 -131
- package/src/util/compare.ts +0 -181
- package/src/util/gen.ts +0 -651
- package/src/util/guard.ts +0 -7
- package/src/util/identifiers.ts +0 -494
- package/src/util/insert.ts +0 -419
- package/src/util/math.ts +0 -15
- package/src/util/object.ts +0 -39
- package/src/util/random.ts +0 -141
- package/src/util/scope.ts +0 -21
- package/test/code/Cash.src.js +0 -1011
- package/test/code/Cash.test.ts +0 -49
- package/test/code/Dynamic.src.js +0 -118
- package/test/code/Dynamic.test.ts +0 -49
- package/test/code/ES6.src.js +0 -235
- package/test/code/ES6.test.ts +0 -42
- package/test/code/NewFeatures.test.ts +0 -19
- package/test/code/StrictMode.src.js +0 -65
- package/test/code/StrictMode.test.js +0 -37
- package/test/compare.test.ts +0 -104
- package/test/index.test.ts +0 -249
- package/test/options.test.ts +0 -132
- package/test/presets.test.ts +0 -22
- package/test/probability.test.ts +0 -44
- package/test/templates/template.test.ts +0 -14
- package/test/transforms/antiTooling.test.ts +0 -52
- package/test/transforms/calculator.test.ts +0 -78
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +0 -1274
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +0 -192
- package/test/transforms/deadCode.test.ts +0 -85
- package/test/transforms/dispatcher.test.ts +0 -457
- package/test/transforms/es5/antiClass.test.ts +0 -427
- package/test/transforms/es5/antiDestructuring.test.ts +0 -157
- package/test/transforms/es5/antiES6Object.test.ts +0 -245
- package/test/transforms/es5/antiTemplate.test.ts +0 -116
- package/test/transforms/es5/es5.test.ts +0 -110
- package/test/transforms/extraction/classExtraction.test.ts +0 -86
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +0 -200
- package/test/transforms/extraction/objectExtraction.test.ts +0 -491
- package/test/transforms/flatten.test.ts +0 -721
- package/test/transforms/hexadecimalNumbers.test.ts +0 -62
- package/test/transforms/identifier/globalConcealing.test.ts +0 -72
- package/test/transforms/identifier/movedDeclarations.test.ts +0 -275
- package/test/transforms/identifier/renameVariables.test.ts +0 -621
- package/test/transforms/lock/antiDebug.test.ts +0 -66
- package/test/transforms/lock/browserLock.test.ts +0 -129
- package/test/transforms/lock/countermeasures.test.ts +0 -100
- package/test/transforms/lock/integrity.test.ts +0 -161
- package/test/transforms/lock/lock.test.ts +0 -204
- package/test/transforms/lock/osLock.test.ts +0 -312
- package/test/transforms/lock/selfDefending.test.ts +0 -68
- package/test/transforms/minify.test.ts +0 -575
- package/test/transforms/opaquePredicates.test.ts +0 -43
- package/test/transforms/preparation.test.ts +0 -157
- package/test/transforms/renameLabels.test.ts +0 -95
- package/test/transforms/rgf.test.ts +0 -378
- package/test/transforms/shuffle.test.ts +0 -135
- package/test/transforms/stack.test.ts +0 -573
- package/test/transforms/string/stringCompression.test.ts +0 -120
- package/test/transforms/string/stringConcealing.test.ts +0 -299
- package/test/transforms/string/stringEncoding.test.ts +0 -95
- package/test/transforms/string/stringSplitting.test.ts +0 -135
- package/test/transforms/transform.test.ts +0 -66
- package/test/traverse.test.ts +0 -139
- package/test/util/compare.test.ts +0 -34
- package/test/util/gen.test.ts +0 -121
- package/test/util/identifiers.test.ts +0 -253
- package/test/util/insert.test.ts +0 -142
- package/test/util/math.test.ts +0 -5
- package/test/util/random.test.ts +0 -71
- /package/dist/{types.js → obfuscationResult.js} +0 -0
|
@@ -1,1274 +0,0 @@
|
|
|
1
|
-
import JsConfuser from "../../../src/index";
|
|
2
|
-
|
|
3
|
-
test("Variant #1: Obfuscate code and still execute in correct order", async () => {
|
|
4
|
-
var code = `
|
|
5
|
-
var array = [];
|
|
6
|
-
|
|
7
|
-
array.push(1);
|
|
8
|
-
array.push(2);
|
|
9
|
-
array.push(3);
|
|
10
|
-
array.push(4);
|
|
11
|
-
array.push(5);
|
|
12
|
-
array.push(6);
|
|
13
|
-
array.push(7);
|
|
14
|
-
array.push(8);
|
|
15
|
-
array.push(9);
|
|
16
|
-
array.push(10);
|
|
17
|
-
|
|
18
|
-
TEST_OUTPUT = array;
|
|
19
|
-
`;
|
|
20
|
-
|
|
21
|
-
var output = await JsConfuser(code, {
|
|
22
|
-
target: "browser",
|
|
23
|
-
controlFlowFlattening: true,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// Ensure Control Flow Flattening applied
|
|
27
|
-
expect(output).toContain("while");
|
|
28
|
-
|
|
29
|
-
// Ensure the output is the exact same
|
|
30
|
-
var TEST_OUTPUT;
|
|
31
|
-
eval(output);
|
|
32
|
-
|
|
33
|
-
expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("Variant #2: Obfuscate for loops", async () => {
|
|
37
|
-
var code = `
|
|
38
|
-
var array = [];
|
|
39
|
-
|
|
40
|
-
for ( var i = 1; i <= 10; i++ ) {
|
|
41
|
-
array.push(i);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
TEST_OUTPUT = array;
|
|
45
|
-
`;
|
|
46
|
-
|
|
47
|
-
var output = await JsConfuser(code, {
|
|
48
|
-
target: "browser",
|
|
49
|
-
controlFlowFlattening: true,
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Ensure Control Flow Flattening applied
|
|
53
|
-
expect(output).toContain("while");
|
|
54
|
-
|
|
55
|
-
// Ensure the for statement got flattened
|
|
56
|
-
expect(output).not.toContain("for");
|
|
57
|
-
|
|
58
|
-
// Ensure the output is the exact same
|
|
59
|
-
var TEST_OUTPUT;
|
|
60
|
-
|
|
61
|
-
eval(output);
|
|
62
|
-
expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
test("Variant #3: Obfuscate while loops", async () => {
|
|
66
|
-
var code = `
|
|
67
|
-
var array = [];
|
|
68
|
-
var i = 1;
|
|
69
|
-
|
|
70
|
-
while ( i <= 10 ) {
|
|
71
|
-
array.push(i);
|
|
72
|
-
i++
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
TEST_OUTPUT = array;
|
|
76
|
-
`;
|
|
77
|
-
|
|
78
|
-
var output = await JsConfuser(code, {
|
|
79
|
-
target: "browser",
|
|
80
|
-
controlFlowFlattening: true,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// Ensure Control Flow Flattening applied
|
|
84
|
-
expect(output).toContain("while");
|
|
85
|
-
|
|
86
|
-
// Ensure the output is the exact same
|
|
87
|
-
var TEST_OUTPUT;
|
|
88
|
-
eval(output);
|
|
89
|
-
|
|
90
|
-
expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test("Variant #4: Work with break statements", async () => {
|
|
94
|
-
var code = `
|
|
95
|
-
|
|
96
|
-
var TEST_ARRAY = [];
|
|
97
|
-
|
|
98
|
-
for ( var i =1; i < 50; i++ ) {
|
|
99
|
-
if ( i == 11 ) {
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
TEST_ARRAY.push(i);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
TEST_OUTPUT = TEST_ARRAY;
|
|
106
|
-
`;
|
|
107
|
-
|
|
108
|
-
var output = await JsConfuser(code, {
|
|
109
|
-
target: "browser",
|
|
110
|
-
controlFlowFlattening: true,
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// Ensure Control Flow Flattening applied
|
|
114
|
-
expect(output).toContain("switch");
|
|
115
|
-
expect(output).toContain("while");
|
|
116
|
-
|
|
117
|
-
// Ensure the output is the exact same
|
|
118
|
-
var TEST_OUTPUT;
|
|
119
|
-
|
|
120
|
-
eval(output);
|
|
121
|
-
expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
test("Variant #5: Don't obfuscate code with `let` (Lexically bound variables)", async () => {
|
|
125
|
-
var code = `
|
|
126
|
-
let array = [];
|
|
127
|
-
|
|
128
|
-
array.push(1);
|
|
129
|
-
array.push(2);
|
|
130
|
-
array.push(3);
|
|
131
|
-
array.push(4);
|
|
132
|
-
array.push(5);
|
|
133
|
-
array.push(6);
|
|
134
|
-
array.push(7);
|
|
135
|
-
array.push(8);
|
|
136
|
-
array.push(9);
|
|
137
|
-
array.push(10);
|
|
138
|
-
|
|
139
|
-
TEST_OUTPUT = array;
|
|
140
|
-
`;
|
|
141
|
-
|
|
142
|
-
var output = await JsConfuser(code, {
|
|
143
|
-
target: "node",
|
|
144
|
-
controlFlowFlattening: true,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// Ensure Control Flow Flattening did NOT apply here
|
|
148
|
-
expect(output).not.toContain("while");
|
|
149
|
-
|
|
150
|
-
// Ensure the output is the exact same
|
|
151
|
-
var TEST_OUTPUT;
|
|
152
|
-
eval(output);
|
|
153
|
-
|
|
154
|
-
expect(TEST_OUTPUT).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test("Variant #6: Don't obfuscate code with `let` (Lexically bound variables)", async () => {
|
|
158
|
-
var code = `
|
|
159
|
-
var array=[];
|
|
160
|
-
for ( let i =1; i <= 10; i++ ) {
|
|
161
|
-
array.push(i);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
TEST_OUTPUT = array;
|
|
165
|
-
`;
|
|
166
|
-
|
|
167
|
-
var output = await JsConfuser(code, {
|
|
168
|
-
target: "node",
|
|
169
|
-
controlFlowFlattening: true,
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// Ensure Control Flow Flattening did NOT apply here
|
|
173
|
-
expect(output).not.toContain("while");
|
|
174
|
-
|
|
175
|
-
// Ensure the output is the exact same
|
|
176
|
-
var TEST_OUTPUT;
|
|
177
|
-
eval(output);
|
|
178
|
-
|
|
179
|
-
expect(TEST_OUTPUT).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
test("Variant #7: Allow option to be set a percentage threshold", async () => {
|
|
183
|
-
var code = `
|
|
184
|
-
var array = [];
|
|
185
|
-
var i = 1;
|
|
186
|
-
|
|
187
|
-
while ( i <= 10 ) {
|
|
188
|
-
array.push(i);
|
|
189
|
-
i++
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
TEST_OUTPUT = array;
|
|
193
|
-
`;
|
|
194
|
-
|
|
195
|
-
var output = await JsConfuser(code, {
|
|
196
|
-
target: "browser",
|
|
197
|
-
controlFlowFlattening: 0.5,
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
// Ensure the output is the exact same
|
|
201
|
-
var TEST_OUTPUT;
|
|
202
|
-
|
|
203
|
-
eval(output);
|
|
204
|
-
expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
test("Variant #8: Work when obfuscated multiple times", async () => {
|
|
208
|
-
var code = `
|
|
209
|
-
var array = [];
|
|
210
|
-
|
|
211
|
-
switch(true){
|
|
212
|
-
case true: // Always true
|
|
213
|
-
if(true){ // Always true
|
|
214
|
-
var i;
|
|
215
|
-
|
|
216
|
-
for ( i = 1; i <= 10; i++ ) {
|
|
217
|
-
if(typeof i === "number") { // Always true
|
|
218
|
-
array.push(i);
|
|
219
|
-
|
|
220
|
-
var filler1;
|
|
221
|
-
var filler2;
|
|
222
|
-
var filler3;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
var filler1;
|
|
226
|
-
var filler2;
|
|
227
|
-
var filler3;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
var filler1;
|
|
231
|
-
var filler2;
|
|
232
|
-
var filler3;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
var filler1;
|
|
236
|
-
var filler2;
|
|
237
|
-
var filler3;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
TEST_OUTPUT = array;
|
|
242
|
-
`; // [1,2,3,4,5,6,7,8,9,10]
|
|
243
|
-
|
|
244
|
-
var output = await JsConfuser(code, {
|
|
245
|
-
target: "node",
|
|
246
|
-
controlFlowFlattening: true,
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
// Ensure Control Flow Flattening applied
|
|
250
|
-
expect(output).toContain("while");
|
|
251
|
-
|
|
252
|
-
var doublyObfuscated = await JsConfuser(output, {
|
|
253
|
-
target: "node",
|
|
254
|
-
controlFlowFlattening: true,
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
// Ensure the output is the exact same
|
|
258
|
-
var TEST_OUTPUT;
|
|
259
|
-
|
|
260
|
-
eval(doublyObfuscated);
|
|
261
|
-
expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
test("Variant #9: Don't entangle floats or NaN", async () => {
|
|
265
|
-
var output = await JsConfuser(
|
|
266
|
-
`
|
|
267
|
-
function TEST_FUNCTION(){
|
|
268
|
-
|
|
269
|
-
var a = NaN;
|
|
270
|
-
var b = 10.01;
|
|
271
|
-
var c = 15.01;
|
|
272
|
-
var d = "MyString";
|
|
273
|
-
input(b + c)
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
TEST_FUNCTION()
|
|
277
|
-
`,
|
|
278
|
-
{
|
|
279
|
-
target: "node",
|
|
280
|
-
controlFlowFlattening: true,
|
|
281
|
-
}
|
|
282
|
-
);
|
|
283
|
-
|
|
284
|
-
expect(output).toContain("10.01");
|
|
285
|
-
expect(output).toContain("15.01");
|
|
286
|
-
expect(output).toContain("NaN");
|
|
287
|
-
expect(output).toContain("MyString");
|
|
288
|
-
|
|
289
|
-
var value = "never_called";
|
|
290
|
-
function input(valueIn) {
|
|
291
|
-
value = valueIn;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
eval(output);
|
|
295
|
-
expect(value).toStrictEqual(25.02);
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
test("Variant #10: Correctly entangle property keys", async () => {
|
|
299
|
-
var output = await JsConfuser(
|
|
300
|
-
`
|
|
301
|
-
function TEST_FUNCTION(){
|
|
302
|
-
|
|
303
|
-
var obj = {
|
|
304
|
-
10: 10,
|
|
305
|
-
9: 9,
|
|
306
|
-
8: 8,
|
|
307
|
-
7: 7,
|
|
308
|
-
6: 6,
|
|
309
|
-
5: 5,
|
|
310
|
-
4: 4,
|
|
311
|
-
3: 3,
|
|
312
|
-
2: 2,
|
|
313
|
-
1: 1,
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
var ten = obj["5"] + obj["3"] + obj["2"];
|
|
317
|
-
|
|
318
|
-
input(ten)
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
TEST_FUNCTION()
|
|
322
|
-
`,
|
|
323
|
-
{
|
|
324
|
-
target: "node",
|
|
325
|
-
controlFlowFlattening: true,
|
|
326
|
-
}
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
var value = "never_called";
|
|
330
|
-
function input(valueIn) {
|
|
331
|
-
value = valueIn;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
eval(output);
|
|
335
|
-
expect(value).toStrictEqual(10);
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
test("Variant #11: Flatten nested if statements", async () => {
|
|
339
|
-
var output = await JsConfuser(
|
|
340
|
-
`
|
|
341
|
-
TEST_ARRAY = [];
|
|
342
|
-
|
|
343
|
-
if(true){
|
|
344
|
-
TEST_ARRAY.push(1);
|
|
345
|
-
} else {
|
|
346
|
-
TEST_ARRAY.push(-1);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if(true){
|
|
350
|
-
TEST_ARRAY.push(2);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if(false){
|
|
354
|
-
TEST_ARRAY.push(-1);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
if(true){
|
|
358
|
-
TEST_ARRAY.push(3);
|
|
359
|
-
if(true){
|
|
360
|
-
TEST_ARRAY.push(4);
|
|
361
|
-
} else {
|
|
362
|
-
TEST_ARRAY.push(-1);
|
|
363
|
-
}
|
|
364
|
-
TEST_ARRAY.push(5);
|
|
365
|
-
}
|
|
366
|
-
var fillerExpr1;
|
|
367
|
-
var fillerExpr2;
|
|
368
|
-
var fillerExpr3;
|
|
369
|
-
var fillerExpr4;
|
|
370
|
-
var fillerExpr5;
|
|
371
|
-
`,
|
|
372
|
-
{
|
|
373
|
-
target: "node",
|
|
374
|
-
controlFlowFlattening: true,
|
|
375
|
-
}
|
|
376
|
-
);
|
|
377
|
-
|
|
378
|
-
var TEST_ARRAY;
|
|
379
|
-
|
|
380
|
-
eval(output);
|
|
381
|
-
expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
test("Variant #12: Flatten nested for loops", async () => {
|
|
385
|
-
var output = await JsConfuser(
|
|
386
|
-
`
|
|
387
|
-
TEST_ARRAY = [];
|
|
388
|
-
|
|
389
|
-
for ( var i = -5; i < 0; i++ ) {
|
|
390
|
-
var o = 0;
|
|
391
|
-
for ( var j = 1; j < 4; j++ ) {
|
|
392
|
-
o += j;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// o is 6
|
|
396
|
-
TEST_ARRAY.push(i + o);
|
|
397
|
-
}
|
|
398
|
-
var fillerExpr1;
|
|
399
|
-
var fillerExpr2;
|
|
400
|
-
var fillerExpr3;
|
|
401
|
-
var fillerExpr4;
|
|
402
|
-
var fillerExpr5;
|
|
403
|
-
`,
|
|
404
|
-
{
|
|
405
|
-
target: "node",
|
|
406
|
-
controlFlowFlattening: true,
|
|
407
|
-
}
|
|
408
|
-
);
|
|
409
|
-
|
|
410
|
-
expect(output).not.toContain("for(var i)");
|
|
411
|
-
expect(output).not.toContain("for(var j)");
|
|
412
|
-
|
|
413
|
-
var TEST_ARRAY;
|
|
414
|
-
|
|
415
|
-
eval(output);
|
|
416
|
-
expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
test("Variant #13: Flatten nested while loops", async () => {
|
|
420
|
-
var output = await JsConfuser(
|
|
421
|
-
`
|
|
422
|
-
TEST_ARRAY = [];
|
|
423
|
-
|
|
424
|
-
var i = -5
|
|
425
|
-
while ( i < 0 ) {
|
|
426
|
-
var o = 0;
|
|
427
|
-
var j = 1;
|
|
428
|
-
|
|
429
|
-
while( j < 4 ){
|
|
430
|
-
o += j;
|
|
431
|
-
|
|
432
|
-
j++;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// o is 6
|
|
436
|
-
TEST_ARRAY.push(i + o);
|
|
437
|
-
i++;
|
|
438
|
-
}
|
|
439
|
-
var fillerExpr1;
|
|
440
|
-
var fillerExpr2;
|
|
441
|
-
var fillerExpr3;
|
|
442
|
-
var fillerExpr4;
|
|
443
|
-
var fillerExpr5;
|
|
444
|
-
`,
|
|
445
|
-
{
|
|
446
|
-
target: "node",
|
|
447
|
-
controlFlowFlattening: true,
|
|
448
|
-
}
|
|
449
|
-
);
|
|
450
|
-
|
|
451
|
-
var TEST_ARRAY;
|
|
452
|
-
|
|
453
|
-
expect(output).not.toContain("while(i<0)");
|
|
454
|
-
expect(output).not.toContain("while(j<4)");
|
|
455
|
-
|
|
456
|
-
eval(output);
|
|
457
|
-
expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
test("Variant #14: Flatten nested switch statements", async () => {
|
|
461
|
-
var output = await JsConfuser(
|
|
462
|
-
`
|
|
463
|
-
TEST_ARRAY = [];
|
|
464
|
-
|
|
465
|
-
var i = 0;
|
|
466
|
-
switch(i){
|
|
467
|
-
case 1: TEST_ARRAY.push(-1); break;
|
|
468
|
-
case 2: TEST_ARRAY.push(-1); break;
|
|
469
|
-
case 0:
|
|
470
|
-
TEST_ARRAY.push(1);
|
|
471
|
-
|
|
472
|
-
var j = 0;
|
|
473
|
-
var i = 0;
|
|
474
|
-
switch(j){
|
|
475
|
-
case 1: TEST_ARRAY.push(-1); break;
|
|
476
|
-
case 2: TEST_ARRAY.push(-1); break;
|
|
477
|
-
case 0:
|
|
478
|
-
TEST_ARRAY.push(2);
|
|
479
|
-
break;
|
|
480
|
-
case 4: TEST_ARRAY.push(-1); break;
|
|
481
|
-
case 8: TEST_ARRAY.push(-1); break;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
TEST_ARRAY.push(3);
|
|
485
|
-
|
|
486
|
-
break;
|
|
487
|
-
case 4: TEST_ARRAY.push(-1); break;
|
|
488
|
-
case 8: TEST_ARRAY.push(-1); break;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
TEST_ARRAY.push(4);
|
|
492
|
-
TEST_ARRAY.push(5);
|
|
493
|
-
`,
|
|
494
|
-
{
|
|
495
|
-
target: "node",
|
|
496
|
-
controlFlowFlattening: true,
|
|
497
|
-
}
|
|
498
|
-
);
|
|
499
|
-
|
|
500
|
-
expect(output).not.toContain("switch(i");
|
|
501
|
-
expect(output).not.toContain("switch(j");
|
|
502
|
-
|
|
503
|
-
var TEST_ARRAY;
|
|
504
|
-
|
|
505
|
-
eval(output);
|
|
506
|
-
expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
|
|
507
|
-
});
|
|
508
|
-
|
|
509
|
-
test("Variant #16: Flatten with nested break and continue statements", async () => {
|
|
510
|
-
var output = await JsConfuser(
|
|
511
|
-
`
|
|
512
|
-
TEST_ARRAY = [];
|
|
513
|
-
|
|
514
|
-
for ( var i =1; i < 10; i++ ) {
|
|
515
|
-
if(i%2==0){
|
|
516
|
-
continue;
|
|
517
|
-
}
|
|
518
|
-
if(i==7){
|
|
519
|
-
break;
|
|
520
|
-
}
|
|
521
|
-
TEST_ARRAY.push(i);
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
var j;
|
|
525
|
-
|
|
526
|
-
a: for ( var i = 0; i < 5; i++ ) {
|
|
527
|
-
if ( i == 3 ) {
|
|
528
|
-
for ( j = 0; j < 5; j++ ) {
|
|
529
|
-
if ( j == 1 ) {break a;}
|
|
530
|
-
if ( j % 2 == 0 ) { continue a;}
|
|
531
|
-
}
|
|
532
|
-
TEST_ARRAY.push(-1);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
var fillerExpr1;
|
|
537
|
-
var fillerExpr2;
|
|
538
|
-
var fillerExpr3;
|
|
539
|
-
var fillerExpr4;
|
|
540
|
-
var fillerExpr5;
|
|
541
|
-
`,
|
|
542
|
-
{
|
|
543
|
-
target: "node",
|
|
544
|
-
controlFlowFlattening: true,
|
|
545
|
-
}
|
|
546
|
-
);
|
|
547
|
-
|
|
548
|
-
var TEST_ARRAY;
|
|
549
|
-
|
|
550
|
-
eval(output);
|
|
551
|
-
expect(TEST_ARRAY).toStrictEqual([1, 3, 5]);
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
test("Variant #17: Flatten with infinite for loop and break", async () => {
|
|
555
|
-
var output = await JsConfuser(
|
|
556
|
-
`
|
|
557
|
-
TEST_ARRAY = [];
|
|
558
|
-
var i = 1;
|
|
559
|
-
|
|
560
|
-
for ( ;; ) {
|
|
561
|
-
if (i == 6){break;}
|
|
562
|
-
|
|
563
|
-
TEST_ARRAY.push(i), i++;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
var fillerExpr1;
|
|
567
|
-
var fillerExpr2;
|
|
568
|
-
var fillerExpr3;
|
|
569
|
-
var fillerExpr4;
|
|
570
|
-
var fillerExpr5;
|
|
571
|
-
`,
|
|
572
|
-
{
|
|
573
|
-
target: "node",
|
|
574
|
-
controlFlowFlattening: true,
|
|
575
|
-
}
|
|
576
|
-
);
|
|
577
|
-
|
|
578
|
-
expect(output).not.toContain("for(;");
|
|
579
|
-
|
|
580
|
-
var TEST_ARRAY;
|
|
581
|
-
|
|
582
|
-
eval(output);
|
|
583
|
-
expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
test("Variant #20: Work with redefined functions", async () => {
|
|
587
|
-
var output = await JsConfuser(
|
|
588
|
-
`
|
|
589
|
-
var counter = 0;
|
|
590
|
-
function increment(){
|
|
591
|
-
counter++;
|
|
592
|
-
|
|
593
|
-
if(counter == 3) {
|
|
594
|
-
increment = () => { counter = "Correct Value" }
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
increment(); // 1
|
|
599
|
-
increment(); // 2
|
|
600
|
-
increment(); // 3
|
|
601
|
-
|
|
602
|
-
var originalIncrement = increment;
|
|
603
|
-
increment = ()=>{};
|
|
604
|
-
|
|
605
|
-
increment(); // 3
|
|
606
|
-
increment(); // 3
|
|
607
|
-
increment(); // 3
|
|
608
|
-
|
|
609
|
-
increment = undefined;
|
|
610
|
-
|
|
611
|
-
increment = typeof increment === "undefined" ? originalIncrement : 0;
|
|
612
|
-
|
|
613
|
-
increment(); // "Correct Value"
|
|
614
|
-
|
|
615
|
-
TEST_OUTPUT = counter;
|
|
616
|
-
`,
|
|
617
|
-
{
|
|
618
|
-
target: "node",
|
|
619
|
-
controlFlowFlattening: true,
|
|
620
|
-
}
|
|
621
|
-
);
|
|
622
|
-
|
|
623
|
-
// Ensure Control Flow Flattening applied
|
|
624
|
-
expect(output).toContain("while");
|
|
625
|
-
|
|
626
|
-
var TEST_OUTPUT;
|
|
627
|
-
|
|
628
|
-
eval(output);
|
|
629
|
-
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
// https://github.com/MichaelXF/js-confuser/issues/70
|
|
633
|
-
test("Variant #21: Don't move Import Declarations", async () => {
|
|
634
|
-
var output = await JsConfuser(
|
|
635
|
-
`
|
|
636
|
-
import {createHash} from "crypto";
|
|
637
|
-
var inputString = "Hash this string";
|
|
638
|
-
var hashed = createHash("sha256").update(inputString).digest("hex");
|
|
639
|
-
TEST_OUTPUT = hashed;
|
|
640
|
-
`,
|
|
641
|
-
{
|
|
642
|
-
target: "node",
|
|
643
|
-
controlFlowFlattening: true,
|
|
644
|
-
}
|
|
645
|
-
);
|
|
646
|
-
|
|
647
|
-
// Ensure Control Flow FLattening was applied
|
|
648
|
-
expect(output).toContain("switch");
|
|
649
|
-
|
|
650
|
-
// Ensure the import declaration wasn't moved
|
|
651
|
-
expect(output.startsWith("import")).toStrictEqual(true);
|
|
652
|
-
|
|
653
|
-
// Convert to runnable code
|
|
654
|
-
output = output.replace(
|
|
655
|
-
`import{createHash}from'crypto';`,
|
|
656
|
-
"const {createHash}=require('crypto');"
|
|
657
|
-
);
|
|
658
|
-
|
|
659
|
-
var TEST_OUTPUT = "";
|
|
660
|
-
|
|
661
|
-
eval(output);
|
|
662
|
-
|
|
663
|
-
expect(TEST_OUTPUT).toStrictEqual(
|
|
664
|
-
"1cac63f39fd68d8c531f27b807610fb3d50f0fc3f186995767fb6316e7200a3e"
|
|
665
|
-
);
|
|
666
|
-
});
|
|
667
|
-
|
|
668
|
-
// https://github.com/MichaelXF/js-confuser/issues/81
|
|
669
|
-
test("Variant #22: Don't break typeof expression", async () => {
|
|
670
|
-
var output = await JsConfuser(
|
|
671
|
-
`
|
|
672
|
-
TEST_OUTPUT = false;
|
|
673
|
-
if(typeof nonExistentVariable === "undefined") {
|
|
674
|
-
TEST_OUTPUT = true;
|
|
675
|
-
}
|
|
676
|
-
`,
|
|
677
|
-
{
|
|
678
|
-
target: "node",
|
|
679
|
-
controlFlowFlattening: true,
|
|
680
|
-
}
|
|
681
|
-
);
|
|
682
|
-
|
|
683
|
-
var TEST_OUTPUT;
|
|
684
|
-
|
|
685
|
-
eval(output);
|
|
686
|
-
|
|
687
|
-
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
688
|
-
});
|
|
689
|
-
|
|
690
|
-
test("Variant #23: Don't break Super calls", async () => {
|
|
691
|
-
var output = await JsConfuser(
|
|
692
|
-
`
|
|
693
|
-
class MyClass1 {
|
|
694
|
-
constructor(val){
|
|
695
|
-
this.val = val;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
class MyClass2 extends MyClass1 {
|
|
699
|
-
constructor(){
|
|
700
|
-
super(10);
|
|
701
|
-
|
|
702
|
-
// Ensure ControlFlowFlattening applies here
|
|
703
|
-
var filler1;
|
|
704
|
-
var filler2;
|
|
705
|
-
var filler3;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
var myObject = new MyClass2();
|
|
710
|
-
TEST_OUTPUT = myObject.val; // 10
|
|
711
|
-
`,
|
|
712
|
-
{ target: "node", controlFlowFlattening: true }
|
|
713
|
-
);
|
|
714
|
-
|
|
715
|
-
var TEST_OUTPUT;
|
|
716
|
-
eval(output);
|
|
717
|
-
|
|
718
|
-
expect(TEST_OUTPUT).toStrictEqual(10);
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
test("Variant #24: Nested function-calls with labeled breaks/continues", async () => {
|
|
722
|
-
var code = `
|
|
723
|
-
function myFunction(){
|
|
724
|
-
function x( STOP_VALUE ){
|
|
725
|
-
function y(){
|
|
726
|
-
function dead(){
|
|
727
|
-
var STOP_VALUE = 3;
|
|
728
|
-
}
|
|
729
|
-
function z(){
|
|
730
|
-
a: for(var i = 0; i < 10; i++) {
|
|
731
|
-
if (i == STOP_VALUE) {
|
|
732
|
-
var counter = 0;
|
|
733
|
-
b: for ( var j = 0; j < 10; j++ ) {
|
|
734
|
-
if(j == 4) {
|
|
735
|
-
counter -= 50;
|
|
736
|
-
continue b;
|
|
737
|
-
}
|
|
738
|
-
counter++;
|
|
739
|
-
if(j == 8) {
|
|
740
|
-
break a;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
var filler1;
|
|
747
|
-
var filler2;
|
|
748
|
-
var filler3;
|
|
749
|
-
return i + j + counter;
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
var filler1;
|
|
753
|
-
var filler2;
|
|
754
|
-
var filler3;
|
|
755
|
-
return z();
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
var filler1;
|
|
759
|
-
var filler2;
|
|
760
|
-
var filler3;
|
|
761
|
-
return y();
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
var filler1;
|
|
765
|
-
var filler2;
|
|
766
|
-
var filler3;
|
|
767
|
-
return x( 1 );
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
var x = myFunction();
|
|
771
|
-
|
|
772
|
-
TEST_OUTPUT = x;`;
|
|
773
|
-
|
|
774
|
-
var output = await JsConfuser(code, {
|
|
775
|
-
target: "node",
|
|
776
|
-
controlFlowFlattening: true,
|
|
777
|
-
renameVariables: true,
|
|
778
|
-
identifierGenerator: "mangled",
|
|
779
|
-
stack: true,
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
var TEST_OUTPUT;
|
|
783
|
-
eval(output);
|
|
784
|
-
|
|
785
|
-
expect(TEST_OUTPUT).toStrictEqual(-33);
|
|
786
|
-
});
|
|
787
|
-
|
|
788
|
-
test("Variant #25: Don't break call expressions to bound functions", async () => {
|
|
789
|
-
var code = `
|
|
790
|
-
var array = [];
|
|
791
|
-
array.push(1);
|
|
792
|
-
array.push(2);
|
|
793
|
-
array.push(3);
|
|
794
|
-
array.push(4);
|
|
795
|
-
array.push(5);
|
|
796
|
-
|
|
797
|
-
TEST_OUTPUT = array;
|
|
798
|
-
`;
|
|
799
|
-
|
|
800
|
-
var output = await JsConfuser(code, {
|
|
801
|
-
target: "node",
|
|
802
|
-
controlFlowFlattening: true,
|
|
803
|
-
});
|
|
804
|
-
|
|
805
|
-
// Ensure Control Flow Flattening applied
|
|
806
|
-
expect(output).toContain("while");
|
|
807
|
-
|
|
808
|
-
var TEST_OUTPUT;
|
|
809
|
-
eval(output);
|
|
810
|
-
|
|
811
|
-
expect(TEST_OUTPUT).toStrictEqual([1, 2, 3, 4, 5]);
|
|
812
|
-
});
|
|
813
|
-
|
|
814
|
-
test("Variant #26: Add opaque predicates and still work", async () => {
|
|
815
|
-
var output = await JsConfuser(
|
|
816
|
-
`
|
|
817
|
-
TEST_OUTPUT = [];
|
|
818
|
-
if(true) TEST_OUTPUT.push(1);
|
|
819
|
-
else TEST_OUTPUT.push("Incorrect If Statement")
|
|
820
|
-
|
|
821
|
-
switch(true){
|
|
822
|
-
case true: TEST_OUTPUT.push(2); break;
|
|
823
|
-
default:
|
|
824
|
-
TEST_OUTPUT.push("Incorrect Switch")
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
TEST_OUTPUT.push( true ? 3 : "Incorrect Conditional Statement" );
|
|
828
|
-
`,
|
|
829
|
-
{ target: "node", controlFlowFlattening: true }
|
|
830
|
-
);
|
|
831
|
-
|
|
832
|
-
expect(output).toContain("while");
|
|
833
|
-
var TEST_OUTPUT = [];
|
|
834
|
-
|
|
835
|
-
eval(output);
|
|
836
|
-
|
|
837
|
-
expect(TEST_OUTPUT).toStrictEqual([1, 2, 3]);
|
|
838
|
-
});
|
|
839
|
-
|
|
840
|
-
test("Variant #27: Work on async/generator functions", async () => {
|
|
841
|
-
var output = await JsConfuser(
|
|
842
|
-
`
|
|
843
|
-
"use strict";
|
|
844
|
-
async function myAsyncFunction(){
|
|
845
|
-
await (1);
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
function* myGeneratorFunction(){
|
|
849
|
-
yield "Correct Value";
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
var x = myAsyncFunction();
|
|
853
|
-
var generatorObject = myGeneratorFunction();
|
|
854
|
-
|
|
855
|
-
TEST_OUTPUT = generatorObject.next().value;
|
|
856
|
-
|
|
857
|
-
var fillerVar1;
|
|
858
|
-
var fillerVar2;
|
|
859
|
-
var fillerVar3;
|
|
860
|
-
`,
|
|
861
|
-
{ target: "node", controlFlowFlattening: true }
|
|
862
|
-
);
|
|
863
|
-
|
|
864
|
-
// Ensure Control Flow Flattening applied
|
|
865
|
-
expect(output).toContain("while");
|
|
866
|
-
|
|
867
|
-
var TEST_OUTPUT;
|
|
868
|
-
eval(output);
|
|
869
|
-
|
|
870
|
-
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
871
|
-
});
|
|
872
|
-
|
|
873
|
-
test("Variant #28: Don't break update expressions", async () => {
|
|
874
|
-
var code = `
|
|
875
|
-
var counter = 0;
|
|
876
|
-
|
|
877
|
-
counter++; // 1
|
|
878
|
-
counter++; // 2
|
|
879
|
-
counter++; // 3
|
|
880
|
-
counter++; // 4
|
|
881
|
-
counter++; // 5
|
|
882
|
-
counter++; // 6
|
|
883
|
-
counter++; // 7
|
|
884
|
-
counter++; // 8
|
|
885
|
-
counter++; // 9
|
|
886
|
-
counter++; // 10
|
|
887
|
-
|
|
888
|
-
TEST_OUTPUT = counter;
|
|
889
|
-
`;
|
|
890
|
-
|
|
891
|
-
var output = await JsConfuser(code, {
|
|
892
|
-
target: "node",
|
|
893
|
-
controlFlowFlattening: true,
|
|
894
|
-
});
|
|
895
|
-
|
|
896
|
-
// Ensure Control Flow Flattening applied
|
|
897
|
-
expect(output).toContain("while");
|
|
898
|
-
|
|
899
|
-
var TEST_OUTPUT;
|
|
900
|
-
eval(output);
|
|
901
|
-
|
|
902
|
-
expect(TEST_OUTPUT).toStrictEqual(10);
|
|
903
|
-
});
|
|
904
|
-
|
|
905
|
-
test("Variant #29: Nested labeled break and continue statements with RGF enabled", async () => {
|
|
906
|
-
var code = `
|
|
907
|
-
function labeledBreaksAndContinues() {
|
|
908
|
-
var flag = true;
|
|
909
|
-
|
|
910
|
-
label_1: for (var i = 0; i < 20; i++) {
|
|
911
|
-
b: switch (i) {
|
|
912
|
-
case 15:
|
|
913
|
-
c: do {
|
|
914
|
-
if (i !== 15) {
|
|
915
|
-
break c;
|
|
916
|
-
}
|
|
917
|
-
flag = true;
|
|
918
|
-
|
|
919
|
-
break label_1;
|
|
920
|
-
|
|
921
|
-
var fillerVar1;
|
|
922
|
-
var fillerVar2;
|
|
923
|
-
var fillerVar3;
|
|
924
|
-
} while (i == 15);
|
|
925
|
-
|
|
926
|
-
break;
|
|
927
|
-
|
|
928
|
-
case 10:
|
|
929
|
-
continue label_1;
|
|
930
|
-
|
|
931
|
-
default:
|
|
932
|
-
flag = false;
|
|
933
|
-
break b;
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
var fillerVar1;
|
|
937
|
-
var fillerVar2;
|
|
938
|
-
var fillerVar3;
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
var fillerVar1;
|
|
942
|
-
var fillerVar2;
|
|
943
|
-
var fillerVar3;
|
|
944
|
-
|
|
945
|
-
if (flag) {
|
|
946
|
-
return i;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
var fillerVar1;
|
|
951
|
-
var fillerVar2;
|
|
952
|
-
var fillerVar3;
|
|
953
|
-
|
|
954
|
-
TEST_OUTPUT = labeledBreaksAndContinues();
|
|
955
|
-
`; // This complex code produces the value of 15
|
|
956
|
-
|
|
957
|
-
var output = await JsConfuser(code, {
|
|
958
|
-
target: "node",
|
|
959
|
-
controlFlowFlattening: true,
|
|
960
|
-
rgf: true,
|
|
961
|
-
renameVariables: true,
|
|
962
|
-
identifierGenerator: "mangled",
|
|
963
|
-
});
|
|
964
|
-
|
|
965
|
-
// Run the code
|
|
966
|
-
var TEST_OUTPUT;
|
|
967
|
-
eval(output);
|
|
968
|
-
|
|
969
|
-
expect(TEST_OUTPUT).toStrictEqual(15);
|
|
970
|
-
});
|
|
971
|
-
|
|
972
|
-
test("Variant #30: Obfuscate switch statements", async () => {
|
|
973
|
-
var output = await JsConfuser(
|
|
974
|
-
`
|
|
975
|
-
switch("DON'T CHANGE ME"){} // Empty switch for testing
|
|
976
|
-
|
|
977
|
-
switch(true){
|
|
978
|
-
case 0:
|
|
979
|
-
TEST_OUTPUT = "Incorrect Value (1)";
|
|
980
|
-
break
|
|
981
|
-
|
|
982
|
-
case true:
|
|
983
|
-
TEST_OUTPUT = "First Correct Value";
|
|
984
|
-
break;
|
|
985
|
-
|
|
986
|
-
case 1:
|
|
987
|
-
case 2:
|
|
988
|
-
case 3:
|
|
989
|
-
case false:
|
|
990
|
-
TEST_OUTPUT = "Incorrect Value (2)";
|
|
991
|
-
break;
|
|
992
|
-
};
|
|
993
|
-
|
|
994
|
-
switch(TEST_OUTPUT){
|
|
995
|
-
case true:
|
|
996
|
-
TEST_OUTPUT = "Incorrect Value (3)";
|
|
997
|
-
break;
|
|
998
|
-
|
|
999
|
-
case false:
|
|
1000
|
-
TEST_OUTPUT = "Incorrect Value (4)";
|
|
1001
|
-
break;
|
|
1002
|
-
|
|
1003
|
-
default:
|
|
1004
|
-
TEST_OUTPUT = "Second Correct Value";
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
switch(true){
|
|
1008
|
-
case false:
|
|
1009
|
-
throw new Error();
|
|
1010
|
-
break;
|
|
1011
|
-
|
|
1012
|
-
default:
|
|
1013
|
-
TEST_OUTPUT = "Incorrect Value";
|
|
1014
|
-
|
|
1015
|
-
case true:
|
|
1016
|
-
TEST_OUTPUT = "Third Correct Value";
|
|
1017
|
-
// Fall-through test
|
|
1018
|
-
case 10:
|
|
1019
|
-
TEST_OUTPUT = "Fourth Correct Value";
|
|
1020
|
-
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
switch(true){
|
|
1024
|
-
default:
|
|
1025
|
-
throw new Error("NO");
|
|
1026
|
-
break;
|
|
1027
|
-
case true:
|
|
1028
|
-
|
|
1029
|
-
break;
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
var hitDefault = false;
|
|
1033
|
-
|
|
1034
|
-
switch(true){
|
|
1035
|
-
case 1:
|
|
1036
|
-
case 2:
|
|
1037
|
-
|
|
1038
|
-
default:
|
|
1039
|
-
hitDefault = true;
|
|
1040
|
-
break;
|
|
1041
|
-
|
|
1042
|
-
case 3:
|
|
1043
|
-
case 4:
|
|
1044
|
-
break;
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
if(!hitDefault) {
|
|
1048
|
-
throw new Error("Did not hit default case");
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
var filler1;
|
|
1052
|
-
var filler2;
|
|
1053
|
-
var filler3;
|
|
1054
|
-
`,
|
|
1055
|
-
{
|
|
1056
|
-
target: "node",
|
|
1057
|
-
controlFlowFlattening: true,
|
|
1058
|
-
}
|
|
1059
|
-
);
|
|
1060
|
-
|
|
1061
|
-
// Ensure Control Flow Flattening applied
|
|
1062
|
-
expect(output).toContain("while");
|
|
1063
|
-
|
|
1064
|
-
// Ensure switch-statements got changed
|
|
1065
|
-
expect(output).not.toContain("switch(true)");
|
|
1066
|
-
expect(output).not.toContain("switch(TEST_OUTPUT)");
|
|
1067
|
-
|
|
1068
|
-
var TEST_OUTPUT;
|
|
1069
|
-
eval(output);
|
|
1070
|
-
|
|
1071
|
-
expect(TEST_OUTPUT).toStrictEqual("Fourth Correct Value");
|
|
1072
|
-
});
|
|
1073
|
-
|
|
1074
|
-
test("Variant #31: Don't break nested function calls", async () => {
|
|
1075
|
-
var output = await JsConfuser(
|
|
1076
|
-
`
|
|
1077
|
-
var i;
|
|
1078
|
-
var counter = 0;
|
|
1079
|
-
for(i = 0; i < 10;) {
|
|
1080
|
-
function logger(x){
|
|
1081
|
-
counter++;
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
logger("Hello World");
|
|
1085
|
-
i++
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
TEST_OUTPUT = counter;
|
|
1089
|
-
`,
|
|
1090
|
-
{ target: "node", controlFlowFlattening: true }
|
|
1091
|
-
);
|
|
1092
|
-
|
|
1093
|
-
expect(output).toContain("while");
|
|
1094
|
-
|
|
1095
|
-
var TEST_OUTPUT;
|
|
1096
|
-
eval(output);
|
|
1097
|
-
|
|
1098
|
-
expect(TEST_OUTPUT).toStrictEqual(10);
|
|
1099
|
-
});
|
|
1100
|
-
|
|
1101
|
-
test("Variant #32: Don't break same name function calls", async () => {
|
|
1102
|
-
var output = await JsConfuser(
|
|
1103
|
-
`
|
|
1104
|
-
var counter = 0;
|
|
1105
|
-
|
|
1106
|
-
function a(){
|
|
1107
|
-
// Outer a called
|
|
1108
|
-
counter *= 2;
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
var i;
|
|
1112
|
-
|
|
1113
|
-
for(i = 0; i < 10;) {
|
|
1114
|
-
function a(){
|
|
1115
|
-
// Inner a called
|
|
1116
|
-
counter += 1;
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
a(); // Inner a
|
|
1120
|
-
i++;
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
a(); // Inner a, Outer a got renamed
|
|
1124
|
-
|
|
1125
|
-
TEST_OUTPUT = counter;
|
|
1126
|
-
`,
|
|
1127
|
-
{ target: "node", controlFlowFlattening: true }
|
|
1128
|
-
);
|
|
1129
|
-
|
|
1130
|
-
expect(output).toContain("while");
|
|
1131
|
-
|
|
1132
|
-
var TEST_OUTPUT;
|
|
1133
|
-
eval(output);
|
|
1134
|
-
|
|
1135
|
-
expect(TEST_OUTPUT).toStrictEqual(11);
|
|
1136
|
-
});
|
|
1137
|
-
|
|
1138
|
-
test("Variant #33: Don't break same name function declarations that are not ran", async () => {
|
|
1139
|
-
var output = await JsConfuser(
|
|
1140
|
-
`
|
|
1141
|
-
var counter = 0;
|
|
1142
|
-
|
|
1143
|
-
function a(){
|
|
1144
|
-
// Outer a called
|
|
1145
|
-
counter += 1;
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
for(var i = 0; i < 10;) {
|
|
1149
|
-
if(false){
|
|
1150
|
-
function a(){
|
|
1151
|
-
// Inner a called
|
|
1152
|
-
counter = 0;
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
a(); // Outer a
|
|
1158
|
-
i++;
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
a(); // Outer a
|
|
1162
|
-
|
|
1163
|
-
TEST_OUTPUT = counter;
|
|
1164
|
-
`,
|
|
1165
|
-
{ target: "node", controlFlowFlattening: true }
|
|
1166
|
-
);
|
|
1167
|
-
|
|
1168
|
-
expect(output).toContain("while");
|
|
1169
|
-
|
|
1170
|
-
var TEST_OUTPUT;
|
|
1171
|
-
eval(output);
|
|
1172
|
-
|
|
1173
|
-
expect(TEST_OUTPUT).toStrictEqual(11);
|
|
1174
|
-
});
|
|
1175
|
-
|
|
1176
|
-
test("Variant #34: Flatten If, For, While, Do-while, and Switch statements multiple times", async () => {
|
|
1177
|
-
var code = `
|
|
1178
|
-
var counter = -1;
|
|
1179
|
-
|
|
1180
|
-
function incrementCounter(){
|
|
1181
|
-
counter++;
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
if(false) {
|
|
1185
|
-
|
|
1186
|
-
} else {
|
|
1187
|
-
counter = 0;
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
if(true){
|
|
1191
|
-
for(var i = 0; i < 10; i++) {
|
|
1192
|
-
switch(i){
|
|
1193
|
-
default:
|
|
1194
|
-
i++;
|
|
1195
|
-
break;
|
|
1196
|
-
|
|
1197
|
-
case 6:
|
|
1198
|
-
if(false){
|
|
1199
|
-
function incrementCounter(){
|
|
1200
|
-
throw new Error("Fake counter function");
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
|
-
while(i != 10) {
|
|
1205
|
-
incrementCounter();
|
|
1206
|
-
if(counter > 10) break;
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
do {
|
|
1210
|
-
counter--;
|
|
1211
|
-
} while (counter > 5)
|
|
1212
|
-
// Fall-through
|
|
1213
|
-
case 8:
|
|
1214
|
-
counter *= 2;
|
|
1215
|
-
break;
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
} else {
|
|
1219
|
-
counter = "Incorrect Value";
|
|
1220
|
-
}
|
|
1221
|
-
if(false){
|
|
1222
|
-
counter = "Incorrect Value";
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
TEST_OUTPUT = counter;
|
|
1226
|
-
`;
|
|
1227
|
-
|
|
1228
|
-
var firstObfuscation = await JsConfuser(code, {
|
|
1229
|
-
target: "node",
|
|
1230
|
-
controlFlowFlattening: true,
|
|
1231
|
-
});
|
|
1232
|
-
var secondObfuscation = await JsConfuser(firstObfuscation, {
|
|
1233
|
-
target: "node",
|
|
1234
|
-
controlFlowFlattening: true,
|
|
1235
|
-
});
|
|
1236
|
-
|
|
1237
|
-
var TEST_OUTPUT;
|
|
1238
|
-
eval(secondObfuscation);
|
|
1239
|
-
|
|
1240
|
-
expect(TEST_OUTPUT).toStrictEqual(10);
|
|
1241
|
-
});
|
|
1242
|
-
|
|
1243
|
-
test("Variant #35: Redefined function declaration + variable declaration", async () => {
|
|
1244
|
-
var code = `
|
|
1245
|
-
function push(str){
|
|
1246
|
-
TEST_OUTPUT.push(str);
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
x();
|
|
1250
|
-
|
|
1251
|
-
var x = ()=>push("Top x");
|
|
1252
|
-
|
|
1253
|
-
x()
|
|
1254
|
-
|
|
1255
|
-
function x(){ push("Bottom x") }
|
|
1256
|
-
|
|
1257
|
-
if(true){
|
|
1258
|
-
|
|
1259
|
-
x();
|
|
1260
|
-
|
|
1261
|
-
function x(){ push("Nested x") }
|
|
1262
|
-
}
|
|
1263
|
-
`;
|
|
1264
|
-
|
|
1265
|
-
var output = await JsConfuser(code, {
|
|
1266
|
-
target: "node",
|
|
1267
|
-
controlFlowFlattening: true,
|
|
1268
|
-
});
|
|
1269
|
-
|
|
1270
|
-
var TEST_OUTPUT = [];
|
|
1271
|
-
eval(output);
|
|
1272
|
-
|
|
1273
|
-
expect(TEST_OUTPUT).toStrictEqual(["Bottom x", "Top x", "Nested x"]);
|
|
1274
|
-
});
|