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

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 (91) hide show
  1. package/.prettierrc +4 -0
  2. package/CHANGELOG.md +42 -8
  3. package/Migration.md +23 -8
  4. package/README.md +2 -2
  5. package/dist/constants.js +11 -2
  6. package/dist/index.js +49 -6
  7. package/dist/obfuscator.js +121 -10
  8. package/dist/order.js +0 -1
  9. package/dist/probability.js +1 -96
  10. package/dist/templates/getGlobalTemplate.js +4 -1
  11. package/dist/templates/integrityTemplate.js +1 -1
  12. package/dist/templates/stringCompressionTemplate.js +3 -3
  13. package/dist/templates/tamperProtectionTemplates.js +1 -1
  14. package/dist/templates/template.js +17 -12
  15. package/dist/transforms/controlFlowFlattening.js +112 -83
  16. package/dist/transforms/deadCode.js +21 -22
  17. package/dist/transforms/dispatcher.js +62 -37
  18. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +5 -0
  19. package/dist/transforms/extraction/objectExtraction.js +1 -2
  20. package/dist/transforms/finalizer.js +1 -1
  21. package/dist/transforms/flatten.js +2 -19
  22. package/dist/transforms/identifier/globalConcealing.js +3 -4
  23. package/dist/transforms/identifier/movedDeclarations.js +12 -5
  24. package/dist/transforms/identifier/renameVariables.js +40 -6
  25. package/dist/transforms/lock/integrity.js +9 -1
  26. package/dist/transforms/lock/lock.js +16 -9
  27. package/dist/transforms/minify.js +64 -27
  28. package/dist/transforms/opaquePredicates.js +6 -7
  29. package/dist/transforms/pack.js +32 -5
  30. package/dist/transforms/plugin.js +20 -39
  31. package/dist/transforms/preparation.js +25 -36
  32. package/dist/transforms/renameLabels.js +1 -2
  33. package/dist/transforms/rgf.js +36 -16
  34. package/dist/transforms/shuffle.js +10 -11
  35. package/dist/transforms/string/stringCompression.js +14 -10
  36. package/dist/transforms/string/stringConcealing.js +7 -5
  37. package/dist/transforms/string/stringEncoding.js +4 -2
  38. package/dist/transforms/string/stringSplitting.js +4 -2
  39. package/dist/transforms/variableMasking.js +3 -2
  40. package/dist/utils/NameGen.js +5 -2
  41. package/dist/utils/PredicateGen.js +62 -0
  42. package/dist/utils/ast-utils.js +24 -9
  43. package/dist/utils/random-utils.js +10 -0
  44. package/dist/validateOptions.js +2 -2
  45. package/index.d.ts +16 -2
  46. package/package.json +2 -2
  47. package/src/constants.ts +15 -5
  48. package/src/index.ts +15 -5
  49. package/src/obfuscationResult.ts +7 -1
  50. package/src/obfuscator.ts +152 -12
  51. package/src/options.ts +26 -8
  52. package/src/order.ts +0 -2
  53. package/src/templates/getGlobalTemplate.ts +5 -1
  54. package/src/templates/integrityTemplate.ts +14 -19
  55. package/src/templates/stringCompressionTemplate.ts +4 -28
  56. package/src/templates/tamperProtectionTemplates.ts +7 -3
  57. package/src/templates/template.ts +5 -3
  58. package/src/transforms/controlFlowFlattening.ts +139 -83
  59. package/src/transforms/deadCode.ts +27 -30
  60. package/src/transforms/dispatcher.ts +24 -5
  61. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +10 -1
  62. package/src/transforms/extraction/objectExtraction.ts +1 -2
  63. package/src/transforms/finalizer.ts +1 -1
  64. package/src/transforms/flatten.ts +3 -22
  65. package/src/transforms/identifier/globalConcealing.ts +26 -17
  66. package/src/transforms/identifier/movedDeclarations.ts +18 -6
  67. package/src/transforms/identifier/renameVariables.ts +48 -6
  68. package/src/transforms/lock/integrity.ts +11 -1
  69. package/src/transforms/lock/lock.ts +26 -10
  70. package/src/transforms/minify.ts +85 -38
  71. package/src/transforms/opaquePredicates.ts +6 -9
  72. package/src/transforms/pack.ts +41 -5
  73. package/src/transforms/plugin.ts +47 -69
  74. package/src/transforms/preparation.ts +33 -46
  75. package/src/transforms/renameLabels.ts +1 -2
  76. package/src/transforms/rgf.ts +52 -23
  77. package/src/transforms/shuffle.ts +28 -26
  78. package/src/transforms/string/encoding.ts +1 -1
  79. package/src/transforms/string/stringCompression.ts +22 -13
  80. package/src/transforms/string/stringConcealing.ts +13 -7
  81. package/src/transforms/string/stringEncoding.ts +6 -2
  82. package/src/transforms/string/stringSplitting.ts +9 -4
  83. package/src/transforms/variableMasking.ts +2 -2
  84. package/src/utils/NameGen.ts +13 -3
  85. package/src/utils/PredicateGen.ts +61 -0
  86. package/src/utils/ast-utils.ts +16 -9
  87. package/src/utils/random-utils.ts +14 -0
  88. package/src/validateOptions.ts +7 -4
  89. package/src/probability.ts +0 -110
  90. package/src/transforms/functionOutlining.ts +0 -225
  91. package/src/utils/ControlObject.ts +0 -141
