js-confuser 1.7.1 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/.github/workflows/node.js.yml +1 -1
  2. package/CHANGELOG.md +73 -0
  3. package/README.md +32 -31
  4. package/dist/compiler.js +2 -8
  5. package/dist/constants.js +22 -10
  6. package/dist/index.js +15 -30
  7. package/dist/obfuscator.js +15 -62
  8. package/dist/options.js +33 -40
  9. package/dist/order.js +4 -7
  10. package/dist/parser.js +5 -13
  11. package/dist/precedence.js +6 -8
  12. package/dist/presets.js +4 -6
  13. package/dist/probability.js +13 -24
  14. package/dist/templates/bufferToString.js +121 -5
  15. package/dist/templates/core.js +35 -0
  16. package/dist/templates/crash.js +22 -11
  17. package/dist/templates/es5.js +125 -6
  18. package/dist/templates/functionLength.js +24 -6
  19. package/dist/templates/globals.js +9 -0
  20. package/dist/templates/template.js +189 -43
  21. package/dist/transforms/antiTooling.js +26 -22
  22. package/dist/transforms/calculator.js +19 -55
  23. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +242 -333
  24. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
  25. package/dist/transforms/deadCode.js +542 -31
  26. package/dist/transforms/dispatcher.js +112 -112
  27. package/dist/transforms/es5/antiClass.js +70 -44
  28. package/dist/transforms/es5/antiDestructuring.js +14 -38
  29. package/dist/transforms/es5/antiES6Object.js +39 -48
  30. package/dist/transforms/es5/antiSpreadOperator.js +5 -14
  31. package/dist/transforms/es5/antiTemplate.js +10 -19
  32. package/dist/transforms/es5/es5.js +7 -40
  33. package/dist/transforms/extraction/classExtraction.js +83 -0
  34. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +41 -80
  35. package/dist/transforms/extraction/objectExtraction.js +24 -56
  36. package/dist/transforms/finalizer.js +6 -20
  37. package/dist/transforms/flatten.js +51 -99
  38. package/dist/transforms/identifier/globalAnalysis.js +21 -26
  39. package/dist/transforms/identifier/globalConcealing.js +72 -56
  40. package/dist/transforms/identifier/movedDeclarations.js +66 -38
  41. package/dist/transforms/identifier/renameVariables.js +36 -68
  42. package/dist/transforms/identifier/variableAnalysis.js +21 -48
  43. package/dist/transforms/lock/antiDebug.js +20 -25
  44. package/dist/transforms/lock/integrity.js +53 -52
  45. package/dist/transforms/lock/lock.js +161 -126
  46. package/dist/transforms/minify.js +77 -108
  47. package/dist/transforms/opaquePredicates.js +12 -49
  48. package/dist/transforms/preparation.js +28 -49
  49. package/dist/transforms/renameLabels.js +5 -22
  50. package/dist/transforms/rgf.js +125 -72
  51. package/dist/transforms/shuffle.js +42 -47
  52. package/dist/transforms/stack.js +41 -98
  53. package/dist/transforms/string/encoding.js +76 -27
  54. package/dist/transforms/string/stringCompression.js +75 -68
  55. package/dist/transforms/string/stringConcealing.js +127 -135
  56. package/dist/transforms/string/stringEncoding.js +6 -26
  57. package/dist/transforms/string/stringSplitting.js +5 -30
  58. package/dist/transforms/transform.js +76 -104
  59. package/dist/traverse.js +11 -18
  60. package/dist/util/compare.js +27 -29
  61. package/dist/util/gen.js +32 -86
  62. package/dist/util/guard.js +5 -1
  63. package/dist/util/identifiers.js +9 -72
  64. package/dist/util/insert.js +27 -77
  65. package/dist/util/math.js +0 -3
  66. package/dist/util/object.js +3 -7
  67. package/dist/util/random.js +31 -36
  68. package/dist/util/scope.js +6 -3
  69. package/docs/Countermeasures.md +13 -6
  70. package/docs/Integrity.md +35 -28
  71. package/docs/RGF.md +6 -1
  72. package/docs/RenameVariables.md +116 -0
  73. package/docs/TamperProtection.md +100 -0
  74. package/docs/Template.md +117 -0
  75. package/package.json +3 -3
  76. package/src/constants.ts +17 -0
  77. package/src/index.ts +7 -5
  78. package/src/options.ts +60 -7
  79. package/src/order.ts +2 -2
  80. package/src/templates/bufferToString.ts +79 -11
  81. package/src/templates/core.ts +29 -0
  82. package/src/templates/crash.ts +6 -38
  83. package/src/templates/es5.ts +1 -1
  84. package/src/templates/functionLength.ts +21 -3
  85. package/src/templates/globals.ts +3 -0
  86. package/src/templates/template.ts +205 -46
  87. package/src/transforms/antiTooling.ts +33 -11
  88. package/src/transforms/calculator.ts +4 -2
  89. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +12 -5
  90. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
  91. package/src/transforms/deadCode.ts +74 -42
  92. package/src/transforms/dispatcher.ts +99 -73
  93. package/src/transforms/es5/antiClass.ts +25 -12
  94. package/src/transforms/es5/antiDestructuring.ts +1 -1
  95. package/src/transforms/es5/antiES6Object.ts +2 -2
  96. package/src/transforms/es5/antiTemplate.ts +1 -1
  97. package/src/transforms/extraction/classExtraction.ts +168 -0
  98. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +11 -16
  99. package/src/transforms/extraction/objectExtraction.ts +4 -15
  100. package/src/transforms/flatten.ts +20 -5
  101. package/src/transforms/identifier/globalAnalysis.ts +18 -1
  102. package/src/transforms/identifier/globalConcealing.ts +119 -72
  103. package/src/transforms/identifier/movedDeclarations.ts +90 -24
  104. package/src/transforms/identifier/renameVariables.ts +16 -1
  105. package/src/transforms/lock/antiDebug.ts +2 -2
  106. package/src/transforms/lock/integrity.ts +13 -11
  107. package/src/transforms/lock/lock.ts +122 -30
  108. package/src/transforms/minify.ts +28 -13
  109. package/src/transforms/opaquePredicates.ts +2 -2
  110. package/src/transforms/preparation.ts +16 -0
  111. package/src/transforms/rgf.ts +139 -12
  112. package/src/transforms/shuffle.ts +3 -3
  113. package/src/transforms/stack.ts +19 -4
  114. package/src/transforms/string/encoding.ts +88 -51
  115. package/src/transforms/string/stringCompression.ts +86 -17
  116. package/src/transforms/string/stringConcealing.ts +148 -118
  117. package/src/transforms/string/stringEncoding.ts +1 -2
  118. package/src/transforms/string/stringSplitting.ts +1 -2
  119. package/src/transforms/transform.ts +63 -46
  120. package/src/types.ts +2 -0
  121. package/src/util/compare.ts +39 -5
  122. package/src/util/gen.ts +10 -3
  123. package/src/util/guard.ts +10 -0
  124. package/src/util/insert.ts +17 -0
  125. package/src/util/random.ts +81 -1
  126. package/src/util/scope.ts +14 -2
  127. package/test/code/Cash.test.ts +94 -5
  128. package/test/code/StrictMode.src.js +65 -0
  129. package/test/code/StrictMode.test.js +37 -0
  130. package/test/compare.test.ts +62 -2
  131. package/test/options.test.ts +129 -55
  132. package/test/templates/template.test.ts +211 -1
  133. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
  134. package/test/transforms/dispatcher.test.ts +55 -0
  135. package/test/transforms/extraction/classExtraction.test.ts +86 -0
  136. package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +8 -0
  137. package/test/transforms/extraction/objectExtraction.test.ts +2 -0
  138. package/test/transforms/identifier/globalConcealing.test.ts +89 -0
  139. package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
  140. package/test/transforms/identifier/renameVariables.test.ts +75 -1
  141. package/test/transforms/lock/tamperProtection.test.ts +336 -0
  142. package/test/transforms/minify.test.ts +37 -0
  143. package/test/transforms/rgf.test.ts +50 -0
  144. package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
  145. package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
  146. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
  147. package/dist/transforms/eval.js +0 -84
  148. package/dist/transforms/hexadecimalNumbers.js +0 -63
  149. package/dist/transforms/hideInitializingCode.js +0 -270
  150. package/dist/transforms/identifier/nameRecycling.js +0 -218
  151. package/dist/transforms/label.js +0 -67
  152. package/dist/transforms/preparation/nameConflicts.js +0 -116
  153. package/dist/transforms/preparation/preparation.js +0 -188
