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
@@ -42,7 +42,7 @@ function cyrb53(str, seed = 0) {
42
42
  }
43
43
 
44
44
  // In template form to be inserted into code
45
- const HashTemplate = Template(`
45
+ const HashTemplate = new Template(`
46
46
  function {name}(str, seed) {
47
47
  var h1 = 0xdeadbeef ^ seed;
48
48
  var h2 = 0x41c6ce57 ^ seed;
@@ -57,7 +57,7 @@ function {name}(str, seed) {
57
57
  };`);
58
58
 
59
59
  // Math.imul polyfill for ES5
60
- const ImulTemplate = Template(`
60
+ const ImulTemplate = new Template(`
61
61
  var {name} = Math.imul || function(opA, opB){
62
62
  opB |= 0; // ensure that opB is an integer. opA will automatically be coerced.
63
63
  // floating points give us 53 bits of precision to work with plus 1 sign bit
@@ -73,7 +73,7 @@ var {name} = Math.imul || function(opA, opB){
73
73
  };`);
74
74
 
75
75
  // Simple function that returns .toString() value with spaces replaced out
76
- const StringTemplate = Template(`
76
+ const StringTemplate = new Template(`
77
77
  function {name}(x){
78
78
  return x.toString().replace(/ |\\n|;|,|\\{|\\}|\\(|\\)|\\.|\\[|\\]/g, "");
79
79
  }
@@ -128,7 +128,7 @@ export default class Integrity extends Transform {
128
128
  var imulName = this.getPlaceholder();
129
129
  var imulVariableDeclaration = ImulTemplate.single({ name: imulName });
130
130
 
131
- imulVariableDeclaration.$dispatcherSkip = true;
131
+ imulVariableDeclaration.$multiTransformSkip = true;
132
132
 
133
133
  this.imulFn = imulVariableDeclaration._hiddenId = Identifier(imulName);
134
134
  hashingUtils.push(imulVariableDeclaration);
@@ -141,7 +141,7 @@ export default class Integrity extends Transform {
141
141
  this.hashFn = hashFunctionDeclaration._hiddenId = Identifier(hashName);
142
142
  hashingUtils.push(hashFunctionDeclaration);
143
143
 
144
- hashFunctionDeclaration.$dispatcherSkip = true;
144
+ hashFunctionDeclaration.$multiTransformSkip = true;
145
145
 
146
146
  var stringName = this.getPlaceholder();
147
147
  var stringFunctionDeclaration = StringTemplate.single({
@@ -151,7 +151,7 @@ export default class Integrity extends Transform {
151
151
  Identifier(stringName);
152
152
  hashingUtils.push(stringFunctionDeclaration);
153
153
 
154
- stringFunctionDeclaration.$dispatcherSkip = true;
154
+ stringFunctionDeclaration.$multiTransformSkip = true;
155
155
 
156
156
  var functionExpression = FunctionExpression([], clone(object.body));
157
157
 
@@ -159,7 +159,7 @@ export default class Integrity extends Transform {
159
159
  ExpressionStatement(CallExpression(functionExpression, [])),
160
160
  ];
161
161
 
162
- object.$dispatcherSkip = true;
162
+ object.$multiTransformSkip = true;
163
163
 
164
164
  object._hiddenHashingUtils = hashingUtils;
165
165
 
@@ -211,7 +211,7 @@ export default class Integrity extends Transform {
211
211
  params: object.params || [],
212
212
  body: object.body || BlockStatement([]),
213
213
  expression: false,
214
- $dispatcherSkip: true,
214
+ $multiTransformSkip: true,
215
215
  };
216
216
 
217
217
  var toString = compileJsSync(functionDeclaration, this.options);
@@ -231,9 +231,11 @@ export default class Integrity extends Transform {
231
231
  var ifStatement = IfStatement(
232
232
  BinaryExpression("==", Identifier(hashName), Literal(hash)),
233
233
  [
234
- Template(`return {functionName}.apply(this, arguments)`).single({
235
- functionName: functionName,
236
- }),
234
+ new Template(`return {functionName}.apply(this, arguments)`).single(
235
+ {
236
+ functionName: functionName,
237
+ }
238
+ ),
237
239
  ]
238
240
  );
239
241
  if (
@@ -20,11 +20,7 @@ import {
20
20
  } from "../../util/gen";
21
21
  import traverse, { getBlock, isBlock } from "../../traverse";
22
22
  import { choice, getRandomInteger } from "../../util/random";
23
- import {
24
- CrashTemplate1,
25
- CrashTemplate2,
26
- CrashTemplate3,
27
- } from "../../templates/crash";
23
+ import { CrashTemplate1, CrashTemplate2 } from "../../templates/crash";
28
24
  import { getBlockBody, getVarContext, prepend } from "../../util/insert";
29
25
  import Template from "../../templates/template";
30
26
  import { ObfuscateOrder } from "../../order";
@@ -33,6 +29,8 @@ import AntiDebug from "./antiDebug";
33
29
  import { getIdentifierInfo } from "../../util/identifiers";
34
30
  import { isLoop, isValidIdentifier } from "../../util/compare";
35
31
  import { ok } from "assert";
32
+ import { variableFunctionName } from "../../constants";
33
+ import { IndexOfTemplate } from "../../templates/core";
36
34
 
37
35
  /**
38
36
  * Applies browser & date locks.
@@ -48,8 +46,44 @@ export default class Lock extends Transform {
48
46
  */
49
47
  counterMeasuresActivated: string;
50
48
 
49
+ /**
50
+ * The name of the native function that is used to check runtime calls for tampering
51
+ */
52
+ nativeFunctionName: string;
53
+
51
54
  made: number;
52
55
 
56
+ shouldTransformNativeFunction(nameAndPropertyPath: string[]) {
57
+ if (!this.options.lock.tamperProtection) {
58
+ return false;
59
+ }
60
+
61
+ if (typeof this.options.lock.tamperProtection === "function") {
62
+ return this.options.lock.tamperProtection(nameAndPropertyPath.join("."));
63
+ }
64
+
65
+ if (
66
+ this.options.target === "browser" &&
67
+ nameAndPropertyPath.length === 1 &&
68
+ nameAndPropertyPath[0] === "fetch"
69
+ ) {
70
+ return true;
71
+ }
72
+
73
+ // TODO: Allow user to customize this behavior
74
+ var globalObject = typeof window !== "undefined" ? window : global;
75
+ var fn = globalObject;
76
+ for (var item of nameAndPropertyPath) {
77
+ fn = fn[item];
78
+ if (typeof fn === "undefined") return false;
79
+ }
80
+
81
+ var hasNativeCode =
82
+ typeof fn === "function" && ("" + fn).includes("[native code]");
83
+
84
+ return hasNativeCode;
85
+ }
86
+
53
87
  constructor(o) {
54
88
  super(o, ObfuscateOrder.Lock);
55
89
 
@@ -115,6 +149,77 @@ export default class Lock extends Transform {
115
149
  }
116
150
 
117
151
  super.apply(tree);
152
+
153
+ if (this.options.lock.tamperProtection) {
154
+ this.nativeFunctionName = this.getPlaceholder() + "_lockNative";
155
+
156
+ // Ensure program is not in strict mode
157
+ // Tamper Protection forces non-strict mode
158
+
159
+ var strictModeCheck = new Template(`
160
+ (function(){
161
+ function isStrictMode(){
162
+ try {
163
+ var arr = []
164
+ delete arr["length"]
165
+ } catch(e) {
166
+ return true;
167
+ }
168
+ return false;
169
+ }
170
+
171
+ if(isStrictMode()) {
172
+ {countermeasures}
173
+ ${this.nativeFunctionName} = undefined;
174
+ }
175
+ })()
176
+ `).single({
177
+ countermeasures: this.getCounterMeasuresCode(tree, []),
178
+ });
179
+
180
+ // $multiTransformSkip is used to prevent scoping between transformations
181
+ strictModeCheck.$multiTransformSkip = true;
182
+
183
+ prepend(tree, strictModeCheck);
184
+
185
+ var nativeFunctionCheck = new Template(`
186
+ function ${this.nativeFunctionName}() {
187
+ {IndexOfTemplate}
188
+
189
+ function checkFunction(fn){
190
+ if (indexOf("" + fn, '{ [native code] }') === -1
191
+ ||
192
+ typeof Object.getOwnPropertyDescriptor(fn, "toString") !== "undefined"
193
+ ) {
194
+ {countermeasures}
195
+ return undefined
196
+ }
197
+
198
+ return fn;
199
+ }
200
+
201
+ var args = arguments
202
+ if(args.length === 1) {
203
+ return checkFunction(args[0]);
204
+ } else if (args.length === 2) {
205
+ var object = args[0];
206
+ var property = args[1];
207
+
208
+ var fn = object[property];
209
+ fn = checkFunction(fn);
210
+
211
+ return fn.bind(object);
212
+ }
213
+ }`).single({
214
+ IndexOfTemplate: IndexOfTemplate,
215
+ countermeasures: this.getCounterMeasuresCode(tree, []),
216
+ });
217
+
218
+ // $multiTransformSkip is used to prevent scoping between transformations
219
+ nativeFunctionCheck.$multiTransformSkip = true;
220
+
221
+ prepend(tree, nativeFunctionCheck);
222
+ }
118
223
  }
119
224
 
120
225
  getCounterMeasuresCode(object: Node, parents: Node[]): Node[] {
@@ -147,31 +252,18 @@ export default class Lock extends Transform {
147
252
  Identifier(this.counterMeasuresActivated),
148
253
  Literal(true)
149
254
  ),
150
- CallExpression(Template(opt).single().expression, []),
255
+ CallExpression(new Template(opt).single().expression, []),
151
256
  ])
152
257
  )
153
258
  ),
154
259
  ];
155
260
  }
156
261
 
157
- var type = choice(["crash", "exit"]);
158
-
159
- switch (type) {
160
- case "crash":
161
- var varName = this.getPlaceholder();
162
- return choice([CrashTemplate1, CrashTemplate2, CrashTemplate3]).compile(
163
- {
164
- var: varName,
165
- }
166
- );
167
-
168
- case "exit":
169
- if (this.options.target == "browser") {
170
- return Template("document.documentElement.innerHTML = '';").compile();
171
- }
172
-
173
- return Template("process.exit()").compile();
174
- }
262
+ // Default fallback to infinite loop
263
+ var varName = this.getPlaceholder();
264
+ return choice([CrashTemplate1, CrashTemplate2]).compile({
265
+ var: varName,
266
+ });
175
267
  }
176
268
 
177
269
  /**
@@ -281,7 +373,7 @@ export default class Lock extends Transform {
281
373
  case "selfDefending":
282
374
  // A very simple mechanism inspired from https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/src/custom-code-helpers/self-defending/templates/SelfDefendingNoEvalTemplate.ts
283
375
  // regExp checks for a newline, formatters add these
284
- var callExpression = Template(
376
+ var callExpression = new Template(
285
377
  `
286
378
  (
287
379
  function(){
@@ -379,7 +471,7 @@ export default class Lock extends Transform {
379
471
  break;
380
472
 
381
473
  case "osLock":
382
- var navigatorUserAgent = Template(
474
+ var navigatorUserAgent = new Template(
383
475
  `window.navigator.userAgent.toLowerCase()`
384
476
  ).single().expression;
385
477
 
@@ -404,7 +496,7 @@ export default class Lock extends Transform {
404
496
  this.iosDetectFn = this.getPlaceholder();
405
497
  prepend(
406
498
  parents[parents.length - 1] || object,
407
- Template(`function ${this.iosDetectFn}() {
499
+ new Template(`function ${this.iosDetectFn}() {
408
500
  return [
409
501
  'iPad Simulator',
410
502
  'iPhone Simulator',
@@ -426,7 +518,7 @@ export default class Lock extends Transform {
426
518
  var platformName =
427
519
  { windows: "win32", osx: "darwin", ios: "darwin" }[osName] ||
428
520
  osName;
429
- thisTest = Template(
521
+ thisTest = new Template(
430
522
  `require('os').platform()==="${platformName}"`
431
523
  ).single().expression;
432
524
  }
@@ -443,7 +535,7 @@ export default class Lock extends Transform {
443
535
  break;
444
536
 
445
537
  case "browserLock":
446
- var navigatorUserAgent = Template(
538
+ var navigatorUserAgent = new Template(
447
539
  `window.navigator.userAgent.toLowerCase()`
448
540
  ).single().expression;
449
541
 
@@ -462,7 +554,7 @@ export default class Lock extends Transform {
462
554
  );
463
555
 
464
556
  if (browserName === "safari") {
465
- thisTest = Template(
557
+ thisTest = new Template(
466
558
  `/^((?!chrome|android).)*safari/i.test(navigator.userAgent)`
467
559
  ).single().expression;
468
560
  }
@@ -29,6 +29,8 @@ import { walk, isBlock } from "../traverse";
29
29
  import { ok } from "assert";
30
30
  import { isLexicalScope } from "../util/scope";
31
31
  import Template from "../templates/template";
32
+ import { ObjectDefineProperty } from "../templates/globals";
33
+ import { getIdentifierInfo } from "../util/identifiers";
32
34
 
33
35
  /**
34
36
  * Basic transformations to reduce code size.
@@ -258,26 +260,35 @@ export default class Minify extends Transform {
258
260
 
259
261
  append(
260
262
  parents[parents.length - 1] || object,
261
- Template(`
262
- function ${this.arrowFunctionName}(arrowFn, functionLength){
263
+ new Template(`
264
+ function ${this.arrowFunctionName}(arrowFn, functionLength = 0){
263
265
  var functionObject = function(){ return arrowFn(...arguments) };
264
266
 
265
- Object["defineProperty"](functionObject, "length", {
266
- "value": functionLength,
267
- "configurable": true
268
- });
269
-
270
- return functionObject;
267
+ ${
268
+ this.options.preserveFunctionLength
269
+ ? `return {ObjectDefineProperty}(functionObject, "length", {
270
+ "value": functionLength,
271
+ "configurable": true
272
+ });`
273
+ : `return functionObject`
274
+ }
275
+
271
276
  }
272
- `).single()
277
+ `).single({
278
+ ObjectDefineProperty: this.options.preserveFunctionLength
279
+ ? this.createInitVariable(ObjectDefineProperty, parents)
280
+ : undefined,
281
+ })
273
282
  );
274
283
  }
275
284
 
276
285
  const wrap = (object: Node) => {
277
- return CallExpression(Identifier(this.arrowFunctionName), [
278
- clone(object),
279
- Literal(computeFunctionLength(object.params)),
280
- ]);
286
+ var args: Node[] = [clone(object)];
287
+ var fnLength = computeFunctionLength(object.params);
288
+ if (this.options.preserveFunctionLength && fnLength != 0) {
289
+ args.push(Literal(fnLength));
290
+ }
291
+ return CallExpression(Identifier(this.arrowFunctionName), args);
281
292
  };
282
293
 
283
294
  if (object.type == "FunctionExpression") {
@@ -619,6 +630,7 @@ export default class Minify extends Transform {
619
630
 
620
631
  if (
621
632
  object.id.type == "ObjectPattern" &&
633
+ object.init &&
622
634
  object.init.type == "ObjectExpression"
623
635
  ) {
624
636
  if (
@@ -673,6 +685,9 @@ export default class Minify extends Transform {
673
685
  }
674
686
  if (object.type == "Identifier") {
675
687
  return () => {
688
+ var info = getIdentifierInfo(object, parents);
689
+ if (info.spec.isDefined || info.spec.isModified) return;
690
+
676
691
  if (object.name == "undefined" && !isForInitialize(object, parents)) {
677
692
  this.replaceIdentifierOrLiteral(
678
693
  object,
@@ -78,7 +78,7 @@ export default class OpaquePredicates extends Transform {
78
78
  match(object: Node, parents: Node[]) {
79
79
  return (
80
80
  (isTestExpression(object, parents) || object.type == "SwitchCase") &&
81
- !parents.find((x) => x.$dispatcherSkip || x.type == "AwaitExpression")
81
+ !parents.find((x) => x.$multiTransformSkip || x.type == "AwaitExpression")
82
82
  );
83
83
  }
84
84
 
@@ -146,7 +146,7 @@ export default class OpaquePredicates extends Transform {
146
146
  Identifier(prop),
147
147
  FunctionExpression(
148
148
  [AssignmentPattern(Identifier(paramName), Literal("length"))],
149
- Template(`
149
+ new Template(`
150
150
  if ( !${this.predicateName}.${arrayProp}[0] ) {
151
151
  ${this.predicateName}.${arrayProp}.push(${getRandomInteger(
152
152
  -100,
@@ -13,6 +13,7 @@ import { clone, getFunction } from "../util/insert";
13
13
  import { getIdentifierInfo } from "../util/identifiers";
14
14
  import { isLoop } from "../util/compare";
15
15
  import { ExitCallback, walk } from "../traverse";
16
+ import { variableFunctionName } from "../constants";
16
17
 
17
18
  /**
18
19
  * Preparation arranges the user's code into an AST the obfuscator can easily transform.
@@ -49,6 +50,21 @@ export default class Preparation extends Transform {
49
50
  return this.transformExplicitIdentifiers(object, parents);
50
51
  }
51
52
 
53
+ // __JS_CONFUSER_VAR__ - Remove when Rename Variables is disabled
54
+ if (
55
+ object.type === "CallExpression" &&
56
+ object.callee.type === "Identifier" &&
57
+ object.callee.name === variableFunctionName
58
+ ) {
59
+ if (object.arguments[0].type === "Identifier") {
60
+ if (!this.obfuscator.transforms["RenameVariables"]) {
61
+ return () => {
62
+ this.replace(object, Literal(object.arguments[0].name));
63
+ };
64
+ }
65
+ }
66
+ }
67
+
52
68
  // ExplicitDeclarations
53
69
  if (object.type === "VariableDeclaration") {
54
70
  return this.transformExplicitDeclarations(object, parents);