js-confuser 1.7.1 → 1.7.3

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 (153) hide show
  1. package/.github/workflows/node.js.yml +1 -1
  2. package/CHANGELOG.md +73 -0
  3. package/README.md +32 -31
  4. package/dist/compiler.js +2 -8
  5. package/dist/constants.js +22 -10
  6. package/dist/index.js +15 -30
  7. package/dist/obfuscator.js +15 -62
  8. package/dist/options.js +33 -40
  9. package/dist/order.js +4 -7
  10. package/dist/parser.js +5 -13
  11. package/dist/precedence.js +6 -8
  12. package/dist/presets.js +4 -6
  13. package/dist/probability.js +13 -24
  14. package/dist/templates/bufferToString.js +121 -5
  15. package/dist/templates/core.js +35 -0
  16. package/dist/templates/crash.js +22 -11
  17. package/dist/templates/es5.js +125 -6
  18. package/dist/templates/functionLength.js +24 -6
  19. package/dist/templates/globals.js +9 -0
  20. package/dist/templates/template.js +189 -43
  21. package/dist/transforms/antiTooling.js +26 -22
  22. package/dist/transforms/calculator.js +19 -55
  23. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +242 -333
  24. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
  25. package/dist/transforms/deadCode.js +542 -31
  26. package/dist/transforms/dispatcher.js +112 -112
  27. package/dist/transforms/es5/antiClass.js +70 -44
  28. package/dist/transforms/es5/antiDestructuring.js +14 -38
  29. package/dist/transforms/es5/antiES6Object.js +39 -48
  30. package/dist/transforms/es5/antiSpreadOperator.js +5 -14
  31. package/dist/transforms/es5/antiTemplate.js +10 -19
  32. package/dist/transforms/es5/es5.js +7 -40
  33. package/dist/transforms/extraction/classExtraction.js +83 -0
  34. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +41 -80
  35. package/dist/transforms/extraction/objectExtraction.js +24 -56
  36. package/dist/transforms/finalizer.js +6 -20
  37. package/dist/transforms/flatten.js +51 -99
  38. package/dist/transforms/identifier/globalAnalysis.js +21 -26
  39. package/dist/transforms/identifier/globalConcealing.js +72 -56
  40. package/dist/transforms/identifier/movedDeclarations.js +66 -38
  41. package/dist/transforms/identifier/renameVariables.js +36 -68
  42. package/dist/transforms/identifier/variableAnalysis.js +21 -48
  43. package/dist/transforms/lock/antiDebug.js +20 -25
  44. package/dist/transforms/lock/integrity.js +53 -52
  45. package/dist/transforms/lock/lock.js +161 -126
  46. package/dist/transforms/minify.js +77 -108
  47. package/dist/transforms/opaquePredicates.js +12 -49
  48. package/dist/transforms/preparation.js +28 -49
  49. package/dist/transforms/renameLabels.js +5 -22
  50. package/dist/transforms/rgf.js +125 -72
  51. package/dist/transforms/shuffle.js +42 -47
  52. package/dist/transforms/stack.js +41 -98
  53. package/dist/transforms/string/encoding.js +76 -27
  54. package/dist/transforms/string/stringCompression.js +75 -68
  55. package/dist/transforms/string/stringConcealing.js +127 -135
  56. package/dist/transforms/string/stringEncoding.js +6 -26
  57. package/dist/transforms/string/stringSplitting.js +5 -30
  58. package/dist/transforms/transform.js +76 -104
  59. package/dist/traverse.js +11 -18
  60. package/dist/util/compare.js +27 -29
  61. package/dist/util/gen.js +32 -86
  62. package/dist/util/guard.js +5 -1
  63. package/dist/util/identifiers.js +9 -72
  64. package/dist/util/insert.js +27 -77
  65. package/dist/util/math.js +0 -3
  66. package/dist/util/object.js +3 -7
  67. package/dist/util/random.js +31 -36
  68. package/dist/util/scope.js +6 -3
  69. package/docs/Countermeasures.md +13 -6
  70. package/docs/Integrity.md +35 -28
  71. package/docs/RGF.md +6 -1
  72. package/docs/RenameVariables.md +116 -0
  73. package/docs/TamperProtection.md +100 -0
  74. package/docs/Template.md +117 -0
  75. package/package.json +3 -3
  76. package/src/constants.ts +17 -0
  77. package/src/index.ts +7 -5
  78. package/src/options.ts +60 -7
  79. package/src/order.ts +2 -2
  80. package/src/templates/bufferToString.ts +79 -11
  81. package/src/templates/core.ts +29 -0
  82. package/src/templates/crash.ts +6 -38
  83. package/src/templates/es5.ts +1 -1
  84. package/src/templates/functionLength.ts +21 -3
  85. package/src/templates/globals.ts +3 -0
  86. package/src/templates/template.ts +205 -46
  87. package/src/transforms/antiTooling.ts +33 -11
  88. package/src/transforms/calculator.ts +4 -2
  89. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +12 -5
  90. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
  91. package/src/transforms/deadCode.ts +74 -42
  92. package/src/transforms/dispatcher.ts +99 -73
  93. package/src/transforms/es5/antiClass.ts +25 -12
  94. package/src/transforms/es5/antiDestructuring.ts +1 -1
  95. package/src/transforms/es5/antiES6Object.ts +2 -2
  96. package/src/transforms/es5/antiTemplate.ts +1 -1
  97. package/src/transforms/extraction/classExtraction.ts +168 -0
  98. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +11 -16
  99. package/src/transforms/extraction/objectExtraction.ts +4 -15
  100. package/src/transforms/flatten.ts +20 -5
  101. package/src/transforms/identifier/globalAnalysis.ts +18 -1
  102. package/src/transforms/identifier/globalConcealing.ts +119 -72
  103. package/src/transforms/identifier/movedDeclarations.ts +90 -24
  104. package/src/transforms/identifier/renameVariables.ts +16 -1
  105. package/src/transforms/lock/antiDebug.ts +2 -2
  106. package/src/transforms/lock/integrity.ts +13 -11
  107. package/src/transforms/lock/lock.ts +122 -30
  108. package/src/transforms/minify.ts +28 -13
  109. package/src/transforms/opaquePredicates.ts +2 -2
  110. package/src/transforms/preparation.ts +16 -0
  111. package/src/transforms/rgf.ts +139 -12
  112. package/src/transforms/shuffle.ts +3 -3
  113. package/src/transforms/stack.ts +19 -4
  114. package/src/transforms/string/encoding.ts +88 -51
  115. package/src/transforms/string/stringCompression.ts +86 -17
  116. package/src/transforms/string/stringConcealing.ts +148 -118
  117. package/src/transforms/string/stringEncoding.ts +1 -2
  118. package/src/transforms/string/stringSplitting.ts +1 -2
  119. package/src/transforms/transform.ts +63 -46
  120. package/src/types.ts +2 -0
  121. package/src/util/compare.ts +39 -5
  122. package/src/util/gen.ts +10 -3
  123. package/src/util/guard.ts +10 -0
  124. package/src/util/insert.ts +17 -0
  125. package/src/util/random.ts +81 -1
  126. package/src/util/scope.ts +14 -2
  127. package/test/code/Cash.test.ts +94 -5
  128. package/test/code/StrictMode.src.js +65 -0
  129. package/test/code/StrictMode.test.js +37 -0
  130. package/test/compare.test.ts +62 -2
  131. package/test/options.test.ts +129 -55
  132. package/test/templates/template.test.ts +211 -1
  133. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
  134. package/test/transforms/dispatcher.test.ts +55 -0
  135. package/test/transforms/extraction/classExtraction.test.ts +86 -0
  136. package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +8 -0
  137. package/test/transforms/extraction/objectExtraction.test.ts +2 -0
  138. package/test/transforms/identifier/globalConcealing.test.ts +89 -0
  139. package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
  140. package/test/transforms/identifier/renameVariables.test.ts +75 -1
  141. package/test/transforms/lock/tamperProtection.test.ts +336 -0
  142. package/test/transforms/minify.test.ts +37 -0
  143. package/test/transforms/rgf.test.ts +50 -0
  144. package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
  145. package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
  146. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
  147. package/dist/transforms/eval.js +0 -84
  148. package/dist/transforms/hexadecimalNumbers.js +0 -63
  149. package/dist/transforms/hideInitializingCode.js +0 -270
  150. package/dist/transforms/identifier/nameRecycling.js +0 -218
  151. package/dist/transforms/label.js +0 -67
  152. package/dist/transforms/preparation/nameConflicts.js +0 -116
  153. package/dist/transforms/preparation/preparation.js +0 -188