@@ -4,160 +4,167 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _assert = require("assert");
9
-
10
8
  var _order = require("../../order");
11
-
12
9
  var _probability = require("../../probability");
13
-
14
10
  var _template = _interopRequireDefault(require("../../templates/template"));
15
-
16
11
  var _compare = require("../../util/compare");
17
-
18
12
  var _gen = require("../../util/gen");
19
-
20
13
  var _insert = require("../../util/insert");
21
-
22
14
  var _transform = _interopRequireDefault(require("../transform"));
23
-
24
- var _stringConcealing = require("./stringConcealing");
25
-
15
+ var _constants = require("../../constants");
26
16
  var _random = require("../../util/random");
27
-
28
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
-
30
- 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; }
31
-
17
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
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; }
19
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
20
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
32
21
  function LZ_encode(c) {
33
22
  (0, _assert.ok)(c);
34
23
  var x = "charCodeAt",
35
- b,
36
- e = {},
37
- f = c.split(""),
38
- d = [],
39
- a = f[0],
40
- g = 256;
41
-
24
+ b,
25
+ e = {},
26
+ f = c.split(""),
27
+ d = [],
28
+ a = f[0],
29
+ g = 256;
42
30
  for (b = 1; b < f.length; b++) c = f[b], null != e[a + c] ? a += c : (d.push(1 < a.length ? e[a] : a[x](0)), e[a + c] = g, g++, a = c);
43
-
44
31
  d.push(1 < a.length ? e[a] : a[x](0));
45
-
46
32
  for (b = 0; b < d.length; b++) d[b] = String.fromCharCode(d[b]);
47
-
48
33
  return d.join("");
49
34
  }
