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
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _template = _interopRequireDefault(require("../../templates/template"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ const Encoding = {
13
+ ascii85: {
14
+ encode(a) {
15
+ var b, c, d, e, f, g, h, i, j, k; // @ts-ignore
16
+
17
+ for ( // @ts-ignore
18
+ !/[^\x00-\xFF]/.test(a), b = "\x00\x00\x00\x00".slice(a.length % 4 || 4), a += b, c = [], d = 0, e = a.length; e > d; d += 4) f = (a.charCodeAt(d) << 24) + (a.charCodeAt(d + 1) << 16) + (a.charCodeAt(d + 2) << 8) + a.charCodeAt(d + 3), 0 !== f ? (k = f % 85, f = (f - k) / 85, j = f % 85, f = (f - j) / 85, i = f % 85, f = (f - i) / 85, h = f % 85, f = (f - h) / 85, g = f % 85, c.push(g + 33, h + 33, i + 33, j + 33, k + 33)) : c.push(122);
19
+
20
+ return function (a, b) {
21
+ for (var c = b; c > 0; c--) a.pop();
22
+ }(c, b.length), "<~" + String.fromCharCode.apply(String, c) + "~>";
23
+ },
24
+
25
+ decode(a) {
26
+ var c,
27
+ d,
28
+ e,
29
+ f,
30
+ g,
31
+ h = String,
32
+ l = "length",
33
+ w = 255,
34
+ x = "charCodeAt",
35
+ y = "slice",
36
+ z = "replace";
37
+
38
+ for ("<~" === a[y](0, 2) && "~>" === a[y](-2), a = a[y](2, -2)[z](/s/g, "")[z]("z", "!!!!!"), c = "uuuuu"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);
39
+
40
+ return function (a, b) {
41
+ for (var c = b; c > 0; c--) a.pop();
42
+ }(e, c[l]), h.fromCharCode.apply(h, e);
43
+ },
44
+
45
+ template: (0, _template.default)("\n function {name}(a, LL = [\"fromCharCode\", \"apply\"]) {\n var c, d, e, f, g, h = String, l = \"length\", w = 255, x = \"charCodeAt\", y = \"slice\", z = \"replace\";\n for (\"<~\" === a[y](0, 2) && \"~>\" === a[y](-2), a = a[y](2, -2)[z](/s/g, \"\")[z](\"z\", \"!!!!!\"), \n c = \"uuuuu\"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), \n e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);\n return function(a, b) {\n for (var c = b; c > 0; c--) a.pop();\n }(e, c[l]), h[LL[0]][LL[1]](h, e);\n }\n ")
46
+ },
47
+ base32: {
48
+ encode: function (s) {
49
+ var a = "!\"#$%&'()*+,-./0123456789:;<=>?@";
50
+ var len = s.length;
51
+ var o = "";
52
+ var w,
53
+ c,
54
+ r = 0,
55
+ sh = 0,
56
+ i;
57
+
58
+ for (i = 0; i < len; i += 5) {
59
+ // mask top 5 bits
60
+ c = s.charCodeAt(i);
61
+ w = 0xf8 & c;
62
+ o += a.charAt(w >> 3);
63
+ r = 0x07 & c;
64
+ sh = 2;
65
+
66
+ if (i + 1 < len) {
67
+ c = s.charCodeAt(i + 1); // mask top 2 bits
68
+
69
+ w = 0xc0 & c;
70
+ o += a.charAt((r << 2) + (w >> 6));
71
+ o += a.charAt((0x3e & c) >> 1);
72
+ r = c & 0x01;
73
+ sh = 4;
74
+ }
75
+
76
+ if (i + 2 < len) {
77
+ c = s.charCodeAt(i + 2); // mask top 4 bits
78
+
79
+ w = 0xf0 & c;
80
+ o += a.charAt((r << 4) + (w >> 4));
81
+ r = 0x0f & c;
82
+ sh = 1;
83
+ }
84
+
85
+ if (i + 3 < len) {
86
+ c = s.charCodeAt(i + 3); // mask top 1 bit
87
+
88
+ w = 0x80 & c;
89
+ o += a.charAt((r << 1) + (w >> 7));
90
+ o += a.charAt((0x7c & c) >> 2);
91
+ r = 0x03 & c;
92
+ sh = 3;
93
+ }
94
+
95
+ if (i + 4 < len) {
96
+ c = s.charCodeAt(i + 4); // mask top 3 bits
97
+
98
+ w = 0xe0 & c;
99
+ o += a.charAt((r << 3) + (w >> 5));
100
+ o += a.charAt(0x1f & c);
101
+ r = 0;
102
+ sh = 0;
103
+ }
104
+ } // Calculate length of pad by getting the
105
+ // number of words to reach an 8th octet.
106
+
107
+
108
+ if (r != 0) {
109
+ o += a.charAt(r << sh);
110
+ }
111
+
112
+ return o;
113
+ },
114
+ decode: function (s) {
115
+ var v,
116
+ x,
117
+ bits = 0,
118
+ o = "",
119
+ len = s.length,
120
+ d = String,
121
+ e = "charCodeAt",
122
+ f = "fromCharCode",
123
+ i;
124
+
125
+ for (i = 0; i < len; i += 1) {
126
+ v = s[e](i) - 33, v >= 0 && v < 32 ? (bits += (x = x << 5 | v, 5), bits >= 8 ? bits -= (o += d[f](x >> bits - 8 & 0xff), 8) : 0) : 0;
127
+ }
128
+
129
+ return o;
130
+ },
131
+ template: (0, _template.default)("\n function {name}(s) {\n var v,\n x,\n b = 0,\n o = \"\",\n len = s.length,\n d = String,\n e = \"charCodeAt\",\n f = \"fromCharCode\", i;\n \n for (i = 0; i < len; i += 1) {\n (v = s[e](i) - 33),\n v >= 0 && v < 32\n ? ((b += ((x = (x << 5) | v), 5)),\n b >= 8\n ? (b -= ((o += d[f]((x >> (b - 8)) & 0xff)), 8))\n : 0)\n : 0;\n }\n return o;\n }\n ")
132
+ },
133
+ hexTable: {
134
+ encode: function (str) {
135
+ var output = "";
136
+
137
+ for (var j = 0; j < str.length; j += 3) {
138
+ var chunk = str.substring(j, j + 3);
139
+
140
+ if (!chunk) {
141
+ continue;
142
+ }
143
+
144
+ chunk = chunk + "~";
145
+ var uniqueChars = new Set([]);
146
+
147
+ for (var char of chunk) {
148
+ uniqueChars.add(char);
149
+ }
150
+
151
+ var keys = Array.from(uniqueChars).sort();
152
+ var table = {},
153
+ i = 0;
154
+
155
+ for (var key of keys) {
156
+ table[key] = i++;
157
+ }
158
+
159
+ var idx = [];
160
+
161
+ for (var char of chunk) {
162
+ idx.push(table[char]);
163
+ }
164
+
165
+ var table64 = "0x";
166
+
167
+ for (var i = keys.length - 1; i >= 0; i--) {
168
+ table64 += keys[i].charCodeAt(0).toString(16).toUpperCase();
169
+ }
170
+
171
+ var idxInt = 0;
172
+
173
+ for (var i = idx.length - 1; i >= 0; i--) {
174
+ idxInt = idxInt << 3 | idx[i];
175
+ }
176
+
177
+ var idx64 = "0x" + idxInt.toString(16).toUpperCase(); // console.log(chunk, table, idx, table64, idx64);
178
+
179
+ output += table64 + "," + idx64 + ",";
180
+ }
181
+
182
+ if (output.endsWith(",")) {
183
+ output = output.substring(0, output.length - 1);
184
+ }
185
+
186
+ return "{" + output + "}";
187
+ },
188
+ decode: function (str) {
189
+ var output = "";
190
+ str = str.substring(1, str.length - 1);
191
+ var chunks = str.split(",");
192
+
193
+ for (var i = 0; i < chunks.length; i += 2) {
194
+ var arr = [chunks[i], chunks[i + 1]];
195
+ var [table, idx] = arr.map(Number); // console.log(table, idx);
196
+
197
+ while (idx) {
198
+ output += String.fromCharCode(table >> 8 * (idx & 7) & 0xff);
199
+ idx >>= 3;
200
+ }
201
+ }
202
+
203
+ return output.replace(/~/g, "");
204
+ },
205
+ template: (0, _template.default)("\n function {name}(str){\n var output = \"\";\n \n str = str.substring(1, str.length - 1);\n var chunks = str.split(\",\");\n \n for (var i = 0; i < chunks.length; i += 2) {\n var arr = [chunks[i], chunks[i + 1]];\n \n var [table, idx] = arr.map(Number);\n \n // console.log(table, idx);\n while (idx) {\n output += String.fromCharCode((table >> (8 * (idx & 7))) & 0xff);\n idx >>= 3;\n }\n }\n \n return output.replace(/~/g, \"\");\n }\n \n ")
206
+ }
207
+ };
208
+ var _default = Encoding;
209
+ exports.default = _default;
@@ -62,7 +62,7 @@ function LZ_decode(b) {
62
62
  return g.join("");
63
63
  }
64
64
 
65
- 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(\"\");\n }");
65
+ 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 }");
66
66
 
67
67
  class StringCompression extends _transform.default {
68
68
  constructor(o) {
@@ -94,17 +94,22 @@ class StringCompression extends _transform.default {
94
94
 
95
95
  var split = this.getPlaceholder();
96
96
  var decoder = this.getPlaceholder();
97
+ var getStringName = this.getPlaceholder();
97
98
  var encoded = LZ_encode(this.string);
98
99
 
99
100
  if (LZ_decode(encoded) !== this.string) {
100
101
  this.error(new Error("String failed to be decoded"));
101
102
  }
102
103
 
103
- var callExpression = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.CallExpression)((0, _gen.Identifier)(decoder), [(0, _gen.Literal)(encoded)]), (0, _gen.Identifier)("split"), false), [(0, _gen.Literal)(this.delimiter)]);
104
- (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(split, callExpression)));
104
+ var getStringParamName = this.getPlaceholder();
105
+ var decoderParamName = this.getPlaceholder();
106
+ var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(decoderParamName), [(0, _gen.CallExpression)((0, _gen.Identifier)(getStringParamName), [])]);
107
+ (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)]))));
108
+ (0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(getStringName, [], [(0, _gen.ReturnStatement)((0, _gen.Literal)(encoded))]));
105
109
  (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))]));
