js-confuser 1.2.1 → 1.4.1

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 (94) hide show
  1. package/CHANGELOG.md +171 -0
  2. package/README.md +7 -6
  3. package/dist/options.js +5 -1
  4. package/dist/parser.js +1 -2
  5. package/dist/presets.js +2 -2
  6. package/dist/transforms/calculator.js +48 -60
  7. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +482 -95
  8. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -0
  9. package/dist/transforms/controlFlowFlattening/{switchCaseObfucation.js → switchCaseObfuscation.js} +2 -2
  10. package/dist/transforms/deadCode.js +1 -1
  11. package/dist/transforms/dispatcher.js +14 -13
  12. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +5 -10
  13. package/dist/transforms/flatten.js +5 -1
  14. package/dist/transforms/hideInitializingCode.js +17 -2
  15. package/dist/transforms/identifier/globalConcealing.js +46 -25
  16. package/dist/transforms/identifier/movedDeclarations.js +69 -68
  17. package/dist/transforms/identifier/renameVariables.js +22 -98
  18. package/dist/transforms/identifier/variableAnalysis.js +133 -0
  19. package/dist/transforms/label.js +11 -2
  20. package/dist/transforms/lock/antiDebug.js +32 -13
  21. package/dist/transforms/lock/lock.js +13 -2
  22. package/dist/transforms/minify.js +117 -120
  23. package/dist/transforms/opaquePredicates.js +4 -2
  24. package/dist/transforms/preparation/preparation.js +8 -0
  25. package/dist/transforms/renameLabels.js +17 -3
  26. package/dist/transforms/rgf.js +8 -3
  27. package/dist/transforms/shuffle.js +25 -9
  28. package/dist/transforms/stack.js +5 -9
  29. package/dist/transforms/string/encoding.js +209 -0
  30. package/dist/transforms/string/stringCompression.js +10 -10
  31. package/dist/transforms/string/stringConcealing.js +94 -65
  32. package/dist/transforms/string/stringSplitting.js +7 -7
  33. package/dist/transforms/transform.js +10 -0
  34. package/dist/traverse.js +1 -35
  35. package/dist/util/gen.js +3 -1
  36. package/dist/util/identifiers.js +9 -19
  37. package/dist/util/insert.js +6 -40
  38. package/dist/util/scope.js +17 -0
  39. package/package.json +2 -2
  40. package/src/options.ts +19 -3
  41. package/src/parser.ts +1 -2
  42. package/src/presets.ts +2 -2
  43. package/src/transforms/calculator.ts +87 -91
  44. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +742 -142
  45. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +6 -0
  46. package/src/transforms/controlFlowFlattening/{switchCaseObfucation.ts → switchCaseObfuscation.ts} +6 -2
  47. package/src/transforms/deadCode.ts +8 -0
  48. package/src/transforms/dispatcher.ts +29 -14
  49. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +43 -19
  50. package/src/transforms/flatten.ts +15 -2
  51. package/src/transforms/hideInitializingCode.ts +432 -406
  52. package/src/transforms/identifier/globalConcealing.ts +148 -46
  53. package/src/transforms/identifier/movedDeclarations.ts +78 -101
  54. package/src/transforms/identifier/renameVariables.ts +21 -96
  55. package/src/transforms/identifier/variableAnalysis.ts +124 -0
  56. package/src/transforms/label.ts +20 -2
  57. package/src/transforms/lock/antiDebug.ts +69 -26
  58. package/src/transforms/lock/lock.ts +37 -3
  59. package/src/transforms/minify.ts +154 -130
  60. package/src/transforms/opaquePredicates.ts +25 -3
  61. package/src/transforms/preparation/preparation.ts +8 -1
  62. package/src/transforms/renameLabels.ts +26 -3
  63. package/src/transforms/rgf.ts +6 -1
  64. package/src/transforms/shuffle.ts +87 -29
  65. package/src/transforms/stack.ts +6 -8
  66. package/src/transforms/string/encoding.ts +310 -0
  67. package/src/transforms/string/stringCompression.ts +37 -24
  68. package/src/transforms/string/stringConcealing.ts +157 -160
  69. package/src/transforms/string/stringSplitting.ts +12 -8
  70. package/src/transforms/transform.ts +15 -2
  71. package/src/traverse.ts +1 -31
  72. package/src/util/gen.ts +5 -3
  73. package/src/util/identifiers.ts +20 -20
  74. package/src/util/insert.ts +12 -78
  75. package/src/util/scope.ts +9 -0
  76. package/test/{transforms/compare.test.ts → compare.test.ts} +2 -2
  77. package/test/index.test.ts +109 -1
  78. package/test/templates/template.test.ts +14 -0
  79. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +392 -10
  80. package/test/transforms/dispatcher.test.ts +30 -0
  81. package/test/transforms/flatten.test.ts +28 -0
  82. package/test/transforms/hideInitializingCode.test.ts +336 -336
  83. package/test/transforms/identifier/globalConcealing.test.ts +1 -2
  84. package/test/transforms/identifier/movedDeclarations.test.ts +137 -112
  85. package/test/transforms/identifier/renameVariables.test.ts +124 -13
  86. package/test/transforms/lock/antiDebug.test.ts +43 -0
  87. package/test/transforms/lock/selfDefending.test.ts +68 -0
  88. package/test/transforms/minify.test.ts +137 -0
  89. package/test/transforms/renameLabels.test.ts +33 -0
  90. package/test/transforms/rgf.test.ts +29 -0
  91. package/test/transforms/string/stringSplitting.test.ts +33 -0
  92. package/test/util/identifiers.test.ts +105 -17
  93. package/dist/util/expr.js +0 -60
  94. package/src/util/expr.ts +0 -56
