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.
Files changed (139) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +69 -0
  3. package/README.md +143 -7
  4. package/dist/index.js +33 -4
  5. package/dist/obfuscator.js +30 -31
  6. package/dist/options.js +4 -5
  7. package/dist/order.js +4 -6
  8. package/dist/probability.js +2 -4
  9. package/dist/templates/bufferToString.js +13 -0
  10. package/dist/templates/crash.js +2 -2
  11. package/dist/templates/es5.js +18 -0
  12. package/dist/transforms/antiTooling.js +1 -1
  13. package/dist/transforms/calculator.js +77 -21
  14. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  15. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
  16. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  17. package/dist/transforms/deadCode.js +33 -25
  18. package/dist/transforms/dispatcher.js +7 -6
  19. package/dist/transforms/es5/antiClass.js +6 -2
  20. package/dist/transforms/es5/antiDestructuring.js +3 -1
  21. package/dist/transforms/es5/es5.js +31 -34
  22. package/dist/transforms/eval.js +11 -0
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
  24. package/dist/transforms/extraction/objectExtraction.js +6 -1
  25. package/dist/transforms/finalizer.js +82 -0
  26. package/dist/transforms/flatten.js +82 -55
  27. package/dist/transforms/hexadecimalNumbers.js +34 -9
  28. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  29. package/dist/transforms/identifier/globalConcealing.js +10 -83
  30. package/dist/transforms/identifier/movedDeclarations.js +2 -8
  31. package/dist/transforms/identifier/renameVariables.js +39 -27
  32. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  33. package/dist/transforms/minify.js +80 -61
  34. package/dist/transforms/opaquePredicates.js +1 -1
  35. package/dist/transforms/preparation/preparation.js +2 -2
  36. package/dist/transforms/preparation.js +231 -0
  37. package/dist/transforms/renameLabels.js +1 -1
  38. package/dist/transforms/rgf.js +4 -5
  39. package/dist/transforms/stack.js +87 -26
  40. package/dist/transforms/string/encoding.js +150 -179
  41. package/dist/transforms/string/stringCompression.js +14 -15
  42. package/dist/transforms/string/stringConcealing.js +25 -8
  43. package/dist/transforms/string/stringEncoding.js +13 -24
  44. package/dist/transforms/transform.js +11 -18
  45. package/dist/traverse.js +24 -18
  46. package/dist/util/compare.js +2 -2
  47. package/dist/util/gen.js +15 -0
  48. package/dist/util/insert.js +31 -7
  49. package/dist/util/random.js +15 -0
  50. package/package.json +5 -5
  51. package/src/index.ts +57 -19
  52. package/src/obfuscator.ts +26 -29
  53. package/src/options.ts +17 -21
  54. package/src/order.ts +4 -8
  55. package/src/probability.ts +2 -3
  56. package/src/templates/bufferToString.ts +68 -0
  57. package/src/templates/crash.ts +5 -9
  58. package/src/templates/es5.ts +131 -0
  59. package/src/transforms/antiTooling.ts +1 -1
  60. package/src/transforms/calculator.ts +122 -59
  61. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  62. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
  63. package/src/transforms/deadCode.ts +383 -26
  64. package/src/transforms/dispatcher.ts +8 -6
  65. package/src/transforms/es5/antiClass.ts +10 -1
  66. package/src/transforms/es5/antiDestructuring.ts +3 -1
  67. package/src/transforms/es5/es5.ts +32 -77
  68. package/src/transforms/eval.ts +18 -0
  69. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
  70. package/src/transforms/extraction/objectExtraction.ts +12 -5
  71. package/src/transforms/finalizer.ts +75 -0
  72. package/src/transforms/flatten.ts +194 -151
  73. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  74. package/src/transforms/identifier/globalConcealing.ts +14 -103
  75. package/src/transforms/identifier/movedDeclarations.ts +4 -11
  76. package/src/transforms/identifier/renameVariables.ts +37 -30
  77. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  78. package/src/transforms/minify.ts +116 -77
  79. package/src/transforms/opaquePredicates.ts +2 -2
  80. package/src/transforms/preparation.ts +238 -0
  81. package/src/transforms/renameLabels.ts +2 -2
  82. package/src/transforms/rgf.ts +6 -7
  83. package/src/transforms/stack.ts +97 -37
  84. package/src/transforms/string/encoding.ts +115 -212
  85. package/src/transforms/string/stringCompression.ts +27 -18
  86. package/src/transforms/string/stringConcealing.ts +41 -11
  87. package/src/transforms/string/stringEncoding.ts +18 -18
  88. package/src/transforms/transform.ts +15 -21
  89. package/src/traverse.ts +24 -12
  90. package/src/types.ts +11 -2
  91. package/src/util/compare.ts +2 -2
  92. package/src/util/gen.ts +21 -1
  93. package/src/util/insert.ts +49 -9
  94. package/src/util/random.ts +13 -0
  95. package/test/code/Cash.test.ts +1 -1
  96. package/test/code/Dynamic.test.ts +12 -10
  97. package/test/code/ES6.src.js +136 -0
  98. package/test/code/ES6.test.ts +28 -2
  99. package/test/code/NewFeatures.test.ts +19 -0
  100. package/test/index.test.ts +15 -2
  101. package/test/probability.test.ts +44 -0
  102. package/test/templates/template.test.ts +1 -1
  103. package/test/transforms/antiTooling.test.ts +52 -0
  104. package/test/transforms/calculator.test.ts +40 -0
  105. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
  106. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  107. package/test/transforms/deadCode.test.ts +66 -15
  108. package/test/transforms/dispatcher.test.ts +44 -1
  109. package/test/transforms/es5/antiClass.test.ts +33 -0
  110. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  111. package/test/transforms/eval.test.ts +53 -0
  112. package/test/transforms/extraction/objectExtraction.test.ts +21 -0
  113. package/test/transforms/flatten.test.ts +195 -3
  114. package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
  115. package/test/transforms/identifier/renameVariables.test.ts +108 -0
  116. package/test/transforms/lock/antiDebug.test.ts +2 -2
  117. package/test/transforms/minify.test.ts +151 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +56 -29
  120. package/test/transforms/stack.test.ts +91 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +115 -0
  123. package/test/transforms/string/stringEncoding.test.ts +53 -2
  124. package/test/transforms/transform.test.ts +66 -0
  125. package/test/traverse.test.ts +139 -0
  126. package/test/util/compare.test.ts +23 -1
  127. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  128. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  129. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  130. package/src/transforms/hexadecimalNumbers.ts +0 -31
  131. package/src/transforms/hideInitializingCode.ts +0 -432
  132. package/src/transforms/label.ts +0 -64
  133. package/src/transforms/preparation/nameConflicts.ts +0 -102
  134. package/src/transforms/preparation/preparation.ts +0 -176
  135. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  136. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  137. package/test/transforms/hideInitializingCode.test.ts +0 -336
  138. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  139. 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, "flatMapName", void 0);
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.flatMapName = null;
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.async && !object.params.find(x => x.type !== "Identifier");
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
- if (parents.find(x => x.type == "ClassExpression" || x.type == "ClassDeclaration" || x.type == "MethodDefinition")) {
92
- return;
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.gen.generate();
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
- if (o.type == "ReturnStatement" && (0, _insert.getVarContext)(o, p) === object) {
197
- var elements = output.map(_gen.Identifier);
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
- elements.unshift((0, _insert.clone)(o.argument));
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.ArrayExpression)(elements);
204
- o.argument = (0, _gen.AssignmentExpression)("=", (0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(propName), false), o.argument);
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 (!this.flatMapName) {
212
- this.flatMapName = this.getPlaceholder();
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)(valName)], newBody);
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
- var property = (0, _gen.Property)((0, _gen.Identifier)(newName), newFunctionExpression, false);
220
- property.kind = "set";
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 call = (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(resultName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)("_", (0, _gen.AssignmentExpression)("=", identifier, (0, _gen.ArrayExpression)([(0, _gen.ArrayExpression)(input.map(_gen.Identifier)), (0, _gen.ArrayExpression)([...newParamNodes]), (0, _gen.Identifier)(resultName)])))]); // result.pop()
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 newObjectBody = [call];
235
- var outputReversed = [...output].reverse(); // DECOY STATEMENTS
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 = [(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(this.gen.generate()), false), [(0, _gen.ThrowStatement)((0, _gen.NewExpression)((0, _gen.Identifier)("Error"), [(0, _gen.Literal)(this.getPlaceholder())]))]), (0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(this.gen.generate()), false), [(0, _gen.ReturnStatement)((0, _gen.Identifier)(resultName))]), (0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(this.gen.generate()), false), [(0, _gen.ReturnStatement)((0, _gen.Identifier)(resultName))]), (0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(decoyKey), false), [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(decoyKey), false))]), (0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(this.gen.generate()), false), [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(this.gen.generate()), false))])];
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
- decoyNodes.forEach(decoyNode => {
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 = newParamNodes;
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
- match(object, parents) {
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
- return () => {
27
- // Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
28
- // This code handles it regardless
29
- var isNegative = object.value < 0;
30
- var hex = Math.abs(object.value).toString(16);
31
- var newStr = (isNegative ? "-" : "") + "0x" + hex;
32
- this.replace(object, (0, _gen.Identifier)(newStr));
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 GlobalAnalysis(o);
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
- }); // this.log(Object.keys(globals).join(', '))
67
+ });
130
68
 
131
69
  if (Object.keys(globals).length > 0) {
132
- var used = new Set(); // 1. Make getter function
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)(-1000, 1000 + used.size + this.options.globalVariables.size * 100);
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 (Math.random() > 0.5 && name) {
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,