106
110
  (0, _insert.append)(tree, DecodeTemplate.single({
107
- name: decoder
111
+ name: decoder,
112
+ delimiter: this.delimiter
108
113
  }));
109
114
  }
110
115
 
@@ -151,12 +156,7 @@ class StringCompression extends _transform.default {
151
156
  }
152
157
 
153
158
  (0, _assert.ok)(typeof index === "number");
154
- this.replace(object, (0, _gen.CallExpression)((0, _gen.Identifier)(this.fnName), [(0, _gen.Literal)(index)])); // Fix 2. Make parent property key computed
155
-
156
- if (parents[0] && (parents[0].type == "Property" || parents[0].type == "MethodDefinition") && parents[0].key == object) {
157
- parents[0].computed = true;
158
- parents[0].shorthand = false;
159
- }
159
+ this.replaceIdentifierOrLiteral(object, (0, _gen.CallExpression)((0, _gen.Identifier)(this.fnName), [(0, _gen.Literal)(index)]), parents);
160
160
  }
161
161
 
162
162
  }
@@ -12,52 +12,24 @@ var _order = require("../../order");
12
12
 
13
13
  var _template = _interopRequireDefault(require("../../templates/template"));
14
14
 
15
+ var _traverse = require("../../traverse");
16
+
15
17
  var _compare = require("../../util/compare");