@@ -4,29 +4,20 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _template = _interopRequireDefault(require("../../templates/template"));
9
-
10
8
  var _transform = _interopRequireDefault(require("../transform"));
11
-
12
9
  var _order = require("../../order");
13
-
14
10
  var _gen = require("../../util/gen");
15
-
16
11
  var _insert = require("../../util/insert");
17
-
18
12
  var _random = require("../../util/random");
19
-
20
13
  var _constants = require("../../constants");
21
-
22
14
  var _probability = require("../../probability");
23
-
24
15
  var _globalAnalysis = _interopRequireDefault(require("./globalAnalysis"));
25
-
26
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
-
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
-
16
+ var _bufferToString = require("../../templates/bufferToString");
17
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
19
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
20
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
30
21
  /**
31
22
  * Global Concealing hides global variables being accessed.
32
23
  *
@@ -35,29 +26,26 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
35
26
  class GlobalConcealing extends _transform.default {
36
27
  constructor(o) {
37
28
  super(o, _order.ObfuscateOrder.GlobalConcealing);
38
-
39
29
  _defineProperty(this, "globalAnalysis", void 0);
40
-
30
+ _defineProperty(this, "ignoreGlobals", new Set(["require", "__dirname", "eval", _constants.variableFunctionName]));
41
31
  this.globalAnalysis = new _globalAnalysis.default(o);
42
32
  this.before.push(this.globalAnalysis);
43
33
  }
44
-
45
34
  match(object, parents) {
46
35
  return object.type == "Program";
47
36
  }
48
-
49
37
  transform(object, parents) {
50
38
  return () => {
51
39
  var globals = this.globalAnalysis.globals;
52
40
  this.globalAnalysis.notGlobals.forEach(del => {
53
41
  delete globals[del];
54
42
  });
55
- delete globals["require"];
56
-
43
+ for (var varName of this.ignoreGlobals) {
44
+ delete globals[varName];
45
+ }
57
46
  _constants.reservedIdentifiers.forEach(x => {
58
47
  delete globals[x];
59
48
  });
60
-
61
49
  Object.keys(globals).forEach(x => {
62
50
  if (this.globalAnalysis.globals[x].length < 1) {
63
51
  delete globals[x];
@@ -65,50 +53,80 @@ class GlobalConcealing extends _transform.default {
65
53
  delete globals[x];
66
54
  }
67
55
  });
68
-
69
56
  if (Object.keys(globals).length > 0) {
70
- var used = new Set(); // Make getter function
71
- // holds "window" or "global"
57
+ var usedStates = new Set();
72
58
 
73
- var globalVar = this.getPlaceholder(); // holds outermost "this"
59
+ // Make getter function
74
60
 
75
- var thisVar = this.getPlaceholder(); // "window" or "global" in node
76
-
77
- var global = this.options.globalVariables.values().next().value || "window";
78
- var alternateGlobal = global === "window" ? "global" : "window";
79
- var getGlobalVariableFnName = this.getPlaceholder();
80
- var getThisVariableFnName = this.getPlaceholder(); // Returns global variable or fall backs to `this`
61
+ // holds "window" or "global"
62
+ var globalVar = this.getPlaceholder();
63
+ var getGlobalVariableFnName = this.getPlaceholder() + _constants.predictableFunctionTag;
81
64
 
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();
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
65
+ // Returns global variable or fall backs to `this`
66
+ var getGlobalVariableFn = (0, _bufferToString.createGetGlobalTemplate)(this, object, parents).compile({
67
+ getGlobalFnName: getGlobalVariableFnName
68
+ });
84
69
 
85
- var globalFn = this.getPlaceholder();
70
+ // 2. Replace old accessors
71
+ var globalFn = this.getPlaceholder() + _constants.predictableFunctionTag;
86
72
  var newNames = Object.create(null);
87
73
  Object.keys(globals).forEach(name => {
88
74
  var locations = globals[name];
89
75
  var state;
90
-
91
76
  do {
92
- state = (0, _random.getRandomInteger)(-1000, 1000 + used.size);
93
- } while (used.has(state));
94
-
95
- used.add(state);
77
+ state = (0, _random.getRandomInteger)(-1000, 1000 + usedStates.size);
78
+ } while (usedStates.has(state));
79
+ usedStates.add(state);
96
80
  newNames[name] = state;
97
81
  locations.forEach(_ref => {
98
- let [node, parents] = _ref;
99
- this.replace(node, (0, _gen.CallExpression)((0, _gen.Identifier)(globalFn), [(0, _gen.Literal)(state)]));
82
+ var _this$options$lock;
83
+ let [node, p] = _ref;
84
+ if (p.find(x => x.$multiTransformSkip)) {
85
+ return;
86
+ }
87
+ var newExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(globalFn), [(0, _gen.Literal)(state)]);
88
+ this.replace(node, newExpression);
89
+ if ((_this$options$lock = this.options.lock) !== null && _this$options$lock !== void 0 && _this$options$lock.tamperProtection && this.lockTransform.nativeFunctionName) {
90
+ var isMemberExpression = false;
91
+ var nameAndPropertyPath = [name];
92
+ var callExpression;
93
+ var index = 0;
94
+ do {
95
+ if (p[index].type === "CallExpression") {
96
+ callExpression = p[index];
97
+ break;
98
+ }
99
+ var memberExpression = p[index];
100
+ if (memberExpression.type !== "MemberExpression") return;
101
+ var property = memberExpression.property;
102
+ var stringValue = property.type === "Literal" ? property.value : memberExpression.computed ? null : property.type === "Identifier" ? property.name : null;
103
+ if (!stringValue) return;
104
+ isMemberExpression = true;
105
+ nameAndPropertyPath.push(stringValue);
106
+ index++;
107
+ } while (index < p.length);
108
+ if (!this.lockTransform.shouldTransformNativeFunction(nameAndPropertyPath)) return;
109
+ if (callExpression && callExpression.type === "CallExpression") {
110
+ if (isMemberExpression) {
111
+ callExpression.callee = (0, _gen.CallExpression)((0, _gen.Identifier)(this.lockTransform.nativeFunctionName), [callExpression.callee.object, callExpression.callee.computed ? callExpression.callee.property : (0, _gen.Literal)(callExpression.callee.property.name || callExpression.callee.property.value)]);
112
+ } else {
113
+ callExpression.callee = (0, _gen.CallExpression)((0, _gen.Identifier)(this.lockTransform.nativeFunctionName), [{
114
+ ...callExpression.callee
115
+ }]);
116
+ }
117
+ }
118
+ }
100
119
  });
101
- }); // Adds all global variables to the switch statement
120
+ });
102
121
 
122
+ // Adds all global variables to the switch statement
103
123
  this.options.globalVariables.forEach(name => {
104
124
  if (!newNames[name]) {
105
125
  var state;
106
-
107
126
  do {
108
- state = (0, _random.getRandomInteger)(0, 1000 + used.size + this.options.globalVariables.size * 100);
109
- } while (used.has(state));
110
-
111
- used.add(state);
127
+ state = (0, _random.getRandomInteger)(0, 1000 + usedStates.size + this.options.globalVariables.size * 100);
128
+ } while (usedStates.has(state));
129
+ usedStates.add(state);
112
130
  newNames[name] = state;
113
131
  }
114
132
  });
@@ -116,23 +134,21 @@ class GlobalConcealing extends _transform.default {
116
134
  var returnName = this.getPlaceholder();
117
135
  var functionDeclaration = (0, _gen.FunctionDeclaration)(globalFn, [(0, _gen.Identifier)(indexParamName)], [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(returnName)), (0, _gen.SwitchStatement)((0, _gen.Identifier)(indexParamName), Object.keys(newNames).map(name => {
118
136
  var code = newNames[name];
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)))];
120
-
137
+ var body = [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(globalVar), (0, _gen.Literal)(name), true))];
121
138
  if ((0, _random.chance)(50)) {
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)()];
139
+ body = [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(returnName), (0, _gen.LogicalExpression)("||", (0, _gen.Literal)(name), (0, _gen.MemberExpression)((0, _gen.Identifier)(globalVar), (0, _gen.Literal)(name), true)))), (0, _gen.BreakStatement)()];
123
140
  }
124
-
125
141
  return (0, _gen.SwitchCase)((0, _gen.Literal)(code), body);
126
- })), (0, _gen.ReturnStatement)((0, _gen.LogicalExpression)("||", (0, _gen.MemberExpression)((0, _gen.Identifier)(globalVar), (0, _gen.Identifier)(returnName), true), (0, _gen.MemberExpression)((0, _gen.Identifier)(thisVar), (0, _gen.Identifier)(returnName), true)))]);
142
+ })), (0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(globalVar), (0, _gen.Identifier)(returnName), true))]);
127
143
  var tempVar = this.getPlaceholder();
128
- var variableDeclaration = (0, _template.default)("\n var ".concat(globalVar, ", ").concat(thisVar, ";\n ")).single();
129
- variableDeclaration.declarations.push((0, _gen.VariableDeclarator)(tempVar, (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.FunctionExpression)([], [getGlobalVariableFn, getThisVariableFn, (0, _template.default)("return ".concat(thisVar, " = ").concat(getThisVariableFnName, "[\"call\"](this, ").concat(globalFn, "), ").concat(globalVar, " = ").concat(getGlobalVariableFnName, "[\"call\"](this)")).single()]), (0, _gen.Literal)("call"), true), [])));
144
+ var variableDeclaration = new _template.default(`
145
+ var ${globalVar};
146
+ `).single();
147
+ variableDeclaration.declarations.push((0, _gen.VariableDeclarator)(tempVar, (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.FunctionExpression)([], [...getGlobalVariableFn, new _template.default(`return ${globalVar} = ${getGlobalVariableFnName}["call"](this)`).single()]), (0, _gen.Literal)("call"), true), [])));
130
148
  (0, _insert.prepend)(object, variableDeclaration);
131
149
  (0, _insert.append)(object, functionDeclaration);
132
150
  }
133
151
  };
134
152
  }
135
-
136
153
  }
137
-
138
154
  exports.default = GlobalConcealing;
@@ -4,21 +4,16 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _transform = _interopRequireDefault(require("../transform"));
9
-
10
- var _traverse = require("../../traverse");
11
-
12
8
  var _gen = require("../../util/gen");
13
-
14
9
  var _insert = require("../../util/insert");
15
-
16
10
  var _assert = require("assert");
17
-
18
11
  var _order = require("../../order");
19
-
20
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
-
12
+ var _constants = require("../../constants");
13
+ var _compare = require("../../util/compare");
14
+ var _identifiers = require("../../util/identifiers");
15
+ var _scope = require("../../util/scope");
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
22
17
  /**
23
18
  * Defines all the names at the top of every lexical block.
24
19
  */