package/.prettierrc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "tabWidth": 2,
3
+ "singleQuote": false
4
+ }
package/CHANGELOG.md CHANGED
@@ -3,10 +3,12 @@
3
3
 
4
4
  **⚠️ Warning: This an alpha release. This version is not stable and the likelihood of encountering bugs is significantly higher.**
5
5
 
6
- ### Complete rewrite of JS-Confuser using Babel!
6
+ ### Complete rewrite of JS-Confuser using Babel! 🎉
7
7
 
8
8
  **⚠️ Breaking changes**
9
9
 
10
+ > Check out the [Migration guide](./Migration.md) on how to properly update from 1.X to 2.0. The obfuscation upgrades in 2.0 are worth the small refactoring.
11
+
10
12
  - Revamped API Interface
11
13
 
12
14
  - - JSConfuser.obfuscate() resolves to an object
@@ -17,13 +19,29 @@
17
19
 
18
20
  - Renamed `Stack` to `Variable Masking`
19
21
 
22
+ - Added configurable limits to options:
23
+
24
+ ```js
25
+ const options = {
26
+ target: "node",
27
+
28
+ rgf: {
29
+ value: 0.5, // = 50% of eligible functions
30
+ limit: 10 // Maximum of 10 changes for performance reasons
31
+ },
32
+
33
+ // Original format is still valid (No limit applied)
34
+ rgf: 0.5
35
+ }
36
+ ```
37
+
20
38
  ### 2.0 Changes
21
39
 