16
18
 
17
19
  var _gen = require("../../util/gen");
18
20
 
19
21
  var _insert = require("../../util/insert");
20
22
 
23
+ var _random = require("../../util/random");
24
+
21
25
  var _transform = _interopRequireDefault(require("../transform"));
22
26
 
27
+ var _encoding = _interopRequireDefault(require("./encoding"));
28
+
23
29
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
30
 
25
31
  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; }
26
32
 
27
- /* eslint-disable @typescript-eslint/no-unused-expressions */
28
- function encode_ascii85(a) {
29
- var b, c, d, e, f, g, h, i, j, k; // @ts-ignore
30
-
31
- for ( // @ts-ignore
32
- !/[^\x00-\xFF]/.test(a), b = "\x00\x00\x00\x00".slice(a.length % 4 || 4), a += b, c = [], d = 0, e = a.length; e > d; d += 4) f = (a.charCodeAt(d) << 24) + (a.charCodeAt(d + 1) << 16) + (a.charCodeAt(d + 2) << 8) + a.charCodeAt(d + 3), 0 !== f ? (k = f % 85, f = (f - k) / 85, j = f % 85, f = (f - j) / 85, i = f % 85, f = (f - i) / 85, h = f % 85, f = (f - h) / 85, g = f % 85, c.push(g + 33, h + 33, i + 33, j + 33, k + 33)) : c.push(122);
33
-
34
- return function (a, b) {
35
- for (var c = b; c > 0; c--) a.pop();
36
- }(c, b.length), "<~" + String.fromCharCode.apply(String, c) + "~>";
37
- }
38
-
39
- function decode_ascii85(a) {
40
- var c,
41
- d,
42
- e,
43
- f,
44
- g,
45
- h = String,
46
- l = "length",
47
- w = 255,
48
- x = "charCodeAt",
49
- y = "slice",
50
- z = "replace";
51
-
52
- for ("<~" === a[y](0, 2) && "~>" === a[y](-2), a = a[y](2, -2)[z](/s/g, "")[z]("z", "!!!!!"), c = "uuuuu"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);
53
-
54
- return function (a, b) {
55
- for (var c = b; c > 0; c--) a.pop();
56
- }(e, c[l]), h.fromCharCode.apply(h, e);
57
- }
58
-
59
- var Ascii85Template = (0, _template.default)("\nfunction {name}(a, LL = [\"fromCharCode\", \"apply\"]) {\n var c, d, e, f, g, h = String, l = \"length\", w = 255, x = \"charCodeAt\", y = \"slice\", z = \"replace\";\n for (\"<~\" === a[y](0, 2) && \"~>\" === a[y](-2), a = a[y](2, -2)[z](/s/g, \"\")[z](\"z\", \"!!!!!\"), \n c = \"uuuuu\"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), \n e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);\n return function(a, b) {\n for (var c = b; c > 0; c--) a.pop();\n }(e, c[l]), h[LL[0]][LL[1]](h, e);\n}\n");
60
-
61
33
  function isModuleSource(object, parents) {
62
34
  if (!parents[0]) {
63
35
  return false;
@@ -90,51 +62,87 @@ class StringConcealing extends _transform.default {
90
62
 
91
63
  _defineProperty(this, "index", void 0);
92
64
 
93
- _defineProperty(this, "getterName", this.getPlaceholder());
94
-
95
65
  _defineProperty(this, "arrayName", this.getPlaceholder());
96
66
 
97
- _defineProperty(this, "decodeFn", this.getPlaceholder());
67
+ _defineProperty(this, "ignore", new Set());
68
+
69
+ _defineProperty(this, "variablesMade", 1);
70
+
71
+ _defineProperty(this, "encoding", Object.create(null));
98
72
 
99
- _defineProperty(this, "decodeNode", void 0);
73
+ _defineProperty(this, "hasAllEncodings", void 0);
100
74
 
101
75
  this.set = new Set();
102
76
  this.index = Object.create(null);
77
+ this.arrayExpression = (0, _gen.ArrayExpression)([]);
78
+ this.hasAllEncodings = false; // Pad array with useless strings
79
+
80
+ var dead = (0, _random.getRandomInteger)(4, 10);
81
+
82
+ for (var i = 0; i < dead; i++) {
83
+ var str = (0, _random.getRandomString)((0, _random.getRandomInteger)(4, 20));
84
+ var fn = this.transform((0, _gen.Literal)(str), []);
85
+
86
+ if (fn) {
87
+ fn();
88
+ }
89
+ }
90
+ }
91
+
92
+ apply(tree) {
93
+ super.apply(tree);
94
+ var cacheName = this.getPlaceholder();
95
+ Object.keys(this.encoding).forEach(type => {
96
+ var {
97
+ template
98
+ } = _encoding.default[type];
99
+ var decodeFn = this.getPlaceholder();
100
+ var getterFn = this.encoding[type];
101
+ (0, _insert.append)(tree, template.single({
102
+ name: decodeFn
103
+ }));
104
+ (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());
105
+ });
106
+ var flowIntegrity = this.getPlaceholder();
107
+ (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()]), []))]));
103
108
  }
