js-confuser 1.5.5 → 1.5.7

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.
package/CHANGELOG.md CHANGED
@@ -1,8 +1,40 @@
1
+ # `1.5.7`
2
+ Countermeasures function fixes
3
+
4
+ This update focuses on fixing Countermeasures bugs
5
+
6
+ The `countermeasures` is custom callback function to invoke when a lock is triggered.
7
+
8
+ - Fixed [#66](https://github.com/MichaelXF/js-confuser/issues/66)
9
+ - - RGF to properly handle the countermeasures function
10
+
11
+ - Added additional code to prevent an infinite loop from occurring
12
+
13
+ - Slight improvements to RGF
14
+
15
+ # `1.5.6`
16
+ Website changed and RGF fixes
17
+
18
+ The website is back at a different domain now: [https://master--hungry-shannon-c1ce6b.netlify.app/](https://master--hungry-shannon-c1ce6b.netlify.app/)
19
+
20
+ This update focuses on fixing RGF bugs
21
+
22
+ - Fixed [#64](https://github.com/MichaelXF/js-confuser/issues/64)
23
+ - - RGF to properly handle Arrow functions and function expressions
24
+
25
+ - RGF will no longer change getter/setter methods
26
+
27
+ - RGF will no longer change class methods
28
+
29
+ - RGF now works when using `mangled` variable names
30
+
31
+ - Minify will remove unreachable code following a Throw statement
32
+
1
33
  # `1.5.5`
2
34
  Updates
3
35
 
4
36
  - Fixed [#53](https://github.com/MichaelXF/js-confuser/issues/53)
5
- - - Shuffle to not use common varialbe names like `x`
37
+ - - Shuffle to not use common variable names like `x`
6
38
 
7
39
  - Fixed [#60](https://github.com/MichaelXF/js-confuser/issues/60)
8
40
  - - Rename Variables to properly handle function parameters
@@ -447,7 +479,7 @@ Available now on NPM: https://www.npmjs.com/package/js-confuser
447
479
  # `1.1.7`
448
480
  Website is Live
449
481
 
450
- - [JsConfuser.com](https://jsconfuser.com) is live!
482
+ - [https://master--hungry-shannon-c1ce6b.netlify.app/](https://master--hungry-shannon-c1ce6b.netlify.app/) is live!
451
483
  - Check out the [js-confuser-website](https://github.com/MichaelXF/js-confuser-website) repo for more info
452
484
 
453
485
  - **⚠️ Breaking change**: `Rename Globals` is now enabled by default
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # JS Confuser
2
2
 
3
- JS-Confuser is a JavaScript obfuscation tool to make your programs _impossible_ to read. [Try the web version](https://jsconfuser.com).
3
+ JS-Confuser is a JavaScript obfuscation tool to make your programs _impossible_ to read. [Try the web version](https://master--hungry-shannon-c1ce6b.netlify.app/).
4
4
 
5
- [![NPM](https://img.shields.io/badge/NPM-%23000000.svg?style=for-the-badge&logo=npm&logoColor=white)](https://npmjs.com/package/js-confuser) [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/MichaelXF/js-confuser) [![Netlify](https://img.shields.io/badge/netlify-%23000000.svg?style=for-the-badge&logo=netlify&logoColor=#00C7B7)](https://jsconfuser.com)
5
+ [![NPM](https://img.shields.io/badge/NPM-%23000000.svg?style=for-the-badge&logo=npm&logoColor=white)](https://npmjs.com/package/js-confuser) [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/MichaelXF/js-confuser) [![Netlify](https://img.shields.io/badge/netlify-%23000000.svg?style=for-the-badge&logo=netlify&logoColor=#00C7B7)](https://master--hungry-shannon-c1ce6b.netlify.app/)
6
6
 
7
7
  ## Key features
8
8
 
@@ -224,7 +224,7 @@ class Flatten extends _transform.default {
224
224
 
225
225
  var call = (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(resultName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)("_", (0, _gen.AssignmentExpression)("=", identifier, (0, _gen.ArrayExpression)([(0, _gen.ArrayExpression)(input.map(_gen.Identifier)), (0, _gen.ArrayExpression)([...newParamNodes]), (0, _gen.Identifier)(resultName)])))]); // result.pop()
226
226
 
227
- var pop = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(propName), false), (0, _gen.Identifier)("pop"), false), []); // var result = newFn.call([...refs], ...arguments)
227
+ var pop = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(propName), false), (0, _gen.Literal)("pop"), true), []); // var result = newFn.call([...refs], ...arguments)
228
228
  // modified1 = result.pop();
229
229
  // modified2 = result.pop();
230
230
  // ...modifiedN = result.pop();...
@@ -103,8 +103,10 @@ class VariableAnalysis extends _transform.default {
103
103
  var definingContexts = info.spec.isDefined ? (0, _insert.getAllDefiningContexts)(o, p) : (0, _insert.getReferencingContexts)(o, p, info);
104
104
  (0, _assert.ok)(definingContexts.length);
105
105
  definingContexts.forEach(definingContext => {
106
- (0, _assert.ok)((0, _insert.isContext)(definingContext), "".concat(definingContext.type, " is not a context"));
107
-
106
+ // ok(
107
+ // isContext(definingContext),
108
+ // `${definingContext.type} is not a context`
109
+ // );
108
110
  if (isDefined) {
109
111
  // Add to defined Map
110
112
  if (!this.defined.has(definingContext)) {
@@ -148,7 +148,7 @@ class Integrity extends _transform.default {
148
148
  }
149
149
 
150
150
  return () => {
151
- object.__hiddenCountermeasures = this.lock.getCounterMeasuresCode();
151
+ object.__hiddenCountermeasures = this.lock.getCounterMeasuresCode(object, parents);
152
152
 
153
153
  object.$eval = () => {
154
154
  var functionName = this.generateIdentifier();
@@ -178,7 +178,11 @@ class Integrity extends _transform.default {
178
178
  ifStatement.alternate = (0, _gen.BlockStatement)(object.__hiddenCountermeasures);
179
179
  }
180
180
 
181
- object.body = (0, _gen.BlockStatement)([functionDeclaration, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(hashName, (0, _gen.CallExpression)((0, _insert.clone)(this.hashFn), [(0, _gen.CallExpression)((0, _insert.clone)(this.stringFn), [(0, _gen.Identifier)(functionName)]), (0, _gen.Literal)(this.seed)]))), ifStatement]);
181
+ object.body = (0, _gen.BlockStatement)([functionDeclaration, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(hashName, (0, _gen.CallExpression)((0, _insert.clone)(this.hashFn), [(0, _gen.CallExpression)((0, _insert.clone)(this.stringFn), [(0, _gen.Identifier)(functionName)]), (0, _gen.Literal)(this.seed)]))), ifStatement]); // Make sure the countermeasures activation variable is present
182
+
183
+ if (this.lock.counterMeasuresActivated) {
184
+ object.body.body.unshift((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.lock.counterMeasuresActivated)));
185
+ }
182
186
 
183
187
  if (object.type == "ArrowFunctionExpression") {
184
188
  object.type = "FunctionExpression";
@@ -43,6 +43,10 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
43
43
  * Applies browser & date locks.
44
44
  */
45
45
  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
+ */
46
50
  constructor(o) {
47
51
  super(o, _order.ObfuscateOrder.Lock); // Removed feature
48
52
  // if (this.options.lock.startDate && this.options.lock.endDate) {
@@ -55,6 +59,8 @@ class Lock extends _transform.default {
55
59
 
56
60
  _defineProperty(this, "iosDetectFn", void 0);
57
61
 
62
+ _defineProperty(this, "counterMeasuresActivated", void 0);
63
+
58
64
  _defineProperty(this, "made", void 0);
59
65
 
60
66
  if (this.options.lock.integrity) {
@@ -70,34 +76,29 @@ class Lock extends _transform.default {
70
76
 
71
77
  apply(tree) {
72
78
  if (typeof this.options.lock.countermeasures === "string" && (0, _compare.isValidIdentifier)(this.options.lock.countermeasures)) {
73
- var defined = new Set();
74
79
  (0, _traverse.default)(tree, (object, parents) => {
75
- if (object.type == "Identifier") {
80
+ if (object.type == "Identifier" && object.name === this.options.lock.countermeasures) {
76
81
  var info = (0, _identifiers.getIdentifierInfo)(object, parents);
77
82
 
78
83
  if (info.spec.isDefined) {
79
- defined.add(object.name);
80
-
81
- if (object.name === this.options.lock.countermeasures) {
82
- if (this.counterMeasuresNode) {
83
- throw new Error("Countermeasures function was already defined, it must have a unique name from the rest of your code");
84
- } else {
85
- var definingContext = (0, _insert.getVarContext)(parents[0], parents.slice(1));
86
-
87
- if (definingContext != tree) {
88
- throw new Error("Countermeasures function must be defined at the global level");
89
- }
84
+ if (this.counterMeasuresNode) {
85
+ throw new Error("Countermeasures function was already defined, it must have a unique name from the rest of your code");
86
+ } else {
87
+ var definingContext = (0, _insert.getVarContext)(parents[0], parents.slice(1));
90
88
 
91
- var chain = [object, parents];
89
+ if (definingContext != tree) {
90
+ throw new Error("Countermeasures function must be defined at the global level");
91
+ }
92
92
 
93
- if (info.isFunctionDeclaration) {
94
- chain = [parents[0], parents.slice(1)];
95
- } else if (info.isVariableDeclaration) {
96
- chain = [parents[1], parents.slice(2)];
97
- }
93
+ var chain = [object, parents];
98
94
 
99
- this.counterMeasuresNode = chain;
95
+ if (info.isFunctionDeclaration) {
96
+ chain = [parents[0], parents.slice(1)];
97
+ } else if (info.isVariableDeclaration) {
98
+ chain = [parents[1], parents.slice(2)];
100
99
  }
100
+
101
+ this.counterMeasuresNode = chain;
101
102
  }
102
103
  }
103
104
  }
@@ -111,7 +112,7 @@ class Lock extends _transform.default {
111
112
  super.apply(tree);
112
113
  }
113
114
 
114
- getCounterMeasuresCode() {
115
+ getCounterMeasuresCode(object, parents) {
115
116
  var opt = this.options.lock.countermeasures;
116
117
 
117
118
  if (opt === false) {
@@ -120,8 +121,13 @@ class Lock extends _transform.default {
120
121
 
121
122
 
122
123
  if (typeof opt === "string") {
123
- // Since Lock occurs before variable renaming, we are using the pre-obfuscated function name
124
- return [(0, _gen.ExpressionStatement)((0, _gen.CallExpression)((0, _template.default)(opt).single().expression, []))];
124
+ if (!this.counterMeasuresActivated) {
125
+ this.counterMeasuresActivated = this.getPlaceholder();
126
+ (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
+
129
+
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, [])])))];
125
131
  }
126
132
 
127
133
  var type = (0, _random.choice)(["crash", "exit"]);
@@ -239,7 +245,7 @@ class Lock extends _transform.default {
239
245
  // A very simple mechanism inspired from https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/src/custom-code-helpers/self-defending/templates/SelfDefendingNoEvalTemplate.ts
240
246
  // regExp checks for a newline, formatters add these
241
247
  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;
242
- nodes.push((0, _gen.IfStatement)(callExpression, this.getCounterMeasuresCode() || [], null));
248
+ nodes.push((0, _gen.IfStatement)(callExpression, this.getCounterMeasuresCode(object, parents) || [], null));
243
249
  break;
244
250
 
245
251
  case "nativeFunction":
@@ -270,23 +276,24 @@ class Lock extends _transform.default {
270
276
  test = (0, _template.default)("".concat(fn, ".toString().split(\"{ [native code] }\").length <= 1")).single().expression;
271
277
  }
272
278
 
273
- nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode() || [], null));
279
+ nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
274
280
  }
275
281
 
276
282
  break;
277
283
 
278
284
  case "startDate":
279
285
  test = (0, _gen.BinaryExpression)("<", dateNow, (0, _gen.Literal)(this.getTime(this.options.lock.startDate)));
280
- nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode() || [], null));
286
+ nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
281
287
  break;
282
288
 
283
289
  case "endDate":
284
290
  test = (0, _gen.BinaryExpression)(">", dateNow, (0, _gen.Literal)(this.getTime(this.options.lock.endDate)));
285
- nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode() || [], null));
291
+ nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
286
292
  break;
287
293
 
288
294
  case "context":
289
- var prop = (0, _random.choice)(this.options.lock.context); // Todo: Alternative to `this`
295
+ var prop = (0, _random.choice)(this.options.lock.context);
296
+ var code = this.getCounterMeasuresCode(object, parents) || []; // Todo: Alternative to `this`
290
297
 
291
298
  if (!this.globalVar) {
292
299
  offset = 1;
@@ -295,12 +302,13 @@ class Lock extends _transform.default {
295
302
  }
296
303
 
297
304
  test = (0, _gen.UnaryExpression)("!", (0, _gen.MemberExpression)((0, _gen.Identifier)(this.globalVar), (0, _gen.Literal)(prop), true));
298
- nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode() || [], null));
305
+ nodes.push((0, _gen.IfStatement)(test, code, null));
299
306
  break;
300
307
 
301
308
  case "osLock":
302
309
  var navigatorUserAgent = (0, _template.default)("window.navigator.userAgent.toLowerCase()").single().expression;
303
310
  (0, _assert.ok)(this.options.lock.osLock);
311
+ var code = this.getCounterMeasuresCode(object, parents) || [];
304
312
  this.options.lock.osLock.forEach(osName => {
305
313
  var agentMatcher = {
306
314
  windows: "Win",
@@ -338,7 +346,7 @@ class Lock extends _transform.default {
338
346
  });
339
347
  test = (0, _gen.UnaryExpression)("!", { ...test
340
348
  });
341
- nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode() || [], null));
349
+ nodes.push((0, _gen.IfStatement)(test, code, null));
342
350
  break;
343
351
 
344
352
  case "browserLock":
@@ -360,7 +368,7 @@ class Lock extends _transform.default {
360
368
  });
361
369
  test = (0, _gen.UnaryExpression)("!", { ...test
362
370
  });
363
- nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode() || [], null));
371
+ nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
364
372
  break;
365
373
 
366
374
  case "domainLock":
@@ -392,7 +400,7 @@ class Lock extends _transform.default {
392
400
  test = (0, _gen.LogicalExpression)("||", (0, _gen.BinaryExpression)("==", (0, _gen.UnaryExpression)("typeof", (0, _gen.Identifier)("location")), (0, _gen.Literal)("undefined")), test);
393
401
  }
394
402
 
395
- nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode() || [], null));
403
+ nodes.push((0, _gen.IfStatement)(test, this.getCounterMeasuresCode(object, parents) || [], null));
396
404
  }
397
405
 
398
406
  break;
@@ -53,7 +53,7 @@ class Minify extends _transform.default {
53
53
  var earlyReturn = body.length;
54
54
  var fnDecs = [];
55
55
  body.forEach((stmt, i) => {
56
- if (stmt.type == "ReturnStatement" || stmt.type == "BreakStatement" || stmt.type == "ContinueStatement") {
56
+ if (stmt.type === "ReturnStatement" || stmt.type === "BreakStatement" || stmt.type === "ContinueStatement" || stmt.type === "ThrowStatement") {
57
57
  if (earlyReturn > i + 1) {
58
58
  earlyReturn = i + 1;
59
59
  }
@@ -136,7 +136,7 @@ class Minify extends _transform.default {
136
136
  if (!lastDec || lastDec.kind !== x.kind || !lastDec.declarations.length) {
137
137
  lastDec = x;
138
138
  } else {
139
- lastDec.declarations.push(...x.declarations);
139
+ lastDec.declarations.push(...(0, _insert.clone)(x.declarations));
140
140
  remove.unshift(i);
141
141
  }
142
142
  } else {
@@ -17,8 +17,6 @@ var _identifiers = require("../../util/identifiers");
17
17
 
18
18
  var _label = _interopRequireDefault(require("../label"));
19
19
 
20
- var _antiDestructuring = _interopRequireDefault(require("../es5/antiDestructuring"));
21
-
22
20
  var _compare = require("../../util/compare");
23
21
 
24
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -179,11 +177,6 @@ class Preparation extends _transform.default {
179
177
  this.before.push(new _label.default(o));
180
178
  this.before.push(new ExplicitIdentifiers(o));
181
179
  this.before.push(new ExplicitDeclarations(o));
182
-
183
- if (this.options.es5) {
184
- this.before.push(new _antiDestructuring.default(o));
185
- } // this.before.push(new NameConflicts(o));
186
-
187
180
  }
188
181
 
189
182
  match() {
@@ -25,6 +25,8 @@ var _identifiers = require("../util/identifiers");
25
25
 
26
26
  var _insert = require("../util/insert");
27
27
 
28
+ var _random = require("../util/random");
29
+
28
30
  var _transform = _interopRequireDefault(require("./transform"));
29
31
 
30
32
  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); }
@@ -69,13 +71,52 @@ class RGF extends _transform.default {
69
71
  var collect = [];
70
72
  var queue = [];
71
73
  var names = new Map();
74
+ var referenceSignatures = {};
72
75
  var definingNodes = new Map();
73
76
  (0, _traverse.walk)(contextObject, contextParents, (object, parents) => {
74
77
  if (object !== contextObject && (0, _insert.isFunction)(object) && !object.$requiresEval && !object.async && !object.generator && (0, _insert.getVarContext)(parents[0], parents.slice(1)) === contextObject) {
78
+ var _this$options$lock;
79
+
80
+ // Discard getter/setter methods
81
+ if (parents[0].type === "Property" && parents[0].value === object) {
82
+ if (parents[0].method || parents[0].kind === "get" || parents[0].kind === "set") {
83
+ return;
84
+ }
85
+ } // Discard class methods
86
+
87
+
88
+ if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
89
+ return;
90
+ } // Avoid applying to the countermeasures function
91
+
92
+
93
+ if (typeof ((_this$options$lock = this.options.lock) === null || _this$options$lock === void 0 ? void 0 : _this$options$lock.countermeasures) === "string") {
94
+ // function countermeasures(){...}
95
+ if (object.type === "FunctionDeclaration" && object.id.type === "Identifier" && object.id.name === this.options.lock.countermeasures) {
96
+ return;
97
+ } // var countermeasures = function(){...}
98
+
99
+
100
+ if (parents[0].type === "VariableDeclarator" && parents[0].init === object && parents[0].id.type === "Identifier" && parents[0].id.name === this.options.lock.countermeasures) {
101
+ return;
102
+ }
103
+ }
104
+
75
105
  var defined = new Set(),
76
106
  referenced = new Set();
77
107
  var isBound = false;
78
- (0, _traverse.walk)(object.body, [object, ...parents], (o, p) => {
108
+ /**
109
+ * The fnTraverses serves two important purposes
110
+ *
111
+ * - Identify all the variables referenced and defined here
112
+ * - Identify is the 'this' keyword is used anywhere
113
+ *
114
+ * @param o
115
+ * @param p
116
+ * @returns
117
+ */
118
+
119
+ const fnTraverser = (o, p) => {
79
120
  if (o.type == "Identifier" && !_constants.reservedIdentifiers.has(o.name) && !this.options.globalVariables.has(o.name)) {
80
121
  var info = (0, _identifiers.getIdentifierInfo)(o, p);
81
122
 
@@ -83,7 +124,7 @@ class RGF extends _transform.default {
83
124
  return;
84
125
  }
85
126
 
86
- if (info.spec.isDefined) {
127
+ if (info.spec.isDefined && (0, _insert.getDefiningContext)(o, p) === object) {
87
128
  defined.add(o.name);
88
129
  } else {
89
130
  referenced.add(o.name);
@@ -93,7 +134,10 @@ class RGF extends _transform.default {
93
134
  if (o.type == "ThisExpression" || o.type == "Super") {
94
135
  isBound = true;
95
136
  }
96
- });
137
+ };
138
+
139
+ (0, _traverse.walk)(object.params, [object, ...parents], fnTraverser);
140
+ (0, _traverse.walk)(object.body, [object, ...parents], fnTraverser);
97
141
 
98
142
  if (!isBound) {
99
143
  var _object$id;
@@ -159,6 +203,7 @@ class RGF extends _transform.default {
159
203
  if (object.type == "FunctionDeclaration" && typeof object.id.name === "string") {
160
204
  var index = names.size;
161
205
  names.set(object.id.name, index);
206
+ referenceSignatures[index] = (0, _random.getRandomString)(10);
162
207
  definingNodes.set(object.id.name, object.id);
163
208
  }
164
209
  }
@@ -166,9 +211,10 @@ class RGF extends _transform.default {
166
211
 
167
212
  if (!queue.length) {
168
213
  return;
169
- }
214
+ } // An array containing all the function declarations
215
+
170
216
 
171
- var referenceArray = this.generateIdentifier();
217
+ var referenceArray = "_" + (0, _random.getRandomString)(10);
172
218
  (0, _traverse.walk)(contextObject, contextParents, (o, p) => {
173
219
  if (o.type == "Identifier" && !_constants.reservedIdentifiers.has(o.name)) {
174
220
  var index = names.get(o.name);
@@ -185,7 +231,19 @@ class RGF extends _transform.default {
185
231
 
186
232
  if (pointingTo == shouldBe) {
187
233
  this.log(o.name, "->", "".concat(referenceArray, "[").concat(index, "]"));
188
- this.replace(o, (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(referenceArray), (0, _gen.Literal)(index), true), [(0, _gen.Identifier)(referenceArray), (0, _gen.SpreadElement)((0, _gen.Identifier)("arguments"))]))]));
234
+ var memberExpression = (0, _gen.MemberExpression)((0, _gen.Identifier)(referenceArray), (0, _gen.Literal)(index), true); // Allow re-assignment to the RGF function
235
+
236
+ if (p[0] && p[0].type === "AssignmentExpression" && p[0].left === o) {
237
+ // fn = ...
238
+ this.replace(o, memberExpression);
239
+ } else {
240
+ // fn()
241
+ // fn
242
+ // In most cases the identifier is being used like this (call expression, or referenced to be called later)
243
+ // Replace it with a simple wrapper function that will pass on the reference array
244
+ var conditionalExpression = (0, _gen.ConditionalExpression)((0, _template.default)("typeof ".concat(referenceArray, "[").concat(index, "] === \"function\" && ").concat(referenceArray, "[").concat(index, "][\"").concat(referenceSignatures[index] || "_", "\"]")).single().expression, (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)((0, _gen.CallExpression)(memberExpression, [(0, _gen.Identifier)(referenceArray), (0, _gen.SpreadElement)((0, _gen.Identifier)("arguments"))]))]), memberExpression);
245
+ this.replace(o, conditionalExpression);
246
+ }
189
247
  }
190
248
  }
191
249
  }
@@ -202,6 +260,7 @@ class RGF extends _transform.default {
202
260
  var name = object === null || object === void 0 ? void 0 : (_object$id2 = object.id) === null || _object$id2 === void 0 ? void 0 : _object$id2.name;
203
261
  var hasName = !!name;
204
262
  var params = object.params.map(x => x.name) || [];
263
+ var signature = referenceSignatures[names.get(name)];
205
264
  var embeddedName = name || this.getPlaceholder(); // Since `new Function` is completely isolated, create an entire new obfuscator and run remaining transformations.
206
265
  // RGF runs early and needs completed code before converting to a string.
207
266
  // (^ the variables haven't been renamed yet)
@@ -222,7 +281,7 @@ class RGF extends _transform.default {
222
281
  };
223
282
  var tree = {
224
283
  type: "Program",
225
- body: [embeddedFunction, (0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(embeddedName), (0, _gen.Identifier)("call"), false), [(0, _gen.ThisExpression)(), (0, _gen.SpreadElement)((0, _template.default)("Array.prototype.slice.call(arguments, 1)").single().expression)]))]
284
+ body: [embeddedFunction, (0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(embeddedName), (0, _gen.Literal)("call"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.SpreadElement)((0, _template.default)("Array.prototype.slice.call(arguments, 1)").single().expression)]))]
226
285
  };
227
286
  tree.__hiddenDeclarations = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(referenceArray));
228
287
  tree.__hiddenDeclarations.hidden = true;
@@ -241,8 +300,17 @@ class RGF extends _transform.default {
241
300
  var toString = (0, _compiler.compileJsSync)(tree, this.options);
242
301
  var newFunction = (0, _gen.NewExpression)((0, _gen.Identifier)("Function"), [(0, _gen.Literal)(referenceArray), (0, _gen.Literal)(toString)]);
243
302
 
244
- if (hasName) {
245
- arrayExpression.elements[names.get(name)] = newFunction;
303
+ function applySignature(fn) {
304
+ if (!signature) {
305
+ return fn;
306
+ } // This code marks the function object with a unique property
307
+
308
+
309
+ return (0, _gen.CallExpression)((0, _gen.FunctionExpression)([], [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)("fn", fn)), (0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.MemberExpression)((0, _gen.Identifier)("fn"), (0, _gen.Literal)(signature), true), (0, _gen.Literal)(true))), (0, _gen.ReturnStatement)((0, _gen.Identifier)("fn"))]), []);
310
+ }
311
+
312
+ if (object.type === "FunctionDeclaration") {
313
+ arrayExpression.elements[names.get(name)] = applySignature(newFunction);
246
314
 
247
315
  if (Array.isArray(parents[0])) {
248
316
  parents[0].splice(parents[0].indexOf(object), 1);
@@ -250,7 +318,9 @@ class RGF extends _transform.default {
250
318
  this.error(new Error("Error deleting function declaration: " + parents.map(x => x.type).join(",")));
251
319
  }
252
320
  } else {
253
- this.replace(object, newFunction);
321
+ // The wrapper function passes the reference array around
322
+ var wrapperFunction = (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)(newFunction, (0, _gen.Literal)("call"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.Identifier)(referenceArray), (0, _gen.SpreadElement)((0, _gen.Identifier)("arguments"))]))]);
323
+ this.replace(object, applySignature(wrapperFunction));
254
324
  }
255
325
  });
256
326
  };
@@ -45,28 +45,8 @@ class StringSplitting extends _transform.default {
45
45
  this.vars = [];
46
46
  }
47
47
 
48
- apply(tree) {
49
- super.apply(tree);
50
-
51
- if (this.vars.length) {
52
- (0, _random.shuffle)(this.adders);
53
- (0, _random.shuffle)(this.vars);
54
- var body = tree.body;
55
- this.adders.forEach(nodes => {
56
- nodes.forEach(x => body.unshift(x));
57
- });
58
- var variableDeclaration = {
59
- type: "VariableDeclaration",
60
- declarations: [],
61
- kind: "var"
62
- };
63
- this.vars.forEach(node => variableDeclaration.declarations.push(node));
64
- body.unshift(variableDeclaration);
65
- }
66
- }
67
-
68
48
  match(object, parents) {
69
- return object.type == "Literal" && typeof object.value === "string" && !(0, _stringConcealing.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents);
49
+ return object.type == "Literal" && typeof object.value === "string" && object.value.length >= 8 && !(0, _stringConcealing.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents);
70
50
  }
71
51
 
72
52
  transform(object, parents) {
@@ -92,7 +72,6 @@ class StringSplitting extends _transform.default {
92
72
  var last = chunks.pop();
93
73
  chunks.forEach((chunk, i) => {
94
74
  if (i == 0) {
95
- (0, _assert.ok)(i == 0);
96
75
  parent = binaryExpression = (0, _gen.BinaryExpression)("+", (0, _gen.Literal)(chunk), (0, _gen.Literal)(""));
97
76
  } else {
98
77
  binaryExpression.left = (0, _gen.BinaryExpression)("+", (0, _insert.clone)(binaryExpression.left), (0, _gen.Literal)(chunk));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-confuser",
3
- "version": "1.5.5",
3
+ "version": "1.5.7",
4
4
  "description": "JavaScript Obfuscation Tool.",
5
5
  "main": "dist/index.js",
6
6
  "types": "index.d.ts",
@@ -45,7 +45,7 @@
45
45
  "bugs": {
46
46
  "url": "https://github.com/MichaelXF/js-confuser/issues"
47
47
  },
48
- "homepage": "https://jsconfuser.com",
48
+ "homepage": "https://master--hungry-shannon-c1ce6b.netlify.app/",
49
49
  "jest": {
50
50
  "coverageReporters": [
51
51
  "html"
@@ -328,8 +328,8 @@ export default class Flatten extends Transform {
328
328
  var pop = CallExpression(
329
329
  MemberExpression(
330
330
  MemberExpression(Identifier(resultName), Identifier(propName), false),
331
- Identifier("pop"),
332
- false
331
+ Literal("pop"),
332
+ true
333
333
  ),
334
334
  []
335
335
  );
@@ -93,10 +93,10 @@ export default class VariableAnalysis extends Transform {
93
93
  ok(definingContexts.length);
94
94
 
95
95
  definingContexts.forEach((definingContext) => {
96
- ok(
97
- isContext(definingContext),
98
- `${definingContext.type} is not a context`
99
- );
96
+ // ok(
97
+ // isContext(definingContext),
98
+ // `${definingContext.type} is not a context`
99
+ // );
100
100
 
101
101
  if (isDefined) {
102
102
  // Add to defined Map
@@ -195,7 +195,10 @@ export default class Integrity extends Transform {
195
195
  }
196
196
 
197
197
  return () => {
198
- object.__hiddenCountermeasures = this.lock.getCounterMeasuresCode();
198
+ object.__hiddenCountermeasures = this.lock.getCounterMeasuresCode(
199
+ object,
200
+ parents
201
+ );
199
202
 
200
203
  object.$eval = () => {
201
204
  var functionName = this.generateIdentifier();
@@ -258,6 +261,15 @@ export default class Integrity extends Transform {
258
261
  ifStatement,
259
262
  ]);
260
263
 
264
+ // Make sure the countermeasures activation variable is present
265
+ if (this.lock.counterMeasuresActivated) {
266
+ object.body.body.unshift(
267
+ VariableDeclaration(
268
+ VariableDeclarator(this.lock.counterMeasuresActivated)
269
+ )
270
+ );
271
+ }
272
+
261
273
  if (object.type == "ArrowFunctionExpression") {
262
274
  object.type = "FunctionExpression";
263
275
  object.expression = false;