50
-
51
35
  function LZ_decode(b) {
52
36
  (0, _assert.ok)(b);
53
37
  var o,
54
- f,
55
- a,
56
- e = {},
57
- d = b.split(""),
58
- c = f = d[0],
59
- g = [c],
60
- h = o = 256;
61
-
38
+ f,
39
+ a,
40
+ e = {},
41
+ d = b.split(""),
42
+ c = f = d[0],
43
+ g = [c],
44
+ h = o = 256;
62
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;
63
-
64
46
  return g.join("");
65
47
  }
66
-
67
- const DecodeTemplate = (0, _template.default)("function {name}(b){\n var o,\n f,\n a,\n e = {},\n d = b.split(\"\"),\n c = (f = d[0]),\n g = [c],\n h = (o = 256);\n for (b = 1; b < d.length; b++)\n (a = d[b].charCodeAt(0)),\n (a = h > a ? d[b] : e[a] ? e[a] : f + c),\n g.push(a),\n (c = a.charAt(0)),\n (e[o] = f + c),\n o++,\n (f = a);\n return g.join(\"\").split(\"{delimiter}\");\n }");
68
-
48
+ const DecodeTemplate = new _template.default(`function {name}(b){
49
+ var o,
50
+ f,
51
+ a,
52
+ e = {},
53
+ d = b.split(""),
54
+ c = (f = d[0]),
55
+ g = [c],
56
+ h = (o = 256);
57
+ for (b = 1; b < d.length; b++)
58
+ (a = d[b].charCodeAt(0)),
59
+ (a = h > a ? d[b] : e[a] ? e[a] : f + c),
60
+ g.push(a),
61
+ (c = a.charAt(0)),
62
+ (e[o] = f + c),
63
+ o++,
64
+ (f = a);
65
+ return g.join("").split("{delimiter}");
66
+ }`);
69
67
  class StringCompression extends _transform.default {
70
68
  constructor(o) {
71
69
  super(o, _order.ObfuscateOrder.StringCompression);
72
-
73
70
  _defineProperty(this, "map", void 0);
74
-
75
71
  _defineProperty(this, "ignore", void 0);
76
-
77
72
  _defineProperty(this, "string", void 0);
78
-
79
73
  _defineProperty(this, "delimiter", "|");
80
-
81
74
  _defineProperty(this, "fnName", void 0);
82
-
83
75
  this.map = new Map();
84
76
  this.ignore = new Set();
85
77
  this.string = "";
86
- this.fnName = this.getPlaceholder();
78
+ this.fnName = this.getPlaceholder() + _constants.predictableFunctionTag;
87
79
  }
88
-
89
80
  apply(tree) {
90
81
  super.apply(tree);
91
82
  this.string = this.string.slice(0, this.string.length - 1);
92
-
93
83
  if (!this.string.length) {
94
84
  return;
95
85
  }
96
-
97
86
  var split = this.getPlaceholder();
98
87
  var decoder = this.getPlaceholder();
99
- var getStringName = this.getPlaceholder();
100
- var encoded = LZ_encode(this.string);
88
+ var getStringName = this.getPlaceholder() + _constants.predictableFunctionTag; // Returns the string payload
101
89
 
90
+ var encoded = LZ_encode(this.string);
102
91
  if (LZ_decode(encoded) !== this.string) {
103
92
  this.error(new Error("String failed to be decoded. Try disabling the 'stringCompression' option."));
104
93
  }
105
-
106
94
  var getStringParamName = this.getPlaceholder();
107
95
  var decoderParamName = this.getPlaceholder();
108
96
  var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(decoderParamName), [(0, _gen.CallExpression)((0, _gen.Identifier)(getStringParamName), [])]);
109
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)]))));
110
- (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));
111
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))]));
112
130
  (0, _insert.append)(tree, DecodeTemplate.single({
113
131
  name: decoder,
114
132
  delimiter: this.delimiter
115
133
  }));