104
109
 
105
110
  match(object, parents) {
106
- return object.type == "Program" || object.type == "Literal" && typeof object.value === "string" && !isModuleSource(object, parents) && !(0, _compare.isDirective)(object, parents) //&&
111
+ return object.type == "Literal" && typeof object.value === "string" && object.value.length >= 3 && !isModuleSource(object, parents) && !(0, _compare.isDirective)(object, parents) //&&
107
112
 
108
113
  /*!parents.find((x) => x.$dispatcherSkip)*/
109
114
  ;
110
115
  }
111
116
 
112
117
  transform(object, parents) {
113
- if (object.type == "Program") {
114
- this.arrayExpression = (0, _gen.ArrayExpression)([]);
115
- return () => {
116
- var cacheName = this.getPlaceholder();
117
- (0, _insert.append)(object, (0, _template.default)("\n \n function ".concat(this.getterName, "(x, y, z){\n if ( z ) {\n return y[").concat(cacheName, "[z]] = x;\n }\n return y ? x[").concat(cacheName, "[y]] : ").concat(cacheName, "[x] || (").concat(cacheName, "[x] = ").concat(this.decodeFn, "(").concat(this.arrayName, "[x]))\n }\n\n ")).single());
118
- (0, _insert.prepend)(object, (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(cacheName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)(this.arrayName, this.arrayExpression)]));
119
- (0, _insert.append)(object, this.decodeNode = Ascii85Template.single({
120
- name: this.decodeFn
121
- }));
122
- };
123
- }
124
-
125
118
  return () => {
126
- // No string concealing in the decoder function
127
- if (parents.find(x => x == this.decodeNode)) {
119
+ // Empty strings are discarded
120
+ if (!object.value || this.ignore.has(object.value)) {
128
121
  return;
129
- } // Empty strings are discarded
122
+ }
130
123
 
124
+ var types = Object.keys(this.encoding);
125
+ var type = (0, _random.choice)(types);
131
126
 
132
- if (!object.value) {
133
- return;
134
- } // The decode function must return correct result
127
+ if (!type || !this.hasAllEncodings && Math.random() > 0.9) {
128
+ var allowed = Object.keys(_encoding.default).filter(type => !this.encoding[type]);
135
129
 
130
+ if (!allowed.length) {
131
+ this.hasAllEncodings = true;
132
+ } else {
133
+ var random = (0, _random.choice)(allowed);
134
+ type = random;
135
+ this.encoding[random] = this.getPlaceholder();
136
+ }
137
+ }
138
+
139
+ var fnName = this.encoding[type];
140
+ var encoder = _encoding.default[type]; // The decode function must return correct result
136
141
 
137
- if (decode_ascii85(encode_ascii85(object.value)) != object.value) {
142
+ var encoded = encoder.encode(object.value);
143
+
144
+ if (encoder.decode(encoded) != object.value) {
145
+ this.ignore.add(object.value);
138
146
  this.warn(object.value.slice(0, 100));
139
147
  return;
140
148
  } // Fix 1. weird undefined error
@@ -144,21 +152,42 @@ class StringConcealing extends _transform.default {
144
152
  var index = -1;
145
153
 
146
154
  if (!this.set.has(object.value)) {
147
- this.arrayExpression.elements.push((0, _gen.Literal)(encode_ascii85(object.value)));
155
+ this.arrayExpression.elements.push((0, _gen.Literal)(encoded));
148
156
  index = this.arrayExpression.elements.length - 1;
149
- this.index[object.value] = index;
157
+ this.index[object.value] = [index, fnName];
150
158
  this.set.add(object.value);
151
159
  } else {
152
- index = this.index[object.value];
160
+ [index, fnName] = this.index[object.value];
153
161
  (0, _assert.ok)(typeof index === "number");
154
162
  }
155
163
 
156
164
  (0, _assert.ok)(index != -1, "index == -1");
157
- this.replace(object, (0, _gen.CallExpression)((0, _gen.Identifier)(this.getterName), [(0, _gen.Literal)(index)])); // Fix 2. Make parent property key computed
165
+ var callExpr = (0, _gen.CallExpression)((0, _gen.Identifier)(fnName), [(0, _gen.Literal)(index)]); // use `.apply` to fool automated de-obfuscators
166
+
167
+ if (Math.random() > 0.5) {
168
+ callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Identifier)("apply"), false), [(0, _gen.ThisExpression)(), (0, _gen.ArrayExpression)([(0, _gen.Literal)(index)])]);
169
+ } // use `.call`
170
+ else if (Math.random() > 0.5) {
171
+ callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Identifier)("call"), false), [(0, _gen.ThisExpression)(), (0, _gen.Literal)(index)]);
172
+ }
158
173
 
