js-confuser 1.7.1 → 1.7.2

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 (123) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +12 -27
  3. package/dist/compiler.js +2 -8
  4. package/dist/constants.js +17 -10
  5. package/dist/index.js +7 -30
  6. package/dist/obfuscator.js +15 -62
  7. package/dist/options.js +21 -38
  8. package/dist/order.js +4 -7
  9. package/dist/parser.js +5 -13
  10. package/dist/precedence.js +6 -8
  11. package/dist/presets.js +4 -6
  12. package/dist/probability.js +13 -24
  13. package/dist/templates/bufferToString.js +100 -5
  14. package/dist/templates/crash.js +51 -9
  15. package/dist/templates/es5.js +125 -6
  16. package/dist/templates/functionLength.js +24 -6
  17. package/dist/templates/globals.js +9 -0
  18. package/dist/templates/template.js +71 -30
  19. package/dist/transforms/antiTooling.js +26 -22
  20. package/dist/transforms/calculator.js +18 -54
  21. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +236 -333
  22. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
  23. package/dist/transforms/deadCode.js +528 -27
  24. package/dist/transforms/dispatcher.js +106 -110
  25. package/dist/transforms/es5/antiClass.js +70 -44
  26. package/dist/transforms/es5/antiDestructuring.js +14 -38
  27. package/dist/transforms/es5/antiES6Object.js +39 -48
  28. package/dist/transforms/es5/antiSpreadOperator.js +5 -14
  29. package/dist/transforms/es5/antiTemplate.js +10 -19
  30. package/dist/transforms/es5/es5.js +7 -40
  31. package/dist/transforms/extraction/classExtraction.js +83 -0
  32. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +41 -80
  33. package/dist/transforms/extraction/objectExtraction.js +24 -56
  34. package/dist/transforms/finalizer.js +6 -20
  35. package/dist/transforms/flatten.js +51 -99
  36. package/dist/transforms/identifier/globalAnalysis.js +8 -26
  37. package/dist/transforms/identifier/globalConcealing.js +35 -54
  38. package/dist/transforms/identifier/movedDeclarations.js +66 -38
  39. package/dist/transforms/identifier/renameVariables.js +29 -68
  40. package/dist/transforms/identifier/variableAnalysis.js +21 -48
  41. package/dist/transforms/lock/antiDebug.js +20 -25
  42. package/dist/transforms/lock/integrity.js +48 -47
  43. package/dist/transforms/lock/lock.js +62 -113
  44. package/dist/transforms/minify.js +77 -108
  45. package/dist/transforms/opaquePredicates.js +11 -48
  46. package/dist/transforms/preparation.js +17 -50
  47. package/dist/transforms/renameLabels.js +5 -22
  48. package/dist/transforms/rgf.js +93 -69
  49. package/dist/transforms/shuffle.js +41 -46
  50. package/dist/transforms/stack.js +35 -98
  51. package/dist/transforms/string/encoding.js +73 -27
  52. package/dist/transforms/string/stringCompression.js +44 -68
  53. package/dist/transforms/string/stringConcealing.js +125 -134
  54. package/dist/transforms/string/stringEncoding.js +6 -26
  55. package/dist/transforms/string/stringSplitting.js +5 -30
  56. package/dist/transforms/transform.js +50 -100
  57. package/dist/traverse.js +11 -18
  58. package/dist/util/compare.js +27 -29
  59. package/dist/util/gen.js +32 -86
  60. package/dist/util/guard.js +0 -1
  61. package/dist/util/identifiers.js +9 -72
  62. package/dist/util/insert.js +27 -77
  63. package/dist/util/math.js +0 -3
  64. package/dist/util/object.js +3 -7
  65. package/dist/util/random.js +5 -36
  66. package/dist/util/scope.js +6 -3
  67. package/package.json +3 -3
  68. package/src/constants.ts +12 -0
  69. package/src/options.ts +13 -0
  70. package/src/order.ts +2 -2
  71. package/src/templates/bufferToString.ts +49 -11
  72. package/src/templates/functionLength.ts +21 -3
  73. package/src/templates/globals.ts +3 -0
  74. package/src/templates/template.ts +85 -25
  75. package/src/transforms/antiTooling.ts +33 -11
  76. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +2 -2
  77. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
  78. package/src/transforms/deadCode.ts +0 -16
  79. package/src/transforms/dispatcher.ts +91 -69
  80. package/src/transforms/es5/antiClass.ts +10 -1
  81. package/src/transforms/extraction/classExtraction.ts +168 -0
  82. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -10
  83. package/src/transforms/extraction/objectExtraction.ts +4 -15
  84. package/src/transforms/flatten.ts +20 -5
  85. package/src/transforms/identifier/globalConcealing.ts +29 -65
  86. package/src/transforms/identifier/movedDeclarations.ts +90 -24
  87. package/src/transforms/minify.ts +27 -12
  88. package/src/transforms/rgf.ts +94 -5
  89. package/src/transforms/stack.ts +12 -3
  90. package/src/transforms/string/encoding.ts +85 -51
  91. package/src/transforms/string/stringCompression.ts +5 -8
  92. package/src/transforms/string/stringConcealing.ts +139 -113
  93. package/src/transforms/string/stringEncoding.ts +1 -2
  94. package/src/transforms/string/stringSplitting.ts +1 -2
  95. package/src/transforms/transform.ts +30 -1
  96. package/src/util/compare.ts +39 -5
  97. package/src/util/gen.ts +10 -3
  98. package/src/util/insert.ts +17 -0
  99. package/src/util/scope.ts +14 -2
  100. package/test/code/Cash.test.ts +10 -4
  101. package/test/code/StrictMode.src.js +65 -0
  102. package/test/code/StrictMode.test.js +37 -0
  103. package/test/compare.test.ts +62 -2
  104. package/test/options.test.ts +111 -55
  105. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
  106. package/test/transforms/dispatcher.test.ts +55 -0
  107. package/test/transforms/extraction/classExtraction.test.ts +86 -0
  108. package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +8 -0
  109. package/test/transforms/extraction/objectExtraction.test.ts +2 -0
  110. package/test/transforms/identifier/globalConcealing.test.ts +19 -0
  111. package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
  112. package/test/transforms/minify.test.ts +37 -0
  113. package/test/transforms/rgf.test.ts +50 -0
  114. package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
  115. package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
  116. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
  117. package/dist/transforms/eval.js +0 -84
  118. package/dist/transforms/hexadecimalNumbers.js +0 -63
  119. package/dist/transforms/hideInitializingCode.js +0 -270
  120. package/dist/transforms/identifier/nameRecycling.js +0 -218
  121. package/dist/transforms/label.js +0 -67
  122. package/dist/transforms/preparation/nameConflicts.js +0 -116
  123. package/dist/transforms/preparation/preparation.js +0 -188