116
134
  }
117
-
118
135
  match(object, parents) {
119
- return object.type == "Literal" && typeof object.value === "string" && object.value && object.value.length > 3 && !(0, _compare.isDirective)(object, parents) && !(0, _stringConcealing.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);
120
137
  }
121
-
122
138
  transform(object, parents) {
123
139
  if (!object.value) {
124
140
  return;
125
141
  }
126
-
127
142
  if (this.ignore.has(object.value) || object.value.includes(this.delimiter)) {
128
143
  return;
129
144
  }
130
-
131
145
  if (!parents[0] || parents[0].type == "CallExpression" && parents[0].callee.type == "Identifier" && parents[0].callee.name == this.fnName) {
132
146
  return;
133
147
  }
134
-
135
148
  if (!(0, _probability.ComputeProbabilityMap)(this.options.stringCompression, x => x, object.value)) {
136
149
  return;
137
- } // HARD CODED LIMIT of 10,000 (after 1,000 elements)
138
-
139
-
140
- if (this.map.size > 1000 && !(0, _random.chance)(this.map.size / 100)) return;
141
- var index = this.map.get(object.value); // New string, add it!
150
+ }
151
+ var index = this.map.get(object.value);
142
152
 
153
+ // New string, add it!
143
154
  if (typeof index !== "number") {
144
155
  // Ensure the string gets properly decoded
145
156
  if (LZ_decode(LZ_encode(object.value)) !== object.value) {
146
157
  this.ignore.add(object.value);
147
158
  return;
148
159
  }
149
-
150
160
  index = this.map.size;
151
161
  this.map.set(object.value, index);
152
162
  this.string += object.value + this.delimiter;
153
163
  }
154
-
155
164
  (0, _assert.ok)(typeof index === "number");
156
165
  return () => {
157
166
  this.replaceIdentifierOrLiteral(object, (0, _gen.CallExpression)((0, _gen.Identifier)(this.fnName), [(0, _gen.Literal)(index)]), parents);
158
167
  };
159
168
  }
160
-
161
169
  }
162
-
163
170
  exports.default = StringCompression;
@@ -4,236 +4,231 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- exports.isModuleSource = isModuleSource;
8
-
9
7
  var _assert = require("assert");
10
-
11
8
  var _order = require("../../order");