159
- if (parents[0] && (parents[0].type == "Property" || parents[0].type == "MethodDefinition") && parents[0].key == object) {
160
- parents[0].computed = true;
161
- parents[0].shorthand = false;
174
+ var constantReference = parents.length && Math.random() > 0.5 / this.variablesMade;
175
+
176
+ if (constantReference) {
177
+ // Define the string earlier, reference the name here
178
+ var name = this.getPlaceholder();
179
+ var place = (0, _random.choice)(parents.filter(node => (0, _traverse.isBlock)(node)));
180
+
181
+ if (!place) {
182
+ this.error(Error("No lexical block to insert code"));
183
+ }
184
+
185
+ place.body.unshift((0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, callExpr)));
186
+ this.replaceIdentifierOrLiteral(object, (0, _gen.Identifier)(name), parents);
187
+ this.variablesMade++;
188
+ } else {
189
+ // Direct call to the getter function
190
+ this.replaceIdentifierOrLiteral(object, callExpr, parents);
162
191
  }
163
192
  }
164
193
  };
@@ -21,6 +21,8 @@ var _compare = require("../../util/compare");
21
21
 
22
22
  var _assert = require("assert");
23
23
 
24
+ var _probability = require("../../probability");
25
+
24
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
27
 
26
28
  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; }
