js-confuser 1.5.9 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +55 -0
  3. package/README.md +346 -165
  4. package/dist/constants.js +6 -2
  5. package/dist/index.js +9 -21
  6. package/dist/obfuscator.js +19 -31
  7. package/dist/options.js +5 -5
  8. package/dist/order.js +1 -3
  9. package/dist/presets.js +6 -7
  10. package/dist/probability.js +2 -4
  11. package/dist/templates/bufferToString.js +13 -0
  12. package/dist/templates/crash.js +3 -3
  13. package/dist/templates/es5.js +18 -0
  14. package/dist/templates/functionLength.js +16 -0
  15. package/dist/transforms/calculator.js +77 -21
  16. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  17. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -1
  18. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  19. package/dist/transforms/deadCode.js +33 -25
  20. package/dist/transforms/dispatcher.js +8 -4
  21. package/dist/transforms/es5/antiDestructuring.js +2 -0
  22. package/dist/transforms/es5/es5.js +31 -34
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +92 -58
  24. package/dist/transforms/finalizer.js +82 -0
  25. package/dist/transforms/flatten.js +229 -148
  26. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  27. package/dist/transforms/identifier/globalConcealing.js +10 -83
  28. package/dist/transforms/identifier/movedDeclarations.js +35 -88
  29. package/dist/transforms/identifier/renameVariables.js +124 -59
  30. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  31. package/dist/transforms/lock/lock.js +0 -37
  32. package/dist/transforms/minify.js +60 -57
  33. package/dist/transforms/opaquePredicates.js +1 -1
  34. package/dist/transforms/preparation/preparation.js +2 -2
  35. package/dist/transforms/preparation.js +231 -0
  36. package/dist/transforms/renameLabels.js +1 -1
  37. package/dist/transforms/rgf.js +139 -247
  38. package/dist/transforms/stack.js +128 -26
  39. package/dist/transforms/string/encoding.js +150 -179
  40. package/dist/transforms/string/stringCompression.js +14 -15
  41. package/dist/transforms/string/stringConcealing.js +25 -8
  42. package/dist/transforms/string/stringEncoding.js +13 -24
  43. package/dist/transforms/transform.js +12 -19
  44. package/dist/traverse.js +24 -10
  45. package/dist/util/gen.js +17 -1
  46. package/dist/util/identifiers.js +37 -3
  47. package/dist/util/insert.js +35 -4
  48. package/dist/util/random.js +15 -0
  49. package/docs/ControlFlowFlattening.md +595 -0
  50. package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
  51. package/{Integrity.md → docs/Integrity.md} +2 -2
  52. package/docs/RGF.md +419 -0
  53. package/package.json +5 -5
  54. package/src/constants.ts +3 -0
  55. package/src/index.ts +2 -2
  56. package/src/obfuscator.ts +19 -31
  57. package/src/options.ts +14 -103
  58. package/src/order.ts +1 -5
  59. package/src/presets.ts +6 -7
  60. package/src/probability.ts +2 -3
  61. package/src/templates/bufferToString.ts +68 -0
  62. package/src/templates/crash.ts +15 -19
  63. package/src/templates/es5.ts +131 -0
  64. package/src/templates/functionLength.ts +14 -0
  65. package/src/transforms/calculator.ts +122 -59
  66. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  67. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +4 -1
  68. package/src/transforms/deadCode.ts +383 -26
  69. package/src/transforms/dispatcher.ts +9 -4
  70. package/src/transforms/es5/antiDestructuring.ts +2 -0
  71. package/src/transforms/es5/es5.ts +32 -77
  72. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +133 -129
  73. package/src/transforms/{hexadecimalNumbers.ts → finalizer.ts} +29 -13
  74. package/src/transforms/flatten.ts +357 -300
  75. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  76. package/src/transforms/identifier/globalConcealing.ts +14 -103
  77. package/src/transforms/identifier/movedDeclarations.ts +49 -102
  78. package/src/transforms/identifier/renameVariables.ts +149 -78
  79. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  80. package/src/transforms/lock/lock.ts +1 -42
  81. package/src/transforms/minify.ts +91 -75
  82. package/src/transforms/opaquePredicates.ts +2 -2
  83. package/src/transforms/preparation.ts +238 -0
  84. package/src/transforms/renameLabels.ts +2 -2
  85. package/src/transforms/rgf.ts +213 -405
  86. package/src/transforms/stack.ts +156 -36
  87. package/src/transforms/string/encoding.ts +115 -212
  88. package/src/transforms/string/stringCompression.ts +27 -18
  89. package/src/transforms/string/stringConcealing.ts +39 -9
  90. package/src/transforms/string/stringEncoding.ts +18 -18
  91. package/src/transforms/transform.ts +21 -23
  92. package/src/traverse.ts +23 -4
  93. package/src/types.ts +2 -1
  94. package/src/util/gen.ts +28 -3
  95. package/src/util/identifiers.ts +43 -2
  96. package/src/util/insert.ts +38 -3
  97. package/src/util/random.ts +13 -0
  98. package/test/code/Cash.test.ts +1 -1
  99. package/test/code/Dynamic.test.ts +12 -10
  100. package/test/code/ES6.src.js +146 -0
  101. package/test/code/ES6.test.ts +28 -2
  102. package/test/index.test.ts +2 -1
  103. package/test/probability.test.ts +44 -0
  104. package/test/templates/template.test.ts +1 -1
  105. package/test/transforms/antiTooling.test.ts +22 -0
  106. package/test/transforms/calculator.test.ts +40 -0
  107. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +702 -160
  108. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  109. package/test/transforms/deadCode.test.ts +66 -15
  110. package/test/transforms/dispatcher.test.ts +20 -1
  111. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  112. package/test/transforms/flatten.test.ts +399 -86
  113. package/test/transforms/identifier/movedDeclarations.test.ts +63 -8
  114. package/test/transforms/identifier/renameVariables.test.ts +119 -0
  115. package/test/transforms/lock/antiDebug.test.ts +2 -2
  116. package/test/transforms/lock/lock.test.ts +1 -48
  117. package/test/transforms/minify.test.ts +104 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +261 -381
  120. package/test/transforms/stack.test.ts +143 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +82 -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/identifiers.test.ts +113 -1
  127. package/test/util/insert.test.ts +57 -3
  128. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  129. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  130. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  131. package/src/transforms/eval.ts +0 -89
  132. package/src/transforms/hideInitializingCode.ts +0 -432
  133. package/src/transforms/identifier/nameRecycling.ts +0 -280
  134. package/src/transforms/label.ts +0 -64
  135. package/src/transforms/preparation/nameConflicts.ts +0 -102
  136. package/src/transforms/preparation/preparation.ts +0 -176
  137. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  138. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  139. package/test/transforms/eval.test.ts +0 -131
  140. package/test/transforms/hideInitializingCode.test.ts +0 -336
  141. package/test/transforms/identifier/nameRecycling.test.ts +0 -205
  142. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  143. package/test/transforms/preparation/preparation.test.ts +0 -62
