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.
- package/.prettierrc +4 -0
- package/CHANGELOG.md +42 -8
- package/Migration.md +23 -8
- package/README.md +2 -2
- package/dist/constants.js +11 -2
- package/dist/index.js +49 -6
- package/dist/obfuscator.js +121 -10
- package/dist/order.js +0 -1
- package/dist/probability.js +1 -96
- package/dist/templates/getGlobalTemplate.js +4 -1
- package/dist/templates/integrityTemplate.js +1 -1
- package/dist/templates/stringCompressionTemplate.js +3 -3
- package/dist/templates/tamperProtectionTemplates.js +1 -1
- package/dist/templates/template.js +17 -12
- package/dist/transforms/controlFlowFlattening.js +112 -83
- package/dist/transforms/deadCode.js +21 -22
- package/dist/transforms/dispatcher.js +62 -37
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +5 -0
- package/dist/transforms/extraction/objectExtraction.js +1 -2
- package/dist/transforms/finalizer.js +1 -1
- package/dist/transforms/flatten.js +2 -19
- package/dist/transforms/identifier/globalConcealing.js +3 -4
- package/dist/transforms/identifier/movedDeclarations.js +12 -5
- package/dist/transforms/identifier/renameVariables.js +40 -6
- package/dist/transforms/lock/integrity.js +9 -1
- package/dist/transforms/lock/lock.js +16 -9
- package/dist/transforms/minify.js +64 -27
- package/dist/transforms/opaquePredicates.js +6 -7
- package/dist/transforms/pack.js +32 -5
- package/dist/transforms/plugin.js +20 -39
- package/dist/transforms/preparation.js +25 -36
- package/dist/transforms/renameLabels.js +1 -2
- package/dist/transforms/rgf.js +36 -16
- package/dist/transforms/shuffle.js +10 -11
- package/dist/transforms/string/stringCompression.js +14 -10
- package/dist/transforms/string/stringConcealing.js +7 -5
- package/dist/transforms/string/stringEncoding.js +4 -2
- package/dist/transforms/string/stringSplitting.js +4 -2
- package/dist/transforms/variableMasking.js +3 -2
- package/dist/utils/NameGen.js +5 -2
- package/dist/utils/PredicateGen.js +62 -0
- package/dist/utils/ast-utils.js +24 -9
- package/dist/utils/random-utils.js +10 -0
- package/dist/validateOptions.js +2 -2
- package/index.d.ts +16 -2
- package/package.json +2 -2
- package/src/constants.ts +15 -5
- package/src/index.ts +15 -5
- package/src/obfuscationResult.ts +7 -1
- package/src/obfuscator.ts +152 -12
- package/src/options.ts +26 -8
- package/src/order.ts +0 -2
- package/src/templates/getGlobalTemplate.ts +5 -1
- package/src/templates/integrityTemplate.ts +14 -19
- package/src/templates/stringCompressionTemplate.ts +4 -28
- package/src/templates/tamperProtectionTemplates.ts +7 -3
- package/src/templates/template.ts +5 -3
- package/src/transforms/controlFlowFlattening.ts +139 -83
- package/src/transforms/deadCode.ts +27 -30
- package/src/transforms/dispatcher.ts +24 -5
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +10 -1
- package/src/transforms/extraction/objectExtraction.ts +1 -2
- package/src/transforms/finalizer.ts +1 -1
- package/src/transforms/flatten.ts +3 -22
- package/src/transforms/identifier/globalConcealing.ts +26 -17
- package/src/transforms/identifier/movedDeclarations.ts +18 -6
- package/src/transforms/identifier/renameVariables.ts +48 -6
- package/src/transforms/lock/integrity.ts +11 -1
- package/src/transforms/lock/lock.ts +26 -10
- package/src/transforms/minify.ts +85 -38
- package/src/transforms/opaquePredicates.ts +6 -9
- package/src/transforms/pack.ts +41 -5
- package/src/transforms/plugin.ts +47 -69
- package/src/transforms/preparation.ts +33 -46
- package/src/transforms/renameLabels.ts +1 -2
- package/src/transforms/rgf.ts +52 -23
- package/src/transforms/shuffle.ts +28 -26
- package/src/transforms/string/encoding.ts +1 -1
- package/src/transforms/string/stringCompression.ts +22 -13
- package/src/transforms/string/stringConcealing.ts +13 -7
- package/src/transforms/string/stringEncoding.ts +6 -2
- package/src/transforms/string/stringSplitting.ts +9 -4
- package/src/transforms/variableMasking.ts +2 -2
- package/src/utils/NameGen.ts +13 -3
- package/src/utils/PredicateGen.ts +61 -0
- package/src/utils/ast-utils.ts +16 -9
- package/src/utils/random-utils.ts +14 -0
- package/src/validateOptions.ts +7 -4
- package/src/probability.ts +0 -110
- package/src/transforms/functionOutlining.ts +0 -225
- package/src/utils/ControlObject.ts +0 -141
package/.prettierrc
ADDED
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
|
|
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
|
|
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
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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.
|
|
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
|
|
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
|
|
61
|
-
var
|
|
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
|
-
|
|
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
|
|
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
|
};
|
package/dist/obfuscator.js
CHANGED
|
@@ -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" &&
|
|
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 (!
|
|
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
|
-
|
|
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:
|
|
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";
|
package/dist/probability.js
CHANGED
|
@@ -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
|
|
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);
|