@@ -69,12 +71,6 @@ class StringSplitting extends _transform.default {
69
71
 
70
72
  transform(object, parents) {
71
73
  return () => {
72
- var propIndex = parents.findIndex(x => x.type == "Property" || x.type == "MethodDefinition");
73
-
74
- if (propIndex !== -1 && parents[propIndex].key == object) {
75
- parents[propIndex].computed = true;
76
- }
77
-
78
74
  var size = Math.round(Math.max(6, object.value.length / (0, _random.getRandomInteger)(3, 8)));
79
75
 
80
76
  if (object.value.length <= size) {
@@ -87,6 +83,10 @@ class StringSplitting extends _transform.default {
87
83
  return;
88
84
  }
89
85
 
86
+ if (!(0, _probability.ComputeProbabilityMap)(this.options.stringSplitting, x => x, object.value)) {
87
+ return;
88
+ }
89
+
90
90
  var binaryExpression;
91
91
  var parent;
92
92
  var last = chunks.pop();
@@ -100,7 +100,7 @@ class StringSplitting extends _transform.default {
100
100
  }
101
101
  });
102
102
  parent.right = (0, _gen.Literal)(last);
103
- this.replace(object, parent);
103
+ this.replaceIdentifierOrLiteral(object, parent, parents);
104
104
  };
105
105
  }