22
- - Added Custom String Encoding and Custom Lock Code options
40
+ - Added [Custom String Encoding](https://new--confuser.netlify.app/docs/options/customStringEncodings) and [Custom Lock Code](https://new--confuser.netlify.app/docs/options/customLocks) options
23
41
 
24
- - Added `Rename Labels` Learn more here
42
+ - Added `Rename Labels` [Learn more here](https://new--confuser.netlify.app/docs/options/renamelabels#rename-labels)
25
43
 
26
- - Added `Pack` Learn more here
44
+ - Added `Pack` [Learn more here](https://new--confuser.netlify.app/docs/options/pack#pack)
27
45
 
28
46
  - RGF no longers uses `new Function` instead uses `eval`
29
47
 
@@ -49,11 +67,27 @@
49
67
 
50
68
  - - [Regular expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions) are now obfuscated (First converted into equivalent RegExp() constructor calls)
51
69
 
52
- - - `String Compression` now uses zlib decompression ([Pako](https://github.com/nodeca/pako))
70
+ - - `String Compression` now uses LZ-string compression ([lz-string](https://www.npmjs.com/package/lz-string))
71
+
72
+ - New Comment Syntax
73
+
74
+ - - `/* @js-confuser-var */ "name"` for improved variable mappings for eval() calls
75
+
76
+ ```js
77
+ // Input
78
+ var name = "Internet User";
79
+ eval( "console.log(" + /* @js-confuser-var */ "name" + ")" );
80
+
81
+ // Output
82
+ var zC3PLKu = "Internet User";
83
+ eval("console.log(" + "zC3PLKu" + ")");
84
+ ```
85
+
86
+ The function `__JS_CONFUSER_VAR__` is identical in outcome and still be used, however, the comment syntax is preferred as the comment syntax's preserves the original script's behavior.
53
87
 
54
88
  ### JS-Confuser.com Revamp
55
89
 
56
- A new UI for JS-Confuser.com, featuring an advanced playground and documentation pages.
90
+ A new UI for [JS-Confuser.com](https://js-confuser.com), featuring an advanced playground and documentation pages.
57
91
 
58
92
  The previous version will remain available: [old--confuser.netlify.com](https://old--confuser.netlify.app/)
59
93
 
@@ -61,11 +95,11 @@ The previous version will remain available: [old--confuser.netlify.com](https://
61
95
 
62
96
  - Removed `ES5` option - Use Babel Instead
63
97
 
64
- - Removed `Browser Lock` and `OS Lock` - Use Custom Locks instead
98
+ - Removed `Browser Lock` and `OS Lock` - Use [Custom Locks](https://new--confuser.netlify.app/docs/options/customlocks#custom-locks) instead
65
99
 
66
100
  - Removed `Shuffle`'s Hash option
67
101
 
68
- - Removed `Indent` option. [`@babel/generator`](https://www.npmjs.com/package/@babel/generator) does not allow customizing the indentation size. Use Prettier if you still wish for 4 space or tabs. Be mindful if you have `Integrity` or `Self Defending` enabled, as you should not alter the obfuscated code.
102
+ - Removed `Indent` option
69
103
 
70
104
 
71
105
  # `1.7.3`
package/Migration.md CHANGED
@@ -6,15 +6,20 @@ JS-Confuser 2.0 is complete rewrite of the original JS-Confuser created in 2020!
6
6
 
7
7
  ### JSConfuser.obfuscate() returns an object now
8
8
 
9
- The method `JSConfuser.obfuscate()` resolves to a object now instead of a string. This result object contains the obfuscated code on the `code` property.
9
+ The method `JSConfuser.obfuscate()` resolves to a object now instead of a string. This result object contains a property `code` which is the obfuscated code.
10
10
 
11
11
  ```diff
12
- +JSConfuser.obfuscate(sourceCode, options).then(result=>{
13
- + console.log(result.code);
14
- +});
15
- -JSConfuser.obfuscate(sourceCode, options).then(obfuscatedCode=>{
16
- - console.log(obfuscatedCode);
17
- -});
12
+ const sourceCode = `console.log("Hello World")`;
13
+ const options = {
14
+ target: "node",
15
+ preset: "high"
16
+ };
17
+
18
+ JSConfuser.obfuscate(sourceCode, options).then(result=>{
19
+ // 'result' is now an object
20
+ - console.log(result);
21
+ + console.log(result.code);
22
+ });
18
23
  ```
19
24
 
20
25
  ### Removed Anti Debug Lock / Browser Lock / OS Lock
@@ -54,4 +59,14 @@ These features have been removed but you can still add these locks using the `lo
54
59
 
55
60
  The option `stack` has been renamed to `variableMasking`
56
61
 
57
- [Similar to JScrambler's Variable Masking](https://docs.jscrambler.com/code-integrity/documentation/transformations/variable-masking)
62
+ [Similar to JScrambler's Variable Masking](https://docs.jscrambler.com/code-integrity/documentation/transformations/variable-masking)
63
+
64
+ ```diff
65
+ const options = {
66
+ target: "node",
67
+ preset: "high"
68
+
69
+ - stack: true,
70
+ + variableMasking: true
71
+ };
72
+ ```
package/README.md CHANGED
@@ -21,9 +21,9 @@ JS-Confuser is a JavaScript obfuscation tool to make your programs _impossible_
21
21
 
22
22
  - - [FAQ](https://new--confuser.netlify.app/docs/getting-started/faq)
23
23
 
24
- - [Options](https://new--confuser.netlify.app/docs)
24
+ - [Options](https://new--confuser.netlify.app/docs/options)
25
25
 
26
- - [Presets](https://new--confuser.netlify.app/docs)
26
+ - [Presets](https://new--confuser.netlify.app/docs/presets)
27
27
 
28
28
  ## API Usage
29
29
 
package/dist/constants.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.variableFunctionName = exports.reservedObjectPrototype = exports.reservedKeywords = exports.reservedIdentifiers = exports.predictableFunctionTag = exports.placeholderVariablePrefix = exports.noRenameVariablePrefix = exports.WITH_STATEMENT = exports.UNSAFE = exports.SKIP = exports.PREDICTABLE = exports.NO_RENAME = exports.MULTI_TRANSFORM = exports.GEN_NODE = exports.FN_LENGTH = exports.CONTROL_OBJECTS = void 0;
6
+ exports.variableFunctionName = exports.reservedObjectPrototype = exports.reservedNodeModuleIdentifiers = exports.reservedKeywords = exports.reservedIdentifiers = exports.predictableFunctionTag = exports.placeholderVariablePrefix = exports.noRenameVariablePrefix = exports.WITH_STATEMENT = exports.UNSAFE = exports.SKIP = exports.PREDICTABLE = exports.NO_RENAME = exports.NO_REMOVE = exports.MULTI_TRANSFORM = exports.GEN_NODE = exports.FN_LENGTH = void 0;
7
7
  var predictableFunctionTag = exports.predictableFunctionTag = "__JS_PREDICT__";
8
8
 
9
9
  /**
@@ -34,7 +34,6 @@ var SKIP = exports.SKIP = Symbol("skip");
34
34
  * Saves the original length of a function.
35
35
  */
36
36
  var FN_LENGTH = exports.FN_LENGTH = Symbol("fnLength");
37
- var CONTROL_OBJECTS = exports.CONTROL_OBJECTS = Symbol("controlObjects");
38
37
  var NO_RENAME = exports.NO_RENAME = Symbol("noRename");
39
38
 
40
39
  /**
@@ -60,6 +59,11 @@ var MULTI_TRANSFORM = exports.MULTI_TRANSFORM = Symbol("multiTransform");
60
59
  */
61
60
  var WITH_STATEMENT = exports.WITH_STATEMENT = Symbol("withStatement");
62
61
 
62
+ /**
63
+ * Tells minify to not remove the node.
64
+ */
65
+ var NO_REMOVE = exports.NO_REMOVE = Symbol("noRemove");
66
+
63
67
  /**
64
68
  * Symbols describe precomputed semantics of a node, allowing the obfuscator to make the best choices for the node.
65
69
  */
@@ -75,6 +79,11 @@ var placeholderVariablePrefix = exports.placeholderVariablePrefix = "__p_";
75
79
  * Identifiers that are not actually variables.
76
80
  */
77
81
  var reservedIdentifiers = exports.reservedIdentifiers = new Set(["undefined", "null", "NaN", "Infinity", "eval", "arguments"]);
82
+
83
+ /**
84
+ * Reserved Node.JS module identifiers.
85
+ */
86
+ var reservedNodeModuleIdentifiers = exports.reservedNodeModuleIdentifiers = new Set(["module", "exports", "require"]);
78
87
  var reservedObjectPrototype = exports.reservedObjectPrototype = new Set(["toString", "valueOf", "constructor", "__proto__", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString"]);
79
88
 
80
89
  /**
package/dist/index.js CHANGED
@@ -3,10 +3,28 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "Obfuscator", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _obfuscator["default"];
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "Template", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _template["default"];
16
+ }
17
+ });
6
18
  exports["default"] = void 0;
7
19
  exports.obfuscate = obfuscate;
8
20
  exports.obfuscateAST = obfuscateAST;
9
21
  exports.obfuscateWithProfiler = obfuscateWithProfiler;
22
+ Object.defineProperty(exports, "presets", {
23
+ enumerable: true,
24
+ get: function get() {
25
+ return _presets["default"];
26
+ }
27
+ });
10
28
  var _obfuscator = _interopRequireDefault(require("./obfuscator"));
11
29
  var _presets = _interopRequireDefault(require("./presets"));
12
30
  var _template = _interopRequireDefault(require("./templates/template"));
@@ -53,15 +71,37 @@ function _obfuscateAST() {
53
71
  }));
54
72
  return _obfuscateAST.apply(this, arguments);
55
73
  }
56
- function obfuscateWithProfiler(_x5, _x6, _x7) {
74
+ function obfuscateWithProfiler(_x5, _x6) {
57
75
  return _obfuscateWithProfiler.apply(this, arguments);
58
76
  }
59
77
  function _obfuscateWithProfiler() {
60
- _obfuscateWithProfiler = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(sourceCode, options, _profiler) {
61
- var startTime, obfuscator, totalTransforms, transformMap, beforeParseTime, ast, parseTime, currentTransformTime, beforeCompileTime, code, compileTime, endTime, obfuscationTime;
78
+ _obfuscateWithProfiler = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(sourceCode, options) {
79
+ var _profiler,
80
+ startTime,
81
+ obfuscator,
82
+ totalTransforms,
83
+ transformMap,
84
+ beforeParseTime,
85
+ ast,
86
+ parseTime,
87
+ currentTransformTime,
88
+ beforeCompileTime,
89
+ code,
90
+ compileTime,
91
+ endTime,
92
+ obfuscationTime,
93
+ _args3 = arguments;
62
94
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
63
95
  while (1) switch (_context3.prev = _context3.next) {
64
96
  case 0:
97
+ _profiler = _args3.length > 2 && _args3[2] !== undefined ? _args3[2] : {};
98
+ if (!_profiler.performance) {
99
+ _profiler.performance = {
100
+ now: function now() {
101
+ return Date.now();
102
+ }
103
+ };
104
+ }
65
105
  startTime = performance.now();
66
106
  obfuscator = new _obfuscator["default"](options);
67
107
  totalTransforms = obfuscator.plugins.length;
@@ -72,13 +112,15 @@ function _obfuscateWithProfiler() {
72
112
  currentTransformTime = performance.now();
73
113
  ast = obfuscator.obfuscateAST(ast, {
74
114
  profiler: function profiler(log) {
115
+ var _profiler$callback;
75
116
  var nowTime = performance.now();
76
- transformMap[log.currentTransform] = {
117
+ var entry = {
77
118
  transformTime: nowTime - currentTransformTime,
78
119
  changeData: {}
79
120
  };
121
+ transformMap[log.currentTransform] = entry;
80
122
  currentTransformTime = nowTime;
81
- _profiler.callback(log);
123
+ (_profiler$callback = _profiler.callback) === null || _profiler$callback === void 0 || _profiler$callback.call(_profiler, log, entry, ast);
82
124
  }
83
125
  });
84
126
  obfuscator.plugins.forEach(function (_ref) {
@@ -103,7 +145,7 @@ function _obfuscateWithProfiler() {
103
145
  totalPossibleTransforms: obfuscator.totalPossibleTransforms
104
146
  }
105
147
  });
106
- case 16:
148
+ case 18:
107
149
  case "end":
108
150
  return _context3.stop();
109
151
  }
@@ -115,6 +157,7 @@ var JsConfuser = {
115
157
  obfuscate: obfuscate,
116
158
  obfuscateAST: obfuscateAST,
117
159
  obfuscateWithProfiler: obfuscateWithProfiler,
160
+ Obfuscator: _obfuscator["default"],
118
161
  presets: _presets["default"],
119
162
  Template: _template["default"]
120
163
  };
@@ -9,17 +9,16 @@ var _generator = _interopRequireDefault(require("@babel/generator"));
9
9
  var _traverse = _interopRequireDefault(require("@babel/traverse"));
10
10
  var _parser = require("@babel/parser");
11
11
  var _validateOptions = require("./validateOptions");
12
- var _probability = require("./probability");
13
12
  var _NameGen = require("./utils/NameGen");
14
13
  var _order = require("./order");
15
14
  var _plugin = require("./transforms/plugin");
15
+ var _objectUtils = require("./utils/object-utils");
16
16
  var _preparation = _interopRequireDefault(require("./transforms/preparation"));
17
17
  var _renameVariables = _interopRequireDefault(require("./transforms/identifier/renameVariables"));
18
18
  var _variableMasking = _interopRequireDefault(require("./transforms/variableMasking"));
19
19
  var _dispatcher = _interopRequireDefault(require("./transforms/dispatcher"));
20
20
  var _duplicateLiteralsRemoval = _interopRequireDefault(require("./transforms/extraction/duplicateLiteralsRemoval"));
21
21
  var _objectExtraction = _interopRequireDefault(require("./transforms/extraction/objectExtraction"));
22
- var _functionOutlining = _interopRequireDefault(require("./transforms/functionOutlining"));
23
22
  var _globalConcealing = _interopRequireDefault(require("./transforms/identifier/globalConcealing"));
24
23
  var _stringCompression = _interopRequireDefault(require("./transforms/string/stringCompression"));
25
24
  var _deadCode = _interopRequireDefault(require("./transforms/deadCode"));
@@ -87,12 +86,13 @@ var Obfuscator = exports["default"] = /*#__PURE__*/function () {
87
86
  }
88
87
  });
89
88
  _defineProperty(this, "index", 0);
89
+ _defineProperty(this, "probabilityMapCounter", new WeakMap());
90
90
  this.parentObfuscator = parentObfuscator;
91
91
  (0, _validateOptions.validateOptions)(userOptions);
92
92
  this.options = (0, _validateOptions.applyDefaultsToOptions)(_objectSpread({}, userOptions));
93
93
  this.nameGen = new _NameGen.NameGen(this.options.identifierGenerator);
94
94
  var shouldAddLockTransform = this.options.lock && (Object.keys(this.options.lock).filter(function (key) {
95
- return key !== "customLocks" && (0, _probability.isProbabilityMapProbable)(_this.options.lock[key]);
95
+ return key !== "customLocks" && _this.isProbabilityMapProbable(_this.options.lock[key]);
96
96
  }).length > 0 || this.options.lock.customLocks.length > 0);
97
97
  var allPlugins = [];
98
98
  var push = function push(probabilityMap) {
@@ -100,7 +100,7 @@ var Obfuscator = exports["default"] = /*#__PURE__*/function () {
100
100
  pluginFns[_key - 1] = arguments[_key];
101
101
  }
102
102
  _this.totalPossibleTransforms += pluginFns.length;
103
- if (!(0, _probability.isProbabilityMapProbable)(probabilityMap)) return;
103
+ if (!_this.isProbabilityMapProbable(probabilityMap)) return;
104
104
  allPlugins.push.apply(allPlugins, pluginFns);
105
105
  };
106
106
  push(true, _preparation["default"]);
@@ -114,10 +114,12 @@ var Obfuscator = exports["default"] = /*#__PURE__*/function () {
114
114
  push(this.options.calculator, _calculator["default"]);
115
115
  push(this.options.globalConcealing, _globalConcealing["default"]);
116
116
  push(this.options.opaquePredicates, _opaquePredicates["default"]);
117
- push(this.options.functionOutlining, _functionOutlining["default"]);
118
117
  push(this.options.stringSplitting, _stringSplitting["default"]);
119
118
  push(this.options.stringConcealing, _stringConcealing["default"]);
120
- push(this.options.stringCompression, _stringCompression["default"]);
119
+ // String Compression is only applied to the main obfuscator
120
+ // Any RGF functions will not have string compression due to the size of the decompression function
121
+
122
+ push(!parentObfuscator && this.options.stringCompression, _stringCompression["default"]);
121
123
  push(this.options.variableMasking, _variableMasking["default"]);
122
124
  push(this.options.duplicateLiteralsRemoval, _duplicateLiteralsRemoval["default"]);
123
125
  push(this.options.shuffle, _shuffle["default"]);
@@ -163,7 +165,10 @@ var Obfuscator = exports["default"] = /*#__PURE__*/function () {
163
165
  }
164
166
  return _createClass(Obfuscator, [{
165
167
  key: "isInternalVariable",
166
- value: function isInternalVariable(name) {
168
+ value:
169
+ // Pack Interface for sharing globals across RGF functions
170
+
171
+ function isInternalVariable(name) {
167
172
  return Object.values(this.globalState.internals).includes(name);
168
173
  }
169
174
  }, {
@@ -231,9 +236,6 @@ var Obfuscator = exports["default"] = /*#__PURE__*/function () {
231
236
  var _this$plugins$i = this.plugins[i],
232
237
  plugin = _this$plugins$i.plugin,
233
238
  pluginInstance = _this$plugins$i.pluginInstance;
234
-
235
- // Skip pack if disabled
236
- if (pluginInstance.order === _order.Order.Pack && options !== null && options !== void 0 && options.disablePack) continue;
237
239
  if (this.options.verbose) {
238
240
  console.log("Applying ".concat(pluginInstance.name, " (").concat(i + 1, "/").concat(this.plugins.length, ")"));
239
241
  }
@@ -311,6 +313,115 @@ var Obfuscator = exports["default"] = /*#__PURE__*/function () {
311
313
  /**
312
314
  * Generates code from an AST using `@babel/generator`
313
315
  */
316
+ }, {
317
+ key: "computeProbabilityMap",
318
+ value:
319
+ /**
320
+ * Evaluates a ProbabilityMap.
321
+ * @param map The setting object.
322
+ * @param customFnArgs Args given to user-implemented function, such as a variable name.
323
+ */
324
+ function computeProbabilityMap(map) {
325
+ for (var _len2 = arguments.length, customImplementationArgs = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
326
+ customImplementationArgs[_key2 - 1] = arguments[_key2];
327
+ }
328
+ // Check if this probability map uses the {value: ..., limit: ...} format
329
+ if (_typeof(map) === "object" && map && "value" in map) {
330
+ // Check for the limit property
331
+ if ("limit" in map && typeof map.limit === "number" && map.limit >= 0) {
332
+ // Check if the limit has been reached
333
+ if (this.probabilityMapCounter.get(map) >= map.limit) {
334
+ return false;
335
+ }
336
+ }
337
+ var value = this.computeProbabilityMap.apply(this, [map.value].concat(customImplementationArgs));
338
+ if (value) {
339
+ // Increment the counter for this map
340
+ this.probabilityMapCounter.set(map, this.probabilityMapCounter.get(map) + 1 || 1);
341
+ }
342
+ return value;
343
+ }
344
+ if (!map) {
345
+ return false;
346
+ }
347
+ if (map === true || map === 1) {
348
+ return true;
349
+ }
350
+ if (typeof map === "number") {
351
+ return Math.random() < map;
352
+ }
353
+ if (typeof map === "function") {
354
+ return map.apply(void 0, customImplementationArgs);
355
+ }
356
+ if (typeof map === "string") {
357
+ return map;
358
+ }
359
+ var asObject = {};
360
+ if (Array.isArray(map)) {
361
+ map.forEach(function (x) {
362
+ asObject[x.toString()] = 1;
363
+ });
364
+ } else {
365
+ asObject = map;
366
+ }
367
+ var total = Object.values(asObject).reduce(function (a, b) {
368
+ return a + b;
369
+ });
370
+ var percentages = (0, _objectUtils.createObject)(Object.keys(asObject), Object.values(asObject).map(function (x) {
371
+ return x / total;
372
+ }));
373
+ var ticket = Math.random();
374
+ var count = 0;
375
+ var winner = null;
376
+ Object.keys(percentages).forEach(function (key) {
377
+ var x = Number(percentages[key]);
378
+ if (ticket >= count && ticket < count + x) {
379
+ winner = key;
380
+ }
381
+ count += x;
382
+ });
383
+ return winner;
384
+ }
385
+
386
+ /**
387
+ * Determines if a probability map can return a positive result (true, or some string mode).
388
+ * - Negative probability maps are used to remove transformations from running entirely.
389
+ * @param map
390
+ */
391
+ }, {
392
+ key: "isProbabilityMapProbable",
393
+ value: function isProbabilityMapProbable(map) {
394
+ (0, _assert.ok)(!Number.isNaN(map), "Numbers cannot be NaN");
395
+ if (!map || typeof map === "undefined") {
396
+ return false;
397
+ }
398
+ if (typeof map === "function") {
399
+ return true;
400
+ }
401
+ if (typeof map === "number") {
402
+ if (map > 1 || map < 0) {
403
+ throw new Error("Numbers must be between 0 and 1 for 0% - 100%");
404
+ }
405
+ }
406
+ if (Array.isArray(map)) {
407
+ (0, _assert.ok)(map.length != 0, "Empty arrays are not allowed for options. Use false instead.");
408
+ if (map.length == 1) {
409
+ return !!map[0];
410
+ }
411
+ }
412
+ if (_typeof(map) === "object") {
413
+ if (map instanceof Date) return true;
414
+ if (map instanceof RegExp) return true;
415
+ if ("value" in map && !map.value) return false;
416
+ if ("limit" in map && map.limit === 0) return false;
417
+ var keys = Object.keys(map);
418
+ (0, _assert.ok)(keys.length != 0, "Empty objects are not allowed for options. Use false instead.");
419
+ if (keys.length == 1) {
420
+ return !!map[keys[0]];
421
+ }
422
+ }
423
+ return true;
424
+ }
314
425
  }], [{
315
426
  key: "generateCode",
316
427
  value: function generateCode(ast) {
package/dist/order.js CHANGED
@@ -26,7 +26,6 @@ var Order = exports.Order = /*#__PURE__*/function (Order) {
26
26
  Order[Order["Shuffle"] = 23] = "Shuffle";
27
27
  Order[Order["ControlFlowFlattening"] = 24] = "ControlFlowFlattening";
28
28
  Order[Order["MovedDeclarations"] = 25] = "MovedDeclarations";
29
- Order[Order["FunctionOutlining"] = 26] = "FunctionOutlining";
30
29
  Order[Order["RenameLabels"] = 27] = "RenameLabels";
31
30
  Order[Order["Minify"] = 28] = "Minify";
32
31
  Order[Order["AstScrambler"] = 29] = "AstScrambler";
@@ -1,96 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.computeProbabilityMap = computeProbabilityMap;
7
- exports.isProbabilityMapProbable = isProbabilityMapProbable;
8
- var _assert = require("assert");
9
- var _objectUtils = require("./utils/object-utils");
10
- 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); }
11
- /**
12
- * Evaluates a ProbabilityMap.
13
- * @param map The setting object.
14
- * @param customFnArgs Args given to user-implemented function, such as a variable name.
15
- */
16
- function computeProbabilityMap(map) {
17
- if (!map) {
18
- return false;
19
- }
20
- if (map === true || map === 1) {
21
- return true;
22
- }
23
- if (typeof map === "number") {
24
- return Math.random() < map;
25
- }
26
- if (typeof map === "function") {
27
- for (var _len = arguments.length, customImplementationArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
28
- customImplementationArgs[_key - 1] = arguments[_key];
29
- }
30
- return map.apply(void 0, customImplementationArgs);
31
- }
32
- if (typeof map === "string") {
33
- return map;
34
- }
35
- var asObject = {};
36
- if (Array.isArray(map)) {
37
- map.forEach(function (x) {
38
- asObject[x.toString()] = 1;
39
- });
40
- } else {
41
- asObject = map;
42
- }
43
- var total = Object.values(asObject).reduce(function (a, b) {
44
- return a + b;
45
- });
46
- var percentages = (0, _objectUtils.createObject)(Object.keys(asObject), Object.values(asObject).map(function (x) {
47
- return x / total;
48
- }));
49
- var ticket = Math.random();
50
- var count = 0;
51
- var winner = null;
52
- Object.keys(percentages).forEach(function (key) {
53
- var x = Number(percentages[key]);
54
- if (ticket >= count && ticket < count + x) {
55
- winner = key;
56
- }
57
- count += x;
58
- });
59
- return winner;
60
- }
61
-
62
- /**
63
- * Determines if a probability map can return a positive result (true, or some string mode).
64
- * - Negative probability maps are used to remove transformations from running entirely.
65
- * @param map
66
- */
67
- function isProbabilityMapProbable(map) {
68
- (0, _assert.ok)(!Number.isNaN(map), "Numbers cannot be NaN");
69
- if (!map || typeof map === "undefined") {
70
- return false;
71
- }
72
- if (typeof map === "function") {
73
- return true;
74
- }
75
- if (typeof map === "number") {
76
- if (map > 1 || map < 0) {
77
- throw new Error("Numbers must be between 0 and 1 for 0% - 100%");
78
- }
79
- }
80
- if (Array.isArray(map)) {
81
- (0, _assert.ok)(map.length != 0, "Empty arrays are not allowed for options. Use false instead.");
82
- if (map.length == 1) {
83
- return !!map[0];
84
- }
85
- }
86
- if (_typeof(map) === "object") {
87
- if (map instanceof Date) return true;
88
- if (map instanceof RegExp) return true;
89
- var keys = Object.keys(map);
90
- (0, _assert.ok)(keys.length != 0, "Empty objects are not allowed for options. Use false instead.");
91
- if (keys.length == 1) {
92
- return !!keys[0];
93
- }
94
- }
95
- return true;
96
- }
1
+ "use strict";
@@ -6,10 +6,13 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createGetGlobalTemplate = void 0;
7
7
  var _template = _interopRequireDefault(require("./template"));
8
8
  var _constants = require("../constants");
9
+ var _astUtils = require("../utils/ast-utils");
9
10
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
10
11
  var createGetGlobalTemplate = exports.createGetGlobalTemplate = function createGetGlobalTemplate(pluginInstance, path) {
11
12
  var _pluginInstance$optio;
12
- if ((_pluginInstance$optio = pluginInstance.options.lock) !== null && _pluginInstance$optio !== void 0 && _pluginInstance$optio.tamperProtection) {
13
+ if ((_pluginInstance$optio = pluginInstance.options.lock) !== null && _pluginInstance$optio !== void 0 && _pluginInstance$optio.tamperProtection && !path.find(function (p) {
14
+ return (0, _astUtils.isStrictMode)(p);
15
+ })) {
13
16
  return new _template["default"]("\n function {getGlobalFnName}(){\n var localVar = false;\n eval(__JS_CONFUSER_VAR__(localVar) + \" = true\")\n if (!localVar) {\n {countermeasures}\n\n return {};\n }\n\n const root = eval(\"this\");\n return root;\n }\n ").addSymbols(_constants.UNSAFE).setDefaultVariables({
14
17
  countermeasures: pluginInstance.globalState.lock.createCountermeasuresCode()
15
18
  });
@@ -27,4 +27,4 @@ function HashFunction(str, seed) {
27
27
  }
28
28
 
29
29
  // In template form to be inserted into code
30
- var HashTemplate = exports.HashTemplate = new _template["default"]("\n// Must be Function Declaration for hoisting\n// Math.imul polyfill for ES5\nfunction {imul}(opA, opB) {\n var MathImul = Math[\"imul\"] || function(opA, opB){\n opB |= 0; // ensure that opB is an integer. opA will automatically be coerced.\n // floating points give us 53 bits of precision to work with plus 1 sign bit\n // automatically handled for our convienence:\n // 1. 0x003fffff /*opA & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001\n // 0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/\n var result = (opA & 0x003fffff) * opB;\n // 2. We can remove an integer coersion from the statement above because:\n // 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001\n // 0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/\n if (opA & 0xffc00000 /*!== 0*/) result += (opA & 0xffc00000) * opB |0;\n return result |0;\n };\n\n var result = MathImul(opA, opB);\n\n return result;\n}\n\n\nfunction {hashingUtilFnName}(str, seed) {\n var h1 = 0xdeadbeef ^ seed;\n var h2 = 0x41c6ce57 ^ seed;\n for (var i = 0, ch; i < str.length; i++) {\n ch = str.charCodeAt(i);\n h1 = {imul}(h1 ^ ch, 2654435761);\n h2 = {imul}(h2 ^ ch, 1597334677);\n }\n h1 = {imul}(h1 ^ (h1>>>16), 2246822507) ^ {imul}(h2 ^ (h2>>>13), 3266489909);\n h2 = {imul}(h2 ^ (h2>>>16), 2246822507) ^ {imul}(h1 ^ (h1>>>13), 3266489909);\n return 4294967296 * (2097151 & h2) + (h1>>>0);\n};\n\n// Simple function that returns .toString() value with spaces replaced out\nfunction {name}(fnObject, seed, regex={sensitivityRegex}){\n var fnStringed = fnObject[\"toString\"]()[\"replace\"](regex, \"\");\n return {hashingUtilFnName}(fnStringed, seed);\n}\n").addSymbols(_constants.SKIP, _constants.MULTI_TRANSFORM);
30
+ var HashTemplate = exports.HashTemplate = new _template["default"]("\n// Must be Function Declaration for hoisting\n// Math.imul polyfill for ES5\nfunction MathImulPolyfill(opA, opB){\n opB |= 0; // ensure that opB is an integer. opA will automatically be coerced.\n // floating points give us 53 bits of precision to work with plus 1 sign bit\n // automatically handled for our convienence:\n // 1. 0x003fffff /*opA & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001\n // 0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/\n var result = (opA & 0x003fffff) * opB;\n // 2. We can remove an integer coersion from the statement above because:\n // 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001\n // 0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/\n if (opA & 0xffc00000 /*!== 0*/) result += (opA & 0xffc00000) * opB |0;\n return result |0;\n};\n\nvar {imul} = Math[\"imul\"] || MathImulPolyfill;\n\nfunction {hashingUtilFnName}(str, seed) {\n var h1 = 0xdeadbeef ^ seed;\n var h2 = 0x41c6ce57 ^ seed;\n for (var i = 0, ch; i < str.length; i++) {\n ch = str.charCodeAt(i);\n h1 = {imul}(h1 ^ ch, 2654435761);\n h2 = {imul}(h2 ^ ch, 1597334677);\n }\n h1 = {imul}(h1 ^ (h1>>>16), 2246822507) ^ {imul}(h2 ^ (h2>>>13), 3266489909);\n h2 = {imul}(h2 ^ (h2>>>16), 2246822507) ^ {imul}(h1 ^ (h1>>>13), 3266489909);\n return 4294967296 * (2097151 & h2) + (h1>>>0);\n};\n\n// Simple function that returns .toString() value with spaces replaced out\nfunction {name}(fnObject, seed, regex={sensitivityRegex}){\n var fnStringed = fnObject[\"toString\"]()[\"replace\"](regex, \"\");\n return {hashingUtilFnName}(fnStringed, seed);\n}\n").addSymbols(_constants.SKIP, _constants.MULTI_TRANSFORM);