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,272 +4,312 @@ 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
8
  var _gen = require("../../util/gen");
11
-
12
9
  var _traverse = _interopRequireWildcard(require("../../traverse"));
13
-
14
10
  var _random = require("../../util/random");
15
-
16
11
  var _crash = require("../../templates/crash");
17
-
18
12
  var _insert = require("../../util/insert");
19
-
20
13
  var _template = _interopRequireDefault(require("../../templates/template"));
21
-
22
14
  var _order = require("../../order");
23
-
24
15
  var _integrity = _interopRequireDefault(require("./integrity"));
25
-
26
16
  var _antiDebug = _interopRequireDefault(require("./antiDebug"));
27
-
28
17
  var _identifiers = require("../../util/identifiers");
29
-
30
18
  var _compare = require("../../util/compare");
31
-
32
19
  var _assert = require("assert");
33
-
34
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
35
-
36
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
37
-
38
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
-
40
- 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; }
41
-
20
+ var _core = require("../../templates/core");
21
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
22
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
23
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
24
+ 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; }
25
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
26
+ 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); }
42
27
  /**
43
28
  * Applies browser & date locks.
44
29
  */
45
30
  class Lock extends _transform.default {
46
- /**
47
- * This is a boolean variable injected into the source code determining wether the countermeasures function has been called.
48
- * This is used to prevent infinite loops from happening
49
- */
31
+ shouldTransformNativeFunction(nameAndPropertyPath) {
32
+ if (!this.options.lock.tamperProtection) {
33
+ return false;
34
+ }
35
+ if (typeof this.options.lock.tamperProtection === "function") {
36
+ return this.options.lock.tamperProtection(nameAndPropertyPath.join("."));
37
+ }
38
+ if (this.options.target === "browser" && nameAndPropertyPath.length === 1 && nameAndPropertyPath[0] === "fetch") {
39
+ return true;
40
+ }
41
+
42
+ // TODO: Allow user to customize this behavior
43
+ var globalObject = typeof window !== "undefined" ? window : global;
44
+ var fn = globalObject;
45
+ for (var item of nameAndPropertyPath) {
46
+ fn = fn[item];
47
+ if (typeof fn === "undefined") return false;
48
+ }
49
+ var hasNativeCode = typeof fn === "function" && ("" + fn).includes("[native code]");
50
+ return hasNativeCode;
51
+ }
50
52
  constructor(o) {
51
- super(o, _order.ObfuscateOrder.Lock); // Removed feature
53
+ super(o, _order.ObfuscateOrder.Lock);
54
+
55
+ // Removed feature
52
56
  // if (this.options.lock.startDate && this.options.lock.endDate) {
53
57
  // this.before.push(new LockStrings(o));
54
58
  // }
55
-
56
59
  _defineProperty(this, "globalVar", void 0);
57
-
58
60
  _defineProperty(this, "counterMeasuresNode", void 0);
59
-
60
61
  _defineProperty(this, "iosDetectFn", void 0);
61
-
62
+ /**
63
+ * This is a boolean variable injected into the source code determining wether the countermeasures function has been called.
64
+ * This is used to prevent infinite loops from happening
65
+ */
62
66
  _defineProperty(this, "counterMeasuresActivated", void 0);
63
-
67
+ /**
68
+ * The name of the native function that is used to check runtime calls for tampering
69
+ */
70
+ _defineProperty(this, "nativeFunctionName", void 0);
64
71
  _defineProperty(this, "made", void 0);
65
-
66
72
  if (this.options.lock.integrity) {
67
73
  this.before.push(new _integrity.default(o, this));
68
74
  }
69
-
70
75
  if (this.options.lock.antiDebug) {
71
76
  this.before.push(new _antiDebug.default(o, this));
72
77
  }
73
-
74
78
  this.made = 0;
75
79
  }
76
-
77
80
  apply(tree) {
78
81
  if (typeof this.options.lock.countermeasures === "string" && (0, _compare.isValidIdentifier)(this.options.lock.countermeasures)) {
79
82
  (0, _traverse.default)(tree, (object, parents) => {
80
83
  if (object.type == "Identifier" && object.name === this.options.lock.countermeasures) {
81
84
  var info = (0, _identifiers.getIdentifierInfo)(object, parents);
82
-
83
85
  if (info.spec.isDefined) {
84
86
  if (this.counterMeasuresNode) {
85
87
  throw new Error("Countermeasures function was already defined, it must have a unique name from the rest of your code");
86
88
  } else {
87
89
  var definingContext = (0, _insert.getVarContext)(parents[0], parents.slice(1));
88
-
89
90
  if (definingContext != tree) {
90
91
  throw new Error("Countermeasures function must be defined at the global level");
91
92
  }
92
-
93
93
  var chain = [object, parents];
94
-
95
94
  if (info.isFunctionDeclaration) {
96
95
  chain = [parents[0], parents.slice(1)];
97
96
  } else if (info.isVariableDeclaration) {
98
97
  chain = [parents[1], parents.slice(2)];
99
98
  }
100
-
101
99
  this.counterMeasuresNode = chain;
102
100
  }
103
101
  }
104
102
  }
105
103
  });
106
-
107
104
  if (!this.counterMeasuresNode) {
108
105
  throw new Error("Countermeasures function named '" + this.options.lock.countermeasures + "' was not found.");
109
106
  }
110
107
  }
111
-
112
108
  super.apply(tree);
113
- }
109
+ if (this.options.lock.tamperProtection) {
110
+ this.nativeFunctionName = this.getPlaceholder() + "_lockNative";
111
+
112
+ // Ensure program is not in strict mode
113
+ // Tamper Protection forces non-strict mode
114
+
115
+ var strictModeCheck = new _template.default(`
116
+ (function(){
117
+ function isStrictMode(){
118
+ try {
119
+ var arr = []
120
+ delete arr["length"]
121
+ } catch(e) {
122
+ return true;
123
+ }
124
+ return false;
125
+ }
114
126
 
127
+ if(isStrictMode()) {
128
+ {countermeasures}
129
+ ${this.nativeFunctionName} = undefined;
130
+ }
131
+ })()
132
+ `).single({
133
+ countermeasures: this.getCounterMeasuresCode(tree, [])
134
+ });
135
+
136
+ // $multiTransformSkip is used to prevent scoping between transformations
137
+ strictModeCheck.$multiTransformSkip = true;
138
+ (0, _insert.prepend)(tree, strictModeCheck);
139
+ var nativeFunctionCheck = new _template.default(`
140
+ function ${this.nativeFunctionName}() {
141
+ {IndexOfTemplate}
142
+
143
+ function checkFunction(fn){
144
+ if (indexOf("" + fn, '{ [native code] }') === -1
145
+ ||
146
+ typeof Object.getOwnPropertyDescriptor(fn, "toString") !== "undefined"
147
+ ) {
148
+ {countermeasures}
149
+ return undefined
150
+ }
151
+
152
+ return fn;
153
+ }
154
+
155
+ var args = arguments
156
+ if(args.length === 1) {
157
+ return checkFunction(args[0]);
158
+ } else if (args.length === 2) {
159
+ var object = args[0];
160
+ var property = args[1];
161
+
162
+ var fn = object[property];
163
+ fn = checkFunction(fn);
164
+
165
+ return fn.bind(object);
166
+ }
167
+ }`).single({
168
+ IndexOfTemplate: _core.IndexOfTemplate,
169
+ countermeasures: this.getCounterMeasuresCode(tree, [])
170
+ });
171
+
172
+ // $multiTransformSkip is used to prevent scoping between transformations
173
+ nativeFunctionCheck.$multiTransformSkip = true;
174
+ (0, _insert.prepend)(tree, nativeFunctionCheck);
175
+ }
176
+ }
115
177
  getCounterMeasuresCode(object, parents) {
116
178
  var opt = this.options.lock.countermeasures;
117
-
118
179
  if (opt === false) {
119
180
  return null;
120
- } // Call function
121
-
181
+ }
122
182
 
