js-confuser 1.5.9 → 1.7.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 +55 -0
- package/README.md +346 -165
- package/dist/constants.js +6 -2
- package/dist/index.js +9 -21
- package/dist/obfuscator.js +19 -31
- package/dist/options.js +5 -5
- package/dist/order.js +1 -3
- package/dist/presets.js +6 -7
- package/dist/probability.js +2 -4
- package/dist/templates/bufferToString.js +13 -0
- package/dist/templates/crash.js +3 -3
- package/dist/templates/es5.js +18 -0
- package/dist/templates/functionLength.js +16 -0
- package/dist/transforms/calculator.js +77 -21
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -1
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
- package/dist/transforms/deadCode.js +33 -25
- package/dist/transforms/dispatcher.js +8 -4
- package/dist/transforms/es5/antiDestructuring.js +2 -0
- package/dist/transforms/es5/es5.js +31 -34
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +92 -58
- package/dist/transforms/finalizer.js +82 -0
- package/dist/transforms/flatten.js +229 -148
- package/dist/transforms/identifier/globalAnalysis.js +88 -0
- package/dist/transforms/identifier/globalConcealing.js +10 -83
- package/dist/transforms/identifier/movedDeclarations.js +35 -88
- package/dist/transforms/identifier/renameVariables.js +124 -59
- package/dist/transforms/identifier/variableAnalysis.js +58 -62
- package/dist/transforms/lock/lock.js +0 -37
- package/dist/transforms/minify.js +60 -57
- 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 +139 -247
- package/dist/transforms/stack.js +128 -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 +12 -19
- package/dist/traverse.js +24 -10
- package/dist/util/gen.js +17 -1
- package/dist/util/identifiers.js +37 -3
- package/dist/util/insert.js +35 -4
- package/dist/util/random.js +15 -0
- package/docs/ControlFlowFlattening.md +595 -0
- package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
- package/{Integrity.md → docs/Integrity.md} +2 -2
- package/docs/RGF.md +419 -0
- package/package.json +5 -5
- package/src/constants.ts +3 -0
- package/src/index.ts +2 -2
- package/src/obfuscator.ts +19 -31
- package/src/options.ts +14 -103
- package/src/order.ts +1 -5
- package/src/presets.ts +6 -7
- package/src/probability.ts +2 -3
- package/src/templates/bufferToString.ts +68 -0
- package/src/templates/crash.ts +15 -19
- package/src/templates/es5.ts +131 -0
- package/src/templates/functionLength.ts +14 -0
- package/src/transforms/calculator.ts +122 -59
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +4 -1
- package/src/transforms/deadCode.ts +383 -26
- package/src/transforms/dispatcher.ts +9 -4
- package/src/transforms/es5/antiDestructuring.ts +2 -0
- package/src/transforms/es5/es5.ts +32 -77
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +133 -129
- package/src/transforms/{hexadecimalNumbers.ts → finalizer.ts} +29 -13
- package/src/transforms/flatten.ts +357 -300
- package/src/transforms/identifier/globalAnalysis.ts +85 -0
- package/src/transforms/identifier/globalConcealing.ts +14 -103
- package/src/transforms/identifier/movedDeclarations.ts +49 -102
- package/src/transforms/identifier/renameVariables.ts +149 -78
- package/src/transforms/identifier/variableAnalysis.ts +66 -73
- package/src/transforms/lock/lock.ts +1 -42
- package/src/transforms/minify.ts +91 -75
- 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 +213 -405
- package/src/transforms/stack.ts +156 -36
- package/src/transforms/string/encoding.ts +115 -212
- package/src/transforms/string/stringCompression.ts +27 -18
- package/src/transforms/string/stringConcealing.ts +39 -9
- package/src/transforms/string/stringEncoding.ts +18 -18
- package/src/transforms/transform.ts +21 -23
- package/src/traverse.ts +23 -4
- package/src/types.ts +2 -1
- package/src/util/gen.ts +28 -3
- package/src/util/identifiers.ts +43 -2
- package/src/util/insert.ts +38 -3
- 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 +146 -0
- package/test/code/ES6.test.ts +28 -2
- package/test/index.test.ts +2 -1
- package/test/probability.test.ts +44 -0
- package/test/templates/template.test.ts +1 -1
- package/test/transforms/antiTooling.test.ts +22 -0
- package/test/transforms/calculator.test.ts +40 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +702 -160
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
- package/test/transforms/deadCode.test.ts +66 -15
- package/test/transforms/dispatcher.test.ts +20 -1
- package/test/transforms/es5/antiDestructuring.test.ts +16 -0
- package/test/transforms/flatten.test.ts +399 -86
- package/test/transforms/identifier/movedDeclarations.test.ts +63 -8
- package/test/transforms/identifier/renameVariables.test.ts +119 -0
- package/test/transforms/lock/antiDebug.test.ts +2 -2
- package/test/transforms/lock/lock.test.ts +1 -48
- package/test/transforms/minify.test.ts +104 -0
- package/test/transforms/preparation.test.ts +157 -0
- package/test/transforms/rgf.test.ts +261 -381
- package/test/transforms/stack.test.ts +143 -21
- package/test/transforms/string/stringCompression.test.ts +39 -0
- package/test/transforms/string/stringConcealing.test.ts +82 -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/identifiers.test.ts +113 -1
- package/test/util/insert.test.ts +57 -3
- 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/eval.ts +0 -89
- package/src/transforms/hideInitializingCode.ts +0 -432
- package/src/transforms/identifier/nameRecycling.ts +0 -280
- 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/eval.test.ts +0 -131
- package/test/transforms/hideInitializingCode.test.ts +0 -336
- package/test/transforms/identifier/nameRecycling.test.ts +0 -205
- package/test/transforms/preparation/nameConflicts.test.ts +0 -52
- package/test/transforms/preparation/preparation.test.ts +0 -62
|
@@ -15,92 +15,30 @@ var _gen = require("../../util/gen");
|
|
|
15
15
|
|
|
16
16
|
var _insert = require("../../util/insert");
|
|
17
17
|
|
|
18
|
-
var _identifiers = require("../../util/identifiers");
|
|
19
|
-
|
|
20
18
|
var _random = require("../../util/random");
|
|
21
19
|
|
|
22
20
|
var _constants = require("../../constants");
|
|
23
21
|
|
|
24
22
|
var _probability = require("../../probability");
|
|
25
23
|
|
|
24
|
+
var _globalAnalysis = _interopRequireDefault(require("./globalAnalysis"));
|
|
25
|
+
|
|
26
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
27
27
|
|
|
28
28
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
29
29
|
|
|
30
|
-
class GlobalAnalysis extends _transform.default {
|
|
31
|
-
constructor(o) {
|
|
32
|
-
super(o);
|
|
33
|
-
|
|
34
|
-
_defineProperty(this, "notGlobals", void 0);
|
|
35
|
-
|
|
36
|
-
_defineProperty(this, "globals", void 0);
|
|
37
|
-
|
|
38
|
-
this.globals = Object.create(null);
|
|
39
|
-
this.notGlobals = new Set();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
match(object, parents) {
|
|
43
|
-
return object.type == "Identifier" && !_constants.reservedKeywords.has(object.name);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
transform(object, parents) {
|
|
47
|
-
// no touching `import()` or `import x from ...`
|
|
48
|
-
var importIndex = parents.findIndex(x => x.type == "ImportExpression" || x.type == "ImportDeclaration");
|
|
49
|
-
|
|
50
|
-
if (importIndex !== -1) {
|
|
51
|
-
if (parents[importIndex].source === (parents[importIndex - 1] || object)) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
57
|
-
|
|
58
|
-
if (!info.spec.isReferenced) {
|
|
59
|
-
return;
|
|
60
|
-
} // Add to globals
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (!this.notGlobals.has(object.name)) {
|
|
64
|
-
if (!this.globals[object.name]) {
|
|
65
|
-
this.globals[object.name] = [];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
this.globals[object.name].push([object, parents]);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (info.spec.isDefined || info.spec.isModified) {
|
|
72
|
-
delete this.globals[object.name];
|
|
73
|
-
this.notGlobals.add(object.name);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
var assignmentIndex = parents.findIndex(x => x.type == "AssignmentExpression");
|
|
77
|
-
var updateIndex = parents.findIndex(x => x.type == "UpdateExpression");
|
|
78
|
-
|
|
79
|
-
if (assignmentIndex != -1 && parents[assignmentIndex].left === (parents[assignmentIndex - 1] || object) || updateIndex != -1) {
|
|
80
|
-
var memberIndex = parents.findIndex(x => x.type == "MemberExpression");
|
|
81
|
-
|
|
82
|
-
if (memberIndex == -1 || memberIndex > (assignmentIndex == -1 ? assignmentIndex : updateIndex)) {
|
|
83
|
-
delete this.globals[object.name];
|
|
84
|
-
this.notGlobals.add(object.name);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
}
|
|
90
30
|
/**
|
|
91
31
|
* Global Concealing hides global variables being accessed.
|
|
92
32
|
*
|
|
93
33
|
* - Any variable that is not defined is considered "global"
|
|
94
34
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
35
|
class GlobalConcealing extends _transform.default {
|
|
98
36
|
constructor(o) {
|
|
99
37
|
super(o, _order.ObfuscateOrder.GlobalConcealing);
|
|
100
38
|
|
|
101
39
|
_defineProperty(this, "globalAnalysis", void 0);
|
|
102
40
|
|
|
103
|
-
this.globalAnalysis = new
|
|
41
|
+
this.globalAnalysis = new _globalAnalysis.default(o);
|
|
104
42
|
this.before.push(this.globalAnalysis);
|
|
105
43
|
}
|
|
106
44
|
|
|
@@ -126,10 +64,10 @@ class GlobalConcealing extends _transform.default {
|
|
|
126
64
|
} else if (!(0, _probability.ComputeProbabilityMap)(this.options.globalConcealing, x => x, x)) {
|
|
127
65
|
delete globals[x];
|
|
128
66
|
}
|
|
129
|
-
});
|
|
67
|
+
});
|
|
130
68
|
|
|
131
69
|
if (Object.keys(globals).length > 0) {
|
|
132
|
-
var used = new Set(); //
|
|
70
|
+
var used = new Set(); // Make getter function
|
|
133
71
|
// holds "window" or "global"
|
|
134
72
|
|
|
135
73
|
var globalVar = this.getPlaceholder(); // holds outermost "this"
|
|
@@ -137,10 +75,11 @@ class GlobalConcealing extends _transform.default {
|
|
|
137
75
|
var thisVar = this.getPlaceholder(); // "window" or "global" in node
|
|
138
76
|
|
|
139
77
|
var global = this.options.globalVariables.values().next().value || "window";
|
|
78
|
+
var alternateGlobal = global === "window" ? "global" : "window";
|
|
140
79
|
var getGlobalVariableFnName = this.getPlaceholder();
|
|
141
80
|
var getThisVariableFnName = this.getPlaceholder(); // Returns global variable or fall backs to `this`
|
|
142
81
|
|
|
143
|
-
var getGlobalVariableFn = (0, _template.default)("\n var ".concat(getGlobalVariableFnName, " = function(){\n try {\n return ").concat(global, ";\n } catch (e){\n return ").concat(getThisVariableFnName, "[\"call\"](this);\n }\n }")).single();
|
|
82
|
+
var getGlobalVariableFn = (0, _template.default)("\n var ".concat(getGlobalVariableFnName, " = function(){\n try {\n return ").concat(global, " || ").concat(alternateGlobal, " || (new Function(\"return this\"))();\n } catch (e){\n return ").concat(getThisVariableFnName, "[\"call\"](this);\n }\n }")).single();
|
|
144
83
|
var getThisVariableFn = (0, _template.default)("\n var ".concat(getThisVariableFnName, " = function(){\n try {\n return this;\n } catch (e){\n return null;\n }\n }")).single(); // 2. Replace old accessors
|
|
145
84
|
|
|
146
85
|
var globalFn = this.getPlaceholder();
|
|
@@ -157,19 +96,7 @@ class GlobalConcealing extends _transform.default {
|
|
|
157
96
|
newNames[name] = state;
|
|
158
97
|
locations.forEach(_ref => {
|
|
159
98
|
let [node, parents] = _ref;
|
|
160
|
-
|
|
161
|
-
if (!parents.find(x => x.$dispatcherSkip)) {
|
|
162
|
-
// Do not replace
|
|
163
|
-
if (parents[0]) {
|
|
164
|
-
if (parents[0].type == "ClassDeclaration" || parents[0].type == "ClassExpression" || parents[0].type == "FunctionExpression" || parents[0].type == "FunctionDeclaration") {
|
|
165
|
-
if (parents[0].id === node) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
this.replace(node, (0, _gen.CallExpression)((0, _gen.Identifier)(globalFn), [(0, _gen.Literal)(state)]));
|
|
172
|
-
}
|
|
99
|
+
this.replace(node, (0, _gen.CallExpression)((0, _gen.Identifier)(globalFn), [(0, _gen.Literal)(state)]));
|
|
173
100
|
});
|
|
174
101
|
}); // Adds all global variables to the switch statement
|
|
175
102
|
|
|
@@ -178,7 +105,7 @@ class GlobalConcealing extends _transform.default {
|
|
|
178
105
|
var state;
|
|
179
106
|
|
|
180
107
|
do {
|
|
181
|
-
state = (0, _random.getRandomInteger)(
|
|
108
|
+
state = (0, _random.getRandomInteger)(0, 1000 + used.size + this.options.globalVariables.size * 100);
|
|
182
109
|
} while (used.has(state));
|
|
183
110
|
|
|
184
111
|
used.add(state);
|
|
@@ -191,7 +118,7 @@ class GlobalConcealing extends _transform.default {
|
|
|
191
118
|
var code = newNames[name];
|
|
192
119
|
var body = [(0, _gen.ReturnStatement)((0, _gen.LogicalExpression)("||", (0, _gen.MemberExpression)((0, _gen.Identifier)(globalVar), (0, _gen.Literal)(name), true), (0, _gen.MemberExpression)((0, _gen.Identifier)(thisVar), (0, _gen.Literal)(name), true)))];
|
|
193
120
|
|
|
194
|
-
if (
|
|
121
|
+
if ((0, _random.chance)(50)) {
|
|
195
122
|
body = [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(returnName), (0, _gen.LogicalExpression)("||", (0, _gen.Literal)(name), (0, _gen.MemberExpression)((0, _gen.Identifier)(thisVar), (0, _gen.Literal)(name), true)))), (0, _gen.BreakStatement)()];
|
|
196
123
|
}
|
|
197
124
|
|
|
@@ -17,10 +17,6 @@ var _assert = require("assert");
|
|
|
17
17
|
|
|
18
18
|
var _order = require("../../order");
|
|
19
19
|
|
|
20
|
-
var _identifiers = require("../../util/identifiers");
|
|
21
|
-
|
|
22
|
-
var _scope = require("../../util/scope");
|
|
23
|
-
|
|
24
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
21
|
|
|
26
22
|
/**
|
|
@@ -32,100 +28,51 @@ class MovedDeclarations extends _transform.default {
|
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
match(object, parents) {
|
|
35
|
-
return
|
|
31
|
+
return object.type === "VariableDeclaration" && object.kind === "var" && object.declarations.length === 1 && object.declarations[0].id.type === "Identifier";
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
transform(object, parents) {
|
|
39
35
|
return () => {
|
|
40
|
-
var
|
|
41
|
-
(0, _assert.ok)(Array.isArray(body));
|
|
42
|
-
var illegal = new Set();
|
|
43
|
-
var defined = new Set();
|
|
44
|
-
var variableDeclarations = Object.create(null);
|
|
45
|
-
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
46
|
-
if (o.type == "Identifier") {
|
|
47
|
-
if (o.hidden || (0, _scope.getLexicalScope)(o, p) !== object) {
|
|
48
|
-
illegal.add(o.name);
|
|
49
|
-
} else {
|
|
50
|
-
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
51
|
-
|
|
52
|
-
if (!info.spec.isReferenced) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (info.spec.isDefined) {
|
|
57
|
-
if (info.isFunctionDeclaration || info.isClassDeclaration) {
|
|
58
|
-
illegal.add(o.name);
|
|
59
|
-
} else {
|
|
60
|
-
if (defined.has(o.name)) {
|
|
61
|
-
illegal.add(o.name);
|
|
62
|
-
} else {
|
|
63
|
-
defined.add(o.name);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
36
|
+
var forInitializeType = (0, _insert.isForInitialize)(object, parents); // Get the block statement or Program node
|
|
69
37
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (variableDeclarations[name] || o.kind !== "var") {
|
|
76
|
-
illegal.add(name);
|
|
77
|
-
return;
|
|
78
|
-
} // Check if already at top
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (body[0] === o) {
|
|
82
|
-
illegal.add(name);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
var replace = (0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(name), o.declarations[0].init || (0, _gen.Identifier)("undefined"));
|
|
87
|
-
var forType = (0, _insert.isForInitialize)(o, p);
|
|
88
|
-
|
|
89
|
-
if (forType === "left-hand") {
|
|
90
|
-
replace = (0, _gen.Identifier)(name);
|
|
91
|
-
} else if (!forType) {
|
|
92
|
-
replace = (0, _gen.ExpressionStatement)(replace);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
variableDeclarations[name] = {
|
|
96
|
-
location: [o, p],
|
|
97
|
-
replace: replace
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
illegal.forEach(name => {
|
|
104
|
-
delete variableDeclarations[name];
|
|
105
|
-
});
|
|
106
|
-
var movingNames = Object.keys(variableDeclarations);
|
|
107
|
-
|
|
108
|
-
if (movingNames.length === 0) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
38
|
+
var blockIndex = parents.findIndex(x => (0, _traverse.isBlock)(x));
|
|
39
|
+
var block = parents[blockIndex];
|
|
40
|
+
var body = block.body;
|
|
41
|
+
var bodyObject = parents[blockIndex - 2] || object; // Make sure in the block statement, and not already at the top of it
|
|
111
42
|
|
|
112
|
-
var
|
|
113
|
-
|
|
114
|
-
|
|
43
|
+
var index = body.indexOf(bodyObject);
|
|
44
|
+
if (index === -1 || index === 0) return;
|
|
45
|
+
var topVariableDeclaration;
|
|
115
46
|
|
|
116
|
-
if (
|
|
117
|
-
|
|
47
|
+
if (body[0].type === "VariableDeclaration" && body[0].kind === "var") {
|
|
48
|
+
topVariableDeclaration = body[0];
|
|
118
49
|
} else {
|
|
119
|
-
|
|
50
|
+
topVariableDeclaration = {
|
|
51
|
+
type: "VariableDeclaration",
|
|
52
|
+
declarations: [],
|
|
53
|
+
kind: "var"
|
|
54
|
+
};
|
|
55
|
+
(0, _insert.prepend)(block, topVariableDeclaration);
|
|
120
56
|
}
|
|
121
57
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
58
|
+
var varName = object.declarations[0].id.name;
|
|
59
|
+
(0, _assert.ok)(typeof varName === "string"); // Add `var x` at the top of the block
|
|
60
|
+
|
|
61
|
+
topVariableDeclaration.declarations.push((0, _gen.VariableDeclarator)((0, _gen.Identifier)(varName)));
|
|
62
|
+
var assignmentExpression = (0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(varName), object.declarations[0].init || (0, _gen.Identifier)(varName));
|
|
63
|
+
|
|
64
|
+
if (forInitializeType) {
|
|
65
|
+
if (forInitializeType === "initializer") {
|
|
66
|
+
// Replace `for (var i = 0...)` to `for (i = 0...)`
|
|
67
|
+
this.replace(object, assignmentExpression);
|
|
68
|
+
} else if (forInitializeType === "left-hand") {
|
|
69
|
+
// Replace `for (var k in...)` to `for (k in ...)`
|
|
70
|
+
this.replace(object, (0, _gen.Identifier)(varName));
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
// Replace `var x = value` to `x = value`
|
|
74
|
+
this.replace(object, (0, _gen.ExpressionStatement)(assignmentExpression));
|
|
75
|
+
}
|
|
129
76
|
};
|
|
130
77
|
}
|
|
131
78
|
|
|
@@ -30,52 +30,58 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
30
30
|
/**
|
|
31
31
|
* Rename variables to randomly generated names.
|
|
32
32
|
*
|
|
33
|
-
* -
|
|
33
|
+
* - 1. First collect data on identifiers in all scope using 'VariableAnalysis'
|
|
34
|
+
* - 2. After 'VariableAnalysis' is finished start applying to each scope (top-down)
|
|
35
|
+
* - 3. Each scope, find the all names used here and exclude those names from being re-named
|
|
36
|
+
* - 4. Now loop through all the defined names in this scope and set it to a random name (or re-use previously generated name)
|
|
37
|
+
* - 5. Update all the Identifiers node's 'name' property to reflect this change
|
|
34
38
|
*/
|
|
35
39
|
class RenameVariables extends _transform.default {
|
|
36
|
-
// Generator object
|
|
37
40
|
// Names already used
|
|
38
41
|
// Map of Context->Object of changes
|
|
39
42
|
// Ref to VariableAnalysis data
|
|
43
|
+
// Option to re-use previously generated names
|
|
40
44
|
constructor(o) {
|
|
41
45
|
super(o, _order.ObfuscateOrder.RenameVariables);
|
|
42
46
|
|
|
43
|
-
_defineProperty(this, "gen", void 0);
|
|
44
|
-
|
|
45
47
|
_defineProperty(this, "generated", void 0);
|
|
46
48
|
|
|
47
49
|
_defineProperty(this, "changed", void 0);
|
|
48
50
|
|
|
49
51
|
_defineProperty(this, "variableAnalysis", void 0);
|
|
50
52
|
|
|
51
|
-
this
|
|
53
|
+
_defineProperty(this, "reusePreviousNames", true);
|
|
54
|
+
|
|
55
|
+
this.changed = new Map(); // 1.
|
|
56
|
+
|
|
52
57
|
this.variableAnalysis = new _variableAnalysis.default(o);
|
|
53
58
|
this.before.push(this.variableAnalysis);
|
|
54
|
-
this.gen = this.getGenerator();
|
|
55
59
|
this.generated = [];
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
match(object, parents) {
|
|
59
|
-
return (0, _insert.isContext)(object);
|
|
63
|
+
return (0, _insert.isContext)(object) || object.type === "Identifier";
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
|
|
66
|
+
transformContext(object, parents) {
|
|
67
|
+
// 2. Notice this is on 'onEnter' (top-down)
|
|
63
68
|
var isGlobal = object.type == "Program";
|
|
64
69
|
var type = isGlobal ? "root" : (0, _insert.isVarContext)(object) ? "var" : (0, _insert.isLexContext)(object) ? "lex" : undefined;
|
|
65
70
|
(0, _assert.ok)(type);
|
|
66
71
|
var newNames = Object.create(null);
|
|
67
72
|
var defined = this.variableAnalysis.defined.get(object) || new Set();
|
|
68
|
-
var references = this.variableAnalysis.references.get(object) || new Set();
|
|
73
|
+
var references = this.variableAnalysis.references.get(object) || new Set(); // No changes needed here
|
|
69
74
|
|
|
70
75
|
if (!defined && !this.changed.has(object)) {
|
|
71
76
|
this.changed.set(object, Object.create(null));
|
|
72
77
|
return;
|
|
73
|
-
}
|
|
78
|
+
} // Names possible to be re-used here
|
|
79
|
+
|
|
74
80
|
|
|
75
|
-
var possible = new Set();
|
|
81
|
+
var possible = new Set(); // 3. Try to re-use names when possible
|
|
76
82
|
|
|
77
|
-
if (this.generated.length && !isGlobal) {
|
|
78
|
-
var allReferences = new Set(
|
|
83
|
+
if (this.reusePreviousNames && this.generated.length && !isGlobal) {
|
|
84
|
+
var allReferences = new Set();
|
|
79
85
|
var nope = new Set(defined);
|
|
80
86
|
(0, _traverse.walk)(object, [], (o, p) => {
|
|
81
87
|
var ref = this.variableAnalysis.references.get(o);
|
|
@@ -98,7 +104,7 @@ class RenameVariables extends _transform.default {
|
|
|
98
104
|
Object.keys(changes).forEach(x => {
|
|
99
105
|
var name = changes[x];
|
|
100
106
|
|
|
101
|
-
if (!allReferences.has(x)) {
|
|
107
|
+
if (!allReferences.has(x) && !references.has(x)) {
|
|
102
108
|
passed.add(name);
|
|
103
109
|
} else {
|
|
104
110
|
nope.add(name);
|
|
@@ -108,80 +114,139 @@ class RenameVariables extends _transform.default {
|
|
|
108
114
|
});
|
|
109
115
|
nope.forEach(x => passed.delete(x));
|
|
110
116
|
possible = passed;
|
|
111
|
-
}
|
|
117
|
+
} // 4. Defined names to new names
|
|
112
118
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
119
|
+
|
|
120
|
+
for (var name of defined) {
|
|
121
|
+
if (!name.startsWith(_constants.noRenameVariablePrefix) && ( // Variables prefixed with '__NO_JS_CONFUSER_RENAME__' are never renamed
|
|
122
|
+
isGlobal && !name.startsWith(_constants.placeholderVariablePrefix) // Variables prefixed with '__p_' are created by the obfuscator, always renamed
|
|
123
|
+
? (0, _probability.ComputeProbabilityMap)(this.options.renameGlobals, x => x, name) : true) && (0, _probability.ComputeProbabilityMap)( // Check the user's option for renaming variables
|
|
124
|
+
this.options.renameVariables, x => x, name, isGlobal)) {
|
|
125
|
+
// Create a new name from (1) or (2) methods
|
|
116
126
|
var newName;
|
|
117
127
|
|
|
118
128
|
do {
|
|
119
129
|
if (possible.size) {
|
|
130
|
+
// (1) Re-use previously generated name
|
|
120
131
|
var first = possible.values().next().value;
|
|
121
132
|
possible.delete(first);
|
|
122
133
|
newName = first;
|
|
123
134
|
} else {
|
|
124
|
-
//
|
|
125
|
-
var
|
|
126
|
-
newName =
|
|
127
|
-
this.generated.push(
|
|
135
|
+
// (2) Create a new name with `generateIdentifier` function
|
|
136
|
+
var generatedName = this.generateIdentifier();
|
|
137
|
+
newName = generatedName;
|
|
138
|
+
this.generated.push(generatedName);
|
|
128
139
|
}
|
|
129
|
-
} while (this.variableAnalysis.globals.has(newName));
|
|
140
|
+
} while (this.variableAnalysis.globals.has(newName)); // Ensure global names aren't overridden
|
|
141
|
+
|
|
130
142
|
|
|
131
143
|
newNames[name] = newName;
|
|
132
144
|
} else {
|
|
145
|
+
// This variable name was deemed not to be renamed.
|
|
133
146
|
newNames[name] = name;
|
|
134
147
|
}
|
|
135
|
-
});
|
|
148
|
+
} // console.log(object.type, newNames);
|
|
149
|
+
|
|
150
|
+
|
|
136
151
|
this.changed.set(object, newNames);
|
|
137
|
-
|
|
138
|
-
if (o.type == "Identifier") {
|
|
139
|
-
if (_constants.reservedIdentifiers.has(o.name) || this.options.globalVariables.has(o.name)) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
152
|
+
}
|
|
142
153
|
|
|
143
|
-
|
|
154
|
+
transformIdentifier(object, parents) {
|
|
155
|
+
const identifierName = object.name;
|
|
144
156
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
157
|
+
if (_constants.reservedIdentifiers.has(identifierName) || this.options.globalVariables.has(identifierName)) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
148
160
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
161
|
+
if (object.$renamed) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
152
164
|
|
|
153
|
-
|
|
154
|
-
var newName = null;
|
|
165
|
+
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
155
166
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
167
|
+
if (info.spec.isExported) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!info.spec.isReferenced) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
164
174
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return;
|
|
168
|
-
} // Strange behavior where the `local` and `imported` objects are the same
|
|
175
|
+
var contexts = [object, ...parents].filter(x => (0, _insert.isContext)(x));
|
|
176
|
+
var newName = null; // Function default parameter check!
|
|
169
177
|
|
|
178
|
+
var functionIndices = [];
|
|
170
179
|
|
|
171
|
-
|
|
172
|
-
|
|
180
|
+
for (var i in parents) {
|
|
181
|
+
if ((0, _insert.isFunction)(parents[i])) {
|
|
182
|
+
functionIndices.push(i);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
173
185
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
186
|
+
for (var functionIndex of functionIndices) {
|
|
187
|
+
if (parents[functionIndex].id === object) {
|
|
188
|
+
// This context is not referenced, so remove it
|
|
189
|
+
contexts = contexts.filter(context => context != parents[functionIndex]);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (parents[functionIndex].params === parents[functionIndex - 1]) {
|
|
194
|
+
var isReferencedHere = true;
|
|
195
|
+
var slicedParents = parents.slice(0, functionIndex);
|
|
196
|
+
var forIndex = 0;
|
|
197
|
+
|
|
198
|
+
for (var parent of slicedParents) {
|
|
199
|
+
var childNode = slicedParents[forIndex - 1] || object;
|
|
178
200
|
|
|
201
|
+
if (parent.type === "AssignmentPattern" && parent.right === childNode) {
|
|
202
|
+
isReferencedHere = false;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
forIndex++;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!isReferencedHere) {
|
|
210
|
+
// This context is not referenced, so remove it
|
|
211
|
+
contexts = contexts.filter(context => context != parents[functionIndex]);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
179
215
|
|
|
180
|
-
|
|
181
|
-
|
|
216
|
+
for (var check of contexts) {
|
|
217
|
+
if (this.variableAnalysis.defined.has(check) && this.variableAnalysis.defined.get(check).has(identifierName)) {
|
|
218
|
+
if (this.changed.has(check) && this.changed.get(check)[identifierName]) {
|
|
219
|
+
newName = this.changed.get(check)[identifierName];
|
|
220
|
+
break;
|
|
182
221
|
}
|
|
183
222
|
}
|
|
184
|
-
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (newName && typeof newName === "string") {
|
|
226
|
+
// Strange behavior where the `local` and `imported` objects are the same
|
|
227
|
+
if (info.isImportSpecifier) {
|
|
228
|
+
var importSpecifierIndex = parents.findIndex(x => x.type === "ImportSpecifier");
|
|
229
|
+
|
|
230
|
+
if (importSpecifierIndex != -1 && parents[importSpecifierIndex].imported === (parents[importSpecifierIndex - 1] || object) && parents[importSpecifierIndex].imported && parents[importSpecifierIndex].imported.type === "Identifier") {
|
|
231
|
+
parents[importSpecifierIndex].imported = (0, _insert.clone)(parents[importSpecifierIndex - 1] || object);
|
|
232
|
+
}
|
|
233
|
+
} // console.log(o.name, "->", newName);
|
|
234
|
+
// 5. Update Identifier node's 'name' property
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
object.name = newName;
|
|
238
|
+
object.$renamed = true;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
transform(object, parents) {
|
|
243
|
+
var matchType = object.type === "Identifier" ? "Identifier" : "Context";
|
|
244
|
+
|
|
245
|
+
if (matchType === "Identifier") {
|
|
246
|
+
this.transformIdentifier(object, parents);
|
|
247
|
+
} else {
|
|
248
|
+
this.transformContext(object, parents);
|
|
249
|
+
}
|
|
185
250
|
}
|
|
186
251
|
|
|
187
252
|
}
|