12
-
13
9
  var _template = _interopRequireDefault(require("../../templates/template"));
14
-
15
10
  var _traverse = require("../../traverse");
16
-
17
11
  var _compare = require("../../util/compare");
18
-
19
12
  var _gen = require("../../util/gen");
20
-
21
13
  var _insert = require("../../util/insert");
22
-
23
14
  var _random = require("../../util/random");
24
-
25
15
  var _transform = _interopRequireDefault(require("../transform"));
26
-
27
- var _encoding = _interopRequireDefault(require("./encoding"));
28
-
16
+ var _encoding = require("./encoding");
29
17
  var _probability = require("../../probability");
30
-
31
18
  var _bufferToString = require("../../templates/bufferToString");
32
-
33
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34
-
35
- 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; }
36
-
37
- function isModuleSource(object, parents) {
38
- if (!parents[0]) {
39
- return false;
40
- }
41
-
42
- if (parents[0].type == "ImportDeclaration" && parents[0].source == object) {
43
- return true;
44
- }
45
-
46
- if (parents[0].type == "ImportExpression" && parents[0].source == object) {
47
- return true;
48
- }
49
-
50
- if (parents[1] && parents[1].type == "CallExpression" && parents[1].arguments[0] === object && parents[1].callee.type == "Identifier") {
51
- if (parents[1].callee.name == "require" || parents[1].callee.name == "import") {
52
- return true;
53
- }
54
- }
55
-
56
- return false;
57
- }
58
-
19
+ var _constants = require("../../constants");
20
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
+ 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
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
23
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
59
24
  class StringConcealing extends _transform.default {
60
25
  constructor(o) {
61
26
  super(o, _order.ObfuscateOrder.StringConcealing);
62
-
63
27
  _defineProperty(this, "arrayExpression", void 0);
64
-
65
28
  _defineProperty(this, "set", void 0);
66
-
67
29
  _defineProperty(this, "index", void 0);
68
-
30
+ // index, fnName, block
69
31
  _defineProperty(this, "arrayName", this.getPlaceholder());
70
-
71
32
  _defineProperty(this, "ignore", new Set());
72
-
73
33
  _defineProperty(this, "variablesMade", 1);
74
-
75
- _defineProperty(this, "encoding", Object.create(null));
76
-
77
34
  _defineProperty(this, "gen", void 0);
78
-
79
- _defineProperty(this, "hasAllEncodings", void 0);
80
-
35
+ _defineProperty(this, "functionObjects", []);
81
36
  this.set = new Set();
82
37
  this.index = Object.create(null);
83
38
  this.arrayExpression = (0, _gen.ArrayExpression)([]);
84
- this.hasAllEncodings = false;
85
- this.gen = this.getGenerator(); // Pad array with useless strings
86
-
87
- var dead = (0, _random.getRandomInteger)(5, 15);
39
+ this.gen = this.getGenerator();
40
+ }
41
+ apply(tree) {
42
+ super.apply(tree);
88
43
 
44
+ // Pad array with useless strings
45
+ var dead = (0, _random.getRandomInteger)(50, 200);
89
46
  for (var i = 0; i < dead; i++) {
90
47
  var str = (0, _random.getRandomString)((0, _random.getRandomInteger)(5, 40));
91
- var fn = this.transform((0, _gen.Literal)(str), []);
92
-
48
+ var fn = this.transform((0, _gen.Literal)(str), [tree]);
93
49
  if (fn) {
94
50
  fn();
95
51
  }
96
52
  }
97
- }
98
-
99
- apply(tree) {
100
- super.apply(tree);
101
53
  var cacheName = this.getPlaceholder();
102
- var bufferToStringName = this.getPlaceholder(); // This helper functions convert UInt8 Array to UTf-string
54
+ var bufferToStringName = this.getPlaceholder() + _constants.predictableFunctionTag;
103
55
 
56
+ // This helper functions convert UInt8 Array to UTf-string
104
57
  (0, _insert.prepend)(tree, ..._bufferToString.BufferToStringTemplate.compile({
105
- name: bufferToStringName
58
+ name: bufferToStringName,
59
+ getGlobalFnName: this.getPlaceholder() + _constants.predictableFunctionTag,
60
+ GetGlobalTemplate: (0, _bufferToString.createGetGlobalTemplate)(this, tree, [])
106
61
  }));
107
- Object.keys(this.encoding).forEach(type => {
62
+ for (var functionObject of this.functionObjects) {
108
63
  var {
109
- template
110
- } = _encoding.default[type];
111
- var decodeFn = this.getPlaceholder();
112
- var getterFn = this.encoding[type];
113
- (0, _insert.append)(tree, template.single({
114
- name: decodeFn,
115
- bufferToString: bufferToStringName
64
+ block,
65
+ fnName: getterFnName,
66
+ encodingImplementation
67
+ } = functionObject;
68
+ var decodeFn = this.getPlaceholder() + _constants.predictableFunctionTag + _constants.criticalFunctionTag;
69
+ (0, _insert.append)(block, encodingImplementation.template.single({
70
+ __fnName__: decodeFn,
71
+ __bufferToString__: bufferToStringName
116
72
  }));
117
- (0, _insert.append)(tree, (0, _template.default)("\n \n function ".concat(getterFn, "(x, y, z, a = ").concat(decodeFn, ", b = ").concat(cacheName, "){\n if ( z ) {\n return y[").concat(cacheName, "[z]] = ").concat(getterFn, "(x, y);\n } else if ( y ) {\n [b, y] = [a(b), x || z]\n }\n \n return y ? x[b[y]] : ").concat(cacheName, "[x] || (z=(b[x], a), ").concat(cacheName, "[x] = z(").concat(this.arrayName, "[x]))\n }\n \n ")).single());
118
- });
119
- var flowIntegrity = this.getPlaceholder();
120
- (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(cacheName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)(flowIntegrity, (0, _gen.Literal)(0)), (0, _gen.VariableDeclarator)(this.arrayName, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([], [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)("a", this.arrayExpression)), (0, _template.default)("return (".concat(flowIntegrity, " ? a[\"pop\"]() : ").concat(flowIntegrity, "++, a)")).single()]), []))]));
121
- }
73
+ // All these are fake and never ran
74
+ var ifStatements = new _template.default(`if ( z == x ) {
75
+ return y[${cacheName}[z]] = ${getterFnName}(x, y);
76
+ }
77
+ if ( y ) {
78
+ [b, y] = [a(b), x || z]
79
+ return ${getterFnName}(x, b, z)
80
+ }
81
+ if ( z && a !== ${decodeFn} ) {
82
+ ${getterFnName} = ${decodeFn}
83
+ return ${getterFnName}(x, -1, z, a, b)
84
+ }
85
+ if ( a === ${getterFnName} ) {
86
+ ${decodeFn} = y
87
+ return ${decodeFn}(z)
88
+ }
89
+ if( a === undefined ) {
90
+ ${getterFnName} = b
91
+ }
92
+ if( z == a ) {
93
+ return y ? x[b[y]] : ${cacheName}[x] || (z=(b[x] || a), ${cacheName}[x] = z(${this.arrayName}[x]))
94
+ }
95
+ `).compile();
122
96
 