183
+ // Call function
123
184
  if (typeof opt === "string") {
124
185
  if (!this.counterMeasuresActivated) {
125
186
  this.counterMeasuresActivated = this.getPlaceholder();
126
187
  (0, _insert.prepend)(parents[parents.length - 1] || object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.counterMeasuresActivated)));
127
- } // Since Lock occurs before variable renaming, we are using the pre-obfuscated function name
128
-
188
+ }
129
189
 
130
- return [(0, _gen.ExpressionStatement)((0, _gen.LogicalExpression)("||", (0, _gen.Identifier)(this.counterMeasuresActivated), (0, _gen.SequenceExpression)([(0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(this.counterMeasuresActivated), (0, _gen.Literal)(true)), (0, _gen.CallExpression)((0, _template.default)(opt).single().expression, [])])))];
190
+ // Since Lock occurs before variable renaming, we are using the pre-obfuscated function name
191
+ return [(0, _gen.ExpressionStatement)((0, _gen.LogicalExpression)("||", (0, _gen.Identifier)(this.counterMeasuresActivated), (0, _gen.SequenceExpression)([(0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(this.counterMeasuresActivated), (0, _gen.Literal)(true)), (0, _gen.CallExpression)(new _template.default(opt).single().expression, [])])))];
131
192
  }