@@ -17,18 +17,20 @@ exports.getIndexDirect = getIndexDirect;
17
17
  exports.getLexContext = getLexContext;
18
18
  exports.getReferencingContexts = getReferencingContexts;
19
19
  exports.getVarContext = getVarContext;
20
+ exports.isClass = isClass;
20
21
  exports.isContext = isContext;
21
22
  exports.isForInitialize = isForInitialize;
22
23
  exports.isFunction = isFunction;
23
24
  exports.isLexContext = isLexContext;
25
+ exports.isStrictModeFunction = isStrictModeFunction;
24
26
  exports.isVarContext = isVarContext;
25
27
  exports.prepend = prepend;
26
-
27
28
  var _assert = require("assert");
28
-
29
29
  var _traverse = require("../traverse");
30
-
31
30
  var _identifiers = require("./identifiers");
31
+ function isClass(object) {
32
+ return object.type === "ClassDeclaration" || object.type === "ClassExpression";
33
+ }
32
34
 
33
35
  /**
34
36
  * - `FunctionDeclaration`
@@ -40,6 +42,11 @@ var _identifiers = require("./identifiers");
40
42
  function isFunction(object) {
41
43
  return ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"].includes(object && object.type);
42
44
  }
45
+ function isStrictModeFunction(object) {
46
+ (0, _assert.ok)(isFunction(object));
47
+ return object.body.type === "BlockStatement" && object.body.body[0] && object.body.body[0].type === "ExpressionStatement" && object.body.body[0].directive === "use strict";
48
+ }
49
+
43
50
  /**
44
51
  * The function context where the object is.
45
52
  *
@@ -49,189 +56,154 @@ function isFunction(object) {
49
56
  * @param object
50
57
  * @param parents
51
58
  */
