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
@@ -46,7 +46,8 @@ export default class Stack extends Transform {
46
46
  isFunction(object) &&
47
47
  !object.params.find((x) => x.type !== "Identifier") &&
48
48
  object.body.type === "BlockStatement" &&
49
- !parents.find((x) => x.$dispatcherSkip)
49
+ !parents.find((x) => x.$dispatcherSkip) &&
50
+ !object.$requiresEval
50
51
  );
51
52
  }
52
53
 
@@ -204,6 +205,7 @@ export default class Stack extends Transform {
204
205
  }
205
206
 
206
207
  var stackName = this.getPlaceholder();
208
+ var made = 1;
207
209
 
208
210
  const scan = (o, p) => {
209
211
  if (o.type == "Identifier") {
@@ -285,16 +287,12 @@ export default class Stack extends Transform {
285
287
  typeof o.value === "number" &&
286
288
  Math.floor(o.value) === o.value &&
287
289
  Math.abs(o.value) < 100_000 &&
288
- Math.random() > 0.5 &&
290
+ Math.random() < 4 / made &&
289
291
  p.find((x) => isFunction(x)) === object
290
292
  ) {
293
+ made++;
291
294
  return () => {
292
- if (p[0].type == "Property" || p[0].type == "MethodDefinition") {
293
- if (!p[0].computed) {
294
- p[0].computed = true;
295
- }
296
- }
297
- this.replace(o, numberLiteral(o.value, 0));
295
+ this.replaceIdentifierOrLiteral(o, numberLiteral(o.value, 0), p);
298
296
  };
299
297
  }
300
298
  };
@@ -0,0 +1,310 @@
1
+ import Template from "../../templates/template";
2
+
3
+ const Encoding: {
4
+ [encoding_name: string]: {
5
+ encode: (s) => string;
6
+ decode: (s) => string;
7
+ template: ReturnType<typeof Template>;
8
+ };
9
+ } = {
10
+ ascii85: {
11
+ encode(a) {
12
+ var b, c, d, e, f, g, h, i, j, k;
13
+ // @ts-ignore
14
+ for (
15
+ // @ts-ignore
16
+ !/[^\x00-\xFF]/.test(a),
17
+ b = "\x00\x00\x00\x00".slice(a.length % 4 || 4),
18
+ a += b,
19
+ c = [],
20
+ d = 0,
21
+ e = a.length;
22
+ e > d;
23
+ d += 4
24
+ )
25
+ (f =
26
+ (a.charCodeAt(d) << 24) +
27
+ (a.charCodeAt(d + 1) << 16) +
28
+ (a.charCodeAt(d + 2) << 8) +
29
+ a.charCodeAt(d + 3)),
30
+ 0 !== f
31
+ ? ((k = f % 85),
32
+ (f = (f - k) / 85),
33
+ (j = f % 85),
34
+ (f = (f - j) / 85),
35
+ (i = f % 85),
36
+ (f = (f - i) / 85),
37
+ (h = f % 85),
38
+ (f = (f - h) / 85),
39
+ (g = f % 85),
40
+ c.push(g + 33, h + 33, i + 33, j + 33, k + 33))
41
+ : c.push(122);
42
+ return (
43
+ (function (a, b) {
44
+ for (var c = b; c > 0; c--) a.pop();
45
+ })(c, b.length),
46
+ "<~" + String.fromCharCode.apply(String, c) + "~>"
47
+ );
48
+ },
49
+ decode(a) {
50
+ var c,
51
+ d,
52
+ e,
53
+ f,
54
+ g,
55
+ h = String,
56
+ l = "length",
57
+ w = 255,
58
+ x = "charCodeAt",
59
+ y = "slice",
60
+ z = "replace";
61
+ for (
62
+ "<~" === a[y](0, 2) && "~>" === a[y](-2),
63
+ a = a[y](2, -2)[z](/s/g, "")[z]("z", "!!!!!"),
64
+ c = "uuuuu"[y](a[l] % 5 || 5),
65
+ a += c,
66
+ e = [],
67
+ f = 0,
68
+ g = a[l];
69
+ g > f;
70
+ f += 5
71
+ )
72
+ (d =
73
+ 52200625 * (a[x](f) - 33) +
74
+ 614125 * (a[x](f + 1) - 33) +
75
+ 7225 * (a[x](f + 2) - 33) +
76
+ 85 * (a[x](f + 3) - 33) +
77
+ (a[x](f + 4) - 33)),
78
+ e.push(w & (d >> 24), w & (d >> 16), w & (d >> 8), w & d);
79
+ return (
80
+ (function (a, b) {
81
+ for (var c = b; c > 0; c--) a.pop();
82
+ })(e, c[l]),
83
+ h.fromCharCode.apply(h, e)
84
+ );
85
+ },
86
+ template: Template(`
87
+ function {name}(a, LL = ["fromCharCode", "apply"]) {
88
+ var c, d, e, f, g, h = String, l = "length", w = 255, x = "charCodeAt", y = "slice", z = "replace";
89
+ for ("<~" === a[y](0, 2) && "~>" === a[y](-2), a = a[y](2, -2)[z](/\s/g, "")[z]("z", "!!!!!"),
90
+ 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),
91
+ e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);
92
+ return function(a, b) {
93
+ for (var c = b; c > 0; c--) a.pop();
94
+ }(e, c[l]), h[LL[0]][LL[1]](h, e);
95
+ }
96
+ `),
97
+ },
98
+
99
+ base32: {
100
+ encode: function (s) {
101
+ var a = "!\"#$%&'()*+,-./0123456789:;<=>?@";
102
+ var len = s.length;
103
+ var o = "";
104
+ var w,
105
+ c,
106
+ r = 0,
107
+ sh = 0,
108
+ i;
109
+ for (i = 0; i < len; i += 5) {
110
+ // mask top 5 bits
111
+ c = s.charCodeAt(i);
112
+ w = 0xf8 & c;
113
+ o += a.charAt(w >> 3);
114
+ r = 0x07 & c;
115
+ sh = 2;
116
+
117
+ if (i + 1 < len) {
118
+ c = s.charCodeAt(i + 1);
119
+ // mask top 2 bits
120
+ w = 0xc0 & c;
121
+ o += a.charAt((r << 2) + (w >> 6));
122
+ o += a.charAt((0x3e & c) >> 1);
123
+ r = c & 0x01;
124
+ sh = 4;
125
+ }
126
+
127
+ if (i + 2 < len) {
128
+ c = s.charCodeAt(i + 2);
129
+ // mask top 4 bits
130
+ w = 0xf0 & c;
131
+ o += a.charAt((r << 4) + (w >> 4));
132
+ r = 0x0f & c;
133
+ sh = 1;
134
+ }
135
+
136
+ if (i + 3 < len) {
137
+ c = s.charCodeAt(i + 3);
138
+ // mask top 1 bit
139
+ w = 0x80 & c;
140
+ o += a.charAt((r << 1) + (w >> 7));
141
+ o += a.charAt((0x7c & c) >> 2);
142
+ r = 0x03 & c;
143
+ sh = 3;
144
+ }
145
+
146
+ if (i + 4 < len) {
147
+ c = s.charCodeAt(i + 4);
148
+ // mask top 3 bits
149
+ w = 0xe0 & c;
150
+ o += a.charAt((r << 3) + (w >> 5));
151
+ o += a.charAt(0x1f & c);
152
+ r = 0;
153
+ sh = 0;
154
+ }
155
+ }
156
+ // Calculate length of pad by getting the
157
+ // number of words to reach an 8th octet.
158
+ if (r != 0) {
159
+ o += a.charAt(r << sh);
160
+ }
161
+ return o;
162
+ },
163
+ decode: function (s) {
164
+ var v,
165
+ x,
166
+ bits = 0,
167
+ o = "",
168
+ len = s.length,
169
+ d = String,
170
+ e = "charCodeAt",
171
+ f = "fromCharCode",
172
+ i;
173
+
174
+ for (i = 0; i < len; i += 1) {
175
+ (v = s[e](i) - 33),
176
+ v >= 0 && v < 32
177
+ ? ((bits += ((x = (x << 5) | v), 5)),
178
+ bits >= 8
179
+ ? (bits -= ((o += d[f]((x >> (bits - 8)) & 0xff)), 8))
180
+ : 0)
181
+ : 0;
182
+ }
183
+ return o;
184
+ },
185
+ template: Template(`
186
+ function {name}(s) {
187
+ var v,
188
+ x,
189
+ b = 0,
190
+ o = "",
191
+ len = s.length,
192
+ d = String,
193
+ e = "charCodeAt",
194
+ f = "fromCharCode", i;
195
+
196
+ for (i = 0; i < len; i += 1) {
197
+ (v = s[e](i) - 33),
198
+ v >= 0 && v < 32
199
+ ? ((b += ((x = (x << 5) | v), 5)),
200
+ b >= 8
201
+ ? (b -= ((o += d[f]((x >> (b - 8)) & 0xff)), 8))
202
+ : 0)
203
+ : 0;
204
+ }
205
+ return o;
206
+ }
207
+ `),
208
+ },
209
+
210
+ hexTable: {
211
+ encode: function (str) {
212
+ var output = "";
213
+
214
+ for (var j = 0; j < str.length; j += 3) {
215
+ var chunk = str.substring(j, j + 3);
216
+ if (!chunk) {
217
+ continue;
218
+ }
219
+
220
+ chunk = chunk + "~";
221
+
222
+ var uniqueChars = new Set([]);
223
+ for (var char of chunk) {
224
+ uniqueChars.add(char);
225
+ }
226
+
227
+ var keys = Array.from(uniqueChars).sort();
228
+ var table = {},
229
+ i = 0;
230
+ for (var key of keys) {
231
+ table[key] = i++;
232
+ }
233
+
234
+ var idx = [];
235
+ for (var char of chunk) {
236
+ idx.push(table[char]);
237
+ }
238
+
239
+ var table64 = "0x";
240
+ for (var i = keys.length - 1; i >= 0; i--) {
241
+ table64 += keys[i].charCodeAt(0).toString(16).toUpperCase();
242
+ }
243
+
244
+ var idxInt = 0;
245
+ for (var i = idx.length - 1; i >= 0; i--) {
246
+ idxInt = (idxInt << 3) | idx[i];
247
+ }
248
+
249
+ var idx64 = "0x" + idxInt.toString(16).toUpperCase();
250
+
251
+ // console.log(chunk, table, idx, table64, idx64);
252
+
253
+ output += table64 + "," + idx64 + ",";
254
+ }
255
+
256
+ if (output.endsWith(",")) {
257
+ output = output.substring(0, output.length - 1);
258
+ }
259
+
260
+ return "{" + output + "}";
261
+ },
262
+
263
+ decode: function (str) {
264
+ var output = "";
265
+
266
+ str = str.substring(1, str.length - 1);
267
+ var chunks = str.split(",");
268
+
269
+ for (var i = 0; i < chunks.length; i += 2) {
270
+ var arr = [chunks[i], chunks[i + 1]];
271
+
272
+ var [table, idx] = arr.map(Number);
273
+
274
+ // console.log(table, idx);
275
+ while (idx) {
276
+ output += String.fromCharCode((table >> (8 * (idx & 7))) & 0xff);
277
+ idx >>= 3;
278
+ }
279
+ }
280
+
281
+ return output.replace(/~/g, "");
282
+ },
283
+
284
+ template: Template(`
285
+ function {name}(str){
286
+ var output = "";
287
+
288
+ str = str.substring(1, str.length - 1);
289
+ var chunks = str.split(",");
290
+
291
+ for (var i = 0; i < chunks.length; i += 2) {
292
+ var arr = [chunks[i], chunks[i + 1]];
293
+
294
+ var [table, idx] = arr.map(Number);
295
+
296
+ // console.log(table, idx);
297
+ while (idx) {
298
+ output += String.fromCharCode((table >> (8 * (idx & 7))) & 0xff);
299
+ idx >>= 3;
300
+ }
301
+ }
302
+
303
+ return output.replace(/~/g, "");
304
+ }
305
+
306
+ `),
307
+ },
308
+ };
309
+
310
+ export default Encoding;
@@ -6,6 +6,7 @@ import { isDirective } from "../../util/compare";
6
6
  import {
7
7
  CallExpression,
8
8
  FunctionDeclaration,
9
+ FunctionExpression,
9
10
  Identifier,
10
11
  Literal,
11
12
  MemberExpression,
@@ -74,7 +75,7 @@ const DecodeTemplate = Template(
74
75
  (e[o] = f + c),
75
76
  o++,
76
77
  (f = a);
77
- return g.join("");
78
+ return g.join("").split("{delimiter}");
78
79
  }`
79
80
  );
80
81
 
@@ -105,24 +106,43 @@ export default class StringCompression extends Transform {
105
106
 
106
107
  var split = this.getPlaceholder();
107
108
  var decoder = this.getPlaceholder();
109
+ var getStringName = this.getPlaceholder();
108
110
 
109
111
  var encoded = LZ_encode(this.string);
110
112
  if (LZ_decode(encoded) !== this.string) {
111
113
  this.error(new Error("String failed to be decoded"));
112
114
  }
113
115
 
114
- var callExpression = CallExpression(
115
- MemberExpression(
116
- CallExpression(Identifier(decoder), [Literal(encoded)]),
117
- Identifier("split"),
118
- false
119
- ),
120
- [Literal(this.delimiter)]
121
- );
116
+ var getStringParamName = this.getPlaceholder();
117
+ var decoderParamName = this.getPlaceholder();
118
+
119
+ var callExpression = CallExpression(Identifier(decoderParamName), [
120
+ CallExpression(Identifier(getStringParamName), []),
121
+ ]);
122
122
 
123
123
  prepend(
124
124
  tree,
125
- VariableDeclaration(VariableDeclarator(split, callExpression))
125
+ VariableDeclaration(
126
+ VariableDeclarator(
127
+ split,
128
+ CallExpression(
129
+ FunctionExpression(
130
+ [Identifier(getStringParamName), Identifier(decoderParamName)],
131
+ [ReturnStatement(callExpression)]
132
+ ),
133
+ [Identifier(getStringName), Identifier(decoder)]
134
+ )
135
+ )
136
+ )
137
+ );
138
+
139
+ append(
140
+ tree,
141
+ FunctionDeclaration(
142
+ getStringName,
143
+ [],
144
+ [ReturnStatement(Literal(encoded))]
145
+ )
126
146
  );
127
147
 
128
148
  append(
@@ -138,7 +158,10 @@ export default class StringCompression extends Transform {
138
158
  )
139
159
  );
140
160
 
141
- append(tree, DecodeTemplate.single({ name: decoder }));
161
+ append(
162
+ tree,
163
+ DecodeTemplate.single({ name: decoder, delimiter: this.delimiter })
164
+ );
142
165
  }
143
166
 
144
167
  match(object, parents) {
@@ -199,20 +222,10 @@ export default class StringCompression extends Transform {
199
222
  }
200
223
  ok(typeof index === "number");
201
224
 
202
- this.replace(
225
+ this.replaceIdentifierOrLiteral(
203
226
  object,
204
- CallExpression(Identifier(this.fnName), [Literal(index)])
227
+ CallExpression(Identifier(this.fnName), [Literal(index)]),
228
+ parents
205
229
  );
206
-
207
- // Fix 2. Make parent property key computed
208
- if (
209
- parents[0] &&
210
- (parents[0].type == "Property" ||
211
- parents[0].type == "MethodDefinition") &&
212
- parents[0].key == object
213
- ) {
214
- parents[0].computed = true;
215
- parents[0].shorthand = false;
216
- }
217
230
  }
218
231
  }