132
193
 
133
- var type = (0, _random.choice)(["crash", "exit"]);
134
-
135
- switch (type) {
136
- case "crash":
137
- var varName = this.getPlaceholder();
138
- return (0, _random.choice)([_crash.CrashTemplate1, _crash.CrashTemplate2, _crash.CrashTemplate3]).compile({
139
- var: varName
140
- });
141
-
142
- case "exit":
143
- if (this.options.target == "browser") {
144
- return (0, _template.default)("document.documentElement.innerHTML = '';").compile();
145
- }
146
-
147
- return (0, _template.default)("process.exit()").compile();
148
- }
194
+ // Default fallback to infinite loop
195
+ var varName = this.getPlaceholder();
196
+ return (0, _random.choice)([_crash.CrashTemplate1, _crash.CrashTemplate2]).compile({
197
+ var: varName
198
+ });
149
199
  }
200
+
150
201
  /**
151
202
  * Converts Dates to numbers, then applies some randomness
152
203
  * @param object
153
204
  */
154
-
155
-
156
205
  getTime(object) {
157
206
  if (!object) {
158
207
  return 0;
159
208
  }
160
-
161
209
  if (object instanceof Date) {
162
210
  return this.getTime(object.getTime());
163
211
  }
164
-
165
212
  return object + (0, _random.getRandomInteger)(-4000, 4000);
166
213
  }
167
-
168
214
  match(object, parents) {
169
215
  return (0, _traverse.isBlock)(object);
170
216
  }
171
-
172
217
  transform(object, parents) {
173
218
  if (parents.find(x => (0, _compare.isLoop)(x) && x.type != "SwitchStatement")) {
174
219
  return;
175
- } // no check in countermeasures code, otherwise it will infinitely call itself
176
-
220
+ }
177
221
 
222
+ // no check in countermeasures code, otherwise it will infinitely call itself
178
223
  if (this.counterMeasuresNode && (object == this.counterMeasuresNode[0] || parents.indexOf(this.counterMeasuresNode[0]) !== -1)) {
179
224
  return;
180
225
  }
181
-
182
226
  var block = (0, _traverse.getBlock)(object, parents);
183
227
  var choices = [];
184
-
185
228
  if (this.options.lock.startDate) {
186
229
  choices.push("startDate");
187
230
  }