52
-
53
-
54
59
  function getFunction(object, parents) {
55
60
  return parents.find(x => isFunction(x));
56
61
  }
62
+
57
63
  /**
58
64
  * Refers to the current function or Root node
59
65
  * @param parents
60
66
  */
61
-
62
-
63
67
  function getVarContext(object, parents) {
64
68
  var fn = getFunction(object, parents);
65
-
66
69
  if (fn) {
67
70
  return fn;
68
71
  }
69
-
70
72
  var top = parents[parents.length - 1] || object;
71
-
72
73
  if (top) {
73
74
  (0, _assert.ok)(top.type == "Program", "Root node not program, its " + top.type);
74
75
  return top;
75
76
  }
76
-
77
77
  throw new Error("Missing root node");
78
78
  }
79
+
79
80
  /**
80
81
  * `Function` or root node
81
82
  * @param object
82
83
  * @returns
83
84
  */
84
-
85
-
86
85
  function isVarContext(object) {
87
86
  return isFunction(object) || object.type == "Program" || object.type == "DoExpression"; // Stage 1
88
87
  }
88
+
89
89
  /**
90
90
  * `Block` or root node
91
91
  * @param object
92
92
  * @returns
93
93
  */
94
-
95
-
96
94
  function isLexContext(object) {
97
95
  return (0, _traverse.isBlock)(object) || object.type == "Program";
98
96
  }
97
+
99
98
  /**
100
99
  * Either a `var context` or `lex context`
101
100
  * @param object
102
101
  * @returns
103
102
  */
104
-
105
-
106
103
  function isContext(object) {
107
104
  return isVarContext(object) || isLexContext(object);
108
105
  }
109
-
110
106
  function getContexts(object, parents) {
111
107
  return [object, ...parents].filter(x => isContext(x));
112
108
  }
109
+
113
110
  /**
114
111
  * Refers to the current lexical block or Root node.
115
112
  * @param parents
116
113
  */
117
-
118
-
119
114
  function getLexContext(object, parents) {
120
115
  var block = (0, _traverse.getBlock)(object, parents);
121
-
122
116
  if (block) {
123
117
  return block;
124
118
  }
125
-
126
119
  var top = parents[parents.length - 1];
127
-
128
120
  if (!top) {
129
121
  throw new Error("Missing root node");
130
122
  }
131
123
  }
132
-
133
124
  function getDefiningContext(o, p) {
134
125
  (0, _identifiers.validateChain)(o, p);
135
126
  (0, _assert.ok)(o.type == "Identifier");
136
127
  var info = (0, _identifiers.getIdentifierInfo)(o, p);
137
128
  (0, _assert.ok)(info.spec.isDefined);
138
-
139
129
  if (info.isVariableDeclaration) {
140
130
  var variableDeclaration = p.find(x => x.type == "VariableDeclaration");
141
131
  (0, _assert.ok)(variableDeclaration);
142
-
143
132
  if (variableDeclaration.kind === "let" || variableDeclaration.kind === "const") {
144
133
  var context = getVarContext(o, p);
145
-
146
134
  if (context && context.type === "Program") {
147
135
  return getLexContext(o, p);
148
136
  }
149
137
  }
150
138
  }
151
-
152
139
  if (info.isFunctionDeclaration) {
153
140
  return getVarContext(p[0], p.slice(1));
154
141
  }
155
-
156
142
  return getVarContext(o, p);
157
143
  }