123
- match(object, parents) {
124
- return object.type == "Literal" && typeof object.value === "string" && object.value.length >= 3 && !isModuleSource(object, parents) && !(0, _compare.isDirective)(object, parents) //&&
97
+ // Not all fake if-statements are needed
98
+ ifStatements = ifStatements.filter(() => (0, _random.chance)(50));
125
99
 
126
- /*!parents.find((x) => x.$dispatcherSkip)*/
127
- ;
100
+ // This one is always used
101
+ ifStatements.push(new _template.default(`
102
+ if ( x !== y ) {
103
+ return b[x] || (b[x] = a(${this.arrayName}[x]))
104
+ }
105
+ `).single());
106
+ (0, _random.shuffle)(ifStatements);
107
+ var varDeclaration = new _template.default(`
108
+ var ${getterFnName} = (x, y, z, a, b)=>{
109
+ if(typeof a === "undefined") {
110
+ a = ${decodeFn}
111
+ }
112
+ if(typeof b === "undefined") {
113
+ b = ${cacheName}
114
+ }
115
+ }
116
+ `).single();
117
+ varDeclaration.declarations[0].init.body.body.push(...ifStatements);
118
+ (0, _insert.prepend)(block, varDeclaration);
119
+ }
120
+ (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(cacheName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)(this.arrayName, this.arrayExpression)]));
121
+ }
122
+ match(object, parents) {
123
+ return object.type == "Literal" && typeof object.value === "string" && object.value.length >= 3 && !(0, _compare.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents) //&&
124
+ /*!parents.find((x) => x.$multiTransformSkip)*/;
128
125
  }