188
-
189
231
  if (this.options.lock.endDate) {
190
232
  choices.push("endDate");
191
233
  }
192
-
193
234
  if (this.options.lock.domainLock && this.options.lock.domainLock.length) {
194
235
  choices.push("domainLock");
195
236
  }
196
-
197
237
  if (this.options.lock.context && this.options.lock.context.length) {
198
238
  choices.push("context");
199
239
  }
200
-
201
240
  if (this.options.lock.browserLock && this.options.lock.browserLock.length) {
202
241
  choices.push("browserLock");
203
242
  }
204
-
205
243
  if (this.options.lock.osLock && this.options.lock.osLock.length) {
206
244
  choices.push("osLock");
207
245
  }
208
-
209
246
  if (this.options.lock.selfDefending) {
210
247
  choices.push("selfDefending");
211
248
  }
212
-
213
249
  if (!choices.length) {
214
250
  return;
215
251
  }
216
-
217
252
  return () => {
218
253
  this.made++;
219
-
220
254
  if (this.made > 150) {
221
255
  return;
222
256
  }
223
-
224
257
  var type = (0, _random.choice)(choices);
225
258
  var nodes = [];
226
259
  var dateNow = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)("Date"), (0, _gen.Literal)("now"), true), []);
227
-
228
260
  if (Math.random() > 0.5) {
229
261
  dateNow = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.NewExpression)((0, _gen.Identifier)("Date"), []), (0, _gen.Literal)("getTime")), []);
230
262
  }
231
-
232
263
  if (Math.random() > 0.5) {
233
264
  dateNow = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)("Date"), (0, _gen.Literal)("prototype"), true), (0, _gen.Literal)("getTime"), true), (0, _gen.Literal)("call"), true), [(0, _gen.NewExpression)((0, _gen.Identifier)("Date"), [])]);
234
265
  }
235
-
236
266
  var test;
237
267
  var offset = 0;
238
-
239
268
  switch (type) {
240
269
  case "selfDefending":
241
270
  // A very simple mechanism inspired from https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/src/custom-code-helpers/self-defending/templates/SelfDefendingNoEvalTemplate.ts
242
271
  // regExp checks for a newline, formatters add these
243
- var callExpression = (0, _template.default)("\n (\n function(){\n // Breaks JSNice.org, beautifier.io\n var namedFunction = function(){\n const test = function(){\n const regExp=new RegExp('\\n');\n return regExp['test'](namedFunction)\n };\n return test()\n }\n\n return namedFunction();\n }\n )()\n ").single().expression;
272
+ var callExpression = new _template.default(`
273
+ (
274
+ function(){
275
+ // Breaks JSNice.org, beautifier.io
276
+ var namedFunction = function(){
277
+ const test = function(){
278
+ const regExp=new RegExp('\\n');
279
+ return regExp['test'](namedFunction)
280
+ };
281
+ return test()
282
+ }
283
+
284
+ return namedFunction();
285
+ }
286
+ )()
287
+ `).single().expression;
244
288
  nodes.push((0, _gen.IfStatement)(callExpression, this.getCounterMeasuresCode(object, parents) || [], null));
245
289
  break;
246
-
247
290
  case "startDate":
248
291
  test = (0, _gen.BinaryExpression)("<", dateNow, (0, _gen.Literal)(this.getTime(this.options.lock.startDate)));
249
292
  nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
250
293
  break;
251
-
252
294
  case "endDate":
253
295
  test = (0, _gen.BinaryExpression)(">", dateNow, (0, _gen.Literal)(this.getTime(this.options.lock.endDate)));
254
296
  nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
255
297
  break;
256
-
257
298
  case "context":
258
299
  var prop = (0, _random.choice)(this.options.lock.context);
259
- var code = this.getCounterMeasuresCode(object, parents) || []; // Todo: Alternative to `this`
300
+ var code = this.getCounterMeasuresCode(object, parents) || [];
260
301
 
302
+ // Todo: Alternative to `this`
261
303
  if (!this.globalVar) {
262
304
  offset = 1;
263
305
  this.globalVar = this.getPlaceholder();
264
306
  (0, _insert.prepend)(parents[parents.length - 1] || block, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.globalVar, (0, _gen.LogicalExpression)("||", (0, _gen.Identifier)(this.options.globalVariables.keys().next().value), (0, _gen.ThisExpression)()))));