@@ -9,8 +9,6 @@ var _assert = require("assert");
9
9
 
10
10
  var _constants = require("../../constants");
11
11
 
12
- var _traverse = require("../../traverse");
13
-
14
12
  var _compare = require("../../util/compare");
15
13
 
16
14
  var _identifiers = require("../../util/identifiers");
@@ -37,10 +35,12 @@ class VariableAnalysis extends _transform.default {
37
35
 
38
36
  /**
39
37
  * Set of global identifiers to never be redefined
38
+ *
39
+ * - Used to not accidentally block access to a global variable
40
40
  */
41
41
 
42
42
  /**
43
- * Set of identifers that are defined within the program
43
+ * Set of identifiers that are defined within the program
44
44
  */
45
45
  constructor(o) {
46
46
  super(o);
@@ -60,72 +60,68 @@ class VariableAnalysis extends _transform.default {
60
60
  }
61
61
 
62
62
  match(object, parents) {
63
- return (0, _insert.isContext)(object);
63
+ return object.type === "Identifier";
64
64
  }
65
65
 
66
66
  transform(object, parents) {
67
- (0, _traverse.walk)(object, parents, (o, p) => {
68
- if (o.type == "Identifier") {
69
- var name = o.name;
70
- (0, _assert.ok)(typeof name === "string");
71
-
72
- if (!(0, _compare.isValidIdentifier)(name)) {
73
- return;
74
- }
75
-
76
- if (_constants.reservedIdentifiers.has(name)) {
77
- return;
78
- }
79
-
80
- if (this.options.globalVariables.has(name)) {
81
- return;
82
- }
83
-
84
- var info = (0, _identifiers.getIdentifierInfo)(o, p);
85
-
86
- if (!info.spec.isReferenced) {
87
- return;
88
- }
89
-
90
- if (info.spec.isExported) {
91
- return;
67
+ var name = object.name;
68
+ (0, _assert.ok)(typeof name === "string");
69
+
70
+ if (!(0, _compare.isValidIdentifier)(name)) {
71
+ return;
72
+ }
73
+
74
+ if (_constants.reservedIdentifiers.has(name)) {
75
+ return;
76
+ }
77
+
78
+ if (this.options.globalVariables.has(name)) {
79
+ return;
80
+ }
81
+
82
+ var info = (0, _identifiers.getIdentifierInfo)(object, parents);
83
+
84
+ if (!info.spec.isReferenced) {
85
+ return;
86
+ }
87
+
88
+ if (info.spec.isExported) {
89
+ return;
90
+ }
91
+
92
+ var isDefined = info.spec.isDefined; // Keep track of defined names within the program
93
+
94
+ if (isDefined) {
95
+ this.notGlobals.add(object.name);
96
+ this.globals.delete(object.name);
97
+ } else if (!this.notGlobals.has(object.name)) {
98
+ this.globals.add(object.name);
99
+ }
100
+
101
+ var definingContexts = info.spec.isDefined ? (0, _insert.getAllDefiningContexts)(object, parents) : (0, _insert.getReferencingContexts)(object, parents, info);
102
+ (0, _assert.ok)(definingContexts.length);
103
+ definingContexts.forEach(definingContext => {
104
+ // ok(
105
+ // isContext(definingContext),
106
+ // `${definingContext.type} is not a context`
107
+ // );
108
+ if (isDefined) {
109
+ // Add to defined Map
110
+ if (!this.defined.has(definingContext)) {
111
+ this.defined.set(definingContext, new Set());
92
112
  }
93
113
 
94
- var isDefined = info.spec.isDefined; // Keep track of defined names within the program
114
+ this.defined.get(definingContext).add(name);
115
+ this.references.has(definingContext) && this.references.get(definingContext).delete(name);
116
+ } else {
117
+ // Add to references Map
118
+ if (!this.defined.has(definingContext) || !this.defined.get(definingContext).has(name)) {
119
+ if (!this.references.has(definingContext)) {
120
+ this.references.set(definingContext, new Set());
121
+ }
95
122
 
96
- if (isDefined) {
97
- this.notGlobals.add(o.name);
98
- this.globals.delete(o.name);
99
- } else if (!this.notGlobals.has(o.name)) {
100
- this.globals.add(o.name);
123
+ this.references.get(definingContext).add(name);
101
124
  }
102
-
103
- var definingContexts = info.spec.isDefined ? (0, _insert.getAllDefiningContexts)(o, p) : (0, _insert.getReferencingContexts)(o, p, info);
104
- (0, _assert.ok)(definingContexts.length);
105
- definingContexts.forEach(definingContext => {
106
- // ok(
107
- // isContext(definingContext),
108
- // `${definingContext.type} is not a context`
109
- // );
110
- if (isDefined) {
111
- // Add to defined Map
112
- if (!this.defined.has(definingContext)) {
113
- this.defined.set(definingContext, new Set());
114
- }
115
-
116
- this.defined.get(definingContext).add(name);
117
- this.references.has(definingContext) && this.references.get(definingContext).delete(name);
118
- } else {
119
- // Add to references Map
120
- if (!this.defined.has(definingContext) || !this.defined.get(definingContext).has(name)) {
121
- if (!this.references.has(definingContext)) {
122
- this.references.set(definingContext, new Set());
123
- }
124
-
125
- this.references.get(definingContext).add(name);
126
- }
127
- }
128
- });
129
125
  }
130
126
  });
131
127
  }
@@ -194,10 +194,6 @@ class Lock extends _transform.default {
194
194
  choices.push("domainLock");
195
195
  }
196
196
 
197
- if (this.options.lock.nativeFunctions) {
198
- choices.push("nativeFunction");
199
- }
200
-
201
197
  if (this.options.lock.context && this.options.lock.context.length) {
202
198
  choices.push("context");
203
199
  }
@@ -248,39 +244,6 @@ class Lock extends _transform.default {
248
244
  nodes.push((0, _gen.IfStatement)(callExpression, this.getCounterMeasuresCode(object, parents) || [], null));
249
245
  break;
250
246
 
251
- case "nativeFunction":
252
- var set = this.options.lock.nativeFunctions;
253
-
254
- if (set === true) {
255
- if (this.options.target == "node") {
256
- set = new Set(["Function", "String"]);
257
- } else {
258
- set = new Set(["Function", "String", "fetch"]);
259
- }
260
- }
261
-
262
- if (Array.isArray(set)) {
263
- set = new Set(set);
264
- }
265
-
266
- if (!set) {
267
- set = new Set();
268
- }
269
-
270
- var fn = (0, _random.choice)(Array.from(set));
271
-
272
- if (fn) {
273
- test = (0, _template.default)("(".concat(fn, "+\"\").indexOf(\"[native code]\") == -1")).single().expression;
274
-
275
- if (Math.random() > 0.5) {
276
- test = (0, _template.default)("".concat(fn, ".toString().split(\"{ [native code] }\").length <= 1")).single().expression;
277
- }
278
-
279
- nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
280
- }
281
-
282
- break;
283
-
284
247
  case "startDate":
285
248
  test = (0, _gen.BinaryExpression)("<", dateNow, (0, _gen.Literal)(this.getTime(this.options.lock.startDate)));
286
249
  nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
@@ -78,7 +78,7 @@ class Minify extends _transform.default {
78
78
  var startIndex = -1;
79
79
  var sequences = [];
80
80
  body.forEach((stmt, i) => {
81
- if (stmt.type == "ExpressionStatement") {
81
+ if (stmt.type == "ExpressionStatement" && !stmt.directive) {
82
82
  exprs.push(stmt.expression);
83
83
 
84
84
  if (startIndex == -1) {
@@ -108,48 +108,44 @@ class Minify extends _transform.default {
108
108
  (0, _assert.ok)(seq.index != -1);
109
109
  body.splice(seq.index, seq.exprs.length, (0, _gen.ExpressionStatement)(seq.exprs.length == 1 ? seq.exprs[0] : (0, _gen.SequenceExpression)(seq.exprs)));
110
110
  });
111
- }
111
+ } // Unnecessary return
112
112
 
113
- if (object.type != "SwitchCase") {
114
- // Unnecessary return
115
- if (body.length && body[body.length - 1]) {
116
- var last = body[body.length - 1];
117
113
 
118
- if (last.type == "ReturnStatement") {
119
- var isUndefined = last.argument == null;
114
+ if (parents[0] && (0, _insert.isVarContext)(parents[0]) && body.length && body[body.length - 1]) {
115
+ var last = body[body.length - 1];
120
116
 
121
- if (isUndefined) {
122
- if ((0, _insert.getFunction)(object, parents).body == object) {
123
- body.pop();
124
- }
125
- }
117
+ if (last.type == "ReturnStatement") {
118
+ var isUndefined = last.argument == null;
119
+
120
+ if (isUndefined) {
121
+ body.pop();
126
122
  }
127
- } // Variable declaration grouping
128
- // var a = 1;
129
- // var b = 1;
130
- // var c = 1;
131
- //
132
- // var a=1,b=1,c=1;
133
-
134
-
135
- var lastDec = null;
136
- var remove = [];
137
- body.forEach((x, i) => {
138
- if (x.type === "VariableDeclaration") {
139
- if (!lastDec || lastDec.kind !== x.kind || !lastDec.declarations.length) {
140
- lastDec = x;
141
- } else {
142
- lastDec.declarations.push(...(0, _insert.clone)(x.declarations));
143
- remove.unshift(i);
144
- }
123
+ }
124
+ } // Variable declaration grouping
125
+ // var a = 1;
126
+ // var b = 1;
127
+ // var c = 1;
128
+ //
129
+ // var a=1,b=1,c=1;
130
+
131
+
132
+ var lastDec = null;
133
+ var remove = [];
134
+ body.forEach((x, i) => {
135
+ if (x.type === "VariableDeclaration") {
136
+ if (!lastDec || lastDec.kind !== x.kind || !lastDec.declarations.length) {
137
+ lastDec = x;
145
138
  } else {
146
- lastDec = null;
139
+ lastDec.declarations.push(...(0, _insert.clone)(x.declarations));
140
+ remove.unshift(i);
147
141
  }
148
- });
149
- remove.forEach(x => {
150
- body.splice(x, 1);
151
- });
152
- }
142
+ } else {
143
+ lastDec = null;
144
+ }
145
+ });
146
+ remove.forEach(x => {
147
+ body.splice(x, 1);
148
+ });
153
149
  };
154
150
  }
155
151
  /**
@@ -172,29 +168,30 @@ class Minify extends _transform.default {
172
168
  }
173
169
  }
174
170
 
175
- var blockIndex = parents.findIndex(x => (0, _insert.isLexContext)(x));
176
-
177
- if (blockIndex !== -1) {
178
- var block = parents[blockIndex];
179
- var body = block.body;
171
+ if (object.type === "FunctionDeclaration") {
172
+ var body = parents[0];
180
173
 
181
174
  if (!Array.isArray(body)) {
182
175
  return;
183
176
  }
184
177
 
185
- var stmt = parents[blockIndex - 2] || object;
186
- var index = body.indexOf(stmt);
178
+ var index = body.indexOf(object);
187
179
 
188
180
  if (index == -1) {
189
181
  return;
190
182
  }
191
183
 
192
184
  var before = body.slice(0, index);
193
- (0, _assert.ok)(!before.includes(stmt));
194
- var set = new Set(before.map(x => x.type));
195
- set.delete("FunctionDeclaration");
185
+ (0, _assert.ok)(!before.includes(object));
186
+ var beforeTypes = new Set(before.map(x => x.type));
187
+ beforeTypes.delete("FunctionDeclaration");
188
+
189
+ if (beforeTypes.size > 0) {
190
+ return;
191
+ } // Test Variant #25: Don't break redefined function declaration
192
+
196
193
 
197
- if (set.size) {
194
+ if (object.id && body.find(x => x.type === "FunctionDeclaration" && x !== object && x.id && x.id.name === object.id.name)) {
198
195
  return;
199
196
  }
200
197
  }
@@ -217,11 +214,11 @@ class Minify extends _transform.default {
217
214
  if (canTransform) {
218
215
  if (!this.arrowFunctionName) {
219
216
  this.arrowFunctionName = this.getPlaceholder();
220
- (0, _insert.append)(parents[parents.length - 1] || object, (0, _template.default)("\n function ".concat(this.arrowFunctionName, "(arrowFn){\n return function(){ return arrowFn(...arguments) }\n }\n ")).single());
217
+ (0, _insert.append)(parents[parents.length - 1] || object, (0, _template.default)("\n function ".concat(this.arrowFunctionName, "(arrowFn, functionLength){\n var functionObject = function(){ return arrowFn(...arguments) };\n\n Object[\"defineProperty\"](functionObject, \"length\", {\n \"value\": functionLength,\n \"configurable\": true\n });\n\n return functionObject;\n }\n ")).single());
221
218
  }
222
219
 
223
220
  const wrap = object => {
224
- return (0, _gen.CallExpression)((0, _gen.Identifier)(this.arrowFunctionName), [(0, _insert.clone)(object)]);
221
+ return (0, _gen.CallExpression)((0, _gen.Identifier)(this.arrowFunctionName), [(0, _insert.clone)(object), (0, _gen.Literal)((0, _insert.computeFunctionLength)(object.params))]);
225
222
  };
226
223
 
227
224
  if (object.type == "FunctionExpression") {
@@ -253,7 +250,7 @@ class Minify extends _transform.default {
253
250
 
254
251
  if (body.length == 1 && stmt1.type == "ReturnStatement") {
255
252
  // x=>{a: 1} // Invalid syntax
256
- if (stmt1.argument.type != "ObjectExpression") {
253
+ if (stmt1.argument && stmt1.argument.type != "ObjectExpression") {
257
254
  object.body = stmt1.argument;
258
255
  object.expression = true;
259
256
  }
@@ -421,8 +418,16 @@ class Minify extends _transform.default {
421
418
  if (property.type == "Literal" && (0, _compare.isValidIdentifier)(property.value)) {
422
419
  object.computed = false;
423
420
  object.property.type = "Identifier";
424
- object.property.name = (0, _insert.clone)(object.property.value);
425
- obj.name && this.log(obj.name + "['" + object.property.name + "'] -> " + obj.name + "." + object.property.name);
421
+ object.property.name = (0, _insert.clone)(object.property.value); // obj.name &&
422
+ // this.log(
423
+ // obj.name +
424
+ // "['" +
425
+ // object.property.name +
426
+ // "'] -> " +
427
+ // obj.name +
428
+ // "." +
429
+ // object.property.name
430
+ // );
426
431
  }
427
432
  }
428
433
 
@@ -437,18 +442,16 @@ class Minify extends _transform.default {
437
442
  } // { "x": 1 } -> {x: 1}
438
443
 
439
444
 
440
- if (object.type == "Property") {
445
+ if (object.type === "Property" || object.type === "MethodDefinition") {
441
446
  if (object.key.type == "SequenceExpression" && object.key.expressions.length == 1) {
442
447
  object.key = object.key.expressions[0];
443
448
  object.computed = true;
444
449
  }
445
450
 
446
- if (object.key.type == "Literal" && (0, _compare.isValidIdentifier)(object.key.value)) {
451
+ if (object.key.type == "Literal" && typeof object.key.value === "string" && (0, _compare.isValidIdentifier)(object.key.value)) {
447
452
  object.key.type = "Identifier";
448
453
  object.key.name = object.key.value;
449
454
  object.computed = false;
450
- } else if (object.key.type == "Identifier" && !(0, _compare.isValidIdentifier)(object.key.name)) {
451
- object.key = (0, _gen.Literal)(object.key.name);
452
455
  }
453
456
  }
454
457
 
@@ -66,7 +66,7 @@ class OpaquePredicates extends _transform.default {
66
66
  _defineProperty(this, "made", void 0);
67
67
 
68
68
  this.predicates = Object.create(null);
69
- this.gen = this.getGenerator((0, _random.getRandomInteger)(0, 20));
69
+ this.gen = this.getGenerator();
70
70
  this.made = 0;
71
71
  }
72
72
 
@@ -103,9 +103,9 @@ class ExplicitIdentifiers extends _transform.default {
103
103
  if (parents[propIndex].type == "MethodDefinition" && parents[propIndex].kind == "constructor") {
104
104
  return;
105
105
  }
106
- }
106
+ } // this.log(object.name, "->", `'${object.name}'`);
107
+
107
108
 
108
- this.log(object.name, "->", "'".concat(object.name, "'"));
109
109
  this.replace(object, (0, _gen.Literal)(object.name));
110
110
  parents[0].computed = true;
111
111
  parents[0].shorthand = false;
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _transform = _interopRequireDefault(require("./transform"));
9
+
10
+ var _gen = require("../util/gen");
11
+
12
+ var _order = require("../order");
13
+
14
+ var _insert = require("../util/insert");
15
+
16
+ var _identifiers = require("../util/identifiers");
17
+
18
+ var _compare = require("../util/compare");
19
+
20
+ var _traverse = require("../traverse");
21
+
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+
24
+ /**
25
+ * Preparation arranges the user's code into an AST the obfuscator can easily transform.
26
+ *
27
+ * ExplicitIdentifiers
28
+ * - `object.IDENTIFIER` -> `object['IDENTIFIER']` // Now String Concealing can apply on it
29
+ * - `{ IDENTIFIER: ... }` -> `{ "IDENTIFIER": ... }`
30
+ *
31
+ * ExplicitDeclarations
32
+ * - `var a,b,c` -> `var a; var b; var c;` // Now Stack can apply on it
33
+ *
34
+ * Block
35
+ * - `x => x * 2` -> `x => { return x * 2 }` // Change into Block Statements
36
+ * - `if(true) return` -> `if (true) { return }`
37
+ * - `while(a) a--;` -> `while(a) { a-- }`
38
+ *
39
+ * Label
40
+ * - `for(...) { break; }` -> `_1: for(...) { break _1; }`
41
+ * - `switch(v) { case 1...break }` -> `_2: switch(v) { case 1...break _2; }`
42
+ * - // Control Flow Flattening can safely apply now
43
+ */
44
+ class Preparation extends _transform.default {
45
+ constructor(o) {
46
+ super(o, _order.ObfuscateOrder.Preparation);
47
+ }
48
+
49
+ match(object, parents) {
50
+ return !!object.type;
51
+ }
52
+
53
+ transform(object, parents) {
54
+ // ExplicitIdentifiers
55
+ if (object.type === "Identifier") {
56
+ return this.transformExplicitIdentifiers(object, parents);
57
+ } // ExplicitDeclarations
58
+
59
+
60
+ if (object.type === "VariableDeclaration") {
61
+ return this.transformExplicitDeclarations(object, parents);
62
+ } // Block
63
+
64
+
65
+ switch (object.type) {
66
+ /**
67
+ * People use shortcuts and its harder to parse.
68
+ *
69
+ * - `if (a) b()` -> `if (a) { b() }`
70
+ * - Ensures all bodies are `BlockStatement`, not individual expression statements
71
+ */
72
+ case "IfStatement":
73
+ if (object.consequent.type != "BlockStatement") {
74
+ object.consequent = (0, _gen.BlockStatement)([(0, _insert.clone)(object.consequent)]);
75
+ }
76
+
77
+ if (object.alternate && object.alternate.type != "BlockStatement") {
78
+ object.alternate = (0, _gen.BlockStatement)([(0, _insert.clone)(object.alternate)]);
79
+ }
80
+
81
+ break;
82
+
83
+ case "WhileStatement":
84
+ case "WithStatement":
85
+ case "ForStatement":
86
+ case "ForOfStatement":
87
+ case "ForInStatement":
88
+ if (object.body.type != "BlockStatement") {
89
+ object.body = (0, _gen.BlockStatement)([(0, _insert.clone)(object.body)]);
90
+ }
91
+
92
+ break;
93
+
94
+ case "ArrowFunctionExpression":
95
+ if (object.body.type !== "BlockStatement" && object.expression) {
96
+ object.body = (0, _gen.BlockStatement)([(0, _gen.ReturnStatement)((0, _insert.clone)(object.body))]);
97
+ object.expression = false;
98
+ }
99
+
100
+ break;
101
+ } // Label
102
+
103
+
104
+ if ((0, _compare.isLoop)(object) || object.type == "BlockStatement" && parents[0] && parents[0].type == "LabeledStatement" && parents[0].body === object) {
105
+ return this.transformLabel(object, parents);
106
+ }
107
+ }
108
+ /**
109
+ * Ensures every break; statement has a label to point to.
110
+ *
111
+ * This is because Control Flow Flattening adds For Loops which label-less break statements point to the nearest,
112
+ * when they actually need to point to the original statement.
113
+ */
114
+
115
+
116
+ transformLabel(object, parents) {
117
+ return () => {
118
+ var currentLabel = parents[0].type == "LabeledStatement" && parents[0].label.name;
119
+ var label = currentLabel || this.getPlaceholder();
120
+ (0, _traverse.walk)(object, parents, (o, p) => {
121
+ if (o.type == "BreakStatement" || o.type == "ContinueStatement") {
122
+ function isContinuableStatement(x) {
123
+ return (0, _compare.isLoop)(x) && x.type !== "SwitchStatement";
124
+ }
125
+
126
+ function isBreakableStatement(x) {
127
+ return (0, _compare.isLoop)(x) || o.label && x.type == "BlockStatement";
128
+ }
129
+
130
+ var fn = o.type == "ContinueStatement" ? isContinuableStatement : isBreakableStatement;
131
+ var loop = p.find(fn);
132
+
133
+ if (object == loop) {
134
+ if (!o.label) {
135
+ o.label = (0, _gen.Identifier)(label);
136
+ }
137
+ }
138
+ }
139
+ }); // Append label statement as this loop has none
140
+
141
+ if (!currentLabel) {
142
+ this.replace(object, (0, _gen.LabeledStatement)(label, { ...object
143
+ }));
144
+ }
145
+ };
146
+ }
147
+ /**
148
+ * Transforms Identifiers (a.IDENTIFIER, {IDENTIFIER:...}) into string properties
149
+ */
150
+
151
+
152
+ transformExplicitIdentifiers(object, parents) {
153
+ // Mark functions containing 'eval'
154
+ // Some transformations avoid functions that have 'eval' to not break them
155
+ if (object.name === "eval") {
156
+ var fn = (0, _insert.getFunction)(object, parents);
157
+
158
+ if (fn) {
159
+ fn.$requiresEval = true;
160
+ }
161
+ }
162
+
163
+ var info = (0, _identifiers.getIdentifierInfo)(object, parents);
164
+
165
+ if (info.isPropertyKey || info.isAccessor) {
166
+ var propIndex = parents.findIndex(x => x.type == "MethodDefinition" || x.type == "Property"); // Don't change constructor!
167
+
168
+ if (propIndex !== -1) {
169
+ if (parents[propIndex].type == "MethodDefinition" && parents[propIndex].kind == "constructor") {
170
+ return;
171
+ }
172
+ }
173
+
174
+ this.replace(object, (0, _gen.Literal)(object.name));
175
+ parents[0].computed = true;
176
+ parents[0].shorthand = false;
177
+ }
178
+ }
179
+ /**
180
+ * Transforms VariableDeclaration into single declarations.
181
+ */
182
+
183
+
184
+ transformExplicitDeclarations(object, parents) {
185
+ // for ( var x in ... ) {...}
186
+ var forIndex = parents.findIndex(x => x.type == "ForInStatement" || x.type == "ForOfStatement");
187
+
188
+ if (forIndex != -1 && parents[forIndex].left == (parents[forIndex - 1] || object)) {
189
+ object.declarations.forEach(x => {
190
+ x.init = null;
191
+ });
192
+ return;
193
+ }
194
+
195
+ var body = parents[0];
196
+
197
+ if ((0, _compare.isLoop)(body) || body.type == "LabeledStatement") {
198
+ return;
199
+ }
200
+
201
+ if (body.type == "ExportNamedDeclaration") {
202
+ return;
203
+ }
204
+
205
+ if (!Array.isArray(body)) {
206
+ this.error(new Error("body is " + body.type));
207
+ }
208
+
209
+ if (object.declarations.length > 1) {
210
+ // Make singular
211
+ var index = body.indexOf(object);
212
+
213
+ if (index == -1) {
214
+ this.error(new Error("index is -1"));
215
+ }
216
+
217
+ var after = object.declarations.slice(1);
218
+ body.splice(index + 1, 0, ...after.map(x => {
219
+ return {
220
+ type: "VariableDeclaration",
221
+ declarations: [(0, _insert.clone)(x)],
222
+ kind: object.kind
223
+ };
224
+ }));
225
+ object.declarations.length = 1;
226
+ }
227
+ }
228
+
229
+ }
230
+
231
+ exports.default = Preparation;
@@ -30,7 +30,7 @@ class RenameLabels extends _transform.default {
30
30
 
31
31
  _defineProperty(this, "gen", void 0);
32
32
 
33
- this.gen = this.getGenerator();
33
+ this.gen = this.getGenerator("randomized");
34
34
  }
35
35
 
36
36
  match(object, parents) {