js-confuser 1.7.2 → 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 (96) hide show
  1. package/.github/workflows/node.js.yml +1 -1
  2. package/CHANGELOG.md +35 -0
  3. package/README.md +20 -4
  4. package/dist/constants.js +7 -2
  5. package/dist/index.js +8 -0
  6. package/dist/options.js +12 -2
  7. package/dist/templates/bufferToString.js +26 -5
  8. package/dist/templates/core.js +35 -0
  9. package/dist/templates/crash.js +8 -39
  10. package/dist/templates/es5.js +1 -1
  11. package/dist/templates/functionLength.js +1 -1
  12. package/dist/templates/globals.js +1 -1
  13. package/dist/templates/template.js +173 -68
  14. package/dist/transforms/antiTooling.js +1 -1
  15. package/dist/transforms/calculator.js +2 -2
  16. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +8 -2
  17. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +1 -1
  18. package/dist/transforms/deadCode.js +34 -24
  19. package/dist/transforms/dispatcher.js +8 -4
  20. package/dist/transforms/es5/antiClass.js +11 -11
  21. package/dist/transforms/es5/antiDestructuring.js +1 -1
  22. package/dist/transforms/es5/antiES6Object.js +2 -2
  23. package/dist/transforms/es5/antiTemplate.js +1 -1
  24. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +2 -2
  25. package/dist/transforms/identifier/globalAnalysis.js +13 -0
  26. package/dist/transforms/identifier/globalConcealing.js +41 -6
  27. package/dist/transforms/identifier/renameVariables.js +7 -0
  28. package/dist/transforms/lock/antiDebug.js +2 -2
  29. package/dist/transforms/lock/integrity.js +9 -9
  30. package/dist/transforms/lock/lock.js +106 -20
  31. package/dist/transforms/minify.js +1 -1
  32. package/dist/transforms/opaquePredicates.js +2 -2
  33. package/dist/transforms/preparation.js +12 -0
  34. package/dist/transforms/rgf.js +32 -3
  35. package/dist/transforms/shuffle.js +3 -3
  36. package/dist/transforms/stack.js +8 -2
  37. package/dist/transforms/string/encoding.js +6 -3
  38. package/dist/transforms/string/stringCompression.js +34 -3
  39. package/dist/transforms/string/stringConcealing.js +7 -6
  40. package/dist/transforms/transform.js +26 -4
  41. package/dist/util/guard.js +5 -0
  42. package/dist/util/random.js +26 -0
  43. package/docs/Countermeasures.md +13 -6
  44. package/docs/Integrity.md +35 -28
  45. package/docs/RGF.md +6 -1
  46. package/docs/RenameVariables.md +116 -0
  47. package/docs/TamperProtection.md +100 -0
  48. package/docs/Template.md +117 -0
  49. package/package.json +1 -1
  50. package/src/constants.ts +5 -0
  51. package/src/index.ts +7 -5
  52. package/src/options.ts +47 -7
  53. package/src/templates/bufferToString.ts +34 -4
  54. package/src/templates/core.ts +29 -0
  55. package/src/templates/crash.ts +6 -38
  56. package/src/templates/es5.ts +1 -1
  57. package/src/templates/functionLength.ts +1 -1
  58. package/src/templates/globals.ts +1 -1
  59. package/src/templates/template.ts +185 -86
  60. package/src/transforms/antiTooling.ts +1 -1
  61. package/src/transforms/calculator.ts +4 -2
  62. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +10 -3
  63. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +1 -1
  64. package/src/transforms/deadCode.ts +74 -26
  65. package/src/transforms/dispatcher.ts +9 -5
  66. package/src/transforms/es5/antiClass.ts +15 -11
  67. package/src/transforms/es5/antiDestructuring.ts +1 -1
  68. package/src/transforms/es5/antiES6Object.ts +2 -2
  69. package/src/transforms/es5/antiTemplate.ts +1 -1
  70. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +2 -6
  71. package/src/transforms/identifier/globalAnalysis.ts +18 -1
  72. package/src/transforms/identifier/globalConcealing.ts +94 -11
  73. package/src/transforms/identifier/renameVariables.ts +16 -1
  74. package/src/transforms/lock/antiDebug.ts +2 -2
  75. package/src/transforms/lock/integrity.ts +13 -11
  76. package/src/transforms/lock/lock.ts +122 -30
  77. package/src/transforms/minify.ts +1 -1
  78. package/src/transforms/opaquePredicates.ts +2 -2
  79. package/src/transforms/preparation.ts +16 -0
  80. package/src/transforms/rgf.ts +46 -8
  81. package/src/transforms/shuffle.ts +3 -3
  82. package/src/transforms/stack.ts +9 -3
  83. package/src/transforms/string/encoding.ts +10 -7
  84. package/src/transforms/string/stringCompression.ts +81 -9
  85. package/src/transforms/string/stringConcealing.ts +10 -6
  86. package/src/transforms/transform.ts +35 -47
  87. package/src/types.ts +2 -0
  88. package/src/util/guard.ts +10 -0
  89. package/src/util/random.ts +81 -1
  90. package/test/code/Cash.test.ts +84 -1
  91. package/test/compare.test.ts +5 -5
  92. package/test/options.test.ts +18 -0
  93. package/test/templates/template.test.ts +211 -1
  94. package/test/transforms/identifier/globalConcealing.test.ts +70 -0
  95. package/test/transforms/identifier/renameVariables.test.ts +75 -1
  96. package/test/transforms/lock/tamperProtection.test.ts +336 -0
