js-confuser 1.2.2 → 1.4.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 (78) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +4 -1
  3. package/dist/parser.js +1 -2
  4. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +482 -91
  5. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -0
  6. package/dist/transforms/controlFlowFlattening/{switchCaseObfucation.js → switchCaseObfuscation.js} +2 -2
  7. package/dist/transforms/deadCode.js +1 -1
  8. package/dist/transforms/dispatcher.js +7 -6
  9. package/dist/transforms/eval.js +1 -1
  10. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +4 -2
  11. package/dist/transforms/hideInitializingCode.js +4 -1
  12. package/dist/transforms/identifier/globalConcealing.js +18 -8
  13. package/dist/transforms/identifier/variableAnalysis.js +1 -1
  14. package/dist/transforms/label.js +11 -2
  15. package/dist/transforms/lock/antiDebug.js +32 -13
  16. package/dist/transforms/lock/lock.js +3 -3
  17. package/dist/transforms/minify.js +2 -2
  18. package/dist/transforms/opaquePredicates.js +4 -2
  19. package/dist/transforms/preparation/preparation.js +8 -0
  20. package/dist/transforms/renameLabels.js +17 -3
  21. package/dist/transforms/rgf.js +8 -3
  22. package/dist/transforms/stack.js +1 -1
  23. package/dist/transforms/string/encoding.js +74 -0
  24. package/dist/transforms/string/stringCompression.js +6 -2
  25. package/dist/transforms/string/stringConcealing.js +1 -1
  26. package/dist/transforms/string/stringSplitting.js +6 -0
  27. package/dist/traverse.js +0 -34
  28. package/dist/util/gen.js +3 -1
  29. package/dist/util/identifiers.js +8 -18
  30. package/dist/util/insert.js +4 -38
  31. package/package.json +2 -2
  32. package/src/options.ts +3 -3
  33. package/src/parser.ts +1 -2
  34. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +735 -134
  35. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +6 -0
  36. package/src/transforms/controlFlowFlattening/{switchCaseObfucation.ts → switchCaseObfuscation.ts} +6 -2
  37. package/src/transforms/deadCode.ts +8 -0
  38. package/src/transforms/dispatcher.ts +16 -6
  39. package/src/transforms/eval.ts +2 -1
  40. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +40 -5
  41. package/src/transforms/hideInitializingCode.ts +432 -425
  42. package/src/transforms/identifier/globalConcealing.ts +102 -38
  43. package/src/transforms/identifier/variableAnalysis.ts +1 -1
  44. package/src/transforms/label.ts +20 -2
  45. package/src/transforms/lock/antiDebug.ts +69 -33
  46. package/src/transforms/lock/lock.ts +4 -5
  47. package/src/transforms/minify.ts +2 -1
  48. package/src/transforms/opaquePredicates.ts +25 -3
  49. package/src/transforms/preparation/preparation.ts +8 -1
  50. package/src/transforms/renameLabels.ts +26 -3
  51. package/src/transforms/rgf.ts +6 -1
  52. package/src/transforms/stack.ts +2 -1
  53. package/src/transforms/string/encoding.ts +107 -1
  54. package/src/transforms/string/stringCompression.ts +28 -3
  55. package/src/transforms/string/stringConcealing.ts +2 -0
  56. package/src/transforms/string/stringSplitting.ts +11 -0
  57. package/src/transforms/transform.ts +1 -2
  58. package/src/traverse.ts +0 -30
  59. package/src/util/gen.ts +5 -3
  60. package/src/util/identifiers.ts +18 -19
  61. package/src/util/insert.ts +10 -76
  62. package/src/util/scope.ts +9 -9
  63. package/test/{transforms/compare.test.ts → compare.test.ts} +2 -2
  64. package/test/index.test.ts +109 -1
  65. package/test/templates/template.test.ts +14 -0
  66. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +392 -10
  67. package/test/transforms/dispatcher.test.ts +30 -0
  68. package/test/transforms/eval.test.ts +28 -0
  69. package/test/transforms/flatten.test.ts +28 -0
  70. package/test/transforms/hideInitializingCode.test.ts +336 -336
  71. package/test/transforms/identifier/renameVariables.test.ts +31 -0
  72. package/test/transforms/lock/antiDebug.test.ts +43 -0
  73. package/test/transforms/renameLabels.test.ts +33 -0
  74. package/test/transforms/rgf.test.ts +29 -0
  75. package/test/transforms/string/stringSplitting.test.ts +33 -0
  76. package/test/util/identifiers.test.ts +105 -17
  77. package/dist/util/expr.js +0 -60
  78. package/src/util/expr.ts +0 -56
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,8 +18,6 @@ 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");
@@ -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
  };
@@ -4,8 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.validateChain = validateChain;
7
- exports.isWithinClass = isWithinClass;
8
- exports.isWithin = isWithin;
9
7
  exports.getIdentifierInfo = getIdentifierInfo;