106
106
 
@@ -317,6 +317,16 @@ class Transform {
317
317
 
318
318
  this.objectAssign(node1, node2);
319
319
  }
320
+
321
+ replaceIdentifierOrLiteral(node1, node2, parents) {
322
+ // Fix 2. Make parent property key computed
323
+ if (parents[0] && (parents[0].type == "Property" || parents[0].type == "MethodDefinition") && parents[0].key == node1) {
324
+ parents[0].computed = true;
325
+ parents[0].shorthand = false;
326
+ }
327
+
328
+ this.replace(node1, node2);
329
+ }
320
330
  /**
321
331
  * Smartly merges two Nodes.
322
332
  * - Null checking
package/dist/traverse.js CHANGED
@@ -3,24 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getBlocks = getBlocks;
7
6
  exports.getBlock = getBlock;
8
7
  exports.isBlock = isBlock;
9
- exports.getDepth = getDepth;
10
8
  exports.walk = walk;
11
9
  exports.default = traverse;
12
10
 
13
11
  var _identifiers = require("./util/identifiers");
14
12
 
15
- /**
16
- * Returns all the scopes given parents array.
17
- * - `[object, ...parents]` is recommended.
18
- *
19
- * @param parents
20
- */
21
- function getBlocks(parents) {
22
- return parents.filter(x => isBlock(x));
23
- }
24
13
  /**
25
14
  * A block refers to any object that has a **`.body`** property where code is nested.
26
15
  *
@@ -29,14 +18,12 @@ function getBlocks(parents) {
29
18
  * @param object
30
19
  * @param parents
31
20
  */
32
-
33
-
34
21
  function getBlock(object, parents) {
35
22
  if (!Array.isArray(parents)) {
36
23
  throw new Error("parents must be an array");
37
24
  }
38
25
 
39
- return getBlocks([object, ...parents])[0];
26
+ return [object, ...parents].find(node => isBlock(node));
40
27
  }
41
28
  /**
42
29
  * Must have a **`.body`** property and be an array.
@@ -51,27 +38,6 @@ function getBlock(object, parents) {
51
38
  function isBlock(object) {
52
39
  return object && (object.type == "BlockStatement" || object.type == "Program");
53
40
  }
54
- /**
55
- * Returns a numerical representation of the depth.
56
- * - Depth is how many blocks nested.
57
- * - Program = 1 depth
58
- * - First Fn = 2 depth
59
- * - Nested Fn = 3 depth
60
- * - Second Fn = 2 depth
61
- * - etc...
62
- * @param object
63
- * @param parents
64
- */
65
-
66
-
67
- function getDepth(object, parents) {
68
- if (!Array.isArray(parents)) {
69
- throw new Error("parents should be an array");
70
- }
71
-
72
- var scopes = getBlocks([object, ...parents].filter(x => x));
73
- return scopes.length;
74
- }
75
41
 
76
42
  function walk(object, parents, onEnter, seen = new Set()) {
77
43
  if (typeof object === "object" && object) {
package/dist/util/gen.js CHANGED
@@ -136,6 +136,8 @@ function ThisExpression() {
136
136
  }
137
137
 
138
138
  function SwitchCase(test, consequent) {
139
+ (0, _assert.ok)(test === null || test);
140
+ (0, _assert.ok)(Array.isArray(consequent));
139
141
  return {
140
142
  type: "SwitchCase",
141
143
  test,
@@ -471,7 +473,7 @@ function AssignmentPattern(left, right) {
471
473
  (0, _assert.ok)(left);
472
474
  (0, _assert.ok)(right);
473
475
  return {
474
- type: "AssignmentExpression",
476
+ type: "AssignmentPattern",
475
477
  left: left,
476
478
  right: right
477
479
  };