@@ -26,56 +21,89 @@ class MovedDeclarations extends _transform.default {
26
21
  constructor(o) {
27
22
  super(o, _order.ObfuscateOrder.MovedDeclarations);
28
23
  }
29
-
30
24
  match(object, parents) {
31
25
  return object.type === "VariableDeclaration" && object.kind === "var" && object.declarations.length === 1 && object.declarations[0].id.type === "Identifier";
32
26
  }
33
-
34
27
  transform(object, parents) {
35
28
  return () => {
36
- var forInitializeType = (0, _insert.isForInitialize)(object, parents); // Get the block statement or Program node
29
+ var _parents, _parents2;
30
+ var forInitializeType = (0, _insert.isForInitialize)(object, parents);
37
31
 
38
- var blockIndex = parents.findIndex(x => (0, _traverse.isBlock)(x));
32
+ // Get the block statement or Program node
33
+ var blockIndex = parents.findIndex(x => (0, _scope.isLexicalScope)(x));
39
34
  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
42
-
35
+ var body = block.type === "SwitchCase" ? block.consequent : block.body;
36
+ (0, _assert.ok)(Array.isArray(body), "No body array found.");
37
+ var bodyObject = parents[blockIndex - 2] || object;
43
38
  var index = body.indexOf(bodyObject);
44
- if (index === -1 || index === 0) return;
45
- var topVariableDeclaration;
46
-
47
- if (body[0].type === "VariableDeclaration" && body[0].kind === "var") {
48
- topVariableDeclaration = body[0];
49
- } else {
50
- topVariableDeclaration = {
51
- type: "VariableDeclaration",
52
- declarations: [],
53
- kind: "var"
54
- };
55
- (0, _insert.prepend)(block, topVariableDeclaration);
56
- }
57
-
58
39
  var varName = object.declarations[0].id.name;
59
- (0, _assert.ok)(typeof varName === "string"); // Add `var x` at the top of the block
40
+ (0, _assert.ok)(typeof varName === "string");
41
+ var predictableFunctionIndex = parents.findIndex(x => (0, _insert.isFunction)(x));
42
+ var predictableFunction = parents[predictableFunctionIndex];
43
+ var deleteStatement = false;
44
+ if (predictableFunction && (predictableFunction.id && predictableFunction.id.name.includes(_constants.predictableFunctionTag) || predictableFunction[_constants.predictableFunctionTag]) &&
45
+ // Must have predictableFunctionTag in the name, or on object
46
+ predictableFunction[_constants.predictableFunctionTag] !== false &&
47
+ // If === false, the function is deemed not predictable
48
+ predictableFunction.params.length < 1000 &&
49
+ // Max 1,000 parameters
50
+ !predictableFunction.params.find(x => x.type === "RestElement") &&
51
+ // Cannot add parameters after spread operator
52
+ !(["Property", "MethodDefinition"].includes((_parents = parents[predictableFunctionIndex + 1]) === null || _parents === void 0 ? void 0 : _parents.type) && ((_parents2 = parents[predictableFunctionIndex + 1]) === null || _parents2 === void 0 ? void 0 : _parents2.kind) !== "init") &&
53
+ // Preserve getter/setter methods
54
+ !(0, _identifiers.getFunctionParameters)(predictableFunction, parents.slice(predictableFunctionIndex)).find(entry => entry[0].name === varName) // Ensure not duplicate param name
55
+ ) {
56
+ // Use function f(..., x, y, z) to declare name
57
+
58
+ var value = object.declarations[0].init;
59
+ var isPredictablyComputed = predictableFunction.body === block && !(0, _insert.isStrictModeFunction)(predictableFunction) && value && (0, _compare.isIndependent)(value, []) && (0, _compare.isMoveable)(value, [object.declarations[0], object, ...parents]);
60
+ var defineWithValue = isPredictablyComputed;
61
+ if (defineWithValue) {
62
+ predictableFunction.params.push((0, _gen.AssignmentPattern)((0, _gen.Identifier)(varName), value));
63
+ object.declarations[0].init = null;
64
+ deleteStatement = true;
65
+ } else {
66
+ predictableFunction.params.push((0, _gen.Identifier)(varName));
67
+ }
68
+ } else {
69
+ // Use 'var x, y, z' to declare name
70
+
71
+ // Make sure in the block statement, and not already at the top of it
72
+ if (index === -1 || index === 0) return;
73
+ var topVariableDeclaration;
74
+ if (body[0].type === "VariableDeclaration" && body[0].kind === "var") {
75
+ topVariableDeclaration = body[0];
76
+ } else {
77
+ topVariableDeclaration = {
78
+ type: "VariableDeclaration",
79
+ declarations: [],
80
+ kind: "var"
81
+ };
82
+ (0, _insert.prepend)(block, topVariableDeclaration);
83
+ }
60
84
 
61
- topVariableDeclaration.declarations.push((0, _gen.VariableDeclarator)((0, _gen.Identifier)(varName)));
85
+ // Add `var x` at the top of the block
86
+ topVariableDeclaration.declarations.push((0, _gen.VariableDeclarator)((0, _gen.Identifier)(varName)));
87
+ }
62
88
  var assignmentExpression = (0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(varName), object.declarations[0].init || (0, _gen.Identifier)(varName));
63
-
64
89
  if (forInitializeType) {
65
90
  if (forInitializeType === "initializer") {
66
91
  // Replace `for (var i = 0...)` to `for (i = 0...)`
67
92
  this.replace(object, assignmentExpression);
68
93
  } else if (forInitializeType === "left-hand") {
69
94
  // Replace `for (var k in...)` to `for (k in ...)`
95
+
70
96
  this.replace(object, (0, _gen.Identifier)(varName));
71
97
  }
72
98
  } else {
73
- // Replace `var x = value` to `x = value`
74
- this.replace(object, (0, _gen.ExpressionStatement)(assignmentExpression));
99
+ if (deleteStatement && index !== -1) {
100
+ body.splice(index, 1);
101
+ } else {
102
+ // Replace `var x = value` to `x = value`
103
+ this.replace(object, (0, _gen.ExpressionStatement)(assignmentExpression));
104
+ }
75
105
  }
76
106
  };
77
107
  }
78
-
79
108
  }