10
8
  exports.getDefiningIdentifier = getDefiningIdentifier;
11
9
  exports.isFunctionParameter = isFunctionParameter;
@@ -44,14 +42,6 @@ function validateChain(object, parents) {
44
42
  }
45
43
  }
46
44
  }
47
-
48
- function isWithinClass(object, parents) {
49
- return isWithin(object, parents, "ClassDeclaration") || isWithin(object, parents, "ClassExpression");
50
- }
51
-
52
- function isWithin(object, parents, type) {
53
- return [object, ...parents].some(x => x.type == type);
54
- }
55
45
  /**
56
46
  * Returns detailed information about the given Identifier node.
57
47
  * @param object
@@ -99,8 +89,9 @@ function getIdentifierInfo(object, parents) {
99
89
  var isImportSpecifier = (parent.type == "ImportDefaultSpecifier" || parent.type == "ImportSpecifier") && parent.local == object;
100
90
  var isFunctionCall = parent.callee == object; // NewExpression and CallExpression
101
91
 
102
- var isAssignmentLeft = parent.type == "AssignmentExpression" && parent.left == object;
103
- var isAssignmentValue = parent.type == "AssignmentExpression" && parent.right == object;
92
+ var assignmentIndex = parents.findIndex(p => p.type === "AssignmentExpression");
93
+ var isAssignmentLeft = assignmentIndex !== -1 && parents[assignmentIndex].left === (parents[assignmentIndex - 1] || object);
94
+ var isAssignmentValue = assignmentIndex !== -1 && parents[assignmentIndex].right === (parents[assignmentIndex - 1] || object);
104
95
  var isUpdateExpression = parent.type == "UpdateExpression";
105
96
  var isClassDeclaration = (parent.type == "ClassDeclaration" || parent.type == "ClassExpression") && parent.id == object;
106
97
  var isMethodDefinition = parent.type == "MethodDefinition" && parent.key == object && !parent.computed;
@@ -300,7 +291,7 @@ function getDefiningIdentifier(object, parents) {
300
291
  }
301
292
  }
302
293
 
303
- function isFunctionParameter(o, p) {
294
+ function isFunctionParameter(o, p, c) {
304
295
  (0, _assert.ok)(o);
305
296
  (0, _assert.ok)(p);
306
297
  validateChain(o, p);
@@ -315,7 +306,7 @@ function isFunctionParameter(o, p) {
315
306
  return false;
316
307
  }
317
308
 
318
- var c = (0, _insert.getVarContext)(o, p);
309
+ c = c || (0, _insert.getVarContext)(o, p);
319
310
 
320
311
  if (c === object) {
321
312
  var pIndex = p.indexOf(object.params);
@@ -327,8 +318,7 @@ function isFunctionParameter(o, p) {
327
318
  var param = p[pIndex - 1] || o;
328
319
  var paramIndex = object.params.indexOf(param);
329
320
  (0, _assert.ok)(paramIndex !== -1);
330
- var sliced = p.slice(p.indexOf(paramIndex));
331
- (0, _assert.ok)(!sliced.includes(o));
321
+ var sliced = p.slice(0, pIndex);
332
322
  var isReferenced = true;
333
323
  var i = 0;
334
324
 
@@ -342,7 +332,7 @@ function isFunctionParameter(o, p) {
342
332
  break;
343
333
  }
344
334
 
345
- if (node.type == "ObjectPattern" && node.key === down) {
335
+ if (node.type == "Property" && node.key === down && sliced[i + 2] && sliced[i + 2].type == "ObjectPattern") {
346
336
  isReferenced = false;
347
337
  break;
348
338
  }
@@ -365,7 +355,7 @@ function getFunctionParameters(object, parents) {
365
355
  var locations = [];
366
356
  (0, _traverse.walk)(object.params, [object, ...parents], (o, p) => {
367
357
  if (o.type == "Identifier") {
368
- if (isFunctionParameter(o, p)) {
358
+ if (isFunctionParameter(o, p, object)) {
369
359
  locations.push([o, p]);
370
360
  }
371
361
  }
@@ -21,7 +21,6 @@ exports.prepend = prepend;
21
21
  exports.append = append;
22
22
  exports.clone = clone;
23
23
  exports.isForInitialize = isForInitialize;
24
- exports.isInBranch = isInBranch;
25
24
 
26
25
  var _assert = require("assert");
27
26
 
@@ -151,27 +150,15 @@ function getDefiningContext(o, p) {
151
150
  return getVarContext(o, p);
152
151
  }
153
152
 
154
- function getReferencingContexts(o, p) {
153
+ function getReferencingContexts(o, p, info) {
155
154
  (0, _identifiers.validateChain)(o, p);
156
155
  (0, _assert.ok)(o.type == "Identifier");
157
- var info = (0, _identifiers.getIdentifierInfo)(o, p);
158
- (0, _assert.ok)(info.spec.isReferenced);
159
- var assignmentPatternIndex = p.findIndex(x => x.type == "AssignmentPattern");
160
-
161
- if (assignmentPatternIndex != -1) {
162
- if (p[assignmentPatternIndex].right == (p[assignmentPatternIndex - 1] || o)) {
163
- var sliced = p.slice(assignmentPatternIndex);
164
- var fnIndex = sliced.findIndex(x => isFunction(x));
165
- var associatedFn = sliced[fnIndex];
166
156
 
167
- if (fnIndex !== -1 && sliced[fnIndex].params == (sliced[fnIndex - 1] || o)) {
168
- if (associatedFn == getVarContext(o, p)) {
169
- return isLexContext(associatedFn.body) ? [associatedFn, associatedFn.body] : [associatedFn];
170
- }
171
- }
172
- }
157
+ if (!info) {
158
+ info = (0, _identifiers.getIdentifierInfo)(o, p);
173
159
  }
174
160
 
161
+ (0, _assert.ok)(info.spec.isReferenced);
175
162
  return [getVarContext(o, p), getLexContext(o, p)];
176
163
  }
177
164
 
@@ -339,25 +326,4 @@ function isForInitialize(o, p) {
339
326
  }
340
327
 
341
328
  return false;
342
- }
343
-
344
- function isInBranch(object, parents, context) {
345
- (0, _assert.ok)(object);
346
- (0, _assert.ok)(parents);
347
- (0, _assert.ok)(context);
348
- (0, _assert.ok)(parents.includes(context));
349
- var definingContext = parents[0].type == "FunctionDeclaration" && parents[0].id == object ? getVarContext(parents[0], parents.slice(1)) : getVarContext(object, parents);
350
- var contextIndex = parents.findIndex(x => x === context);
351
- var slicedParents = parents.slice(0, contextIndex);
352
- (0, _assert.ok)(!slicedParents.includes(object), "slicedParents includes object");
353
- var slicedTypes = new Set(slicedParents.map(x => x.type));
354
- var isBranch = definingContext !== context;
355
-
356
- if (!isBranch) {
357
- if (["IfStatement", "ForStatement", "ForInStatement", "ForOfStatement", "WhileStatement", "DoWhileStatement", "SwitchStatement", "ConditionalExpression", "LogicalExpression", "TryStatement", "ChainExpression", "BinaryExpression", "FunctionExpression", "FunctionDeclaration", "ArrowFunctionExpression", "ClassExpression", "ClassDeclaration"].find(x => slicedTypes.has(x))) {
358
- isBranch = true;
359
- }
360
- }
361
-
362
- return isBranch;
363
329
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-confuser",
3
- "version": "1.2.2",
3
+ "version": "1.4.2",
4
4
  "description": "JavaScript Obfuscation Tool.",
5
5
  "main": "dist/index.js",
6
6
  "types": "index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "author": "MichaelXF",
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "acorn": "^8.4.0",
25
+ "acorn": "^8.5.0",
26
26
  "escodegen": "^2.0.0"
27
27
  },
28
28
  "devDependencies": {
package/src/options.ts CHANGED
@@ -224,7 +224,7 @@ export interface ObfuscateOptions {
224
224
  /**
225
225
  * ### `stringConcealing`
226
226
  *
227
- * [String Concealing](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-concealing) involves encoding strings to conceal plain-text values. (`true/false`)
227
+ * [String Concealing](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-concealing) involves encoding strings to conceal plain-text values. (`true/false/0-1`)
228
228
  *
229
229
  * `"console"` -> `decrypt('<~@rH7+Dert~>')`
230
230
  *
@@ -237,7 +237,7 @@ export interface ObfuscateOptions {
237
237
  /**
238
238
  * ### `stringEncoding`
239
239
  *
240
- * [String Encoding](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-encoding) transforms a string into an encoded representation. (`true/false`)
240
+ * [String Encoding](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-encoding) transforms a string into an encoded representation. (`true/false/0-1`)
241
241
  *
242
242
  * `"console"` -> `'\x63\x6f\x6e\x73\x6f\x6c\x65'`
243
243
  *
@@ -252,7 +252,7 @@ export interface ObfuscateOptions {
252
252
  /**
253
253
  * ### `stringSplitting`
254
254
  *
255
- * [String Splitting](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-splitting) splits your strings into multiple expressions. (`true/false`)
255
+ * [String Splitting](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-splitting) splits your strings into multiple expressions. (`true/false/0-1`)
256
256
  *
257
257
  * `"console"` -> `String.fromCharCode(99) + 'ons' + 'ole'`
258
258
  *
package/src/parser.ts CHANGED
@@ -18,8 +18,7 @@ export default async function parseJS(code: string): Promise<{
18
18
  var parsed = parseSync(code);
19
19
  return parsed as any;
20
20
  } catch (e) {
21
- console.error(e);
22
- throw new Error("Failed to parse code.");
21
+ throw e;
23
22
  }
24
23
  }
25
24