js-confuser 2.0.0-alpha.2 → 2.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +24 -6
  2. package/dist/constants.js +6 -2
  3. package/dist/index.js +12 -0
  4. package/dist/obfuscator.js +117 -6
  5. package/dist/order.js +0 -1
  6. package/dist/probability.js +1 -96
  7. package/dist/templates/getGlobalTemplate.js +4 -1
  8. package/dist/templates/stringCompressionTemplate.js +3 -3
  9. package/dist/templates/tamperProtectionTemplates.js +1 -1
  10. package/dist/templates/template.js +17 -12
  11. package/dist/transforms/controlFlowFlattening.js +2 -6
  12. package/dist/transforms/deadCode.js +8 -15
  13. package/dist/transforms/dispatcher.js +1 -2
  14. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +5 -0
  15. package/dist/transforms/extraction/objectExtraction.js +1 -2
  16. package/dist/transforms/finalizer.js +1 -1
  17. package/dist/transforms/flatten.js +2 -19
  18. package/dist/transforms/identifier/globalConcealing.js +1 -2
  19. package/dist/transforms/identifier/movedDeclarations.js +12 -5
  20. package/dist/transforms/identifier/renameVariables.js +7 -6
  21. package/dist/transforms/lock/lock.js +9 -2
  22. package/dist/transforms/minify.js +14 -1
  23. package/dist/transforms/opaquePredicates.js +5 -6
  24. package/dist/transforms/pack.js +5 -0
  25. package/dist/transforms/plugin.js +20 -39
  26. package/dist/transforms/renameLabels.js +1 -2
  27. package/dist/transforms/rgf.js +29 -11
  28. package/dist/transforms/shuffle.js +10 -11
  29. package/dist/transforms/string/stringCompression.js +14 -10
  30. package/dist/transforms/string/stringConcealing.js +4 -4
  31. package/dist/transforms/string/stringEncoding.js +4 -2
  32. package/dist/transforms/string/stringSplitting.js +4 -2
  33. package/dist/transforms/variableMasking.js +1 -2
  34. package/dist/utils/NameGen.js +3 -2
  35. package/dist/utils/PredicateGen.js +62 -0
  36. package/dist/utils/ast-utils.js +24 -9
  37. package/dist/validateOptions.js +2 -2
  38. package/package.json +2 -2
  39. package/src/constants.ts +6 -5
  40. package/src/index.ts +1 -0
  41. package/src/obfuscator.ts +148 -7
  42. package/src/options.ts +14 -6
  43. package/src/order.ts +0 -2
  44. package/src/probability.ts +0 -110
  45. package/src/templates/getGlobalTemplate.ts +5 -1
  46. package/src/templates/stringCompressionTemplate.ts +4 -28
  47. package/src/templates/tamperProtectionTemplates.ts +7 -3
  48. package/src/templates/template.ts +5 -3
  49. package/src/transforms/controlFlowFlattening.ts +2 -7
  50. package/src/transforms/deadCode.ts +11 -23
  51. package/src/transforms/dispatcher.ts +1 -2
  52. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +10 -1
  53. package/src/transforms/extraction/objectExtraction.ts +1 -2
  54. package/src/transforms/finalizer.ts +1 -1
  55. package/src/transforms/flatten.ts +3 -22
  56. package/src/transforms/identifier/globalConcealing.ts +4 -2
  57. package/src/transforms/identifier/movedDeclarations.ts +18 -6
  58. package/src/transforms/identifier/renameVariables.ts +10 -6
  59. package/src/transforms/lock/lock.ts +14 -3
  60. package/src/transforms/minify.ts +24 -2
  61. package/src/transforms/opaquePredicates.ts +5 -8
  62. package/src/transforms/pack.ts +6 -0
  63. package/src/transforms/plugin.ts +47 -69
  64. package/src/transforms/renameLabels.ts +1 -2
  65. package/src/transforms/rgf.ts +39 -14
  66. package/src/transforms/shuffle.ts +28 -26
  67. package/src/transforms/string/encoding.ts +1 -1
  68. package/src/transforms/string/stringCompression.ts +22 -13
  69. package/src/transforms/string/stringConcealing.ts +11 -7
  70. package/src/transforms/string/stringEncoding.ts +6 -2
  71. package/src/transforms/string/stringSplitting.ts +9 -4
  72. package/src/transforms/variableMasking.ts +1 -2
  73. package/src/utils/NameGen.ts +4 -2
  74. package/src/utils/PredicateGen.ts +61 -0
  75. package/src/utils/ast-utils.ts +16 -9
  76. package/src/validateOptions.ts +7 -4
  77. package/src/transforms/functionOutlining.ts +0 -225
  78. package/src/utils/ControlObject.ts +0 -141
@@ -7,12 +7,11 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports["default"] = void 0;
8
8
  var _randomUtils = require("../utils/random-utils");