265
307
  }
266
-
267
308
  test = (0, _gen.UnaryExpression)("!", (0, _gen.MemberExpression)((0, _gen.Identifier)(this.globalVar), (0, _gen.Literal)(prop), true));
268
309
  nodes.push((0, _gen.IfStatement)(test, code, null));
269
310
  break;
270
-
271
311
  case "osLock":
272
- var navigatorUserAgent = (0, _template.default)("window.navigator.userAgent.toLowerCase()").single().expression;
312
+ var navigatorUserAgent = new _template.default(`window.navigator.userAgent.toLowerCase()`).single().expression;
273
313
  (0, _assert.ok)(this.options.lock.osLock);
274
314
  var code = this.getCounterMeasuresCode(object, parents) || [];
275
315
  this.options.lock.osLock.forEach(osName => {
@@ -281,74 +321,76 @@ class Lock extends _transform.default {
281
321
  ios: "---"
282
322
  }[osName];
283
323
  var thisTest = (0, _gen.CallExpression)((0, _gen.MemberExpression)(navigatorUserAgent, (0, _gen.Literal)("match"), true), [(0, _gen.Literal)(agentMatcher.toLowerCase())]);
284
-
285
324
  if (osName == "ios" && this.options.target === "browser") {
286
325
  if (!this.iosDetectFn) {
287
326
  this.iosDetectFn = this.getPlaceholder();
288
- (0, _insert.prepend)(parents[parents.length - 1] || object, (0, _template.default)("function ".concat(this.iosDetectFn, "() {\n return [\n 'iPad Simulator',\n 'iPhone Simulator',\n 'iPod Simulator',\n 'iPad',\n 'iPhone',\n 'iPod'\n ].includes(navigator.platform)\n // iPad on iOS 13 detection\n || (navigator.userAgent.includes(\"Mac\") && \"ontouchend\" in document)\n }")).single());
327
+ (0, _insert.prepend)(parents[parents.length - 1] || object, new _template.default(`function ${this.iosDetectFn}() {
328
+ return [
329
+ 'iPad Simulator',
330
+ 'iPhone Simulator',
331
+ 'iPod Simulator',
332
+ 'iPad',
333
+ 'iPhone',
334
+ 'iPod'
335
+ ].includes(navigator.platform)
336
+ // iPad on iOS 13 detection
337
+ || (navigator.userAgent.includes("Mac") && "ontouchend" in document)
338
+ }`).single());
289
339
  }
290
-
291
340
  thisTest = (0, _gen.CallExpression)((0, _gen.Identifier)(this.iosDetectFn), []);
292
341
  }
293
-
294
342
  if (this.options.target === "node") {
295
343
  var platformName = {
296
344
  windows: "win32",
297
345
  osx: "darwin",
298
346
  ios: "darwin"
299
347
  }[osName] || osName;
300
- thisTest = (0, _template.default)("require('os').platform()===\"".concat(platformName, "\"")).single().expression;
348
+ thisTest = new _template.default(`require('os').platform()==="${platformName}"`).single().expression;
301
349
  }
302
-
303
350
  if (!test) {
304
351
  test = thisTest;
305
352
  } else {
306
- test = (0, _gen.LogicalExpression)("||", { ...test
353
+ test = (0, _gen.LogicalExpression)("||", {
354
+ ...test
307
355
  }, thisTest);
308
356
  }
309
357
  });
310
- test = (0, _gen.UnaryExpression)("!", { ...test
358
+ test = (0, _gen.UnaryExpression)("!", {
359
+ ...test
311
360
  });
312
361
  nodes.push((0, _gen.IfStatement)(test, code, null));
313
362
  break;
314
-
315
363
  case "browserLock":
316
- var navigatorUserAgent = (0, _template.default)("window.navigator.userAgent.toLowerCase()").single().expression;
364
+ var navigatorUserAgent = new _template.default(`window.navigator.userAgent.toLowerCase()`).single().expression;
317
365
  (0, _assert.ok)(this.options.lock.browserLock);
318
366
  this.options.lock.browserLock.forEach(browserName => {
319
367
  var thisTest = (0, _gen.CallExpression)((0, _gen.MemberExpression)(navigatorUserAgent, (0, _gen.Literal)("match"), true), [(0, _gen.Literal)(browserName == "iexplorer" ? "msie" : browserName.toLowerCase())]);
320
-
321
368
  if (browserName === "safari") {
322
- thisTest = (0, _template.default)("/^((?!chrome|android).)*safari/i.test(navigator.userAgent)").single().expression;
369
+ thisTest = new _template.default(`/^((?!chrome|android).)*safari/i.test(navigator.userAgent)`).single().expression;
323
370
  }
324
-
325
371
  if (!test) {
326
372
  test = thisTest;
327
373
  } else {
328
- test = (0, _gen.LogicalExpression)("||", { ...test
374
+ test = (0, _gen.LogicalExpression)("||", {
375
+ ...test
329
376
  }, thisTest);
330
377
  }
331
378
  });
332
- test = (0, _gen.UnaryExpression)("!", { ...test
379
+ test = (0, _gen.UnaryExpression)("!", {
380
+ ...test
333
381
  });
334
382
  nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
335
383
  break;
336
-
337
384
  case "domainLock":
338
385
  function removeSlashes(path) {
339
386
  var count = path.length - 1;
340
387
  var index = 0;
341
-
342
388
  while (path.charCodeAt(index) === 47 && ++index);
343
-
344
389
  while (path.charCodeAt(count) === 47 && --count);
345
-
346
390
  return path.slice(index, count + 1);
347
391
  }
348
-
349
392
  var locationHref = (0, _gen.MemberExpression)((0, _gen.Identifier)("location"), (0, _gen.Literal)("href"), true);
350
393
  var random = (0, _random.choice)(this.options.lock.domainLock);
351
-
352
394
  if (random) {
353
395
  test = (0, _gen.CallExpression)((0, _gen.MemberExpression)(locationHref, (0, _gen.Literal)("match"), true), [{
354
396
  type: "Literal",
@@ -358,21 +400,16 @@ class Lock extends _transform.default {
358
400
  }
359
401
  }]);
360
402
  test = (0, _gen.UnaryExpression)("!", test);
361
-
362
403
  if (Math.random() > 0.5) {
363
404
  test = (0, _gen.LogicalExpression)("||", (0, _gen.BinaryExpression)("==", (0, _gen.UnaryExpression)("typeof", (0, _gen.Identifier)("location")), (0, _gen.Literal)("undefined")), test);
364
405
  }
365
-
366
406
  nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
367
407
  }
368
-
369
408
  break;
370
409
  }
371
-
372
410
  if (nodes.length) {
373
411
  var body = (0, _insert.getBlockBody)(block);
374
412
  var randomIndex = (0, _random.getRandomInteger)(0, body.length) + offset;
375
-
376
413
  if (randomIndex >= body.length) {
377
414
  body.push(...nodes);
378
415
  } else {
@@ -381,7 +418,5 @@ class Lock extends _transform.default {
381
418
  }
382
419
  };
383
420
  }
384
-
385
421
  }
386
-
387
422
  exports.default = Lock;