144
+
158
145
  /**
159
146
  * A more accurate context finding function.
160
147
  * @param o Object
161
148
  * @param p Parents
162
149
  * @returns Contexts
163
150
  */
164
-
165
-
166
151
  function getAllDefiningContexts(o, p) {
167
152
  var contexts = [getDefiningContext(o, p)];
168
153
  var info = (0, _identifiers.getIdentifierInfo)(o, p);
169
-
170
154
  if (info.isFunctionParameter) {
171
155
  // Get Function
172
- var fn = getFunction(o, p); // contexts.push(fn.body);
173
- }
156
+ var fn = getFunction(o, p);
174
157
 
158
+ // contexts.push(fn.body);
159
+ }
175
160
  if (info.isClauseParameter) {
176
161
  var catchClause = p.find(x => x.type === "CatchClause");
177
-
178
162
  if (catchClause) {
179
163
  return [catchClause];
180
164
  }
181
165
  }
182
-
183
166
  return contexts;
184
167
  }
185
-
186
168
  function getReferencingContexts(o, p, info) {
187
169
  (0, _identifiers.validateChain)(o, p);
188
170
  (0, _assert.ok)(o.type == "Identifier");
189
-
190
171
  if (!info) {
191
172
  info = (0, _identifiers.getIdentifierInfo)(o, p);
192
173
  }
193
-
194
174
  (0, _assert.ok)(info.spec.isReferenced);
195
175
  return [getVarContext(o, p), getLexContext(o, p)];
196
176
  }
197
-
198
177
  function getBlockBody(block) {
199
178
  if (!block) {
200
179
  throw new Error("no block body");
201
180
  }
202
-
203
181
  if (Array.isArray(block)) {
204
182
  return block;
205
183
  }
206
-
207
184
  return getBlockBody(block.body);
208
185
  }
209
-
210
186
  function getIndexDirect(object, parent) {
211
187
  return Object.keys(parent).find(x => parent[x] == object);
212
188
  }
189
+
213
190
  /**
214
191
  * Attempts to a delete a variable/functions declaration.
215
192
  * @param object
216
193
  * @param parents
217
194
  */