@@ -35,7 +35,7 @@ function cyrb53(str) {
35
35
  }
36
36
 
37
37
  // In template form to be inserted into code
38
- const HashTemplate = (0, _template.default)(`
38
+ const HashTemplate = new _template.default(`
39
39
  function {name}(str, seed) {
40
40
  var h1 = 0xdeadbeef ^ seed;
41
41
  var h2 = 0x41c6ce57 ^ seed;
@@ -50,7 +50,7 @@ function {name}(str, seed) {
50
50
  };`);
51
51
 
52
52
  // Math.imul polyfill for ES5
53
- const ImulTemplate = (0, _template.default)(`
53
+ const ImulTemplate = new _template.default(`
54
54
  var {name} = Math.imul || function(opA, opB){
55
55
  opB |= 0; // ensure that opB is an integer. opA will automatically be coerced.
56
56
  // floating points give us 53 bits of precision to work with plus 1 sign bit
@@ -66,7 +66,7 @@ var {name} = Math.imul || function(opA, opB){
66
66
  };`);
67
67
 
68
68
  // Simple function that returns .toString() value with spaces replaced out
69
- const StringTemplate = (0, _template.default)(`
69
+ const StringTemplate = new _template.default(`
70
70
  function {name}(x){
71
71
  return x.toString().replace(/ |\\n|;|,|\\{|\\}|\\(|\\)|\\.|\\[|\\]/g, "");
72
72
  }
@@ -114,7 +114,7 @@ class Integrity extends _transform.default {
114
114
  var imulVariableDeclaration = ImulTemplate.single({
115
115
  name: imulName
116
116
  });
117
- imulVariableDeclaration.$dispatcherSkip = true;
117
+ imulVariableDeclaration.$multiTransformSkip = true;
118
118
  this.imulFn = imulVariableDeclaration._hiddenId = (0, _gen.Identifier)(imulName);
119
119
  hashingUtils.push(imulVariableDeclaration);
120
120
  var hashName = this.getPlaceholder();
@@ -124,17 +124,17 @@ class Integrity extends _transform.default {
124
124
  });
125
125
  this.hashFn = hashFunctionDeclaration._hiddenId = (0, _gen.Identifier)(hashName);
126
126
  hashingUtils.push(hashFunctionDeclaration);
127
- hashFunctionDeclaration.$dispatcherSkip = true;
127
+ hashFunctionDeclaration.$multiTransformSkip = true;
128
128
  var stringName = this.getPlaceholder();
129
129
  var stringFunctionDeclaration = StringTemplate.single({
130
130
  name: stringName
131
131
  });
132
132
  this.stringFn = stringFunctionDeclaration._hiddenId = (0, _gen.Identifier)(stringName);
133
133
  hashingUtils.push(stringFunctionDeclaration);
134
- stringFunctionDeclaration.$dispatcherSkip = true;
134
+ stringFunctionDeclaration.$multiTransformSkip = true;
135
135
  var functionExpression = (0, _gen.FunctionExpression)([], (0, _insert.clone)(object.body));
136
136
  object.body = [(0, _gen.ExpressionStatement)((0, _gen.CallExpression)(functionExpression, []))];
137
- object.$dispatcherSkip = true;
137
+ object.$multiTransformSkip = true;
138
138
  object._hiddenHashingUtils = hashingUtils;
139
139
  var ok = this.transform(functionExpression, [object.body[0], object.body, object]);
140
140
  if (ok) {
@@ -166,7 +166,7 @@ class Integrity extends _transform.default {
166
166
  params: object.params || [],
167
167
  body: object.body || (0, _gen.BlockStatement)([]),
168
168
  expression: false,
169
- $dispatcherSkip: true
169
+ $multiTransformSkip: true
170
170
  };
171
171
  var toString = (0, _compiler.compileJsSync)(functionDeclaration, this.options);
172
172
  if (!toString) {
@@ -175,7 +175,7 @@ class Integrity extends _transform.default {
175
175
  var minified = toString.replace(/ |\n|;|,|\{|\}|\(|\)|\.|\[|\]/g, "");
176
176
  var hash = cyrb53(minified, this.seed);
177
177
  this.log((object.id ? object.id.name : "function") + " -> " + hash, minified);
178
- var ifStatement = (0, _gen.IfStatement)((0, _gen.BinaryExpression)("==", (0, _gen.Identifier)(hashName), (0, _gen.Literal)(hash)), [(0, _template.default)(`return {functionName}.apply(this, arguments)`).single({
178
+ var ifStatement = (0, _gen.IfStatement)((0, _gen.BinaryExpression)("==", (0, _gen.Identifier)(hashName), (0, _gen.Literal)(hash)), [new _template.default(`return {functionName}.apply(this, arguments)`).single({
179
179
  functionName: functionName
180
180
  })]);
181
181
  if (object.__hiddenCountermeasures && object.__hiddenCountermeasures.length) {
@@ -17,6 +17,7 @@ var _antiDebug = _interopRequireDefault(require("./antiDebug"));
17
17
  var _identifiers = require("../../util/identifiers");
18
18
  var _compare = require("../../util/compare");
19
19
  var _assert = require("assert");
20
+ var _core = require("../../templates/core");
20
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); }
21
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; }
22
23
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -27,6 +28,27 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
27
28
  * Applies browser & date locks.
28
29
  */
29
30
  class Lock extends _transform.default {
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
+ }
30
52
  constructor(o) {
31
53
  super(o, _order.ObfuscateOrder.Lock);
32
54
 
@@ -42,6 +64,10 @@ class Lock extends _transform.default {
42
64
  * This is used to prevent infinite loops from happening
43
65
  */
44
66
  _defineProperty(this, "counterMeasuresActivated", void 0);
67
+ /**
68
+ * The name of the native function that is used to check runtime calls for tampering
69
+ */
70
+ _defineProperty(this, "nativeFunctionName", void 0);
45
71
  _defineProperty(this, "made", void 0);
46
72
  if (this.options.lock.integrity) {
47
73
  this.before.push(new _integrity.default(o, this));
@@ -80,6 +106,73 @@ class Lock extends _transform.default {
80
106
  }
81
107
  }
82
108
  super.apply(tree);
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
+ }
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
+ }
83
176
  }
84
177
  getCounterMeasuresCode(object, parents) {
85
178
  var opt = this.options.lock.countermeasures;
@@ -95,21 +188,14 @@ class Lock extends _transform.default {
95
188
  }
96
189
 
97
190
  // Since Lock occurs before variable renaming, we are using the pre-obfuscated function name
98
- 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, [])])))];
99
- }
100
- var type = (0, _random.choice)(["crash", "exit"]);
101
- switch (type) {
102
- case "crash":
103
- var varName = this.getPlaceholder();
104
- return (0, _random.choice)([_crash.CrashTemplate1, _crash.CrashTemplate2, _crash.CrashTemplate3]).compile({
105
- var: varName
106
- });
107
- case "exit":
108
- if (this.options.target == "browser") {
109
- return (0, _template.default)("document.documentElement.innerHTML = '';").compile();
110
- }
111
- return (0, _template.default)("process.exit()").compile();
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, [])])))];
112
192
  }
