js-confuser 1.5.8 → 1.6.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/workflows/node.js.yml +2 -2
- package/CHANGELOG.md +69 -0
- package/README.md +143 -7
- package/dist/index.js +33 -4
- package/dist/obfuscator.js +30 -31
- package/dist/options.js +4 -5
- package/dist/order.js +4 -6
- package/dist/probability.js +2 -4
- package/dist/templates/bufferToString.js +13 -0
- package/dist/templates/crash.js +2 -2
- package/dist/templates/es5.js +18 -0
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/calculator.js +77 -21
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
- package/dist/transforms/deadCode.js +33 -25
- package/dist/transforms/dispatcher.js +7 -6
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +3 -1
- package/dist/transforms/es5/es5.js +31 -34
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/finalizer.js +82 -0
- package/dist/transforms/flatten.js +82 -55
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/globalAnalysis.js +88 -0
- package/dist/transforms/identifier/globalConcealing.js +10 -83
- package/dist/transforms/identifier/movedDeclarations.js +2 -8
- package/dist/transforms/identifier/renameVariables.js +39 -27
- package/dist/transforms/identifier/variableAnalysis.js +58 -62
- package/dist/transforms/minify.js +80 -61
- package/dist/transforms/opaquePredicates.js +1 -1
- package/dist/transforms/preparation/preparation.js +2 -2
- package/dist/transforms/preparation.js +231 -0
- package/dist/transforms/renameLabels.js +1 -1
- package/dist/transforms/rgf.js +4 -5
- package/dist/transforms/stack.js +87 -26
- package/dist/transforms/string/encoding.js +150 -179
- package/dist/transforms/string/stringCompression.js +14 -15
- package/dist/transforms/string/stringConcealing.js +25 -8
- package/dist/transforms/string/stringEncoding.js +13 -24
- package/dist/transforms/transform.js +11 -18
- package/dist/traverse.js +24 -18
- package/dist/util/compare.js +2 -2
- package/dist/util/gen.js +15 -0
- package/dist/util/insert.js +31 -7
- package/dist/util/random.js +15 -0
- package/package.json +5 -5
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +26 -29
- package/src/options.ts +17 -21
- package/src/order.ts +4 -8
- package/src/probability.ts +2 -3
- package/src/templates/bufferToString.ts +68 -0
- package/src/templates/crash.ts +5 -9
- package/src/templates/es5.ts +131 -0
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/calculator.ts +122 -59
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
- package/src/transforms/deadCode.ts +383 -26
- package/src/transforms/dispatcher.ts +8 -6
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +3 -1
- package/src/transforms/es5/es5.ts +32 -77
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/finalizer.ts +75 -0
- package/src/transforms/flatten.ts +194 -151
- package/src/transforms/identifier/globalAnalysis.ts +85 -0
- package/src/transforms/identifier/globalConcealing.ts +14 -103
- package/src/transforms/identifier/movedDeclarations.ts +4 -11
- package/src/transforms/identifier/renameVariables.ts +37 -30
- package/src/transforms/identifier/variableAnalysis.ts +66 -73
- package/src/transforms/minify.ts +116 -77
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +238 -0
- package/src/transforms/renameLabels.ts +2 -2
- package/src/transforms/rgf.ts +6 -7
- package/src/transforms/stack.ts +97 -37
- package/src/transforms/string/encoding.ts +115 -212
- package/src/transforms/string/stringCompression.ts +27 -18
- package/src/transforms/string/stringConcealing.ts +41 -11
- package/src/transforms/string/stringEncoding.ts +18 -18
- package/src/transforms/transform.ts +15 -21
- package/src/traverse.ts +24 -12
- package/src/types.ts +11 -2
- package/src/util/compare.ts +2 -2
- package/src/util/gen.ts +21 -1
- package/src/util/insert.ts +49 -9
- package/src/util/random.ts +13 -0
- package/test/code/Cash.test.ts +1 -1
- package/test/code/Dynamic.test.ts +12 -10
- package/test/code/ES6.src.js +136 -0
- package/test/code/ES6.test.ts +28 -2
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +15 -2
- package/test/probability.test.ts +44 -0
- package/test/templates/template.test.ts +1 -1
- package/test/transforms/antiTooling.test.ts +52 -0
- package/test/transforms/calculator.test.ts +40 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
- package/test/transforms/deadCode.test.ts +66 -15
- package/test/transforms/dispatcher.test.ts +44 -1
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/es5/antiDestructuring.test.ts +16 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +195 -3
- package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
- package/test/transforms/identifier/renameVariables.test.ts +108 -0
- package/test/transforms/lock/antiDebug.test.ts +2 -2
- package/test/transforms/minify.test.ts +151 -0
- package/test/transforms/preparation.test.ts +157 -0
- package/test/transforms/rgf.test.ts +56 -29
- package/test/transforms/stack.test.ts +91 -21
- package/test/transforms/string/stringCompression.test.ts +39 -0
- package/test/transforms/string/stringConcealing.test.ts +115 -0
- package/test/transforms/string/stringEncoding.test.ts +53 -2
- package/test/transforms/transform.test.ts +66 -0
- package/test/traverse.test.ts +139 -0
- package/test/util/compare.test.ts +23 -1
- package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
- package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
- package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
- package/src/transforms/hexadecimalNumbers.ts +0 -31
- package/src/transforms/hideInitializingCode.ts +0 -432
- package/src/transforms/label.ts +0 -64
- package/src/transforms/preparation/nameConflicts.ts +0 -102
- package/src/transforms/preparation/preparation.ts +0 -176
- package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
- package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
- package/test/transforms/hideInitializingCode.test.ts +0 -336
- package/test/transforms/preparation/nameConflicts.test.ts +0 -52
- package/test/transforms/preparation/preparation.test.ts +0 -62
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The file contains all preparation transformations
|
|
3
|
-
*/
|
|
4
|
-
import Transform from "../transform";
|
|
5
|
-
|
|
6
|
-
import { BlockStatement, Literal, ReturnStatement } from "../../util/gen";
|
|
7
|
-
import { ObfuscateOrder } from "../../order";
|
|
8
|
-
import { clone, getFunction } from "../../util/insert";
|
|
9
|
-
import { getIdentifierInfo } from "../../util/identifiers";
|
|
10
|
-
import Label from "../label";
|
|
11
|
-
import { isLoop } from "../../util/compare";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* People use shortcuts and its harder to parse.
|
|
15
|
-
*
|
|
16
|
-
* - `if (a) b()` -> `if (a) { b() }`
|
|
17
|
-
* - Ensures all bodies are `BlockStatement`, not individual expression statements
|
|
18
|
-
*/
|
|
19
|
-
class Block extends Transform {
|
|
20
|
-
constructor(o) {
|
|
21
|
-
super(o);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
match(object, parents) {
|
|
25
|
-
return !Array.isArray(object);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
transform(object, parents) {
|
|
29
|
-
switch (object.type) {
|
|
30
|
-
case "IfStatement":
|
|
31
|
-
if (object.consequent.type != "BlockStatement") {
|
|
32
|
-
object.consequent = BlockStatement([clone(object.consequent)]);
|
|
33
|
-
}
|
|
34
|
-
if (object.alternate && object.alternate.type != "BlockStatement") {
|
|
35
|
-
object.alternate = BlockStatement([clone(object.alternate)]);
|
|
36
|
-
}
|
|
37
|
-
break;
|
|
38
|
-
|
|
39
|
-
case "WhileStatement":
|
|
40
|
-
case "WithStatement":
|
|
41
|
-
case "ForStatement":
|
|
42
|
-
case "ForOfStatement":
|
|
43
|
-
case "ForInStatement":
|
|
44
|
-
if (object.body.type != "BlockStatement") {
|
|
45
|
-
object.body = BlockStatement([clone(object.body)]);
|
|
46
|
-
}
|
|
47
|
-
break;
|
|
48
|
-
|
|
49
|
-
case "ArrowFunctionExpression":
|
|
50
|
-
if (object.body.type !== "BlockStatement" && object.expression) {
|
|
51
|
-
object.body = BlockStatement([ReturnStatement(clone(object.body))]);
|
|
52
|
-
object.expression = false;
|
|
53
|
-
}
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
class ExplicitIdentifiers extends Transform {
|
|
60
|
-
constructor(o) {
|
|
61
|
-
super(o);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
match(object, parents) {
|
|
65
|
-
return object.type == "Identifier";
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
transform(object, parents) {
|
|
69
|
-
if (object.name === "eval") {
|
|
70
|
-
var fn = getFunction(object, parents);
|
|
71
|
-
if (fn) {
|
|
72
|
-
fn.$requiresEval = true;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
var info = getIdentifierInfo(object, parents);
|
|
77
|
-
if (info.isPropertyKey || info.isAccessor) {
|
|
78
|
-
var propIndex = parents.findIndex(
|
|
79
|
-
(x) => x.type == "MethodDefinition" || x.type == "Property"
|
|
80
|
-
);
|
|
81
|
-
if (propIndex !== -1) {
|
|
82
|
-
if (
|
|
83
|
-
parents[propIndex].type == "MethodDefinition" &&
|
|
84
|
-
parents[propIndex].kind == "constructor"
|
|
85
|
-
) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
this.log(object.name, "->", `'${object.name}'`);
|
|
91
|
-
|
|
92
|
-
this.replace(object, Literal(object.name));
|
|
93
|
-
parents[0].computed = true;
|
|
94
|
-
parents[0].shorthand = false;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
class ExplicitDeclarations extends Transform {
|
|
100
|
-
constructor(o) {
|
|
101
|
-
super(o);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
match(object, parents) {
|
|
105
|
-
return object.type == "VariableDeclaration";
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
transform(object, parents) {
|
|
109
|
-
// for ( var x in ... ) {...}
|
|
110
|
-
var forIndex = parents.findIndex(
|
|
111
|
-
(x) => x.type == "ForInStatement" || x.type == "ForOfStatement"
|
|
112
|
-
);
|
|
113
|
-
if (
|
|
114
|
-
forIndex != -1 &&
|
|
115
|
-
parents[forIndex].left == (parents[forIndex - 1] || object)
|
|
116
|
-
) {
|
|
117
|
-
object.declarations.forEach((x) => {
|
|
118
|
-
x.init = null;
|
|
119
|
-
});
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
var body = parents[0];
|
|
124
|
-
if (isLoop(body) || body.type == "LabeledStatement") {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (body.type == "ExportNamedDeclaration") {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (!Array.isArray(body)) {
|
|
133
|
-
this.error(new Error("body is " + body.type));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (object.declarations.length > 1) {
|
|
137
|
-
// Make singular
|
|
138
|
-
|
|
139
|
-
var index = body.indexOf(object);
|
|
140
|
-
if (index == -1) {
|
|
141
|
-
this.error(new Error("index is -1"));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
var after = object.declarations.slice(1);
|
|
145
|
-
|
|
146
|
-
body.splice(
|
|
147
|
-
index + 1,
|
|
148
|
-
0,
|
|
149
|
-
...after.map((x) => {
|
|
150
|
-
return {
|
|
151
|
-
type: "VariableDeclaration",
|
|
152
|
-
declarations: [clone(x)],
|
|
153
|
-
kind: object.kind,
|
|
154
|
-
};
|
|
155
|
-
})
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
object.declarations.length = 1;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export default class Preparation extends Transform {
|
|
164
|
-
constructor(o) {
|
|
165
|
-
super(o, ObfuscateOrder.Preparation);
|
|
166
|
-
|
|
167
|
-
this.before.push(new Block(o));
|
|
168
|
-
this.before.push(new Label(o));
|
|
169
|
-
this.before.push(new ExplicitIdentifiers(o));
|
|
170
|
-
this.before.push(new ExplicitDeclarations(o));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
match() {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import JsConfuser from "../../../src/index";
|
|
2
|
-
|
|
3
|
-
it("should obfuscate for loops (ControlFlowObfuscation)", async () => {
|
|
4
|
-
var code = `
|
|
5
|
-
var array = [];
|
|
6
|
-
|
|
7
|
-
for ( var i = 1; i <= 10; i++ ) {
|
|
8
|
-
array.push(i);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
input(array);
|
|
12
|
-
`;
|
|
13
|
-
|
|
14
|
-
var output = await JsConfuser(code, {
|
|
15
|
-
target: "browser",
|
|
16
|
-
controlFlowFlattening: true,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
expect(output).toContain("switch");
|
|
20
|
-
|
|
21
|
-
function input(array) {
|
|
22
|
-
expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
eval(output);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("should obfuscate while loops (ControlFlowObfuscation)", async () => {
|
|
29
|
-
var code = `
|
|
30
|
-
var array = [];
|
|
31
|
-
var i = 1;
|
|
32
|
-
|
|
33
|
-
while ( i <= 10 ) {
|
|
34
|
-
array.push(i);
|
|
35
|
-
i++
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
input(array);
|
|
39
|
-
`;
|
|
40
|
-
|
|
41
|
-
var output = await JsConfuser(code, {
|
|
42
|
-
target: "browser",
|
|
43
|
-
controlFlowFlattening: true,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
expect(output).toContain("switch");
|
|
47
|
-
|
|
48
|
-
function input(array) {
|
|
49
|
-
expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
eval(output);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should work with break statements (ControlFlowObfuscation)", async () => {
|
|
56
|
-
var code = `
|
|
57
|
-
|
|
58
|
-
var TEST_ARRAY = [];
|
|
59
|
-
|
|
60
|
-
for ( var i =1; true; i++ ) {
|
|
61
|
-
if ( i == 11 ) {
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
TEST_ARRAY.push(i);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
input(TEST_ARRAY);
|
|
68
|
-
`;
|
|
69
|
-
|
|
70
|
-
var output = await JsConfuser(code, {
|
|
71
|
-
target: "browser",
|
|
72
|
-
controlFlowFlattening: true,
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
expect(output).toContain("switch");
|
|
76
|
-
expect(output).toContain("while");
|
|
77
|
-
|
|
78
|
-
function input(array) {
|
|
79
|
-
expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
eval(output);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("should not obfuscate code with `let` (Lexically bound variables, ControlFlowObfuscation)", async () => {
|
|
86
|
-
var code = `
|
|
87
|
-
var array=[];
|
|
88
|
-
for ( let i =1; i <= 10; i++ ) {
|
|
89
|
-
array.push(i);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
input(array);
|
|
93
|
-
`;
|
|
94
|
-
|
|
95
|
-
var output = await JsConfuser(code, {
|
|
96
|
-
target: "node",
|
|
97
|
-
controlFlowFlattening: true,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
expect(output).not.toContain("switch");
|
|
101
|
-
});
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import JsConfuser from "../../../src/index";
|
|
2
|
-
|
|
3
|
-
it("should obfuscate numbered switch statements (SwitchCaseObfuscation)", async () => {
|
|
4
|
-
var code = `
|
|
5
|
-
var array = [];
|
|
6
|
-
|
|
7
|
-
function runOnce(stateParam){
|
|
8
|
-
switch(stateParam){
|
|
9
|
-
case 1: array.push(1, 2, 3); break;
|
|
10
|
-
case 2: array.push(4, 5, 6); break;
|
|
11
|
-
case 3: array.push(7, 8, 9); break;
|
|
12
|
-
case 4: array.push(10); break;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
runOnce(1);
|
|
17
|
-
runOnce(2);
|
|
18
|
-
runOnce(3);
|
|
19
|
-
runOnce(4);
|
|
20
|
-
|
|
21
|
-
input(array);
|
|
22
|
-
`;
|
|
23
|
-
|
|
24
|
-
var output = await JsConfuser(code, {
|
|
25
|
-
target: "browser",
|
|
26
|
-
controlFlowFlattening: true,
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
expect(
|
|
30
|
-
output.includes("case 1:") &&
|
|
31
|
-
output.includes("case 2:") &&
|
|
32
|
-
output.includes("case 3:") &&
|
|
33
|
-
output.includes("case 4:")
|
|
34
|
-
).toStrictEqual(false);
|
|
35
|
-
|
|
36
|
-
function input(array) {
|
|
37
|
-
expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
eval(output);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("should not obfuscate switch statements with complex discriminants (SwitchCaseObfuscation)", async () => {
|
|
44
|
-
var code = `
|
|
45
|
-
var array = [];
|
|
46
|
-
|
|
47
|
-
function runOnce(stateParam){
|
|
48
|
-
switch(stateParam || 0){
|
|
49
|
-
case 1: array.push(1, 2, 3); break;
|
|
50
|
-
case 2: array.push(4, 5, 6); break;
|
|
51
|
-
case 3: array.push(7, 8, 9); break;
|
|
52
|
-
case 4: array.push(10); break;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
runOnce(1);
|
|
57
|
-
runOnce(2);
|
|
58
|
-
runOnce(3);
|
|
59
|
-
runOnce(4);
|
|
60
|
-
|
|
61
|
-
input(array);
|
|
62
|
-
`;
|
|
63
|
-
|
|
64
|
-
var output = await JsConfuser(code, {
|
|
65
|
-
target: "browser",
|
|
66
|
-
controlFlowFlattening: true,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
expect(output).toContain("stateParam||0");
|
|
70
|
-
|
|
71
|
-
function input(array) {
|
|
72
|
-
expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
eval(output);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// https://github.com/MichaelXF/js-confuser/issues/41
|
|
79
|
-
it("Not apply to switch statements with default cases", async ()=>{
|
|
80
|
-
|
|
81
|
-
var code = `
|
|
82
|
-
var array = [];
|
|
83
|
-
|
|
84
|
-
function runOnce(stateParam){
|
|
85
|
-
switch(stateParam){
|
|
86
|
-
case 1: array.push(1, 2, 3); break;
|
|
87
|
-
case 2: array.push(4, 5, 6); break;
|
|
88
|
-
case 3: array.push(7, 8, 9); break;
|
|
89
|
-
default: array.push(10); break;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
runOnce(1);
|
|
94
|
-
runOnce(2);
|
|
95
|
-
runOnce(3);
|
|
96
|
-
runOnce(-1); // default case
|
|
97
|
-
|
|
98
|
-
input(array);
|
|
99
|
-
`;
|
|
100
|
-
|
|
101
|
-
var output = await JsConfuser(code, {
|
|
102
|
-
target: "browser",
|
|
103
|
-
controlFlowFlattening: true,
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
expect(
|
|
107
|
-
output.includes("case 1:") &&
|
|
108
|
-
output.includes("case 2:") &&
|
|
109
|
-
output.includes("case 3:")
|
|
110
|
-
).toStrictEqual(true);
|
|
111
|
-
|
|
112
|
-
function input(array) {
|
|
113
|
-
expect(array).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
eval(output);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
});
|
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
import JsConfuser from "../../src/index";
|
|
2
|
-
|
|
3
|
-
test("Variant #1: Do not apply with exported names", async () => {
|
|
4
|
-
var output = await JsConfuser.obfuscate(
|
|
5
|
-
`
|
|
6
|
-
export function myFunction(){
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
`,
|
|
10
|
-
{
|
|
11
|
-
target: "node",
|
|
12
|
-
hideInitializingCode: true,
|
|
13
|
-
}
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
expect(output).not.toContain("__p_");
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test("Variant #2: Add ternary expressions and wrap initializing code in a function and still work", async () => {
|
|
20
|
-
var output = await JsConfuser.obfuscate(
|
|
21
|
-
`
|
|
22
|
-
var myNumber = 10;
|
|
23
|
-
input(myNumber)
|
|
24
|
-
`,
|
|
25
|
-
{
|
|
26
|
-
target: "node",
|
|
27
|
-
hideInitializingCode: true,
|
|
28
|
-
}
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
expect(output).toContain("__p_");
|
|
32
|
-
expect(output).toContain("function ");
|
|
33
|
-
expect(output).toContain("?");
|
|
34
|
-
|
|
35
|
-
var value = "never_called";
|
|
36
|
-
function input(valueIn) {
|
|
37
|
-
value = valueIn;
|
|
38
|
-
}
|
|
39
|
-
eval(output);
|
|
40
|
-
|
|
41
|
-
expect(value).toStrictEqual(10);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test("Variant #3: Should work with other function declarations", async () => {
|
|
45
|
-
var output = await JsConfuser.obfuscate(
|
|
46
|
-
`
|
|
47
|
-
var myNumber = myFunction();
|
|
48
|
-
input(myNumber)
|
|
49
|
-
|
|
50
|
-
function myFunction(){
|
|
51
|
-
return 10;
|
|
52
|
-
}
|
|
53
|
-
`,
|
|
54
|
-
{
|
|
55
|
-
target: "node",
|
|
56
|
-
hideInitializingCode: true,
|
|
57
|
-
}
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
expect(output).toContain("__p_");
|
|
61
|
-
expect(output).toContain("function ");
|
|
62
|
-
|
|
63
|
-
var value = "never_called";
|
|
64
|
-
function input(valueIn) {
|
|
65
|
-
value = valueIn;
|
|
66
|
-
}
|
|
67
|
-
eval(output);
|
|
68
|
-
|
|
69
|
-
expect(value).toStrictEqual(10);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test("Variant #4: Should work when doubly obfuscated", async () => {
|
|
73
|
-
var output = await JsConfuser.obfuscate(
|
|
74
|
-
`
|
|
75
|
-
var myNumber = myFunction();
|
|
76
|
-
input(myNumber)
|
|
77
|
-
|
|
78
|
-
function myFunction(){
|
|
79
|
-
return 10;
|
|
80
|
-
}
|
|
81
|
-
`,
|
|
82
|
-
{
|
|
83
|
-
target: "node",
|
|
84
|
-
hideInitializingCode: true,
|
|
85
|
-
}
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
expect(output).toContain("__p_");
|
|
89
|
-
expect(output).toContain("function ");
|
|
90
|
-
|
|
91
|
-
var doublyObfuscated = await JsConfuser.obfuscate(output, {
|
|
92
|
-
target: "node",
|
|
93
|
-
hideInitializingCode: true,
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
var value = "never_called";
|
|
97
|
-
function input(valueIn) {
|
|
98
|
-
value = valueIn;
|
|
99
|
-
}
|
|
100
|
-
eval(doublyObfuscated);
|
|
101
|
-
|
|
102
|
-
expect(value).toStrictEqual(10);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test("Variant #5: Should bring up variable declarations", async () => {
|
|
106
|
-
var output = await JsConfuser.obfuscate(
|
|
107
|
-
`
|
|
108
|
-
var myNumber = 10;
|
|
109
|
-
function myFunction(){
|
|
110
|
-
return myNumber;
|
|
111
|
-
}
|
|
112
|
-
input(myFunction())
|
|
113
|
-
`,
|
|
114
|
-
{
|
|
115
|
-
target: "node",
|
|
116
|
-
hideInitializingCode: true,
|
|
117
|
-
}
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
expect(output).toContain("__p_");
|
|
121
|
-
expect(output).toContain("function ");
|
|
122
|
-
expect(output).toContain("var myNumber;");
|
|
123
|
-
expect(output).toContain("myNumber=");
|
|
124
|
-
|
|
125
|
-
var value = "never_called";
|
|
126
|
-
function input(valueIn) {
|
|
127
|
-
value = valueIn;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
eval(output);
|
|
131
|
-
|
|
132
|
-
expect(value).toStrictEqual(10);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
test("Variant #6: Should not bring up variable declarations in nested contexts", async () => {
|
|
136
|
-
var output = await JsConfuser.obfuscate(
|
|
137
|
-
`
|
|
138
|
-
function myFunction(){
|
|
139
|
-
function myNestedFunction(){
|
|
140
|
-
var myNumber = 10;
|
|
141
|
-
return myNumber;
|
|
142
|
-
}
|
|
143
|
-
return myNestedFunction();
|
|
144
|
-
}
|
|
145
|
-
input(myFunction())
|
|
146
|
-
`,
|
|
147
|
-
{
|
|
148
|
-
target: "node",
|
|
149
|
-
hideInitializingCode: true,
|
|
150
|
-
}
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
expect(output).toContain("__p_");
|
|
154
|
-
expect(output).toContain("function ");
|
|
155
|
-
expect(output).toContain("var myNumber=");
|
|
156
|
-
|
|
157
|
-
var value = "never_called";
|
|
158
|
-
function input(valueIn) {
|
|
159
|
-
value = valueIn;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
eval(output);
|
|
163
|
-
|
|
164
|
-
expect(value).toStrictEqual(10);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
test("Variant #7: Should bring up class declarations", async () => {
|
|
168
|
-
var output = await JsConfuser.obfuscate(
|
|
169
|
-
`
|
|
170
|
-
|
|
171
|
-
class MyClass {
|
|
172
|
-
static getNumber(){
|
|
173
|
-
return 10;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function myFunction(){
|
|
178
|
-
return MyClass.getNumber();
|
|
179
|
-
}
|
|
180
|
-
input(myFunction())
|
|
181
|
-
`,
|
|
182
|
-
{
|
|
183
|
-
target: "node",
|
|
184
|
-
hideInitializingCode: true,
|
|
185
|
-
}
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
expect(output).toContain("__p_");
|
|
189
|
-
expect(output).toContain("function ");
|
|
190
|
-
expect(output).toContain("var MyClass;");
|
|
191
|
-
expect(output).toContain("MyClass=class MyClass{");
|
|
192
|
-
|
|
193
|
-
var value = "never_called";
|
|
194
|
-
function input(valueIn) {
|
|
195
|
-
value = valueIn;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
eval(output);
|
|
199
|
-
|
|
200
|
-
expect(value).toStrictEqual(10);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test("Variant #8: Should bring up variable declarations in for statements", async () => {
|
|
204
|
-
var output = await JsConfuser.obfuscate(
|
|
205
|
-
`
|
|
206
|
-
|
|
207
|
-
for(var i=0; i <= 9; i++){
|
|
208
|
-
|
|
209
|
-
} // i ends as 10
|
|
210
|
-
|
|
211
|
-
function myFunction(){
|
|
212
|
-
return i;
|
|
213
|
-
}
|
|
214
|
-
input(myFunction())
|
|
215
|
-
`,
|
|
216
|
-
{
|
|
217
|
-
target: "node",
|
|
218
|
-
hideInitializingCode: true,
|
|
219
|
-
}
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
expect(output).toContain("__p_");
|
|
223
|
-
expect(output).toContain("function ");
|
|
224
|
-
|
|
225
|
-
var value = "never_called";
|
|
226
|
-
function input(valueIn) {
|
|
227
|
-
value = valueIn;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
eval(output);
|
|
231
|
-
|
|
232
|
-
expect(value).toStrictEqual(10);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
test("Variant #9: Should bring up variable declarations in for in statements", async () => {
|
|
236
|
-
var output = await JsConfuser.obfuscate(
|
|
237
|
-
`
|
|
238
|
-
|
|
239
|
-
var myNumber = 0;
|
|
240
|
-
var myArray = [0,1,2,3,4,5,6,7,8,9,10];
|
|
241
|
-
for(var i in myArray){
|
|
242
|
-
if(i==10){
|
|
243
|
-
myNumber = 10;
|
|
244
|
-
}
|
|
245
|
-
} // i ends as "10"
|
|
246
|
-
|
|
247
|
-
function myFunction(){
|
|
248
|
-
return parseInt(i);
|
|
249
|
-
}
|
|
250
|
-
input(myFunction())
|
|
251
|
-
`,
|
|
252
|
-
{
|
|
253
|
-
target: "node",
|
|
254
|
-
hideInitializingCode: true,
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
expect(output).toContain("__p_");
|
|
259
|
-
expect(output).toContain("function ");
|
|
260
|
-
|
|
261
|
-
var value = "never_called";
|
|
262
|
-
function input(valueIn) {
|
|
263
|
-
value = valueIn;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
eval(output);
|
|
267
|
-
|
|
268
|
-
expect(value).toStrictEqual(10);
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
test("Variant #10: Should work with multiple variable declarations", async () => {
|
|
272
|
-
var output = await JsConfuser.obfuscate(
|
|
273
|
-
`
|
|
274
|
-
|
|
275
|
-
var myNumber1 = 3, myNumber2 = 2;
|
|
276
|
-
|
|
277
|
-
function myFunction(){
|
|
278
|
-
return myNumber1*2 + myNumber2*2;
|
|
279
|
-
}
|
|
280
|
-
input(myFunction())
|
|
281
|
-
`,
|
|
282
|
-
{
|
|
283
|
-
target: "node",
|
|
284
|
-
hideInitializingCode: true,
|
|
285
|
-
}
|
|
286
|
-
);
|
|
287
|
-
|
|
288
|
-
expect(output).toContain("__p_");
|
|
289
|
-
expect(output).toContain("function ");
|
|
290
|
-
|
|
291
|
-
var value = "never_called";
|
|
292
|
-
function input(valueIn) {
|
|
293
|
-
value = valueIn;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
eval(output);
|
|
297
|
-
|
|
298
|
-
expect(value).toStrictEqual(10);
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
test("Variant #11: Should bring up variable declaration but not default values function expression's variables", async () => {
|
|
302
|
-
var output = await JsConfuser.obfuscate(
|
|
303
|
-
`
|
|
304
|
-
|
|
305
|
-
var [myNumber1 = function(){
|
|
306
|
-
var myNumber = 2;
|
|
307
|
-
}] = [10];
|
|
308
|
-
|
|
309
|
-
function myFunction(){
|
|
310
|
-
return myNumber1;
|
|
311
|
-
}
|
|
312
|
-
input(myFunction())
|
|
313
|
-
`,
|
|
314
|
-
{
|
|
315
|
-
target: "node",
|
|
316
|
-
hideInitializingCode: true,
|
|
317
|
-
}
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
expect(output).toContain("__p_");
|
|
321
|
-
expect(output).toContain("function ");
|
|
322
|
-
expect(output).toContain("var myNumber1;");
|
|
323
|
-
expect(output).toContain("[myNumber1");
|
|
324
|
-
expect(output).toContain("=[");
|
|
325
|
-
|
|
326
|
-
expect(output).toContain("var myNumber=");
|
|
327
|
-
|
|
328
|
-
var value = "never_called";
|
|
329
|
-
function input(valueIn) {
|
|
330
|
-
value = valueIn;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
eval(output);
|
|
334
|
-
|
|
335
|
-
expect(value).toStrictEqual(10);
|
|
336
|
-
});
|