218
-
219
-
220
195
  function deleteDeclaration(object, parents) {
221
- (0, _identifiers.validateChain)(object, parents); // variables
196
+ (0, _identifiers.validateChain)(object, parents);
222
197
 
198
+ // variables
223
199
  var list = [object, ...parents];
224
200
  var declaratorIndex = list.findIndex(x => x.type == "VariableDeclarator");
225
-
226
201
  if (declaratorIndex != -1) {
227
202
  var declarator = list[declaratorIndex]; // {type: VariableDeclarator, id: Identifier, init: Literal|Expression...}
228
-
229
203
  var declarations = list[declaratorIndex + 1]; // declarator[]
230
-
231
204
  var VariableDeclaration = list[declaratorIndex + 2];
232
205
  var body = list[declaratorIndex + 3];
233
206
  deleteDirect(declarator, declarations);
234
-
235
207
  if (VariableDeclaration.declarations.length == 0) {
236
208
  deleteDirect(VariableDeclaration, body);
237
209
  }
@@ -239,30 +211,24 @@ function deleteDeclaration(object, parents) {
239
211
  if (object.type != "FunctionDeclaration") {
240
212
  throw new Error("No method to delete: " + object.type);
241
213
  }
242
-
243
214
  deleteDirect(object, parents[0]);
244
215
  }
245
216
  }
217
+
246
218
  /**
247
219
  * Object must be directly nested in parent
248
220
  */
249
-
250
-
251
221
  function deleteDirect(object, parent) {
252
222
  if (!object) {
253
223
  throw new Error("object undefined");
254
224
  }
255
-
256
225
  if (!parent) {
257
226
  throw new Error("parent undefined");
258
227
  }
259
-
260
228
  (0, _identifiers.validateChain)(object, [parent]);
261
-
262
229
  if (typeof parent === "object") {
263
230
  if (Array.isArray(parent)) {
264
231
  var index = parent.indexOf(object);
265
-
266
232
  if (index != -1) {
267
233
  // delete
268
234
  parent.splice(index, 1);
@@ -273,7 +239,6 @@ function deleteDirect(object, parent) {
273
239
  }
274
240
  } else {
275
241
  var keyName = Object.keys(parent).find(x => parent[x] == object);
276
-
277
242
  if (keyName) {
278
243
  delete parent[keyName];
279
244
  } else {
@@ -282,14 +247,11 @@ function deleteDirect(object, parent) {
282
247
  }
283
248
  }
284
249
  }
285
-
286
250
  function prepend(block) {
287
251
  (0, _assert.ok)(!Array.isArray(block), "block should not be array");
288
-
289
252
  for (var _len = arguments.length, nodes = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
290
253
  nodes[_key - 1] = arguments[_key];
291
254
  }
292
-
293
255
  if (block.type == "Program") {
294
256
  var moveBy = 0;
295
257
  block.body.forEach((stmt, i) => {
@@ -298,7 +260,6 @@ function prepend(block) {
298
260
  moveBy++;
299
261
  }
300
262
  }
301
-
302
263
  if (stmt.type === "ExpressionStatement" && typeof stmt.directive === "string") {
303
264
  if (moveBy == i) {
304
265
  moveBy++;
@@ -309,8 +270,9 @@ function prepend(block) {
309
270
  } else if (block.type === "SwitchCase") {
310
271
  block.consequent.unshift(...nodes);
311
272
  } else {
312
- var bodyArray = getBlockBody(block); // Check for 'use strict'
273
+ var bodyArray = getBlockBody(block);
313
274
 
275
+ // Check for 'use strict'
314
276
  if (bodyArray[0] && bodyArray[0].directive) {
315
277
  // Insert under 'use strict' directive
316
278
  bodyArray.splice(1, 0, ...nodes);
@@ -320,17 +282,13 @@ function prepend(block) {
320
282
  }
321
283
  }
322
284
  }
323
-
324
285
  function append(block) {
325
286
  (0, _assert.ok)(!Array.isArray(block), "block should not be array");
326
-
327
287
  for (var _len2 = arguments.length, nodes = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
328
288
  nodes[_key2 - 1] = arguments[_key2];
329
289
  }
330
-
331
290
  getBlockBody(block).push(...nodes);
332
291
  }
333
-
334
292
  function clone(object) {
335
293
  if (typeof object === "object" && object) {
336
294
  if (Array.isArray(object)) {
@@ -349,9 +307,9 @@ function clone(object) {
349
307
  return newObject;
350
308
  }
351
309
  }
352
-
353
310
  return object;
354
311
  }
312
+
355
313
  /**
356
314
  * | Return Value | Description |
357
315
  * | --- | --- |
@@ -365,16 +323,12 @@ function clone(object) {
365
323
  * @param p
366
324
  * @returns
367
325
  */
368
-
369
-
370
326
  function isForInitialize(o, p) {
371
327
  (0, _identifiers.validateChain)(o, p);
372
328
  var forIndex = p.findIndex(x => x.type == "ForStatement" || x.type == "ForInStatement" || x.type == "ForOfStatement");
373
-
374
329
  if (p.slice(0, forIndex).find(x => ["ArrowFunctionExpression", "BlockStatement"].includes(x.type))) {
375
330
  return false;
376
331
  }
377
-
378
332
  if (forIndex !== -1) {
379
333
  if (p[forIndex].type == "ForStatement") {
380
334
  if (p[forIndex].init == (p[forIndex - 1] || o)) {
@@ -386,20 +340,17 @@ function isForInitialize(o, p) {
386
340
  }
387
341
  }
388
342
  }
389
-
390
343
  return false;
391
344
  }
345
+
392
346
  /**
393
347
  * Computes the `function.length` property given the parameter nodes.
394
348
  *
395
349
  * @param params
396
350
  * @returns
397
351
  */
398
-
399
-
400
352
  function computeFunctionLength(params) {
401
353
  var count = 0;
402
-
403
354
  for (var parameterNode of params) {
404
355
  if (parameterNode.type === "Identifier" || parameterNode.type === "ObjectPattern" || parameterNode.type === "ArrayPattern") {
405
356
  count++;
@@ -407,6 +358,5 @@ function computeFunctionLength(params) {
407
358
  break;
408
359
  }
409
360
  }
410
-
411
361
  return count;
412
362
  }
package/dist/util/math.js CHANGED
@@ -4,19 +4,16 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getFactors = getFactors;
7
-
8
7
  function getFactors(num) {
9
8
  const isEven = num % 2 === 0;
10
9
  const max = Math.sqrt(num);
11
10
  const inc = isEven ? 1 : 2;
12
11
  let factors = [1, num];
13
-
14
12
  for (let curFactor = isEven ? 2 : 3; curFactor <= max; curFactor += inc) {
15
13
  if (num % curFactor !== 0) continue;
16
14
  factors.push(curFactor);
17
15
  let compliment = num / curFactor;
18
16
  if (compliment !== curFactor) factors.push(compliment);
19
17
  }
20
-
21
18
  return factors;
22
19
  }
@@ -5,33 +5,29 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createObject = createObject;
7
7
  exports.remove$Properties = remove$Properties;
8
-
9
8
  function createObject(keys, values) {
10
9
  if (keys.length != values.length) {
11
10
  throw new Error("length mismatch");
12
11
  }
13
-
14
12
  var newObject = {};
15
13
  keys.forEach((x, i) => {
16
14
  newObject[x] = values[i];
17
15
  });
18
16
  return newObject;
19
17
  }
18
+
20
19
  /**
21
20
  * Removes all `$`-prefixed properties on a deeply nested object.
22
21
  *
23
22
  * - Modifies the object.
24
23
  */
25
-
26
-
27
24
  function remove$Properties(object) {
28
25
  let seen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
29
-
30
26
  if (typeof object === "object" && object) {
31
- if (seen.has(object)) {// console.log(object);
27
+ if (seen.has(object)) {
28
+ // console.log(object);
32
29
  // throw new Error("Already seen");
33
30
  }
34
-
35
31
  seen.add(object);
36
32
  Object.keys(object).forEach(key => {
37
33
  if (key.charAt(0) == "$") {
@@ -13,11 +13,8 @@ exports.getRandomString = getRandomString;
13
13
  exports.getRandomTrueExpression = getRandomTrueExpression;
14
14
  exports.shuffle = shuffle;
15
15
  exports.splitIntoChunks = splitIntoChunks;
16
-
17
16
  var _assert = require("assert");
18
-
19
17
  var _gen = require("./gen");
20
-
21
18
  /**
22
19
  * Returns a random element from the given array
23
20
  * @param choices Array of items
@@ -27,135 +24,107 @@ function choice(choices) {
27
24
  var index = Math.floor(Math.random() * choices.length);
28
25
  return choices[index];
29
26
  }
27
+
30
28
  /**
31
29
  * Returns a true/false based on the percent chance (0%-100%)
32
30
  * @param percentChance AS A PERCENTAGE 0 - 100%
33
31
  */
34
-
35
-
36
32
  function chance(percentChance) {
37
33
  return Math.random() < percentChance / 100;
38
34
  }
35
+
39
36
  /**
40
37
  * **Mutates the given array**
41
38
  * @param array
42
39
  */
43
-
44
-
45
40
  function shuffle(array) {
46
41
  array.sort(() => Math.random() - 0.5);
47
42
  return array;
48
43
  }
44
+
49
45
  /**
50
46
  * Returns a random string.
51
47
  */
52
-
53
-
54
48
  function getRandomString(length) {
55
49
  var result = "";
56
50
  var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
57
51
  var charactersLength = characters.length;
58
-
59
52
  for (var i = 0; i < length; i++) {
60
53
  result += characters.charAt(Math.floor(Math.random() * charactersLength));
61
54
  }
62
-
63
55
  return result;
64
56
  }
65
-
66
57
  function getRandom(min, max) {
67
58
  return Math.random() * (max - min) + min;
68
59
  }
69
-
70
60
  function getRandomInteger(min, max) {
71
61
  return Math.floor(getRandom(min, max));
72
62
  }
73
-
74
63
  function splitIntoChunks(str, size) {
75
64
  (0, _assert.ok)(typeof str === "string", "str must be typeof string");
76
65
  (0, _assert.ok)(typeof size === "number", "size must be typeof number");
77
66
  (0, _assert.ok)(Math.floor(size) === size, "size must be integer");
78
67
  const numChunks = Math.ceil(str.length / size);
79
68
  const chunks = new Array(numChunks);
80
-
81
69
  for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
82
70
  chunks[i] = str.substr(o, size);
83
71
  }
84
-
85
72
  return chunks;
86
73
  }
74
+
87
75
  /**
88
76
  * Returns a random expression that will test to `false`.
89
77
  */
90
-
91
-
92
78
  function getRandomFalseExpression() {
93
79
  var type = choice(["0", "false", "null", "undefined", "NaN", "emptyString"]);
94
-
95
80
  switch (type) {
96
81
  case "0":
97
82
  return (0, _gen.Literal)(0);
98
-
99
83
  case "false":
100
84
  return (0, _gen.Literal)(false);
101
-
102
85
  case "null":
103
86
  return (0, _gen.Identifier)("null");
104
-
105
87
  case "undefined":
106
88
  return (0, _gen.Identifier)("undefined");
107
-
108
89
  case "NaN":
109
90
  return (0, _gen.Identifier)("NaN");
110
-
111
91
  default:
112
92
  // case "emptyString":
113
93
  return (0, _gen.Literal)("");
114
94
  }
115
95
  }
96
+
116
97
  /**
117
98
  * Returns a random expression that will test to `true`
118
99
  */
119
-
120
-
121
100
  function getRandomTrueExpression() {
122
101
  var type = choice(["number", "true", "Infinity", "nonEmptyString", "array", "object"]);
123
-
124
102
  switch (type) {
125
103
  case "number":
126
104
  return (0, _gen.Literal)(getRandomInteger(1, 100));
127
-
128
105
  case "true":
129
106
  return (0, _gen.Identifier)("true");
130
-
131
107
  case "Infinity":
132
108
  return (0, _gen.Identifier)("Infinity");
133
-
134
109
  case "nonEmptyString":
135
110
  return (0, _gen.Literal)(getRandomString(getRandomInteger(3, 9)));
136
-
137
111
  case "array":
138
112
  return (0, _gen.ArrayExpression)([]);
139
-
140
113
  default:
141
114
  //case "object":
142
115
  return (0, _gen.ObjectExpression)([]);
143
116
  }
144
117
  }
145
-
146
118
  function alphabeticalGenerator(index) {
147
119
  let name = "";
148
-
149
120
  while (index > 0) {
150
121
  var t = (index - 1) % 52;
151
122
  var thisChar = t >= 26 ? String.fromCharCode(65 + t - 26) : String.fromCharCode(97 + t);
152
123
  name = thisChar + name;
153
124
  index = (index - t) / 52 | 0;
154
125
  }
155
-
156
126
  if (!name) {
157
127
  name = "_";
158
128
  }
159
-
160
129
  return name;
161
130
  }
@@ -4,14 +4,17 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getLexicalScope = getLexicalScope;
7
+ exports.getLexicalScopeBody = getLexicalScopeBody;
7
8
  exports.isLexicalScope = isLexicalScope;
8
-
9
+ var _assert = require("assert");
9
10
  var _traverse = require("../traverse");
10
-
11
11
  function isLexicalScope(object) {
12
12
  return (0, _traverse.isBlock)(object) || object.type == "SwitchCase";
13
13
  }
14
-
15
14
  function getLexicalScope(object, parents) {
16
15
  return [object, ...parents].find(node => isLexicalScope(node));
16
+ }
17
+ function getLexicalScopeBody(object) {
18
+ (0, _assert.ok)(isLexicalScope(object));
19
+ return (0, _traverse.isBlock)(object) ? object.body : object.type === "SwitchCase" ? object.consequent : (0, _assert.ok)("Unhandled case");
17
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-confuser",
3
- "version": "1.7.1",
3
+ "version": "1.7.2",
4
4
  "description": "JavaScript Obfuscation Tool.",
5
5
  "main": "dist/index.js",
6
6
  "types": "index.d.ts",
@@ -22,8 +22,8 @@
22
22
  "author": "MichaelXF",
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "acorn": "^8.10.0",
26
- "escodegen": "^2.0.0"
25
+ "acorn": "^8.12.1",
26
+ "escodegen": "^2.1.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@babel/cli": "^7.17.6",
package/src/constants.ts CHANGED
@@ -82,3 +82,15 @@ export const reservedIdentifiers = new Set([
82
82
 
83
83
  export const noRenameVariablePrefix = "__NO_JS_CONFUSER_RENAME__";
84
84
  export const placeholderVariablePrefix = "__p_";
85
+
86
+ /**
87
+ * Tells the obfuscator this function is predictable:
88
+ * - Never called with extraneous parameters
89
+ */
90
+ export const predictableFunctionTag = "__JS_PREDICT__";
91
+
92
+ /**
93
+ * Tells the obfuscator this function is critical for the Obfuscated code.
94
+ * - Example: string decryption function
95
+ */
96
+ export const criticalFunctionTag = "__JS_CRITICAL__";
package/src/options.ts CHANGED
@@ -585,6 +585,15 @@ export interface ObfuscateOptions {
585
585
  * [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
586
586
  */
587
587
  debugComments?: boolean;
588
+
589
+ /**
590
+ * ### `preserveFunctionLength`
591
+ *
592
+ * Modified functions will retain the correct `function.length` property. Enabled by default. (`true/false`)
593
+ *
594
+ * [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
595
+ */
596
+ preserveFunctionLength?: boolean;
588
597
  }
589
598
 
590
599
  const validProperties = new Set([
@@ -619,6 +628,7 @@ const validProperties = new Set([
619
628
  "verbose",
620
629
  "globalVariables",
621
630
  "debugComments",
631
+ "preserveFunctionLength",
622
632
  ]);
623
633
 
624
634
  const validOses = new Set(["windows", "linux", "osx", "ios", "android"]);
@@ -764,6 +774,9 @@ export async function correctOptions(
764
774
  if (!options.hasOwnProperty("renameGlobals")) {
765
775
  options.renameGlobals = true; // RenameGlobals is on by default
766
776
  }
777
+ if (!options.hasOwnProperty("preserveFunctionLength")) {
778
+ options.preserveFunctionLength = true; // preserveFunctionLength is on by default
779
+ }
767
780
 
768
781
  if (options.globalVariables && !(options.globalVariables instanceof Set)) {
769
782
  options.globalVariables = new Set(Object.keys(options.globalVariables));
package/src/order.ts CHANGED
@@ -46,11 +46,11 @@ export enum ObfuscateOrder {
46
46
 
47
47
  Minify = 28,
48
48
 
49
+ AntiTooling = 29,
50
+
49
51
  RenameVariables = 30,
50
52
 
51
53
  ES5 = 31,
52
54
 
53
- AntiTooling = 34,
54
-
55
55
  Finalizer = 35,
56
56
  }