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
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
+
var _assert = require("assert");
|
|
9
|
+
|
|
8
10
|
var _constants = require("../constants");
|
|
9
11
|
|
|
10
12
|
var _order = require("../order");
|
|
@@ -39,6 +41,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
39
41
|
* return [ref1, ref2, refN, returnValue];
|
|
40
42
|
* }
|
|
41
43
|
* ```
|
|
44
|
+
*
|
|
45
|
+
* Flatten is used to make functions eligible for the RGF transformation.
|
|
42
46
|
*/
|
|
43
47
|
class Flatten extends _transform.default {
|
|
44
48
|
constructor(o) {
|
|
@@ -46,15 +50,12 @@ class Flatten extends _transform.default {
|
|
|
46
50
|
|
|
47
51
|
_defineProperty(this, "definedNames", void 0);
|
|
48
52
|
|
|
49
|
-
_defineProperty(this, "
|
|
50
|
-
|
|
51
|
-
_defineProperty(this, "flatNode", void 0);
|
|
53
|
+
_defineProperty(this, "flattenedFns", void 0);
|
|
52
54
|
|
|
53
55
|
_defineProperty(this, "gen", void 0);
|
|
54
56
|
|
|
55
57
|
this.definedNames = new Map();
|
|
56
|
-
this.
|
|
57
|
-
this.flatNode = null;
|
|
58
|
+
this.flattenedFns = [];
|
|
58
59
|
this.gen = this.getGenerator();
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -79,19 +80,43 @@ class Flatten extends _transform.default {
|
|
|
79
80
|
}
|
|
80
81
|
});
|
|
81
82
|
super.apply(tree);
|
|
83
|
+
|
|
84
|
+
if (this.flattenedFns.length) {
|
|
85
|
+
(0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)(this.flattenedFns));
|
|
86
|
+
}
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
match(object, parents) {
|
|
85
|
-
return object.type == "FunctionDeclaration" && object.body.type == "BlockStatement" && !object.generator && !object.
|
|
90
|
+
return (object.type == "FunctionDeclaration" || object.type === "FunctionExpression") && object.body.type == "BlockStatement" && !object.generator && !object.params.find(x => x.type !== "Identifier");
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
transform(object, parents) {
|
|
89
94
|
return () => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
95
|
+
var _object$id, _parents$, _parents$0$id, _parents$0$id2, _parents$2, _parents$3;
|
|
96
|
+
|
|
97
|
+
if (parents[0]) {
|
|
98
|
+
// Don't change class methods
|
|
99
|
+
if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
|
|
100
|
+
return;
|
|
101
|
+
} // Don't change getter/setter methods
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if (parents[0].type === "Property" && parents[0].value === object && parents[0].kind !== "init") {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
(0, _assert.ok)(object.type === "FunctionDeclaration" || object.type === "FunctionExpression"); // The name is purely for debugging purposes
|
|
110
|
+
|
|
111
|
+
var currentFnName = object.type === "FunctionDeclaration" ? (_object$id = object.id) === null || _object$id === void 0 ? void 0 : _object$id.name : ((_parents$ = parents[0]) === null || _parents$ === void 0 ? void 0 : _parents$.type) === "VariableDeclarator" && ((_parents$0$id = parents[0].id) === null || _parents$0$id === void 0 ? void 0 : _parents$0$id.type) === "Identifier" && ((_parents$0$id2 = parents[0].id) === null || _parents$0$id2 === void 0 ? void 0 : _parents$0$id2.name);
|
|
112
|
+
|
|
113
|
+
if (((_parents$2 = parents[0]) === null || _parents$2 === void 0 ? void 0 : _parents$2.type) === "Property" && (_parents$3 = parents[0]) !== null && _parents$3 !== void 0 && _parents$3.key) {
|
|
114
|
+
var _parents$4, _parents$4$key, _parents$5, _parents$5$key;
|
|
115
|
+
|
|
116
|
+
currentFnName = currentFnName || String(((_parents$4 = parents[0]) === null || _parents$4 === void 0 ? void 0 : (_parents$4$key = _parents$4.key) === null || _parents$4$key === void 0 ? void 0 : _parents$4$key.name) || ((_parents$5 = parents[0]) === null || _parents$5 === void 0 ? void 0 : (_parents$5$key = _parents$5.key) === null || _parents$5$key === void 0 ? void 0 : _parents$5$key.value));
|
|
93
117
|
}
|
|
94
118
|
|
|
119
|
+
if (!currentFnName) currentFnName = "unnamed";
|
|
95
120
|
var defined = new Set();
|
|
96
121
|
var references = new Set();
|
|
97
122
|
var modified = new Set();
|
|
@@ -119,9 +144,7 @@ class Flatten extends _transform.default {
|
|
|
119
144
|
|
|
120
145
|
if (o.hidden) {
|
|
121
146
|
illegal.add(o.name);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (info.spec.isDefined) {
|
|
147
|
+
} else if (info.spec.isDefined) {
|
|
125
148
|
defined.add(o.name);
|
|
126
149
|
} else if (info.spec.isModified) {
|
|
127
150
|
modified.add(o.name);
|
|
@@ -171,9 +194,6 @@ class Flatten extends _transform.default {
|
|
|
171
194
|
return;
|
|
172
195
|
}
|
|
173
196
|
|
|
174
|
-
illegal.forEach(name => {
|
|
175
|
-
defined.delete(name);
|
|
176
|
-
});
|
|
177
197
|
defined.forEach(name => {
|
|
178
198
|
references.delete(name);
|
|
179
199
|
modified.delete(name);
|
|
@@ -186,67 +206,74 @@ class Flatten extends _transform.default {
|
|
|
186
206
|
}
|
|
187
207
|
|
|
188
208
|
var output = Array.from(modified);
|
|
189
|
-
var newName = this.
|
|
190
|
-
var valName = this.getPlaceholder();
|
|
209
|
+
var newName = this.getPlaceholder() + "_flat_" + currentFnName;
|
|
191
210
|
var resultName = this.getPlaceholder();
|
|
192
211
|
var propName = this.gen.generate();
|
|
212
|
+
var newOutputNames = Object.create(null);
|
|
213
|
+
output.forEach(name => {
|
|
214
|
+
newOutputNames[name] = this.gen.generate();
|
|
215
|
+
});
|
|
216
|
+
var returnOutputName = this.gen.generate();
|
|
193
217
|
(0, _insert.getBlockBody)(object.body).push((0, _gen.ReturnStatement)());
|
|
194
218
|
(0, _traverse.walk)(object.body, [object, ...parents], (o, p) => {
|
|
195
|
-
return
|
|
196
|
-
|
|
197
|
-
|
|
219
|
+
// Change return statements from
|
|
220
|
+
// return (argument)
|
|
221
|
+
// to
|
|
222
|
+
// return [ [modifiedRefs], ]
|
|
223
|
+
if (o.type == "ReturnStatement" && (0, _insert.getVarContext)(o, p) === object) {
|
|
224
|
+
return () => {
|
|
225
|
+
var returnObject = (0, _gen.ObjectExpression)(output.map(outputName => (0, _gen.Property)((0, _gen.Literal)(newOutputNames[outputName]), (0, _gen.Identifier)(outputName), true)));
|
|
198
226
|
|
|
199
227
|
if (o.argument && !(o.argument.type == "Identifier" && o.argument.name == "undefined")) {
|
|
200
|
-
|
|
228
|
+
// FIX: The return argument must be executed first so it must use 'unshift'
|
|
229
|
+
returnObject.properties.unshift((0, _gen.Property)((0, _gen.Literal)(returnOutputName), (0, _insert.clone)(o.argument), true));
|
|
201
230
|
}
|
|
202
231
|
|
|
203
|
-
o.argument = (0, _gen.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
};
|
|
232
|
+
o.argument = (0, _gen.AssignmentExpression)("=", (0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(propName), false), returnObject);
|
|
233
|
+
};
|
|
234
|
+
}
|
|
207
235
|
});
|
|
208
|
-
var newBody = (0, _insert.getBlockBody)(object.body);
|
|
209
|
-
newBody.unshift((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.ArrayPattern)([(0, _gen.ArrayPattern)(input.map(_gen.Identifier)), (0, _gen.ArrayPattern)((0, _insert.clone)(object.params)), (0, _gen.Identifier)(resultName)]), (0, _gen.Identifier)(valName))));
|
|
236
|
+
var newBody = (0, _insert.getBlockBody)(object.body); // Remove 'use strict' directive
|
|
210
237
|
|
|
211
|
-
if (
|
|
212
|
-
|
|
213
|
-
(0, _insert.prepend)(parents[parents.length - 1], (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.flatMapName, this.flatNode = (0, _gen.ObjectExpression)([]))));
|
|
238
|
+
if (newBody.length > 0 && newBody[0].directive) {
|
|
239
|
+
newBody.shift();
|
|
214
240
|
}
|
|
215
241
|
|
|
216
|
-
var newFunctionExpression = (0, _gen.FunctionExpression)([(0, _gen.Identifier)(
|
|
242
|
+
var newFunctionExpression = (0, _gen.FunctionExpression)([(0, _gen.ArrayPattern)(input.map(name => (0, _gen.Identifier)(name))), (0, _gen.ArrayPattern)((0, _insert.clone)(object.params)), (0, _gen.Identifier)(resultName)], newBody);
|
|
217
243
|
newFunctionExpression.async = !!object.async;
|
|
218
244
|
newFunctionExpression.generator = !!object.generator;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
this.flatNode.properties.push(property);
|
|
222
|
-
var identifier = (0, _gen.MemberExpression)((0, _gen.Identifier)(this.flatMapName), (0, _gen.Identifier)(newName), false);
|
|
223
|
-
var newParamNodes = object.params.map(() => (0, _gen.Identifier)(this.getPlaceholder())); // var result = newFn.call([...refs], ...arguments)
|
|
245
|
+
this.flattenedFns.push((0, _gen.VariableDeclarator)(newName, newFunctionExpression));
|
|
246
|
+
var newParamNames = object.params.map(() => this.getPlaceholder()); // result.pop()
|
|
224
247
|
|
|
225
|
-
var
|
|
248
|
+
var getOutputMemberExpression = outputName => (0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(propName), true), (0, _gen.Literal)(outputName), true); // newFn.call([...refs], ...arguments, resultObject)
|
|
226
249
|
|
|
227
|
-
var pop = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(propName), false), (0, _gen.Literal)("pop"), true), []); // var result = newFn.call([...refs], ...arguments)
|
|
228
|
-
// modified1 = result.pop();
|
|
229
|
-
// modified2 = result.pop();
|
|
230
|
-
// ...modifiedN = result.pop();...
|
|
231
|
-
//
|
|
232
|
-
// return result.pop()
|
|
233
250
|
|
|
234
|
-
var
|
|
235
|
-
var
|
|
251
|
+
var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(newName), [(0, _gen.ArrayExpression)(input.map(name => (0, _gen.Identifier)(name))), (0, _gen.ArrayExpression)(newParamNames.map(name => (0, _gen.Identifier)(name))), (0, _gen.Identifier)(resultName)]);
|
|
252
|
+
var newObjectBody = [// var resultObject = {};
|
|
253
|
+
(0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(resultName, (0, _gen.ObjectExpression)([]))]), (0, _gen.ExpressionStatement)(newFunctionExpression.async ? (0, _gen.AwaitExpression)(callExpression) : callExpression)];
|
|
254
|
+
var outputReversed = [...output].reverse(); // realVar
|
|
255
|
+
|
|
256
|
+
outputReversed.forEach(outputName => {
|
|
257
|
+
newObjectBody.push((0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(outputName), getOutputMemberExpression(newOutputNames[outputName]))));
|
|
258
|
+
}); // DECOY STATEMENTS
|
|
236
259
|
|
|
237
260
|
var decoyKey = this.gen.generate();
|
|
238
|
-
var decoyNodes = [
|
|
261
|
+
var decoyNodes = [// if (result.random) throw result.prop.random
|
|
262
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ThrowStatement)((0, _gen.NewExpression)((0, _gen.Identifier)("Error"), [getOutputMemberExpression(this.gen.generate())]))]), // if (result.random) return true;
|
|
263
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ReturnStatement)((0, _gen.Literal)(true))]), // if (result.random) return result;
|
|
264
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ReturnStatement)((0, _gen.Identifier)(resultName))]), // if (result.random) return result.random;
|
|
265
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(decoyKey), true), [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(decoyKey), true))]), // if(result.random1) return result.random2;
|
|
266
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true))]), // if(result.random) return flatFn;
|
|
267
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ReturnStatement)((0, _gen.Identifier)(newName))]), // if(result.random) flatFn = undefined;
|
|
268
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(newName), (0, _gen.Identifier)("undefined")))]), // if(!result) return;
|
|
269
|
+
(0, _gen.IfStatement)((0, _gen.UnaryExpression)("!", (0, _gen.Identifier)(resultName)), [(0, _gen.ReturnStatement)()])].filter(() => (0, _random.chance)(25)); // if (result.output) return result.output.returnValue;
|
|
270
|
+
// this is the real return statement, it is always added
|
|
271
|
+
|
|
272
|
+
decoyNodes.push((0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(propName), true), [(0, _gen.ReturnStatement)(getOutputMemberExpression(returnOutputName))]));
|
|
239
273
|
(0, _random.shuffle)(decoyNodes);
|
|
240
|
-
|
|
241
|
-
if (Math.random() < 0.5) {
|
|
242
|
-
newObjectBody.push(decoyNode);
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
newObjectBody.push(...outputReversed.map(name => {
|
|
246
|
-
return (0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(name), (0, _insert.clone)(pop)));
|
|
247
|
-
}), (0, _gen.ReturnStatement)((0, _insert.clone)(pop)));
|
|
274
|
+
newObjectBody.push(...decoyNodes);
|
|
248
275
|
object.body = (0, _gen.BlockStatement)(newObjectBody);
|
|
249
|
-
object.params =
|
|
276
|
+
object.params = newParamNames.map(name => (0, _gen.Identifier)(name));
|
|
250
277
|
};
|
|
251
278
|
}
|
|
252
279
|
|
|
@@ -13,24 +13,49 @@ var _gen = require("../util/gen");
|
|
|
13
13
|
|
|
14
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* The HexadecimalNumbers transformation converts number literals into the hexadecimal form.
|
|
18
|
+
*
|
|
19
|
+
* This is done by replacing the number literal with an Identifier to ensure escodegen properly outputs it as such
|
|
20
|
+
*
|
|
21
|
+
* This transformation also handles BigInt support, so its always enabled for this reason.
|
|
22
|
+
*/
|
|
16
23
|
class HexadecimalNumbers extends _transform.default {
|
|
17
24
|
constructor(o) {
|
|
18
25
|
super(o, _order.ObfuscateOrder.HexadecimalNumbers);
|
|
19
26
|
}
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
isNumberLiteral(object) {
|
|
22
29
|
return object.type === "Literal" && typeof object.value === "number" && Math.floor(object.value) === object.value;
|
|
23
30
|
}
|
|
24
31
|
|
|
32
|
+
isBigIntLiteral(object) {
|
|
33
|
+
return object.type === "Literal" && typeof object.value === "bigint";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
match(object, parents) {
|
|
37
|
+
return this.options.hexadecimalNumbers && this.isNumberLiteral(object) || this.isBigIntLiteral(object);
|
|
38
|
+
}
|
|
39
|
+
|
|
25
40
|
transform(object, parents) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
if (this.isNumberLiteral(object)) {
|
|
42
|
+
return () => {
|
|
43
|
+
// Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
|
|
44
|
+
// This code handles it regardless
|
|
45
|
+
var isNegative = object.value < 0;
|
|
46
|
+
var hex = Math.abs(object.value).toString(16);
|
|
47
|
+
var newStr = (isNegative ? "-" : "") + "0x" + hex;
|
|
48
|
+
this.replace(object, (0, _gen.Identifier)(newStr));
|
|
49
|
+
};
|
|
50
|
+
} // https://github.com/MichaelXF/js-confuser/issues/79
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if (this.isBigIntLiteral(object)) {
|
|
54
|
+
return () => {
|
|
55
|
+
// Use an Identifier with the raw string
|
|
56
|
+
this.replace(object, (0, _gen.Identifier)(object.raw));
|
|
57
|
+
};
|
|
58
|
+
}
|
|
34
59
|
}
|
|
35
60
|
|
|
36
61
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _constants = require("../../constants");
|
|
9
|
+
|
|
10
|
+
var _identifiers = require("../../util/identifiers");
|
|
11
|
+
|
|
12
|
+
var _transform = _interopRequireDefault(require("../transform"));
|
|
13
|
+
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
|
|
16
|
+
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; }
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Global Analysis is responsible for finding all the global variables used in the code.
|
|
20
|
+
*
|
|
21
|
+
* A 'global variable' is one that is:
|
|
22
|
+
* - Referenced
|
|
23
|
+
* - Never defined or overridden
|
|
24
|
+
*/
|
|
25
|
+
class GlobalAnalysis extends _transform.default {
|
|
26
|
+
constructor(o) {
|
|
27
|
+
super(o);
|
|
28
|
+
|
|
29
|
+
_defineProperty(this, "notGlobals", void 0);
|
|
30
|
+
|
|
31
|
+
_defineProperty(this, "globals", void 0);
|
|
32
|
+
|
|
33
|
+
this.globals = Object.create(null);
|
|
34
|
+
this.notGlobals = new Set();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
match(object, parents) {
|
|
38
|
+
return object.type == "Identifier" && !_constants.reservedKeywords.has(object.name);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
transform(object, parents) {
|
|
42
|
+
// no touching `import()` or `import x from ...`
|
|
43
|
+
var importIndex = parents.findIndex(x => x.type == "ImportExpression" || x.type == "ImportDeclaration");
|
|
44
|
+
|
|
45
|
+
if (importIndex !== -1) {
|
|
46
|
+
if (parents[importIndex].source === (parents[importIndex - 1] || object)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
52
|
+
|
|
53
|
+
if (!info.spec.isReferenced) {
|
|
54
|
+
return;
|
|
55
|
+
} // Cannot be defined or overridden
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if (info.spec.isDefined || info.spec.isModified) {
|
|
59
|
+
delete this.globals[object.name];
|
|
60
|
+
this.notGlobals.add(object.name);
|
|
61
|
+
return;
|
|
62
|
+
} // Add to globals
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
if (!this.notGlobals.has(object.name)) {
|
|
66
|
+
if (!this.globals[object.name]) {
|
|
67
|
+
this.globals[object.name] = [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.globals[object.name].push([object, parents]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
var assignmentIndex = parents.findIndex(x => x.type == "AssignmentExpression");
|
|
74
|
+
var updateIndex = parents.findIndex(x => x.type == "UpdateExpression");
|
|
75
|
+
|
|
76
|
+
if (assignmentIndex != -1 && parents[assignmentIndex].left === (parents[assignmentIndex - 1] || object) || updateIndex != -1) {
|
|
77
|
+
var memberIndex = parents.findIndex(x => x.type == "MemberExpression");
|
|
78
|
+
|
|
79
|
+
if (memberIndex == -1 || memberIndex > (assignmentIndex == -1 ? assignmentIndex : updateIndex)) {
|
|
80
|
+
delete this.globals[object.name];
|
|
81
|
+
this.notGlobals.add(object.name);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
exports.default = GlobalAnalysis;
|
|
@@ -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
|
|
|
@@ -44,7 +44,7 @@ class MovedDeclarations extends _transform.default {
|
|
|
44
44
|
var variableDeclarations = Object.create(null);
|
|
45
45
|
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
46
46
|
if (o.type == "Identifier") {
|
|
47
|
-
if ((0, _scope.getLexicalScope)(o, p) !== object) {
|
|
47
|
+
if (o.hidden || (0, _scope.getLexicalScope)(o, p) !== object) {
|
|
48
48
|
illegal.add(o.name);
|
|
49
49
|
} else {
|
|
50
50
|
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
@@ -112,13 +112,7 @@ class MovedDeclarations extends _transform.default {
|
|
|
112
112
|
var variableDeclaration = (0, _gen.VariableDeclaration)(movingNames.map(name => {
|
|
113
113
|
return (0, _gen.VariableDeclarator)(name);
|
|
114
114
|
}));
|
|
115
|
-
|
|
116
|
-
if (object.type == "Program") {
|
|
117
|
-
(0, _insert.prepend)(object, variableDeclaration);
|
|
118
|
-
} else {
|
|
119
|
-
body.unshift(variableDeclaration);
|
|
120
|
-
}
|
|
121
|
-
|
|
115
|
+
(0, _insert.prepend)(object, variableDeclaration);
|
|
122
116
|
movingNames.forEach(name => {
|
|
123
117
|
var {
|
|
124
118
|
location,
|