129
-
130
126
  transform(object, parents) {
131
127
  return () => {
132
128
  // Empty strings are discarded
133
129
  if (!object.value || this.ignore.has(object.value) || object.value.length == 0) {
134
130
  return;
135
- } // Allow user to choose which strings get changed
136
-
131
+ }
137
132
 
133
+ // Allow user to choose which strings get changed
138
134
  if (!(0, _probability.ComputeProbabilityMap)(this.options.stringConcealing, x => x, object.value)) {
139
135
  return;
140
- } // HARD CODED LIMIT of 10,000 (after 1,000 elements)
141
-
142
-
143
- if (this.set.size > 1000 && !(0, _random.chance)(this.set.size / 100)) return;
144
- var types = Object.keys(this.encoding);
145
- var type = (0, _random.choice)(types);
146
-
147
- if (!type || !this.hasAllEncodings && (0, _random.chance)(10)) {
148
- var allowed = Object.keys(_encoding.default).filter(type => !this.encoding[type]);
149
-
150
- if (!allowed.length) {
151
- this.hasAllEncodings = true;
152
- } else {
153
- var random = (0, _random.choice)(allowed);
154
- type = random;
155
- this.encoding[random] = this.getPlaceholder();
156
- }
157
136
  }
158
-
159
- var fnName = this.encoding[type];
160
- var encoder = _encoding.default[type]; // The decode function must return correct result
161
-
162
- var encoded = encoder.encode(object.value);
163
-
164
- if (encoder.decode(encoded) != object.value) {
165
- this.ignore.add(object.value);
166
- this.warn(type, object.value.slice(0, 100));
167
- return;
137
+ var currentBlock = (0, _traverse.getBlock)(object, parents);
138
+
139
+ // Find created functions
140
+ var functionObjects = parents.filter(node => node.$stringConcealingFunctionObject).map(item => item.$stringConcealingFunctionObject);
141
+
142
+ // Choose random functionObject to use
143
+ var functionObject = (0, _random.choice)(functionObjects);
144
+ if (!functionObject || !(0, _encoding.hasAllEncodings)() && (0, _random.chance)(25 / this.functionObjects.length) && !currentBlock.$stringConcealingFunctionObject) {
145
+ // No functions, create one
146
+
147
+ var newFunctionObject = {
148
+ block: currentBlock,
149
+ encodingImplementation: (0, _encoding.createEncodingImplementation)(),
150
+ fnName: this.getPlaceholder() + _constants.predictableFunctionTag
151
+ };
152
+ this.functionObjects.push(newFunctionObject);
153
+ currentBlock.$stringConcealingFunctionObject = newFunctionObject;
154
+ functionObject = newFunctionObject;
168
155
  }
169
-
156
+ var {
157
+ fnName,
158
+ encodingImplementation
159
+ } = functionObject;
170
160
  var index = -1;
171
161
 
172
- if (!this.set.has(object.value)) {
162
+ // String already decoded?
163
+ if (this.set.has(object.value)) {
164
+ var row = this.index[object.value];
165
+ if (parents.includes(row[2])) {
166
+ [index, fnName] = row;
167
+ (0, _assert.ok)(typeof index === "number");
168
+ }
169
+ }
170
+ if (index == -1) {
171
+ // The decode function must return correct result
172
+ var encoded = encodingImplementation.encode(object.value);
173
+ if (encodingImplementation.decode(encoded) !== object.value) {
174
+ this.ignore.add(object.value);
175
+ this.warn(encodingImplementation.identity, object.value.slice(0, 100));
176
+ delete _encoding.EncodingImplementations[encodingImplementation.identity];
177
+ return;
178
+ }
173
179
  this.arrayExpression.elements.push((0, _gen.Literal)(encoded));
174
180
  index = this.arrayExpression.elements.length - 1;
175
- this.index[object.value] = [index, fnName];
181
+ this.index[object.value] = [index, fnName, currentBlock];
176
182
  this.set.add(object.value);
177
- } else {
178
- [index, fnName] = this.index[object.value];
179
- (0, _assert.ok)(typeof index === "number");
180
183
  }
181
-
182
184
  (0, _assert.ok)(index != -1, "index == -1");
183
- var callExpr = (0, _gen.CallExpression)((0, _gen.Identifier)(fnName), [(0, _gen.Literal)(index)]); // use `.apply` to fool automated de-obfuscators
185
+ var callExpr = (0, _gen.CallExpression)((0, _gen.Identifier)(fnName), [(0, _gen.Literal)(index)]);
184
186
 
187
+ // use `.apply` to fool automated de-obfuscators
185
188
  if ((0, _random.chance)(10)) {
186
189
  callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Literal)("apply"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.ArrayExpression)([(0, _gen.Literal)(index)])]);
187
- } // use `.call`
190
+ }
191
+
192
+ // use `.call`
188
193
  else if ((0, _random.chance)(10)) {
189
194
  callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Literal)("call"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.Literal)(index)]);