@@ -19,153 +19,138 @@ var _traverse = require("../traverse");
19
19
 
20
20
  var _assert = require("assert");
21
21
 
22
+ var _scope = require("../util/scope");
23
+
22
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
25
 
24
26
  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; }
25
27
 
26
- class MinifyBlock extends _transform.default {
28
+ /**
29
+ * Basic transformations to reduce code size.
30
+ *
31
+ * Examples:
32
+ * - `if(a) { b() }` **->** `a && b()`
33
+ * - `if(a){b()}else{c()}` **->** `a?b():c()`
34
+ * - `x['y']` **->** `x.y`
35
+ */
36
+ class Minify extends _transform.default {
27
37
  constructor(o) {
28
- super(o);
38
+ super(o, _order.ObfuscateOrder.Minify);
39
+
40
+ _defineProperty(this, "variables", void 0);
41
+
42
+ this.variables = new Map();
29
43
  }
30
44
 
31
45
  match(object, parents) {
32
- return (0, _traverse.isBlock)(object) || object.type == "SwitchCase";
46
+ return object.hasOwnProperty("type");
33
47
  }
34
48
 
35
49
  transform(object, parents) {
36
- return () => {
37
- var body = object.type == "SwitchCase" ? object.consequent : (0, _insert.getBlockBody)(object);
38
- var earlyReturn = body.length;
39
- var fnDecs = [];
40
- body.forEach((stmt, i) => {
41
- if (stmt.type == "ReturnStatement" || stmt.type == "BreakStatement" || stmt.type == "ContinueStatement") {
42
- if (earlyReturn > i + 1) {
43
- earlyReturn = i + 1;
50
+ if ((0, _scope.isLexicalScope)(object)) {
51
+ return () => {
52
+ var body = object.type == "SwitchCase" ? object.consequent : (0, _insert.getBlockBody)(object);
53
+ var earlyReturn = body.length;
54
+ var fnDecs = [];
55
+ body.forEach((stmt, i) => {
56
+ if (stmt.type == "ReturnStatement" || stmt.type == "BreakStatement" || stmt.type == "ContinueStatement") {
57
+ if (earlyReturn > i + 1) {
58
+ earlyReturn = i + 1;
59
+ }
44
60
  }
45
- }
46
61
 
47
- if (stmt.type == "FunctionDeclaration") {
48
- fnDecs.push([stmt, i]);
49
- }
50
- });
62
+ if (stmt.type == "FunctionDeclaration") {
63
+ fnDecs.push([stmt, i]);
64
+ }
65
+ });
51
66
 
52
- if (earlyReturn < body.length) {
53
- body.length = earlyReturn;
54
- body.push(...fnDecs.filter(x => x[1] >= earlyReturn).map(x => x[0]));
55
- } // Now combine ExpressionStatements
67
+ if (earlyReturn < body.length) {
68
+ body.length = earlyReturn;
69
+ body.push(...fnDecs.filter(x => x[1] >= earlyReturn).map(x => x[0]));
70
+ } // Now combine ExpressionStatements
56
71
 
57
72
 
58
- if (body.length > 1) {
59
- var exprs = [];
60
- var startIndex = -1;
61
- var sequences = [];
62
- body.forEach((stmt, i) => {
63
- if (stmt.type == "ExpressionStatement") {
64
- exprs.push(stmt.expression);
73
+ if (body.length > 1) {
74
+ var exprs = [];
75
+ var startIndex = -1;
76
+ var sequences = [];
77
+ body.forEach((stmt, i) => {
78
+ if (stmt.type == "ExpressionStatement") {
79
+ exprs.push(stmt.expression);
65
80
 
66
- if (startIndex == -1) {
67
- startIndex = i;
68
- }
69
- } else {
70
- if (exprs.length) {
71
- sequences.push({
72
- exprs: exprs,
73
- index: startIndex
74
- });
81
+ if (startIndex == -1) {
82
+ startIndex = i;
83
+ }
84
+ } else {
85
+ if (exprs.length) {
86
+ sequences.push({
87
+ exprs: exprs,
88
+ index: startIndex
89
+ });
90
+ }
91
+
92
+ exprs = [];
93
+ startIndex = -1;
75
94
  }
95
+ });
76
96
 
77
- exprs = [];
78
- startIndex = -1;
97
+ if (exprs.length) {
98
+ sequences.push({
99
+ exprs: exprs,
100
+ index: startIndex
101
+ });
79
102
  }
80
- });
81
103
 
82
- if (exprs.length) {
83
- sequences.push({
84
- exprs: exprs,
85
- index: startIndex
104
+ sequences.reverse().forEach(seq => {
105
+ (0, _assert.ok)(seq.index != -1);
106
+ body.splice(seq.index, seq.exprs.length, (0, _gen.ExpressionStatement)(seq.exprs.length == 1 ? seq.exprs[0] : (0, _gen.SequenceExpression)(seq.exprs)));
86
107
  });
87
108
  }
88
109
 
89
- sequences.reverse().forEach(seq => {
90
- (0, _assert.ok)(seq.index != -1);
91
- body.splice(seq.index, seq.exprs.length, (0, _gen.ExpressionStatement)(seq.exprs.length == 1 ? seq.exprs[0] : (0, _gen.SequenceExpression)(seq.exprs)));
92
- });
93
- }
94
-
95
- if (object.type != "SwitchCase") {
96
- // Unnecessary return
97
- if (body.length && body[body.length - 1]) {
98
- var last = body[body.length - 1];
99
- var isUndefined = last.argument == null;
110
+ if (object.type != "SwitchCase") {
111
+ // Unnecessary return
112
+ if (body.length && body[body.length - 1]) {
113
+ var last = body[body.length - 1];
114
+ var isUndefined = last.argument == null;
100
115
 
101
- if (last.type == "ReturnStatement" && isUndefined) {
102
- body.pop();
103
- }
104
- } // Variable declaration grouping
105
- // var a = 1;
106
- // var b = 1;
107
- // var c = 1;
108
- //
109
- // var a=1,b=1,c=1;
110
-
111
-
112
- var lastDec = null;
113
- var remove = [];
114
- body.forEach((x, i) => {
115
- if (x.type === "VariableDeclaration") {
116
- if (!lastDec || lastDec.kind !== x.kind || !lastDec.declarations.length) {
117
- lastDec = x;
116
+ if (last.type == "ReturnStatement" && isUndefined) {
117
+ body.pop();
118
+ }
119
+ } // Variable declaration grouping
120
+ // var a = 1;
121
+ // var b = 1;
122
+ // var c = 1;
123
+ //
124
+ // var a=1,b=1,c=1;
125
+
126
+
127
+ var lastDec = null;
128
+ var remove = [];
129
+ body.forEach((x, i) => {
130
+ if (x.type === "VariableDeclaration") {
131
+ if (!lastDec || lastDec.kind !== x.kind || !lastDec.declarations.length) {
132
+ lastDec = x;
133
+ } else {
134
+ lastDec.declarations.push(...x.declarations);
135
+ remove.unshift(i);
136
+ }
118
137
  } else {
119
- lastDec.declarations.push(...x.declarations);
120
- remove.unshift(i);
138
+ lastDec = null;
121
139
  }
122
- } else {
123
- lastDec = null;
124
- }
125
- });
126
- remove.forEach(x => {
127
- body.splice(x, 1);
128
- });
129
- }
130
- };
131
- }
132
-
133
- }
134
- /**
135
- * Basic transformations to reduce code size.
136
- *
137
- * Examples:
138
- * - `if(a) { b() }` **->** `a && b()`
139
- * - `if(a){b()}else{c()}` **->** `a?b():c()`
140
- * - `x['y']` **->** `x.y`
141
- */
142
-
143
-
144
- class Minify extends _transform.default {
145
- constructor(o) {
146
- super(o, _order.ObfuscateOrder.Minify);
147
-
148
- _defineProperty(this, "variables", void 0);
149
-
150
- this.variables = new Map();
151
- /**
152
- * Minify runs at every Node, making Expression-based minification.
153
- * MinifyBlock runs only on Blocks, making Statement-based minification.
154
- */
155
-
156
- this.after.push(new MinifyBlock(o));
157
- }
158
-
159
- match(object, parents) {
160
- return object.hasOwnProperty("type");
161
- }
162
-
163
- transform(object, parents) {
140
+ });
141
+ remove.forEach(x => {
142
+ body.splice(x, 1);
143
+ });
144
+ }
145
+ };
146
+ }
164
147
  /**
165
148
  * ES6 and higher only
166
149
  * - `function(){}` -> `()=>{}`
167
150
  * - `function abc(){}` -> `var abc = ()=>{}`
168
151
  */
152
+
153
+
169
154
  if (!this.options.es5 && (object.type == "FunctionExpression" || object.type == "FunctionDeclaration")) {
170
155
  return () => {
171
156
  // Don't touch `{get key(){...}}`
@@ -329,7 +314,7 @@ class Minify extends _transform.default {
329
314
  if (last) {
330
315
  var lastStatement = last.consequent[last.consequent.length - 1];
331
316
 
332
- if (lastStatement.type == "BreakStatement" && lastStatement.label == null) {
317
+ if (lastStatement && lastStatement.type == "BreakStatement" && lastStatement.label == null) {
333
318
  last.consequent.pop();
334
319
  }
335
320
  } else {
@@ -425,7 +410,7 @@ class Minify extends _transform.default {
425
410
  var key = object.callee.computed ? object.callee.property.value : object.callee.property.name;
426
411
 
427
412
  if (key == "toString" && object.arguments.length == 0) {
428
- this.replace(object, (0, _gen.BinaryExpression)("+", (0, _insert.clone)(object.callee.object), (0, _gen.Literal)("")));
413
+ this.replace(object, (0, _gen.BinaryExpression)("+", (0, _gen.Literal)(""), (0, _insert.clone)(object.callee.object)));
429
414
  }
430
415
  }
431
416
  } // { "x": 1 } -> {x: 1}
@@ -452,6 +437,18 @@ class Minify extends _transform.default {
452
437
  if (object.init.name == "undefined") {
453
438
  object.init = null;
454
439
  }
440
+ }
441
+
442
+ if (object.id.type == "ObjectPattern" && object.init.type == "ObjectExpression") {
443
+ if (object.id.properties.length === 1 && object.init.properties.length === 1) {
444
+ var key1 = object.id.properties[0].computed ? object.id.properties[0].key.value : object.id.properties[0].key.name;
445
+ var key2 = object.init.properties[0].computed ? object.init.properties[0].key.value : object.init.properties[0].key.name; // console.log(key1, key2);
446
+
447
+ if (key1 && key2 && key1 === key2) {
448
+ object.id = object.id.properties[0].value;
449
+ object.init = object.init.properties[0].value;
450
+ }
451
+ }
455
452
  } // check for redundant patterns
456
453
 
457
454
 
@@ -467,7 +464,7 @@ class Minify extends _transform.default {
467
464
  return () => {
468
465
  switch (typeof object.value) {
469
466
  case "boolean":
470
- // this.replace(object, UnaryExpression("!", Literal(object.value ? 0 : 1)));
467
+ this.replaceIdentifierOrLiteral(object, (0, _gen.UnaryExpression)("!", (0, _gen.Literal)(object.value ? 0 : 1)), parents);
471
468
  break;
472
469
  }
473
470
  };
@@ -476,9 +473,9 @@ class Minify extends _transform.default {
476
473
  if (object.type == "Identifier") {
477
474
  return () => {
478
475
  if (object.name == "undefined" && !(0, _insert.isForInitialize)(object, parents)) {
479
- this.replace(object, (0, _gen.UnaryExpression)("void", (0, _gen.Literal)(0)));
476
+ this.replaceIdentifierOrLiteral(object, (0, _gen.UnaryExpression)("void", (0, _gen.Literal)(0)), parents);
480
477
  } else if (object.name == "Infinity") {
481
- this.replace(object, (0, _gen.BinaryExpression)("/", (0, _gen.Literal)(1), (0, _gen.Literal)(0)));
478
+ this.replaceIdentifierOrLiteral(object, (0, _gen.BinaryExpression)("/", (0, _gen.Literal)(1), (0, _gen.Literal)(0)), parents);
482
479
  }
483
480
  };
484
481
  }
@@ -89,7 +89,8 @@ class OpaquePredicates extends _transform.default {
89
89
  if (!this.predicate) {
90
90
  this.predicateName = this.getPlaceholder();
91
91
  this.predicate = (0, _gen.ObjectExpression)([]);
92
- (0, _insert.prepend)(parents[parents.length - 1] || object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.predicateName, this.predicate)));
92
+ var tempName = this.getPlaceholder();
93
+ (0, _insert.prepend)(parents[parents.length - 1] || object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.predicateName, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([], [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(tempName, this.predicate)), (0, _gen.ReturnStatement)((0, _gen.Identifier)(tempName))]), []))));
93
94
  }
94
95
 
95
96
  var expr = (0, _random.choice)(Object.values(this.predicates));
@@ -102,7 +103,8 @@ class OpaquePredicates extends _transform.default {
102
103
  case "array":
103
104
  var arrayProp = this.gen.generate();
104
105
  this.predicate.properties.push((0, _gen.Property)((0, _gen.Identifier)(arrayProp), (0, _gen.ArrayExpression)([])));
105
- this.predicate.properties.push((0, _gen.Property)((0, _gen.Identifier)(prop), (0, _gen.FunctionExpression)([], (0, _template.default)("\n if ( !".concat(this.predicateName, ".").concat(arrayProp, "[0] ) {\n ").concat(this.predicateName, ".").concat(arrayProp, ".push(").concat((0, _random.getRandomInteger)(-100, 100), ");\n }\n return ").concat(this.predicateName, ".").concat(arrayProp, ".length;\n ")).compile())));
106
+ var paramName = this.getPlaceholder();
107
+ 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)("\n if ( !".concat(this.predicateName, ".").concat(arrayProp, "[0] ) {\n ").concat(this.predicateName, ".").concat(arrayProp, ".push(").concat((0, _random.getRandomInteger)(-100, 100), ");\n }\n return ").concat(this.predicateName, ".").concat(arrayProp, "[").concat(paramName, "];\n ")).compile())));
106
108
  expr = (0, _gen.CallExpression)(accessor, []);
107
109
  break;
108
110
 
@@ -88,6 +88,14 @@ class ExplicitIdentifiers extends _transform.default {
88
88
  }
89
89
 
90
90
  transform(object, parents) {
91
+ if (object.name === "eval") {
92
+ var fn = (0, _insert.getFunction)(object, parents);
93
+
94
+ if (fn) {
95
+ fn.$requiresEval = true;
96
+ }
97
+ }
98
+
91
99
  var info = (0, _identifiers.getIdentifierInfo)(object, parents);
92
100
 
93
101
  if (info.isPropertyKey || info.isAccessor) {
@@ -40,12 +40,25 @@ class RenameLabels extends _transform.default {
40
40
  transform(object, parents) {
41
41
  return () => {
42
42
  var newName = null;
43
+ var isRemovable = object.body.type !== "BlockStatement";
44
+ var labelNeverUsed = true;
43
45
  (0, _traverse.walk)(object, parents, (o, p) => {
44
46
  if (o.type == "BreakStatement" || o.type == "ContinueStatement") {
45
- var labelStatement = p.find(x => (0, _compare.isLoop)(x));
47
+ function isContinuableStatement(x, stmtParents) {
48
+ return (0, _compare.isLoop)(x) && x.type !== "SwitchStatement";
49
+ }
50
+
51
+ function isBreakableStatement(x, stmtParents) {
52
+ return (0, _compare.isLoop)(x) || x.type == "BlockStatement" && o.label && stmtParents[0] && stmtParents[0].type == "LabeledStatement";
53
+ }
54
+
55
+ var fn = o.type == "ContinueStatement" ? isContinuableStatement : isBreakableStatement;
56
+ var labelStatement = p.find((node, i) => {
57
+ return fn(node, p.slice(i + 1));
58
+ });
46
59
 
47
60
  if (o.label && o.label.name == object.label.name) {
48
- if (object.body == labelStatement) {
61
+ if (object.body == labelStatement && isRemovable) {
49
62
  // In same loop
50
63
  o.label = null;
51
64
  } else {
@@ -54,6 +67,7 @@ class RenameLabels extends _transform.default {
54
67
  }
55
68
 
56
69
  o.label = (0, _gen.Identifier)(newName);
70
+ labelNeverUsed = false;
57
71
  }
58
72
  }
59
73
  }
@@ -61,7 +75,7 @@ class RenameLabels extends _transform.default {
61
75
 
62
76
  if (newName) {
63
77
  object.label = (0, _gen.Identifier)(newName);
64
- } else {
78
+ } else if (isRemovable || labelNeverUsed) {
65
79
  this.replace(object, (0, _insert.clone)(object.body));
66
80
  }
67
81
  };
@@ -71,7 +71,7 @@ class RGF extends _transform.default {
71
71
  var names = new Map();
72
72
  var definingNodes = new Map();
73
73
  (0, _traverse.walk)(contextObject, contextParents, (object, parents) => {
74
- if (object !== contextObject && (0, _insert.isFunction)(object) && !object.async && !object.generator && (0, _insert.getVarContext)(parents[0], parents.slice(1)) === contextObject) {
74
+ if (object !== contextObject && (0, _insert.isFunction)(object) && !object.$requiresEval && !object.async && !object.generator && (0, _insert.getVarContext)(parents[0], parents.slice(1)) === contextObject) {
75
75
  var defined = new Set(),
76
76
  referenced = new Set();
77
77
  var isBound = false;
@@ -79,9 +79,13 @@ class RGF extends _transform.default {
79
79
  if (o.type == "Identifier" && !_constants.reservedIdentifiers.has(o.name) && !this.options.globalVariables.has(o.name)) {
80
80
  var info = (0, _identifiers.getIdentifierInfo)(o, p);
81
81
 
82
+ if (!info.spec.isReferenced) {
83
+ return;
84
+ }
85
+
82
86
  if (info.spec.isDefined) {
83
87
  defined.add(o.name);
84
- } else if (info.spec.isReferenced || info.spec.isModified) {
88
+ } else {
85
89
  referenced.add(o.name);
86
90
  }
87
91
  }
@@ -205,7 +209,8 @@ class RGF extends _transform.default {
205
209
  lock: {
206
210
  integrity: false
207
211
  },
208
- eval: false
212
+ eval: false,
213
+ hideInitializingCode: false
209
214
  });
210
215
  var transforms = Object.values(obfuscator.transforms).filter(x => x.priority > this.priority);
211
216
  var embeddedFunction = { ...object,
@@ -85,15 +85,16 @@ class Shuffle extends _transform.default {
85
85
  return;
86
86
  }
87
87
 
88
- var mode = (0, _probability.ComputeProbabilityMap)(this.options.shuffle, x => x, object.elements.map(x => x.value));
88
+ var mapped = object.elements.map(x => x.value);
89
+ var mode = (0, _probability.ComputeProbabilityMap)(this.options.shuffle, x => x, mapped);
89
90
 
90
91
  if (mode) {
91
- var shift = (0, _random.getRandomInteger)(1, Math.min(100, object.elements.length * 6));
92
+ var shift = (0, _random.getRandomInteger)(1, Math.min(60, object.elements.length * 6));
92
93
  var expr = (0, _gen.Literal)(shift);
93
94
  var name = this.getPlaceholder();
94
95
 
95
96
  if (mode == "hash") {
96
- var str = object.elements.map(x => x.value + "").join("");
97
+ var str = mapped.join("");
97
98
  shift = Hash(str);
98
99
 
99
100
  if (!this.hashName) {
@@ -116,8 +117,10 @@ class Shuffle extends _transform.default {
116
117
 
117
118
  var code = [];
118
119
  var iName = this.getPlaceholder();
119
- code.push((0, _gen.ForStatement)((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(iName, expr)), (0, _gen.Identifier)(iName), (0, _gen.UpdateExpression)("--", (0, _gen.Identifier)(iName), false), [(0, _template.default)("".concat(name, ".unshift(").concat(name, ".pop())")).single()]));
120
120
  var inPlace = false;
121
+ var inPlaceName;
122
+ var inPlaceBody;
123
+ var inPlaceIndex;
121
124
  var varDeclarator = parents[0];
122
125
 
123
126
  if (varDeclarator.type == "VariableDeclarator") {
@@ -126,15 +129,28 @@ class Shuffle extends _transform.default {
126
129
  if (varDec.type == "VariableDeclaration") {
127
130
  var body = parents[3];
128
131
 
129
- if (varDec.declarations.length == 1 && Array.isArray(body)) {
130
- inPlace = true;
131
- var i = body.indexOf(varDec);
132
- (0, _assert.ok)(i != -1);
133
- body.splice(i + 1, 0, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, (0, _gen.Identifier)(varDeclarator.id.name))), ...code);
132
+ if (varDec.declarations.length == 1 && Array.isArray(body) && varDeclarator.id.type === "Identifier" && varDeclarator.init === object) {
133
+ inPlaceIndex = body.indexOf(varDec);
134
+ inPlaceBody = body;
135
+ inPlace = inPlaceIndex !== -1;
136
+ inPlaceName = varDeclarator.id.name;
134
137
  }
135
138
  }
136
139
  }
137
140
 
141
+ if (mode !== "hash") {
142
+ code.push((0, _template.default)("\n for ( var x = 16; x%4 === 0; x++) {\n var z = 0;\n ".concat(inPlace ? "".concat(inPlaceName, " = ").concat(name) : name, " = ").concat(name, ".concat((function(){\n z++;\n if(z === 1){\n return [];\n }\n\n for( var i = ").concat((0, _random.getRandomInteger)(5, 105), "; i; i-- ){\n ").concat(name, ".unshift(").concat(name, ".pop());\n }\n return [];\n })());\n }\n ")).single());
143
+ }
144
+
145
+ code.push((0, _gen.ForStatement)((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(iName, expr)), (0, _gen.Identifier)(iName), (0, _gen.UpdateExpression)("--", (0, _gen.Identifier)(iName), false), [// ${name}.unshift(${name}.pop());
146
+ (0, _gen.ExpressionStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(name), (0, _gen.Identifier)("unshift"), false), [(0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(name), (0, _gen.Identifier)("pop"), false), [])]))]));
147
+
148
+ if (inPlace) {
149
+ var varDeclarator = parents[0];
150
+ (0, _assert.ok)(i != -1);
151
+ inPlaceBody.splice(inPlaceIndex + 1, 0, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, (0, _gen.Identifier)(varDeclarator.id.name))), ...code);
152
+ }
153
+
138
154
  if (!inPlace) {
139
155
  this.replace(object, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([(0, _gen.Identifier)(name)], [...code, (0, _gen.ReturnStatement)((0, _gen.Identifier)(name))]), [(0, _insert.clone)(object)]));
140
156
  }
@@ -37,7 +37,7 @@ class Stack extends _transform.default {
37
37
  }
38
38
 
39
39
  match(object, parents) {
40
- return (0, _insert.isFunction)(object) && !object.params.find(x => x.type !== "Identifier") && object.body.type === "BlockStatement" && !parents.find(x => x.$dispatcherSkip);
40
+ return (0, _insert.isFunction)(object) && !object.params.find(x => x.type !== "Identifier") && object.body.type === "BlockStatement" && !parents.find(x => x.$dispatcherSkip) && !object.$requiresEval;
41
41
  }
42
42
 
43
43
  transform(object, parents) {
@@ -160,6 +160,7 @@ class Stack extends _transform.default {
160
160
  }
161
161
 
162
162
  var stackName = this.getPlaceholder();
163
+ var made = 1;
163
164
 
164
165
  const scan = (o, p) => {
165
166
  if (o.type == "Identifier") {
@@ -214,15 +215,10 @@ class Stack extends _transform.default {
214
215
  }
215
216
  }
216
217
 
217
- if (o.type == "Literal" && typeof o.value === "number" && Math.floor(o.value) === o.value && Math.abs(o.value) < 100000 && Math.random() > 0.5 && p.find(x => (0, _insert.isFunction)(x)) === object) {
218
+ if (o.type == "Literal" && typeof o.value === "number" && Math.floor(o.value) === o.value && Math.abs(o.value) < 100000 && Math.random() < 4 / made && p.find(x => (0, _insert.isFunction)(x)) === object) {
219
+ made++;
218
220
  return () => {
219
- if (p[0].type == "Property" || p[0].type == "MethodDefinition") {
220
- if (!p[0].computed) {
221
- p[0].computed = true;
222
- }
223
- }
224
-
225
- this.replace(o, numberLiteral(o.value, 0));
221
+ this.replaceIdentifierOrLiteral(o, numberLiteral(o.value, 0), p);
226
222
  };
227
223
  }
228
224
  };