80
-
81
109
  exports.default = MovedDeclarations;
@@ -4,29 +4,20 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _assert = require("assert");
9
-
10
8
  var _order = require("../../order");
11
-
12
9
  var _traverse = require("../../traverse");
13
-
10
+ var _gen = require("../../util/gen");
14
11
  var _identifiers = require("../../util/identifiers");
15
-
16
12
  var _insert = require("../../util/insert");
17
-
18
13
  var _transform = _interopRequireDefault(require("../transform"));
19
-
20
14
  var _constants = require("../../constants");
21
-
22
15
  var _probability = require("../../probability");
23
-
24
16
  var _variableAnalysis = _interopRequireDefault(require("./variableAnalysis"));
25
-
26
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
-
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
-
17
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
19
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
20
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
30
21
  /**
31
22
  * Rename variables to randomly generated names.
32
23
  *
@@ -37,32 +28,26 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
37
28
  * - 5. Update all the Identifiers node's 'name' property to reflect this change
38
29
  */
39
30
  class RenameVariables extends _transform.default {
40
- // Names already used
41
- // Map of Context->Object of changes
42
- // Ref to VariableAnalysis data
43
- // Option to re-use previously generated names
44
31
  constructor(o) {
45
32
  super(o, _order.ObfuscateOrder.RenameVariables);
46
-
33
+ // Names already used
47
34
  _defineProperty(this, "generated", void 0);
48
-
35
+ // Map of Context->Object of changes
49
36
  _defineProperty(this, "changed", void 0);
50
-
37
+ // Ref to VariableAnalysis data
51
38
  _defineProperty(this, "variableAnalysis", void 0);
52
-
39
+ // Option to re-use previously generated names
53
40
  _defineProperty(this, "reusePreviousNames", true);
41
+ this.changed = new Map();
54
42
 
55
- this.changed = new Map(); // 1.
56
-
43
+ // 1.
57
44
  this.variableAnalysis = new _variableAnalysis.default(o);
58
45
  this.before.push(this.variableAnalysis);
59
46
  this.generated = [];
60
47
  }
61
-
62
48
  match(object, parents) {
63
49
  return (0, _insert.isContext)(object) || object.type === "Identifier";
64
50
  }
65
-
66
51
  transformContext(object, parents) {
67
52
  // 2. Notice this is on 'onEnter' (top-down)
68
53
  var isGlobal = object.type == "Program";
@@ -70,28 +55,27 @@ class RenameVariables extends _transform.default {
70
55
  (0, _assert.ok)(type);
71
56
  var newNames = Object.create(null);
72
57
  var defined = this.variableAnalysis.defined.get(object) || new Set();
73
- var references = this.variableAnalysis.references.get(object) || new Set(); // No changes needed here
58
+ var references = this.variableAnalysis.references.get(object) || new Set();
74
59
 
60
+ // No changes needed here
75
61
  if (!defined && !this.changed.has(object)) {
76
62
  this.changed.set(object, Object.create(null));
77
63
  return;
78
- } // Names possible to be re-used here
79
-
64
+ }
80
65
 
81
- var possible = new Set(); // 3. Try to re-use names when possible
66
+ // Names possible to be re-used here
67
+ var possible = new Set();
82
68
 
69
+ // 3. Try to re-use names when possible
83
70
  if (this.reusePreviousNames && this.generated.length && !isGlobal) {
84
71
  var allReferences = new Set();
85
72
  var nope = new Set(defined);
86
73
  (0, _traverse.walk)(object, [], (o, p) => {
87
74
  var ref = this.variableAnalysis.references.get(o);
88
-
89
75
  if (ref) {
90
76
  ref.forEach(x => allReferences.add(x));
91
77
  }
92
-
93
78
  var def = this.variableAnalysis.defined.get(o);
94
-
95
79
  if (def) {
96
80
  def.forEach(x => allReferences.add(x));
97
81
  }
@@ -99,11 +83,9 @@ class RenameVariables extends _transform.default {
99
83
  var passed = new Set();
100
84
  parents.forEach(p => {
101
85
  var changes = this.changed.get(p);
102
-
103
86
  if (changes) {
104
87
  Object.keys(changes).forEach(x => {
105
88
  var name = changes[x];
106
-
107
89
  if (!allReferences.has(x) && !references.has(x)) {
108
90
  passed.add(name);
109
91
  } else {
@@ -114,17 +96,18 @@ class RenameVariables extends _transform.default {
114
96
  });
115
97
  nope.forEach(x => passed.delete(x));
116
98
  possible = passed;
117
- } // 4. Defined names to new names
118
-
99
+ }
119
100
 
101
+ // 4. Defined names to new names
120
102
  for (var name of defined) {
121
- if (!name.startsWith(_constants.noRenameVariablePrefix) && ( // Variables prefixed with '__NO_JS_CONFUSER_RENAME__' are never renamed
103
+ if (!name.startsWith(_constants.noRenameVariablePrefix) && (
104
+ // Variables prefixed with '__NO_JS_CONFUSER_RENAME__' are never renamed
122
105
  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
106
+ ? (0, _probability.ComputeProbabilityMap)(this.options.renameGlobals, x => x, name) : true) && (0, _probability.ComputeProbabilityMap)(
107
+ // Check the user's option for renaming variables
124
108
  this.options.renameVariables, x => x, name, isGlobal)) {
125
109
  // Create a new name from (1) or (2) methods
126
110
  var newName;
127
-
128
111
  do {
129
112
  if (possible.size) {
130
113
  // (1) Re-use previously generated name
@@ -139,80 +122,65 @@ class RenameVariables extends _transform.default {
139
122
  }
140
123
  } while (this.variableAnalysis.globals.has(newName)); // Ensure global names aren't overridden
141
124
 
142
-
143
125
  newNames[name] = newName;
144
126
  } else {
145
127
  // This variable name was deemed not to be renamed.
146
128
  newNames[name] = name;
147
129
  }
148
- } // console.log(object.type, newNames);
149
-
130
+ }
150
131
 
132
+ // console.log(object.type, newNames);
151
133
  this.changed.set(object, newNames);
152
134
  }
153
-
154
135
  transformIdentifier(object, parents) {
155
136
  const identifierName = object.name;
156
-
157
137
  if (_constants.reservedIdentifiers.has(identifierName) || this.options.globalVariables.has(identifierName)) {
158
138
  return;
159
139
  }
160
-
161
140
  if (object.$renamed) {
162
141
  return;
163
142
  }
164
-
165
143
  var info = (0, _identifiers.getIdentifierInfo)(object, parents);
166
-
167
144
  if (info.spec.isExported) {
168
145
  return;
169
146
  }
170
-
171
147
  if (!info.spec.isReferenced) {
172
148
  return;
173
149
  }
174
-
175
150
  var contexts = [object, ...parents].filter(x => (0, _insert.isContext)(x));
176
- var newName = null; // Function default parameter check!
151
+ var newName = null;
177
152
 
153
+ // Function default parameter check!
178
154
  var functionIndices = [];
179
-
180
155
  for (var i in parents) {
181
156
  if ((0, _insert.isFunction)(parents[i])) {
182
157
  functionIndices.push(i);
183
158
  }
184
159
  }
185
-
186
160
  for (var functionIndex of functionIndices) {
187
161
  if (parents[functionIndex].id === object) {
188
162
  // This context is not referenced, so remove it
189
163
  contexts = contexts.filter(context => context != parents[functionIndex]);
190
164
  continue;
191
165
  }
192
-
193
166
  if (parents[functionIndex].params === parents[functionIndex - 1]) {
194
167
  var isReferencedHere = true;
195
168
  var slicedParents = parents.slice(0, functionIndex);
196
169
  var forIndex = 0;
197
-
198
170
  for (var parent of slicedParents) {
199
171
  var childNode = slicedParents[forIndex - 1] || object;
200
-
201
172
  if (parent.type === "AssignmentPattern" && parent.right === childNode) {
202
173
  isReferencedHere = false;
203
174
  break;
204
175
  }
205
-
206
176
  forIndex++;
207
177
  }
208
-
209
178
  if (!isReferencedHere) {
210
179
  // This context is not referenced, so remove it
211
180
  contexts = contexts.filter(context => context != parents[functionIndex]);
212
181
  }
213
182
  }
214
183
  }
215
-
216
184
  for (var check of contexts) {
217
185
  if (this.variableAnalysis.defined.has(check) && this.variableAnalysis.defined.get(check).has(identifierName)) {
218
186
  if (this.changed.has(check) && this.changed.get(check)[identifierName]) {
@@ -221,34 +189,34 @@ class RenameVariables extends _transform.default {
221
189
  }
222
190
  }
223
191
  }
224
-
225
192
  if (newName && typeof newName === "string") {
226
193
  // Strange behavior where the `local` and `imported` objects are the same
227
194
  if (info.isImportSpecifier) {
228
195
  var importSpecifierIndex = parents.findIndex(x => x.type === "ImportSpecifier");
229
-
230
196
  if (importSpecifierIndex != -1 && parents[importSpecifierIndex].imported === (parents[importSpecifierIndex - 1] || object) && parents[importSpecifierIndex].imported && parents[importSpecifierIndex].imported.type === "Identifier") {
231
197
  parents[importSpecifierIndex].imported = (0, _insert.clone)(parents[importSpecifierIndex - 1] || object);
232
198
  }
233
- } // console.log(o.name, "->", newName);
234
- // 5. Update Identifier node's 'name' property
235
-
199
+ }
200
+ if (parents[1] && parents[1].type === "CallExpression" && parents[1].arguments === parents[0]) {
201
+ if (parents[1].callee.type === "Identifier" && parents[1].callee.name === _constants.variableFunctionName) {
202
+ this.replace(parents[1], (0, _gen.Literal)(newName));
203
+ return;
204
+ }
205
+ }
236
206
 
207
+ // console.log(o.name, "->", newName);
208
+ // 5. Update Identifier node's 'name' property
237
209
  object.name = newName;
238
210
  object.$renamed = true;
239
211
  }
240
212
  }
241
-
242
213
  transform(object, parents) {
243
214
  var matchType = object.type === "Identifier" ? "Identifier" : "Context";
244
-
245
215
  if (matchType === "Identifier") {
246
216
  this.transformIdentifier(object, parents);
247
217
  } else {
248
218
  this.transformContext(object, parents);
249
219
  }
250
220
  }
251
-
252
221
  }
253
-
254
222
  exports.default = RenameVariables;