190
195
  }
191
-
192
196
  var referenceType = "call";
193
-
194
197
  if (parents.length && (0, _random.chance)(50 - this.variablesMade)) {
195
198
  referenceType = "constantReference";
196
199
  }
197
-
198
200
  var newExpr = callExpr;
199
-
200
201
  if (referenceType === "constantReference") {
201
202
  // Define the string earlier, reference the name here
202
203
  this.variablesMade++;
203
204
  var constantReferenceType = (0, _random.choice)(["variable", "array", "object"]);
204
- var place = (0, _random.choice)(parents.filter(node => (0, _traverse.isBlock)(node)));
205
-
205
+ var place = currentBlock;
206
206
  if (!place) {
207
207
  this.error(new Error("No lexical block to insert code"));
208
208
  }
209
-
210
209
  switch (constantReferenceType) {
211
210
  case "variable":
212
211
  var name = this.getPlaceholder();
213
212
  (0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, callExpr)));
214
213
  newExpr = (0, _gen.Identifier)(name);
215
214
  break;
216
-
217
215
  case "array":
218
216
  if (!place.$stringConcealingArray) {
219
217
  place.$stringConcealingArray = (0, _gen.ArrayExpression)([]);
220
218
  place.$stringConcealingArrayName = this.getPlaceholder();
221
219
  (0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(place.$stringConcealingArrayName, place.$stringConcealingArray)));
222
220
  }
223
-
224
221
  var arrayIndex = place.$stringConcealingArray.elements.length;
225
222
  place.$stringConcealingArray.elements.push(callExpr);
226
223
  var memberExpression = (0, _gen.MemberExpression)((0, _gen.Identifier)(place.$stringConcealingArrayName), (0, _gen.Literal)(arrayIndex), true);
227
224
  newExpr = memberExpression;
228
225
  break;
229
-
230
226
  case "object":
231
227
  if (!place.$stringConcealingObject) {
232
228
  place.$stringConcealingObject = (0, _gen.ObjectExpression)([]);
233
229
  place.$stringConcealingObjectName = this.getPlaceholder();
234
230
  (0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(place.$stringConcealingObjectName, place.$stringConcealingObject)));
235
231
  }
236
-
237
232
  var propName = this.gen.generate();
238
233
  var property = (0, _gen.Property)((0, _gen.Literal)(propName), callExpr, true);
239
234
  place.$stringConcealingObject.properties.push(property);
@@ -242,11 +237,8 @@ class StringConcealing extends _transform.default {
242
237
  break;
243
238
  }
244
239
  }
245
-
246
240
  this.replaceIdentifierOrLiteral(object, newExpr, parents);
247
241
  };
248
242
  }
249
-
250
243
  }
251
-
252
244
  exports.default = StringConcealing;