9
9
  var _deadCodeTemplates = require("../templates/deadCodeTemplates");
10
- var _probability = require("../probability");
11
10
  var _order = require("../order");
12
11
  var t = _interopRequireWildcard(require("@babel/types"));
13
12
  var _template = _interopRequireDefault(require("../templates/template"));
14
- var _NameGen = require("../utils/NameGen");
15
13
  var _astUtils = require("../utils/ast-utils");
14
+ var _PredicateGen = _interopRequireDefault(require("../utils/PredicateGen"));
16
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
17
16
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
18
17
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
@@ -30,6 +29,7 @@ var _default = exports["default"] = function _default(_ref) {
30
29
  }
31
30
  });
32
31
  var created = 0;
32
+ var predicateGen = new _PredicateGen["default"](me);
33
33
  return {
34
34
  visitor: {
35
35
  Block: {
@@ -37,7 +37,7 @@ var _default = exports["default"] = function _default(_ref) {
37
37
  if (blockPath.find(function (p) {
38
38
  return me.isSkipped(p);
39
39
  })) return;
40
- if (!(0, _probability.computeProbabilityMap)(me.options.deadCode)) {
40
+ if (!me.computeProbabilityMap(me.options.deadCode)) {
41
41
  return;
42
42
  }
43
43
  if (typeof me.options.deadCode !== "function") {
@@ -52,19 +52,12 @@ var _default = exports["default"] = function _default(_ref) {
52
52
  var template = (0, _randomUtils.choice)(_deadCodeTemplates.deadCodeTemplates);
53
53
  var nodes = template.compile();
54
54
  var containingFnName = me.getPlaceholder("dead_" + created);
55
- var newPath = blockPath.unshiftContainer("body", t.functionDeclaration(t.identifier(containingFnName), [], t.blockStatement(_toConsumableArray(nodes))));
56
55
 
57
- // Overcomplicated way to get a random property name that doesn't exist on the Function
58
- var randomProperty;
59
- var nameGen = new _NameGen.NameGen("randomized");
60
- function PrototypeCollision() {}
61
- PrototypeCollision(); // Call it for code coverage :D
62
-
63
- do {
64
- randomProperty = nameGen.generate();
65
- } while (!randomProperty || PrototypeCollision[randomProperty] !== undefined);
66
- me.changeData.deadCode++;
67
- (0, _astUtils.prepend)(blockPath, new _template["default"]("\n if(\"".concat(randomProperty, "\" in ").concat(containingFnName, ") {\n ").concat(containingFnName, "()\n }\n ")).single());
56
+ // Insert dummy function
57
+ (0, _astUtils.prepend)(blockPath, t.functionDeclaration(t.identifier(containingFnName), [], t.blockStatement(_toConsumableArray(nodes))));
58
+ (0, _astUtils.prepend)(blockPath, new _template["default"]("\n if({falsePredicate}) {\n ".concat(containingFnName, "()\n }\n ")).single({
59
+ falsePredicate: predicateGen.generateFalseExpression(blockPath)
60
+ }));
68
61
  me.skip(blockPath);
69
62
  }
70
63
  }
@@ -9,7 +9,6 @@ var t = _interopRequireWildcard(require("@babel/types"));
9
9
  var _template = _interopRequireDefault(require("../templates/template"));
10
10
  var _assert = require("assert");
11
11
  var _randomUtils = require("../utils/random-utils");
12
- var _probability = require("../probability");
13
12
  var _order = require("../order");
14
13
  var _constants = require("../constants");
15
14
  var _functionUtils = require("../utils/function-utils");
@@ -148,7 +147,7 @@ var _default = exports["default"] = function _default(_ref) {
148
147
  try {
149
148
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
150
149
  var name = _step2.value;
151
- if (!(0, _probability.computeProbabilityMap)(me.options.dispatcher, name)) {
150
+ if (!me.computeProbabilityMap(me.options.dispatcher, name)) {
152
151
  functionPaths["delete"](name);
153
152
  }
154
153
  }
@@ -40,6 +40,11 @@ var _default = exports["default"] = function _default(_ref) {
40
40
  programPath.traverse({
41
41
  "StringLiteral|BooleanLiteral|NumericLiteral|NullLiteral|Identifier": function StringLiteralBooleanLiteralNumericLiteralNullLiteralIdentifier(_path) {
42
42
  var literalPath = _path;
43
+
44
+ // Don't change module imports
45
+ if (literalPath.isStringLiteral()) {
46
+ if ((0, _astUtils.isModuleImport)(literalPath)) return;
47
+ }
43
48
  var node = literalPath.node;
44
49
  var isUndefined = false;
45
50
  if (literalPath.isIdentifier()) {
@@ -8,7 +8,6 @@ exports["default"] = void 0;
8
8
  var _order = require("../../order");
9
9
  var t = _interopRequireWildcard(require("@babel/types"));
10
10
  var _astUtils = require("../../utils/ast-utils");
11
- var _probability = require("../../probability");
12
11
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
13
12
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
14
13
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
@@ -134,7 +133,7 @@ var _default = exports["default"] = function _default(_ref) {
134
133
 
135
134
  // Object references are too complex to safely extract
136
135
  if (!isObjectSafe) return;
137
- if (!(0, _probability.computeProbabilityMap)(me.options.objectExtraction, identifier.node.name)) return;
136
+ if (!me.computeProbabilityMap(me.options.objectExtraction, identifier.node.name)) return;
138
137
  var newDeclarationKind = varDecPath.node.kind === "const" ? "let" : varDecPath.node.kind;
139
138
  varDecPath.replaceWithMultiple(newDeclarations.map(function (declaration) {
140
139
  return t.variableDeclaration(newDeclarationKind, [declaration]);
@@ -40,7 +40,7 @@ var _default = exports["default"] = function _default(_ref) {
40
40
  }
41
41
  }), {}, {
42
42
  // Hexadecimal numbers
43
- NumberLiteral: {
43
+ NumericLiteral: {
44
44
  exit: function exit(path) {
45
45
  if (me.options.hexadecimalNumbers) {
46
46
  var value = path.node.value;
@@ -7,11 +7,9 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports["default"] = void 0;
8
8
  var t = _interopRequireWildcard(require("@babel/types"));
9
9
  var _astUtils = require("../utils/ast-utils");
10
- var _probability = require("../probability");
11
10
  var _order = require("../order");
12
11
  var _constants = require("../constants");
13
12
  var _functionUtils = require("../utils/function-utils");
14
- var _assert = require("assert");
15
13
  var _NameGen = require("../utils/NameGen");
16
14
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
17
15
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
@@ -59,7 +57,7 @@ var _default = exports["default"] = function _default(_ref) {
59
57
  if (!t.isValidIdentifier(functionName, true)) {
60
58
  functionName = "anonymous";
61
59
  }
62
- if (!(0, _probability.computeProbabilityMap)(me.options.flatten, functionName)) {
60
+ if (!me.computeProbabilityMap(me.options.flatten, functionName)) {
63
61
  return;
64
62
  }
65
63
  var strictMode = fnPath.find(function (path) {
@@ -99,22 +97,7 @@ var _default = exports["default"] = function _default(_ref) {
99
97
  if (!binding) {
100
98
  return;
101
99
  }
102
- var definedLocal = identifierPath.scope;
103
- do {
104
- if (definedLocal.hasOwnBinding(identifierName)) return;
105
- if (definedLocal === fnPath.scope) break;
106
- definedLocal = definedLocal.parent;
107
- if (definedLocal === program.scope) (0, _assert.ok)(functionName + ":" + identifierName);
108
- } while (definedLocal);
109
- var cursor = fnPath.scope.parent;
110
- var isOutsideVariable = false;
111
- do {
112
- if (cursor.hasBinding(identifierName)) {
113
- isOutsideVariable = true;
114
- break;
115
- }
116
- cursor = cursor.parent;
117
- } while (cursor);
100
+ var isOutsideVariable = fnPath.scope.parent.getBinding(identifierName) === binding;
118
101
  if (!isOutsideVariable) {
119
102
  return;
120
103
  }
@@ -9,7 +9,6 @@ var t = _interopRequireWildcard(require("@babel/types"));
9
9
  var _NameGen = require("../../utils/NameGen");
10
10
  var _template = _interopRequireDefault(require("../../templates/template"));
11
11
  var _order = require("../../order");
12
- var _probability = require("../../probability");
13
12
  var _constants = require("../../constants");
14
13
  var _astUtils = require("../../utils/ast-utils");
15
14
  var _getGlobalTemplate = require("../../templates/getGlobalTemplate");
@@ -110,7 +109,7 @@ var _default = exports["default"] = function _default(_ref) {
110
109
  var mapping = globalMapping.get(globalName);
111
110
  if (!mapping) {
112
111
  // Allow user to disable custom global variables
113
- if (!(0, _probability.computeProbabilityMap)(me.options.globalConcealing, globalName)) continue;
112
+ if (!me.computeProbabilityMap(me.options.globalConcealing, globalName)) continue;
114
113
  mapping = gen.generate();
115
114
  globalMapping.set(globalName, mapping);
116
115
  }
@@ -60,9 +60,11 @@ var _default = exports["default"] = function _default(_ref) {
60
60
  return path.isFunction();
61
61
  });
62
62
  if (!functionPath || !functionPath.node[_constants.PREDICTABLE]) return;
63
+ var fnBody = functionPath.get("body");
64
+ if (!fnBody.isBlockStatement()) return;
63
65
 
64
66
  // Must be direct child of the function
65
- if (path.parentPath !== functionPath.get("body")) return;
67
+ if (path.parentPath !== fnBody) return;
66
68
  var functionName = path.node.id.name;
67
69
 
68
70
  // Must be eligible for parameter packing
@@ -85,7 +87,7 @@ var _default = exports["default"] = function _default(_ref) {
85
87
  binding.path = paramPath;
86
88
  binding.identifier = identifier;
87
89
  }
88
- (0, _astUtils.prepend)(functionPath, new _template["default"]("\n if(!".concat(functionName, ") {\n ").concat(functionName, " = {functionExpression};\n }\n ")).single({
90
+ (0, _astUtils.prepend)(fnBody, new _template["default"]("\n if(!".concat(functionName, ") {\n ").concat(functionName, " = {functionExpression};\n }\n ")).single({
89
91
  functionExpression: functionExpression
90
92
  }));
91
93
  path.remove();
@@ -94,6 +96,7 @@ var _default = exports["default"] = function _default(_ref) {
94
96
  },
95
97
  VariableDeclaration: {
96
98
  exit: function exit(path) {
99
+ if (me.isSkipped(path)) return;
97
100
  if (path.node.kind !== "var") return;
98
101
  if (path.node.declarations.length !== 1) return;
99
102
  var insertionMethod = "variableDeclaration";
@@ -125,7 +128,9 @@ var _default = exports["default"] = function _default(_ref) {
125
128
  var isDefinedAtTop = false;
126
129
  var parentPath = path.parentPath;
127
130
  if (parentPath.isBlock()) {
128
- isDefinedAtTop = parentPath.get("body").indexOf(path) === 0;
131
+ isDefinedAtTop = parentPath.get("body").filter(function (x) {
132
+ return x.type !== "ImportDeclaration";
133
+ }).indexOf(path) === 0;
129
134
  }
130
135
 
131
136
  // Already at the top - nothing will change
@@ -167,13 +172,15 @@ var _default = exports["default"] = function _default(_ref) {
167
172
  var block = path.findParent(function (path) {
168
173
  return path.isBlock();
169
174
  });
170
- var topNode = block.node.body[0];
175
+ var topNode = block.node.body.filter(function (x) {
176
+ return x.type !== "ImportDeclaration";
177
+ })[0];
171
178
  var variableDeclarator = t.variableDeclarator(t.identifier(name));
172
179
  if (t.isVariableDeclaration(topNode) && topNode.kind === "var") {
173
180
  topNode.declarations.push(variableDeclarator);
174
181
  break;
175
182
  } else {
176
- block.node.body.unshift(t.variableDeclaration("var", [variableDeclarator]));
183
+ (0, _astUtils.prepend)(block, me.skip(t.variableDeclaration("var", [variableDeclarator])));
177
184
  }
178
185
  me.changeData.variableDeclarations++;
179
186
  break;
@@ -8,7 +8,6 @@ exports["default"] = void 0;
8
8
  var t = _interopRequireWildcard(require("@babel/types"));
9
9
  var _order = require("../../order");
10
10
  var _constants = require("../../constants");
11
- var _probability = require("../../probability");
12
11
  var _astUtils = require("../../utils/ast-utils");
13
12
  var _functionUtils = require("../../utils/function-utils");
14
13
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
@@ -211,16 +210,18 @@ var _default = exports["default"] = function _default(_ref) {
211
210
 
212
211
  // Placeholder variables should always be renamed
213
212
  if (name.startsWith(_constants.placeholderVariablePrefix)) return true;
214
-
215
- // Do not rename exports
216
- if ((0, _astUtils.isExportedIdentifier)(bindings === null || bindings === void 0 ? void 0 : bindings.get(name))) return false;
213
+ var binding = bindings === null || bindings === void 0 ? void 0 : bindings.get(name);
214
+ if (binding) {
215
+ // Do not rename exports
216
+ if ((0, _astUtils.isExportedIdentifier)(binding)) return false;
217
+ }
217
218
  if (name === me.obfuscator.getStringCompressionLibraryName()) return false;
218
219
 
219
220
  // Global variables are additionally checked against user option
220
221
  if (isGlobal) {
221
- if (!(0, _probability.computeProbabilityMap)(me.options.renameGlobals, name)) return false;
222
+ if (!me.computeProbabilityMap(me.options.renameGlobals, name)) return false;
222
223
  }
223
- if (!(0, _probability.computeProbabilityMap)(me.options.renameVariables, name, isGlobal)) return false;
224
+ if (!me.computeProbabilityMap(me.options.renameVariables, name, isGlobal)) return false;
224
225
  return true;
225
226
  }
226
227
 
@@ -14,7 +14,6 @@ var _integrity = require("./integrity");
14
14
  var _integrityTemplate = require("../../templates/integrityTemplate");
15
15
  var _constants = require("../../constants");
16
16
  var _tamperProtectionTemplates = require("../../templates/tamperProtectionTemplates");
17
- var _probability = require("../../probability");
18
17
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
19
18
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
20
19
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
@@ -33,12 +32,20 @@ var _default = exports["default"] = function _default(_ref) {
33
32
  }
34
33
  });
35
34
  if (me.options.lock.startDate instanceof Date) {
35
+ // Ensure date is in the past
36
+ if (me.options.lock.startDate.getTime() > Date.now()) {
37
+ me.warn("lock.startDate is detected to be in the future");
38
+ }
36
39
  me.options.lock.customLocks.push({
37
40
  code: ["\n if(Date.now()<".concat(me.options.lock.startDate.getTime(), ") {\n {countermeasures}\n }\n "), "\n if((new Date()).getTime()<".concat(me.options.lock.startDate.getTime(), ") {\n {countermeasures}\n }\n ")],
38
41
  percentagePerBlock: 0.5
39
42
  });
40
43
  }
41
44
  if (me.options.lock.endDate instanceof Date) {
45
+ // Ensure date is in the future
46
+ if (me.options.lock.endDate.getTime() < Date.now()) {
47
+ me.warn("lock.endDate is detected to be in the past");
48
+ }
42
49
  me.options.lock.customLocks.push({
43
50
  code: ["\n if(Date.now()>".concat(me.options.lock.endDate.getTime(), ") {\n {countermeasures}\n }\n "), "\n if((new Date()).getTime()>".concat(me.options.lock.endDate.getTime(), ") {\n {countermeasures}\n }\n ")],
44
51
  percentagePerBlock: 0.5
@@ -257,7 +264,7 @@ var _default = exports["default"] = function _default(_ref) {
257
264
  if (me.options.lock.countermeasures && functionName === me.options.lock.countermeasures) return;
258
265
  // Don't apply to invokeCountermeasures function (Intended)
259
266
  if (me.obfuscator.isInternalVariable(functionName)) return;
260
- if (!(0, _probability.computeProbabilityMap)(me.options.lock.integrity, functionName)) return;
267
+ if (!me.computeProbabilityMap(me.options.lock.integrity, functionName)) return;
261
268
  var newFnName = me.getPlaceholder();
262
269
  var newFunctionDeclaration = t.functionDeclaration(t.identifier(newFnName), funcDecPath.node.params, funcDecPath.node.body);
263
270
 
@@ -125,6 +125,16 @@ var _default = exports["default"] = function _default(_ref) {
125
125
  }
126
126
  }
127
127
  },
128
+ // "a" + "b" -> "ab"
129
+ BinaryExpression: {
130
+ exit: function exit(path) {
131
+ if (path.node.operator !== "+") return;
132
+ var left = path.get("left");
133
+ var right = path.get("right");
134
+ if (!left.isStringLiteral() || !right.isStringLiteral()) return;
135
+ path.replaceWith(t.stringLiteral(left.node.value + right.node.value));
136
+ }
137
+ },
128
138
  // a["key"] -> a.key
129
139
  MemberExpression: {
130
140
  exit: function exit(path) {
@@ -204,7 +214,7 @@ var _default = exports["default"] = function _default(_ref) {
204
214
  FunctionDeclaration: {
205
215
  exit: function exit(path) {
206
216
  var id = path.get("id");
207
- if (id.isIdentifier() && !id.node.name.startsWith(_constants.placeholderVariablePrefix)) {
217
+ if (id.isIdentifier() && !id.node.name.startsWith(_constants.placeholderVariablePrefix) && !path.node[_constants.NO_REMOVE]) {
208
218
  var binding = path.scope.getBinding(id.node.name);
209
219
  if (binding && binding.constantViolations.length === 0 && binding.referencePaths.length === 0 && !binding.referenced) {
210
220
  path.remove();
@@ -255,6 +265,9 @@ var _default = exports["default"] = function _default(_ref) {
255
265
  // Do not remove variables in unsafe functions
256
266
  var fn = (0, _astUtils.getParentFunctionOrProgram)(path);
257
267
  if (fn.node[_constants.UNSAFE]) return;
268
+
269
+ // Node explicitly marked as not to be removed
270
+ if (id[_constants.NO_REMOVE]) return;
258
271
  var binding = path.scope.getBinding(id.node.name);
259
272
  if (binding && binding.constantViolations.length === 0 && binding.referencePaths.length === 0) {
260
273
  if (!init.node || init.isPure()) {
@@ -7,9 +7,9 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports["default"] = void 0;
8
8
  var _order = require("../order");
9
9
  var t = _interopRequireWildcard(require("@babel/types"));
10
- var _astUtils = require("../utils/ast-utils");
11
10
  var _randomUtils = require("../utils/random-utils");
12
- var _probability = require("../probability");
11
+ var _PredicateGen = _interopRequireDefault(require("../utils/PredicateGen"));
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
13
13
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
14
14
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
15
15
  var _default = exports["default"] = function _default(_ref) {
@@ -19,10 +19,9 @@ var _default = exports["default"] = function _default(_ref) {
19
19
  opaquePredicates: 0
20
20
  }
21
21
  });
22
+ var predicateGen = new _PredicateGen["default"](me);
22
23
  function createTruePredicate(path) {
23
- var controlObject = me.getControlObject((0, _astUtils.getBlock)(path));
24
- var trueValue = controlObject.createTruePredicate();
25
- return trueValue;
24
+ return predicateGen.generateTrueExpression(path);
26
25
  }
27
26
  var active = true;
28
27
  var transformCount = 0;
@@ -31,7 +30,7 @@ var _default = exports["default"] = function _default(_ref) {
31
30
  if (path.find(function (p) {
32
31
  return me.isSkipped(p);
33
32
  })) return false;
34
- if (!(0, _probability.computeProbabilityMap)(me.options.opaquePredicates)) return false;
33
+ if (!me.computeProbabilityMap(me.options.opaquePredicates)) return false;
35
34
  transformCount++;
36
35
  var depth = path.getAncestry().length;
37
36
  return (0, _randomUtils.chance)(1000 - transformCount - depth * 100);
@@ -61,7 +61,12 @@ function pack(_ref) {
61
61
  if (_constants.reservedIdentifiers.has(identifierName)) return;
62
62
  if (me.obfuscator.options.globalVariables.has(identifierName)) return;
63
63
  if (identifierName === _constants.variableFunctionName) return;
64
+ if (identifierName === _objectName) return;
64
65
  if (!path.scope.hasGlobal(identifierName)) return;
66
+ if (path.scope.hasBinding(identifierName)) return;
67
+
68
+ // Check user's custom implementation
69
+ if (!me.computeProbabilityMap(me.options.pack, identifierName)) return;
65
70
  if (path.key === "argument" && path.parentPath.isUnaryExpression({
66
71
  operator: "typeof"
67
72
  })) {
@@ -9,10 +9,7 @@ var t = _interopRequireWildcard(require("@babel/types"));
9
9
  var _constants = require("../constants");
10
10
  var _setFunctionLengthTemplate = require("../templates/setFunctionLengthTemplate");
11
11
  var _astUtils = require("../utils/ast-utils");
12
- var _ControlObject = _interopRequireDefault(require("../utils/ControlObject"));
13
- var _assert = require("assert");
14
12
  var _node = require("../utils/node");
15
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
16
13
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
17
14
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
18
15
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
@@ -28,6 +25,7 @@ var PluginInstance = exports.PluginInstance = /*#__PURE__*/function () {
28
25
  _defineProperty(this, "changeData", {});
29
26
  this.pluginOptions = pluginOptions;
30
27
  this.obfuscator = obfuscator;
28
+ this.computeProbabilityMap = obfuscator.computeProbabilityMap.bind(this.obfuscator);
31
29
  }
32
30
  return _createClass(PluginInstance, [{
33
31
  key: "name",
@@ -78,21 +76,25 @@ var PluginInstance = exports.PluginInstance = /*#__PURE__*/function () {
78
76
  value: function setFunctionLength(path, originalLength) {
79
77
  path.node[_constants.FN_LENGTH] = originalLength;
80
78
 
81
- // Function length
82
- if (this.options.preserveFunctionLength && originalLength > 0) {
83
- if (!this.setFunctionLengthName) {
84
- this.setFunctionLengthName = this.getPlaceholder("fnLength");
85
- this.skip((0, _astUtils.prependProgram)(path, _setFunctionLengthTemplate.SetFunctionLengthTemplate.compile({
86
- fnName: this.setFunctionLengthName
87
- })));
88
- }
89
- if (t.isFunctionDeclaration(path.node)) {
90
- (0, _astUtils.prepend)(path.parentPath, t.expressionStatement(t.callExpression(t.identifier(this.setFunctionLengthName), [t.identifier(path.node.id.name), (0, _node.numericLiteral)(originalLength)])));
91
- } else if (t.isFunctionExpression(path.node) || t.isArrowFunctionExpression(path.node)) {
92
- path.replaceWith(t.callExpression(t.identifier(this.setFunctionLengthName), [path.node, (0, _node.numericLiteral)(originalLength)]));
93
- } else {
94
- // TODO
95
- }
79
+ // Skip if user disabled this feature
80
+ if (!this.options.preserveFunctionLength) return;
81
+
82
+ // Skip if function has no parameters
83
+ if (originalLength === 0) return;
84
+
85
+ // Create the function length setter if it doesn't exist
86
+ if (!this.setFunctionLengthName) {
87
+ this.setFunctionLengthName = this.getPlaceholder("fnLength");
88
+ this.skip((0, _astUtils.prependProgram)(path, _setFunctionLengthTemplate.SetFunctionLengthTemplate.compile({
89
+ fnName: this.setFunctionLengthName
90
+ })));
91
+ }
92
+ if (t.isFunctionDeclaration(path.node)) {
93
+ (0, _astUtils.prepend)(path.parentPath, t.expressionStatement(t.callExpression(t.identifier(this.setFunctionLengthName), [t.identifier(path.node.id.name), (0, _node.numericLiteral)(originalLength)])));
94
+ } else if (t.isFunctionExpression(path.node) || t.isArrowFunctionExpression(path.node)) {
95
+ path.replaceWith(t.callExpression(t.identifier(this.setFunctionLengthName), [path.node, (0, _node.numericLiteral)(originalLength)]));
96
+ } else {
97
+ // TODO
96
98
  }
97
99
  }
98
100
 
@@ -110,27 +112,6 @@ var PluginInstance = exports.PluginInstance = /*#__PURE__*/function () {
110
112
  return "__p_" + (0, _randomUtils.getRandomString)(4) + (suffix ? "_" + suffix : "");
111
113
  }
112
114
 
113
- /**
114
- * Retrieves (or creates) a `ControlObject` for the given `blockPath`.
115
- */
116
- }, {
117
- key: "getControlObject",
118
- value: function getControlObject(blockPath) {
119
- var createMultiple = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
120
- (0, _assert.ok)(blockPath.isBlock());
121
- var controlObjects = blockPath.node[_constants.CONTROL_OBJECTS];
122
- if (!controlObjects) {
123
- controlObjects = [];
124
- }
125
- if (controlObjects.length === 0 || createMultiple && (0, _randomUtils.chance)(controlObjects[0].propertyNames.size - 15 * controlObjects.length)) {
126
- var newControlObject = new _ControlObject["default"](this, blockPath);
127
- controlObjects.push(newControlObject);
128
- blockPath.node[_constants.CONTROL_OBJECTS] = controlObjects;
129
- return newControlObject;
130
- }
131
- return (0, _randomUtils.choice)(controlObjects);
132
- }
133
-
134
115
  /**
135
116
  * Logs a message to the console, only if `verbose` is enabled.
136
117
  * @param messages
@@ -9,7 +9,6 @@ var t = _interopRequireWildcard(require("@babel/types"));
9
9
  var _order = require("../order");
10
10
  var _NameGen = require("../utils/NameGen");
11
11
  var _assert = require("assert");
12
- var _probability = require("../probability");
13
12
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
14
13
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
15
14
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
@@ -91,7 +90,7 @@ function _default(_ref) {
91
90
  var isRequired = labelInterface.required;
92
91
  if (isRequired) {
93
92
  var newName = labelInterface.label;
94
- if ((0, _probability.computeProbabilityMap)(me.options.renameLabels, labelInterface.label)) {
93
+ if (me.computeProbabilityMap(me.options.renameLabels, labelInterface.label)) {
95
94
  newName = nameGen.generate();
96
95
  }
97
96
  labelInterface.renamed = newName;
@@ -8,7 +8,6 @@ exports["default"] = void 0;
8
8
  var _order = require("../order");
9
9
  var t = _interopRequireWildcard(require("@babel/types"));
10
10
  var _obfuscator = _interopRequireDefault(require("../obfuscator"));
11
- var _probability = require("../probability");
12
11
  var _astUtils = require("../utils/ast-utils");
13
12
  var _constants = require("../constants");
14
13
  var _functionUtils = require("../utils/function-utils");
@@ -18,6 +17,8 @@ var _tamperProtectionTemplates = require("../templates/tamperProtectionTemplates
18
17
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
19
18
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
20
19
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
20
+ var RGF_ELIGIBLE = Symbol("rgfEligible");
21
+
21
22
  /**
22
23
  * RGF (Runtime-Generated-Function) uses the `new Function("code")` syntax to create executable code from strings.
23
24
  *
@@ -58,19 +59,26 @@ var _default = exports["default"] = function _default(_ref) {
58
59
  }
59
60
  },
60
61
  "FunctionDeclaration|FunctionExpression": {
61
- exit: function exit(_path) {
62
+ enter: function enter(_path) {
62
63
  var _me$options$lock;
63
64
  if (!active) return;
65
+
66
+ // On enter, determine if Function is eligible for RGF transformation
67
+
64
68
  var path = _path;
65
69
  if (me.isSkipped(path)) return;
66
70
 
71
+ // Skip nested functions if the parent function is already deemed eligible
72
+ if (path.find(function (p) {
73
+ return p.node[RGF_ELIGIBLE] || p.node[_constants.MULTI_TRANSFORM];
74
+ })) return;
75
+
67
76
  // Skip async and generator functions
68
77
  if (path.node.async || path.node.generator) return;
69
78
  var name = (0, _astUtils.getFunctionName)(path);
70
79
  if (name === ((_me$options$lock = me.options.lock) === null || _me$options$lock === void 0 ? void 0 : _me$options$lock.countermeasures)) return;
71
80
  if (me.obfuscator.isInternalVariable(name)) return;
72
- me.log(name);
73
- if (!(0, _probability.computeProbabilityMap)(me.options.rgf, name, path.getFunctionParent() === null)) return;
81
+ if (!me.computeProbabilityMap(me.options.rgf, name, path.getFunctionParent() === null)) return;
74
82
 
75
83
  // Skip functions with references to outside variables
76
84
  // Check the scope to see if this function relies on any variables defined outside the function
@@ -86,13 +94,12 @@ var _default = exports["default"] = function _default(_ref) {
86
94
  if (me.options.globalVariables.has(name)) return;
87
95
  var binding = idPath.scope.getBinding(name);
88
96
  if (!binding) {
89
- identifierPreventingTransform = name;
90
- idPath.stop();
97
+ // Global variables are allowed
91
98
  return;
92
99
  }
93
-
100
+ var isOutsideVariable = path.scope.parent.getBinding(name) === binding;
94
101
  // If the binding is not in the current scope, it is an outside reference
95
- if (binding.scope !== path.scope) {
102
+ if (isOutsideVariable) {
96
103
  identifierPreventingTransform = name;
97
104
  idPath.stop();
98
105
  }
@@ -102,14 +109,24 @@ var _default = exports["default"] = function _default(_ref) {
102
109
  me.log("Skipping function " + name + " due to reference to outside variable: " + identifierPreventingTransform);
103
110
  return;
104
111
  }
112
+ me.log("Function " + name + " is eligible for RGF transformation");
113
+ path.node[RGF_ELIGIBLE] = true;
114
+ },
115
+ exit: function exit(_path) {
116
+ if (!active) return;
117
+ var path = _path;
118
+ if (me.isSkipped(path)) return;
119
+
120
+ // Function is not eligible for RGF transformation
121
+ if (!path.node[RGF_ELIGIBLE]) return;
105
122
  var embeddedName = me.getPlaceholder() + "_embedded";
106
123
  var replacementName = me.getPlaceholder() + "_replacement";
107
- var thisName = me.getPlaceholder() + "_this";
124
+ var argumentsName = me.getPlaceholder() + "_args";
108
125
  var lastNode = t.expressionStatement(t.identifier(embeddedName));
109
126
  lastNode[_constants.SKIP] = true;
110
127
 
111
128
  // Transform the function
112
- var evalProgram = t.program([t.functionDeclaration(t.identifier(embeddedName), [], t.blockStatement([t.variableDeclaration("var", [t.variableDeclarator(t.arrayPattern([t.identifier(thisName), t.identifier(rgfArrayName)]), t.thisExpression())]), t.functionDeclaration(t.identifier(replacementName), path.node.params, path.node.body), t.returnStatement(t.callExpression(t.memberExpression(t.identifier(replacementName), t.identifier("apply")), [t.identifier(thisName), t.identifier("arguments")]))])), lastNode]);
129
+ var evalProgram = t.program([t.functionDeclaration(t.identifier(embeddedName), [], t.blockStatement([t.variableDeclaration("var", [t.variableDeclarator(t.arrayPattern([t.identifier(rgfArrayName), t.identifier(argumentsName)]), t.identifier("arguments"))]), t.functionDeclaration(t.identifier(replacementName), path.node.params, path.node.body), t.returnStatement(t.callExpression(t.memberExpression(t.identifier(replacementName), t.identifier("apply")), [t.thisExpression(), t.identifier(argumentsName)]))])), lastNode]);
113
130
  var strictModeEnforcingBlock = path.find(function (p) {
114
131
  return (0, _astUtils.isStrictMode)(p);
115
132
  });
@@ -147,7 +164,8 @@ var _default = exports["default"] = function _default(_ref) {
147
164
  me.skip(path);
148
165
 
149
166
  // Update body to point to new function
150
- path.get("body").replaceWith(t.blockStatement([t.returnStatement(t.callExpression(t.memberExpression(t.memberExpression(t.identifier(rgfArrayName), (0, _node.numericLiteral)(index), true), t.stringLiteral("apply"), true), [t.arrayExpression([t.thisExpression(), t.identifier(rgfArrayName)]), t.identifier("arguments")]))]));
167
+ path.get("body").replaceWith(t.blockStatement([t.returnStatement(t.callExpression(t.memberExpression(t.memberExpression(t.identifier(rgfArrayName), (0, _node.numericLiteral)(index), true), t.stringLiteral("apply"), true), [t.thisExpression(), t.arrayExpression([t.identifier(rgfArrayName), t.identifier("arguments")])]))]));
168
+ path.skip();
151
169
  me.setFunctionLength(path, originalLength);
152
170
  me.changeData.functions++;
153
171
  }