193
+
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
+ });
113
199
  }
114
200
 
115
201
  /**
@@ -183,7 +269,7 @@ class Lock extends _transform.default {
183
269
  case "selfDefending":
184
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
185
271
  // regExp checks for a newline, formatters add these
186
- var callExpression = (0, _template.default)(`
272
+ var callExpression = new _template.default(`
187
273
  (
188
274
  function(){
189
275
  // Breaks JSNice.org, beautifier.io
@@ -223,7 +309,7 @@ class Lock extends _transform.default {
223
309
  nodes.push((0, _gen.IfStatement)(test, code, null));
224
310
  break;
225
311
  case "osLock":
226
- var navigatorUserAgent = (0, _template.default)(`window.navigator.userAgent.toLowerCase()`).single().expression;
312
+ var navigatorUserAgent = new _template.default(`window.navigator.userAgent.toLowerCase()`).single().expression;
227
313
  (0, _assert.ok)(this.options.lock.osLock);
228
314
  var code = this.getCounterMeasuresCode(object, parents) || [];
229
315
  this.options.lock.osLock.forEach(osName => {
@@ -238,7 +324,7 @@ class Lock extends _transform.default {
238
324
  if (osName == "ios" && this.options.target === "browser") {
239
325
  if (!this.iosDetectFn) {
240
326
  this.iosDetectFn = this.getPlaceholder();
241
- (0, _insert.prepend)(parents[parents.length - 1] || object, (0, _template.default)(`function ${this.iosDetectFn}() {
327
+ (0, _insert.prepend)(parents[parents.length - 1] || object, new _template.default(`function ${this.iosDetectFn}() {
242
328
  return [
243
329
  'iPad Simulator',
244
330
  'iPhone Simulator',
@@ -259,7 +345,7 @@ class Lock extends _transform.default {
259
345
  osx: "darwin",
260
346
  ios: "darwin"
261
347
  }[osName] || osName;
262
- thisTest = (0, _template.default)(`require('os').platform()==="${platformName}"`).single().expression;
348
+ thisTest = new _template.default(`require('os').platform()==="${platformName}"`).single().expression;
263
349
  }
264
350
  if (!test) {
265
351
  test = thisTest;
@@ -275,12 +361,12 @@ class Lock extends _transform.default {
275
361
  nodes.push((0, _gen.IfStatement)(test, code, null));
276
362
  break;
277
363
  case "browserLock":
278
- var navigatorUserAgent = (0, _template.default)(`window.navigator.userAgent.toLowerCase()`).single().expression;
364
+ var navigatorUserAgent = new _template.default(`window.navigator.userAgent.toLowerCase()`).single().expression;
279
365
  (0, _assert.ok)(this.options.lock.browserLock);
280
366
  this.options.lock.browserLock.forEach(browserName => {
281
367
  var thisTest = (0, _gen.CallExpression)((0, _gen.MemberExpression)(navigatorUserAgent, (0, _gen.Literal)("match"), true), [(0, _gen.Literal)(browserName == "iexplorer" ? "msie" : browserName.toLowerCase())]);
282
368
  if (browserName === "safari") {
283
- 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;
284
370
  }
285
371
  if (!test) {
286
372
  test = thisTest;
@@ -185,7 +185,7 @@ class Minify extends _transform.default {
185
185
  if (canTransform) {
186
186
  if (!this.arrowFunctionName) {
187
187
  this.arrowFunctionName = this.getPlaceholder();
188
- (0, _insert.append)(parents[parents.length - 1] || object, (0, _template.default)(`
188
+ (0, _insert.append)(parents[parents.length - 1] || object, new _template.default(`
189
189
  function ${this.arrowFunctionName}(arrowFn, functionLength = 0){
190
190
  var functionObject = function(){ return arrowFn(...arguments) };
191
191
 
@@ -48,7 +48,7 @@ class OpaquePredicates extends _transform.default {
48
48
  this.made = 0;
49
49
  }
50
50
  match(object, parents) {
51
- return (isTestExpression(object, parents) || object.type == "SwitchCase") && !parents.find(x => x.$dispatcherSkip || x.type == "AwaitExpression");
51
+ return (isTestExpression(object, parents) || object.type == "SwitchCase") && !parents.find(x => x.$multiTransformSkip || x.type == "AwaitExpression");
52
52
  }
53
53
  transform(object, parents) {
54
54
  return () => {
@@ -74,7 +74,7 @@ class OpaquePredicates extends _transform.default {
74
74
  var arrayProp = this.gen.generate();
75
75
  this.predicate.properties.push((0, _gen.Property)((0, _gen.Identifier)(arrayProp), (0, _gen.ArrayExpression)([])));
76
76
  var paramName = this.getPlaceholder();
77
- this.predicate.properties.push((0, _gen.Property)((0, _gen.Identifier)(prop), (0, _gen.FunctionExpression)([(0, _gen.AssignmentPattern)((0, _gen.Identifier)(paramName), (0, _gen.Literal)("length"))], (0, _template.default)(`
77
+ this.predicate.properties.push((0, _gen.Property)((0, _gen.Identifier)(prop), (0, _gen.FunctionExpression)([(0, _gen.AssignmentPattern)((0, _gen.Identifier)(paramName), (0, _gen.Literal)("length"))], new _template.default(`
78
78
  if ( !${this.predicateName}.${arrayProp}[0] ) {
79
79
  ${this.predicateName}.${arrayProp}.push(${(0, _random.getRandomInteger)(-100, 100)});
80
80
  }
@@ -11,6 +11,7 @@ var _insert = require("../util/insert");
11
11
  var _identifiers = require("../util/identifiers");
12
12
  var _compare = require("../util/compare");
13
13
  var _traverse = require("../traverse");
14
+ var _constants = require("../constants");
14
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
16
  /**
16
17
  * Preparation arranges the user's code into an AST the obfuscator can easily transform.
@@ -45,6 +46,17 @@ class Preparation extends _transform.default {
45
46
  return this.transformExplicitIdentifiers(object, parents);
46
47
  }
47
48
 
49
+ // __JS_CONFUSER_VAR__ - Remove when Rename Variables is disabled
50
+ if (object.type === "CallExpression" && object.callee.type === "Identifier" && object.callee.name === _constants.variableFunctionName) {
51
+ if (object.arguments[0].type === "Identifier") {
52
+ if (!this.obfuscator.transforms["RenameVariables"]) {
53
+ return () => {
54
+ this.replace(object, (0, _gen.Literal)(object.arguments[0].name));
55
+ };
56
+ }
57
+ }
58
+ }
59
+
48
60
  // ExplicitDeclarations
49
61
  if (object.type === "VariableDeclaration") {
50
62
  return this.transformExplicitDeclarations(object, parents);
@@ -11,6 +11,7 @@ var _order = require("../order");
11
11
  var _probability = require("../probability");
12
12
  var _functionLength = require("../templates/functionLength");
13
13
  var _globals = require("../templates/globals");
14
+ var _template = _interopRequireDefault(require("../templates/template"));
14
15
  var _traverse = require("../traverse");
15
16
  var _gen = require("../util/gen");
16
17
  var _identifiers = require("../util/identifiers");
@@ -52,7 +53,26 @@ class RGF extends _transform.default {
52
53
 
53
54
  // Only add the array if there were converted functions
54
55
  if (this.arrayExpressionElements.length > 0) {
55
- (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.Identifier)(this.arrayExpressionName), (0, _gen.ArrayExpression)(this.arrayExpressionElements))));
56
+ var _this$options$lock;
57
+ var variableDeclaration = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.Identifier)(this.arrayExpressionName), (0, _gen.ArrayExpression)(this.arrayExpressionElements)));
58
+ var nodes = [variableDeclaration];
59
+ if ((_this$options$lock = this.options.lock) !== null && _this$options$lock !== void 0 && _this$options$lock.tamperProtection) {
60
+ // The name of the variable flag if eval is safe to use
61
+ var tamperProtectionCheckName = this.getPlaceholder() + "_rgfEvalCheck";
62
+ variableDeclaration.declarations[0].init = (0, _gen.LogicalExpression)("&&", (0, _gen.Identifier)(tamperProtectionCheckName), {
63
+ ...variableDeclaration.declarations[0].init
64
+ });
65
+ nodes.unshift(...new _template.default(`
66
+ var ${tamperProtectionCheckName} = false;
67
+ eval(${this.jsConfuserVar(tamperProtectionCheckName)} + "=true");
68
+ if(!${tamperProtectionCheckName}) {
69
+ {countermeasures}
70
+ }
71
+ `).compile({
72
+ countermeasures: this.lockTransform.getCounterMeasuresCode(tree, [])
73
+ }));
74
+ }
75
+ (0, _insert.prepend)(tree, ...nodes);
56
76
  }
57
77
 
58
78
  // The function.length helper function must be placed last
@@ -71,7 +91,7 @@ class RGF extends _transform.default {
71
91
  !object.generator;
72
92
  }
73
93
  transform(object, parents) {
74
- var _this$options$lock, _object$id;
94
+ var _this$options$lock2, _object$id;
75
95
  // Discard getter/setter methods
76
96
  if (parents[0].type === "Property" && parents[0].value === object) {
77
97
  if (parents[0].method || parents[0].kind === "get" || parents[0].kind === "set") {
@@ -85,7 +105,7 @@ class RGF extends _transform.default {
85
105
  }
86
106
 
87
107
  // Avoid applying to the countermeasures function
88
- if (typeof ((_this$options$lock = this.options.lock) === null || _this$options$lock === void 0 ? void 0 : _this$options$lock.countermeasures) === "string") {
108
+ if (typeof ((_this$options$lock2 = this.options.lock) === null || _this$options$lock2 === void 0 ? void 0 : _this$options$lock2.countermeasures) === "string") {
89
109
  // function countermeasures(){...}
90
110
  if (object.type === "FunctionDeclaration" && object.id.type === "Identifier" && object.id.name === this.options.lock.countermeasures) {
91
111
  return;
@@ -113,6 +133,7 @@ class RGF extends _transform.default {
113
133
  });
114
134
  if (isIllegal) return;
115
135
  return () => {
136
+ var _this$options$lock3;
116
137
  // Make sure function is 'reference-less'
117
138
  var definedMap = new Map();
118
139
  var isReferenceLess = true;
@@ -169,6 +190,9 @@ class RGF extends _transform.default {
169
190
  compact: true
170
191
  });
171
192
  if (obfuscator.options.lock) {
193
+ obfuscator.options.lock = {
194
+ ...obfuscator.options.lock
195
+ };
172
196
  delete obfuscator.options.lock.countermeasures;
173
197
 
174
198
  // Integrity will not recursively apply to RGF'd functions. This is intended.
@@ -210,6 +234,11 @@ class RGF extends _transform.default {
210
234
 
211
235
  // new Function(code)
212
236
  var newFunctionExpression = (0, _gen.NewExpression)((0, _gen.Identifier)("Function"), [(0, _gen.Literal)(toString)]);
237
+ if ((_this$options$lock3 = this.options.lock) !== null && _this$options$lock3 !== void 0 && _this$options$lock3.tamperProtection) {
238
+ // If tamper protection is enabled, wrap the function in an eval
239
+ var randomName = this.getGenerator("randomized").generate();
240
+ newFunctionExpression = (0, _gen.CallExpression)((0, _gen.Identifier)("eval"), [(0, _gen.Literal)(`function ${randomName}(){ ${toString} } ${randomName}`)]);
241
+ }
213
242
 
214
243
  // The index where this function is placed in the array
215
244
  var newFunctionExpressionIndex = this.arrayExpressionElements.length;
@@ -32,7 +32,7 @@ var Hash = function (s) {
32
32
  }
33
33
  return ~~String(a).slice(0, 3);
34
34
  };
35
- var HashTemplate = (0, _template.default)(`
35
+ var HashTemplate = new _template.default(`
36
36
  var {name} = function(arr) {
37
37
  var s = arr.map(x=>x+"").join(''), a = 1, c = 0, h, o;
38
38
  if (s) {
@@ -58,7 +58,7 @@ class Shuffle extends _transform.default {
58
58
  _defineProperty(this, "hashName", void 0);
59
59
  }
60
60
  match(object, parents) {
61
- return object.type == "ArrayExpression" && !parents.find(x => x.$dispatcherSkip);
61
+ return object.type == "ArrayExpression" && !parents.find(x => x.$multiTransformSkip);
62
62
  }
63
63
  transform(object, parents) {
64
64
  return () => {
@@ -124,7 +124,7 @@ class Shuffle extends _transform.default {
124
124
  }
125
125
  if (mode !== "hash") {
126
126
  var varPrefix = this.getPlaceholder();
127
- code.push((0, _template.default)(`
127
+ code.push(new _template.default(`
128
128
  for ( var ${varPrefix}x = 16; ${varPrefix}x%4 === 0; ${varPrefix}x++) {
129
129
  var ${varPrefix}z = 0;
130
130
  ${inPlace ? `${inPlaceName} = ${name}` : name} = ${name}.concat((function(){
@@ -17,6 +17,7 @@ var _transform = _interopRequireDefault(require("./transform"));
17
17
  var _constants = require("../constants");
18
18
  var _functionLength = require("../templates/functionLength");
19
19
  var _globals = require("../templates/globals");
20
+ var _guard = require("../util/guard");
20
21
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
22
  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; }
22
23
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
@@ -29,7 +30,7 @@ class Stack extends _transform.default {
29
30
  this.mangledExpressionsMade = 0;
30
31
  }
31
32
  match(object, parents) {
32
- return (0, _insert.isFunction)(object) && !object.params.find(x => x.type !== "Identifier") && object.body.type === "BlockStatement" && !parents.find(x => x.$dispatcherSkip) && !object.$requiresEval;
33
+ return (0, _insert.isFunction)(object) && !object.params.find(x => x.type !== "Identifier") && object.body.type === "BlockStatement" && !parents.find(x => x.$multiTransformSkip) && !object.$requiresEval;
33
34
  }
34
35
  transform(object, parents) {
35
36
  var _this = this;
@@ -104,6 +105,11 @@ class Stack extends _transform.default {
104
105
  if (o.name.startsWith(_constants.noRenameVariablePrefix)) {
105
106
  illegal.add(o.name);
106
107
  }
108
+
109
+ // Ignore __JS_CONFUSER_VAR__()
110
+ if ((0, _guard.isJSConfuserVar)(p)) {
111
+ illegal.add(o.name);
112
+ }
107
113
  if (info.isClauseParameter || info.isFunctionParameter || (0, _insert.isForInitialize)(o, p)) {
108
114
  // this.log(
109
115
  // o.name + " is illegal due to clause parameter/function parameter"
@@ -315,7 +321,7 @@ class Stack extends _transform.default {
315
321
  object.params = [(0, _gen.RestElement)((0, _gen.Identifier)(stackName))];
316
322
 
317
323
  // Ensure the array is correct length
318
- (0, _insert.prepend)(object.body, (0, _template.default)(`${stackName}["length"] = ${startingSize}`).single());
324
+ (0, _insert.prepend)(object.body, new _template.default(`${stackName}["length"] = ${startingSize}`).single());
319
325
  if (this.options.preserveFunctionLength && originalFunctionLength !== 0) {
320
326
  if (!this.functionLengthName) {
321
327
  this.functionLengthName = this.getPlaceholder();
@@ -7,6 +7,7 @@ exports.EncodingImplementations = void 0;
7
7
  exports.createEncodingImplementation = createEncodingImplementation;
8
8
  exports.hasAllEncodings = hasAllEncodings;
9
9
  var _template = _interopRequireDefault(require("../../templates/template"));
10
+ var _gen = require("../../util/gen");
10
11
  var _random = require("../../util/random");
11
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
13
  /**
@@ -93,9 +94,9 @@ function createEncodingImplementation() {
93
94
  }
94
95
  return Buffer.from(ret).toString("utf-8");
95
96
  },
96
- template: (0, _template.default)(`
97
+ template: new _template.default(`
97
98
  function {__fnName__}(str){
98
- var table = '${strTable}';
99
+ var table = {__strTable__};
99
100
 
100
101
  var raw = "" + (str || "");
101
102
  var len = raw.length;
@@ -129,7 +130,9 @@ function createEncodingImplementation() {
129
130
 
130
131
  return {__bufferToString__}(ret);
131
132
  }
132
- `).ignoreMissingVariables()
133
+ `).setDefaultVariables({
134
+ __strTable__: (0, _gen.Literal)(strTable)
135
+ })
133
136
  };
134
137
  EncodingImplementations[identity] = encodingImplementation;
135
138
  return encodingImplementation;
@@ -13,6 +13,7 @@ var _gen = require("../../util/gen");
13
13
  var _insert = require("../../util/insert");
14
14
  var _transform = _interopRequireDefault(require("../transform"));
15
15
  var _constants = require("../../constants");
16
+ var _random = require("../../util/random");
16
17
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
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; }
18
19
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
@@ -44,7 +45,7 @@ function LZ_decode(b) {
44
45
  for (var i = 1; i < d.length; i++) a = d[i].charCodeAt(0), a = h > a ? d[i] : e[a] ? e[a] : f + c, g.push(a), c = a.charAt(0), e[o] = f + c, o++, f = a;
45
46
  return g.join("");
46
47
  }
47
- const DecodeTemplate = (0, _template.default)(`function {name}(b){
48
+ const DecodeTemplate = new _template.default(`function {name}(b){
48
49
  var o,
49
50
  f,
50
51
  a,
@@ -94,7 +95,37 @@ class StringCompression extends _transform.default {
94
95
  var decoderParamName = this.getPlaceholder();
95
96
  var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(decoderParamName), [(0, _gen.CallExpression)((0, _gen.Identifier)(getStringParamName), [])]);
96
97
  (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(split, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([(0, _gen.Identifier)(getStringParamName), (0, _gen.Identifier)(decoderParamName)], [(0, _gen.ReturnStatement)(callExpression)]), [(0, _gen.Identifier)(getStringName), (0, _gen.Identifier)(decoder)]))));
97
- (0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(getStringName, [], [(0, _gen.ReturnStatement)((0, _gen.Literal)(encoded))]));
98
+ var keys = new Set();
99
+ var keysToMake = (0, _random.getRandomInteger)(4, 14);
100
+ for (var i = 0; i < keysToMake; i++) {
101
+ keys.add((0, _random.getRandomString)((0, _random.getRandomInteger)(4, 14)));
102
+ }
103
+ var objectExpression = (0, _gen.ObjectExpression)(Array.from(keys).map(key => {
104
+ return (0, _gen.Property)((0, _gen.Literal)(key), (0, _random.getRandomFalseExpression)(), true);
105
+ }));
106
+
107
+ // Get string function
108
+ var getStringBody = [];
109
+ var splits = (0, _random.splitIntoChunks)(encoded, Math.floor(encoded.length / (0, _random.getRandomInteger)(3, 6)));
110
+ getStringBody.push((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)("str", (0, _gen.Literal)(splits.shift()))));
111
+ getStringBody.push((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)("objectToTest", objectExpression)));
112
+ const addIfStatement = (testingFor, literalValueToBeAppended) => {
113
+ getStringBody.push((0, _gen.IfStatement)((0, _gen.BinaryExpression)("in", (0, _gen.Literal)(testingFor), (0, _gen.Identifier)("objectToTest")), [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("+=", (0, _gen.Identifier)("str"), (0, _gen.Literal)(literalValueToBeAppended)))]));
114
+ };
115
+ for (const split of splits) {
116
+ if ((0, _random.chance)(50)) {
117
+ var fakeKey;
118
+ do {
119
+ fakeKey = (0, _random.getRandomString)((0, _random.getRandomInteger)(4, 14));
120
+ } while (keys.has(fakeKey) || fakeKey in {});
121
+ addIfStatement(fakeKey, (0, _random.getRandomString)(split.length));
122
+ }
123
+ addIfStatement((0, _random.choice)(Array.from(keys)), split);
124
+ }
125
+
126
+ // Return computed string
127
+ getStringBody.push((0, _gen.ReturnStatement)((0, _gen.Identifier)("str")));
128
+ (0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(getStringName, [], getStringBody));
98
129
  (0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(this.fnName, [(0, _gen.Identifier)("index")], [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(split), (0, _gen.Identifier)("index"), true))]));
99
130
  (0, _insert.append)(tree, DecodeTemplate.single({
100
131
  name: decoder,
@@ -102,7 +133,7 @@ class StringCompression extends _transform.default {
102
133
  }));
103
134
  }
104
135
  match(object, parents) {
105
- return object.type == "Literal" && typeof object.value === "string" && object.value && object.value.length > 3 && !(0, _compare.isDirective)(object, parents) && !(0, _compare.isModuleSource)(object, parents);
136
+ return object.type == "Literal" && typeof object.value === "string" && object.value && object.value.length > 3 && !(0, _compare.isDirective)(object, parents) && !(0, _compare.isModuleSource)(object, parents) && !parents.find(x => x.$multiTransformSkip);
106
137
  }
107
138
  transform(object, parents) {
108
139
  if (!object.value) {
@@ -42,7 +42,7 @@ class StringConcealing extends _transform.default {
42
42
  super.apply(tree);
43
43
 
44
44
  // Pad array with useless strings
45
- var dead = (0, _random.getRandomInteger)(5, 15);
45
+ var dead = (0, _random.getRandomInteger)(50, 200);
46
46
  for (var i = 0; i < dead; i++) {
47
47
  var str = (0, _random.getRandomString)((0, _random.getRandomInteger)(5, 40));
48
48
  var fn = this.transform((0, _gen.Literal)(str), [tree]);
@@ -56,7 +56,8 @@ class StringConcealing extends _transform.default {
56
56
  // This helper functions convert UInt8 Array to UTf-string
57
57
  (0, _insert.prepend)(tree, ..._bufferToString.BufferToStringTemplate.compile({
58
58
  name: bufferToStringName,
59
- getGlobalFnName: this.getPlaceholder() + _constants.predictableFunctionTag
59
+ getGlobalFnName: this.getPlaceholder() + _constants.predictableFunctionTag,
60
+ GetGlobalTemplate: (0, _bufferToString.createGetGlobalTemplate)(this, tree, [])
60
61
  }));
61
62
  for (var functionObject of this.functionObjects) {
62
63
  var {
@@ -70,7 +71,7 @@ class StringConcealing extends _transform.default {
70
71
  __bufferToString__: bufferToStringName
71
72
  }));
72
73
  // All these are fake and never ran
73
- var ifStatements = (0, _template.default)(`if ( z == x ) {
74
+ var ifStatements = new _template.default(`if ( z == x ) {
74
75
  return y[${cacheName}[z]] = ${getterFnName}(x, y);
75
76
  }
76
77
  if ( y ) {
@@ -97,13 +98,13 @@ class StringConcealing extends _transform.default {
97
98
  ifStatements = ifStatements.filter(() => (0, _random.chance)(50));
98
99
 
99
100
  // This one is always used
100
- ifStatements.push((0, _template.default)(`
101
+ ifStatements.push(new _template.default(`
101
102
  if ( x !== y ) {
102
103
  return b[x] || (b[x] = a(${this.arrayName}[x]))
103
104
  }
104
105
  `).single());
105
106
  (0, _random.shuffle)(ifStatements);
106
- var varDeclaration = (0, _template.default)(`
107
+ var varDeclaration = new _template.default(`
107
108
  var ${getterFnName} = (x, y, z, a, b)=>{
108
109
  if(typeof a === "undefined") {
109
110
  a = ${decodeFn}
@@ -120,7 +121,7 @@ class StringConcealing extends _transform.default {
120
121
  }
121
122
  match(object, parents) {
122
123
  return object.type == "Literal" && typeof object.value === "string" && object.value.length >= 3 && !(0, _compare.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents) //&&
123
- /*!parents.find((x) => x.$dispatcherSkip)*/;
124
+ /*!parents.find((x) => x.$multiTransformSkip)*/;
124
125
  }
125
126
  transform(object, parents) {
126
127
  return () => {