js-confuser 1.7.2 → 1.7.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.
- package/.github/workflows/node.js.yml +1 -1
- package/CHANGELOG.md +35 -0
- package/README.md +20 -4
- package/dist/constants.js +7 -2
- package/dist/index.js +8 -0
- package/dist/options.js +12 -2
- package/dist/templates/bufferToString.js +26 -5
- package/dist/templates/core.js +35 -0
- package/dist/templates/crash.js +8 -39
- package/dist/templates/es5.js +1 -1
- package/dist/templates/functionLength.js +1 -1
- package/dist/templates/globals.js +1 -1
- package/dist/templates/template.js +173 -68
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/calculator.js +2 -2
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +8 -2
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +1 -1
- package/dist/transforms/deadCode.js +34 -24
- package/dist/transforms/dispatcher.js +8 -4
- package/dist/transforms/es5/antiClass.js +11 -11
- package/dist/transforms/es5/antiDestructuring.js +1 -1
- package/dist/transforms/es5/antiES6Object.js +2 -2
- package/dist/transforms/es5/antiTemplate.js +1 -1
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +2 -2
- package/dist/transforms/identifier/globalAnalysis.js +13 -0
- package/dist/transforms/identifier/globalConcealing.js +41 -6
- package/dist/transforms/identifier/renameVariables.js +7 -0
- package/dist/transforms/lock/antiDebug.js +2 -2
- package/dist/transforms/lock/integrity.js +9 -9
- package/dist/transforms/lock/lock.js +106 -20
- package/dist/transforms/minify.js +1 -1
- package/dist/transforms/opaquePredicates.js +2 -2
- package/dist/transforms/preparation.js +12 -0
- package/dist/transforms/rgf.js +32 -3
- package/dist/transforms/shuffle.js +3 -3
- package/dist/transforms/stack.js +8 -2
- package/dist/transforms/string/encoding.js +6 -3
- package/dist/transforms/string/stringCompression.js +34 -3
- package/dist/transforms/string/stringConcealing.js +7 -6
- package/dist/transforms/transform.js +26 -4
- package/dist/util/guard.js +5 -0
- package/dist/util/random.js +26 -0
- package/docs/Countermeasures.md +13 -6
- package/docs/Integrity.md +35 -28
- package/docs/RGF.md +6 -1
- package/docs/RenameVariables.md +116 -0
- package/docs/TamperProtection.md +100 -0
- package/docs/Template.md +117 -0
- package/package.json +1 -1
- package/src/constants.ts +5 -0
- package/src/index.ts +7 -5
- package/src/options.ts +47 -7
- package/src/templates/bufferToString.ts +34 -4
- package/src/templates/core.ts +29 -0
- package/src/templates/crash.ts +6 -38
- package/src/templates/es5.ts +1 -1
- package/src/templates/functionLength.ts +1 -1
- package/src/templates/globals.ts +1 -1
- package/src/templates/template.ts +185 -86
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/calculator.ts +4 -2
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +10 -3
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +1 -1
- package/src/transforms/deadCode.ts +74 -26
- package/src/transforms/dispatcher.ts +9 -5
- package/src/transforms/es5/antiClass.ts +15 -11
- package/src/transforms/es5/antiDestructuring.ts +1 -1
- package/src/transforms/es5/antiES6Object.ts +2 -2
- package/src/transforms/es5/antiTemplate.ts +1 -1
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +2 -6
- package/src/transforms/identifier/globalAnalysis.ts +18 -1
- package/src/transforms/identifier/globalConcealing.ts +94 -11
- package/src/transforms/identifier/renameVariables.ts +16 -1
- package/src/transforms/lock/antiDebug.ts +2 -2
- package/src/transforms/lock/integrity.ts +13 -11
- package/src/transforms/lock/lock.ts +122 -30
- package/src/transforms/minify.ts +1 -1
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +16 -0
- package/src/transforms/rgf.ts +46 -8
- package/src/transforms/shuffle.ts +3 -3
- package/src/transforms/stack.ts +9 -3
- package/src/transforms/string/encoding.ts +10 -7
- package/src/transforms/string/stringCompression.ts +81 -9
- package/src/transforms/string/stringConcealing.ts +10 -6
- package/src/transforms/transform.ts +35 -47
- package/src/types.ts +2 -0
- package/src/util/guard.ts +10 -0
- package/src/util/random.ts +81 -1
- package/test/code/Cash.test.ts +84 -1
- package/test/compare.test.ts +5 -5
- package/test/options.test.ts +18 -0
- package/test/templates/template.test.ts +211 -1
- package/test/transforms/identifier/globalConcealing.test.ts +70 -0
- package/test/transforms/identifier/renameVariables.test.ts +75 -1
- package/test/transforms/lock/tamperProtection.test.ts +336 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
# `1.7.3`
|
|
2
|
+
Tamper Protection
|
|
3
|
+
|
|
4
|
+
### `Tamper Protection`
|
|
5
|
+
|
|
6
|
+
Tamper Protection safeguards the runtime behavior from being altered by JavaScript pitfalls.
|
|
7
|
+
|
|
8
|
+
[Learn more here.](/docs/TamperProtection.md)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
- Rename Variables improvements:
|
|
13
|
+
|
|
14
|
+
- A new exposed function, `__JS_CONFUSER_VAR__`, can be used to access renamed variables. [Learn more here](/docs/RenameVariables.md).
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
// Input
|
|
19
|
+
var name = "John Doe";
|
|
20
|
+
eval("console.log(" + __JS_CONFUSER_VAR__(name) + ")");
|
|
21
|
+
|
|
22
|
+
// Output
|
|
23
|
+
var CA1HU0 = 'John Doe';
|
|
24
|
+
eval('console.log(' + 'CA1HU0' + ')');
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- Improved the `Zero Width` identifier generator (Thanks @doctor8296!)
|
|
28
|
+
|
|
29
|
+
- Pad the `String Concealing` array with more fake strings
|
|
30
|
+
|
|
31
|
+
- Improve `String Compression`
|
|
32
|
+
|
|
33
|
+
- New Web UI sneak peak: https://new--confuser.netlify.app/
|
|
34
|
+
|
|
35
|
+
|
|
1
36
|
# `1.7.2`
|
|
2
37
|
Updates
|
|
3
38
|
|
package/README.md
CHANGED
|
@@ -183,6 +183,8 @@ var qFaI6S = function () {
|
|
|
183
183
|
qFaI6S();
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
+
[Learn mode here.](https://github.com/MichaelXF/js-confuser/blob/master/docs/RenameVariables.md)
|
|
187
|
+
|
|
186
188
|
### `renameGlobals`
|
|
187
189
|
|
|
188
190
|
Renames top-level variables, turn this off for web-related scripts. Enabled by default. (`true/false`)
|
|
@@ -390,6 +392,8 @@ Use a number to control the percentage of strings.
|
|
|
390
392
|
|
|
391
393
|
String Encoding transforms a string into an encoded representation. (`true/false/0-1`)
|
|
392
394
|
|
|
395
|
+
**⚠️ Warning: Significantly increases file size! It is not recommended for most use cases.**
|
|
396
|
+
|
|
393
397
|
Use a number to control the percentage of strings.
|
|
394
398
|
|
|
395
399
|
`"console"` -> `'\x63\x6f\x6e\x73\x6f\x6c\x65'`
|
|
@@ -577,9 +581,16 @@ Creates a calculator function to handle arithmetic and logical expressions. (`tr
|
|
|
577
581
|
|
|
578
582
|
Adds `debugger` statements throughout the code. Additionally adds a background function for DevTools detection. (`true/false/0-1`)
|
|
579
583
|
|
|
580
|
-
### `lock.
|
|
584
|
+
### `lock.tamperProtection`
|
|
581
585
|
|
|
582
|
-
|
|
586
|
+
Tamper Protection safeguards the runtime behavior from being altered by JavaScript pitfalls. (`true/false`)
|
|
587
|
+
|
|
588
|
+
**⚠️ Tamper Protection requires eval and ran in a non-strict mode environment!**
|
|
589
|
+
|
|
590
|
+
- **This can break your code.**
|
|
591
|
+
- **Due to the security concerns of arbitrary code execution, you must enable this yourself.**
|
|
592
|
+
|
|
593
|
+
[Learn more here](https://github.com/MichaelXF/js-confuser/blob/master/TamperProtection.md).
|
|
583
594
|
|
|
584
595
|
### `lock.startDate`
|
|
585
596
|
|
|
@@ -629,10 +640,14 @@ Integrity ensures the source code is unchanged. (`true/false/0-1`)
|
|
|
629
640
|
|
|
630
641
|
A custom callback function to invoke when a lock is triggered. (`string/false`)
|
|
631
642
|
|
|
632
|
-
[Learn more
|
|
643
|
+
[Learn more here.](https://github.com/MichaelXF/js-confuser/blob/master/docs/Countermeasures.md)
|
|
633
644
|
|
|
634
645
|
Otherwise, the obfuscator falls back to crashing the process.
|
|
635
646
|
|
|
647
|
+
### `lock.context`
|
|
648
|
+
|
|
649
|
+
Properties that must be present on the `window` object (or `global` for NodeJS). (`string[]`)
|
|
650
|
+
|
|
636
651
|
### `movedDeclarations`
|
|
637
652
|
|
|
638
653
|
Moves variable declarations to the top of the context. (`true/false`)
|
|
@@ -785,6 +800,7 @@ You must enable locks yourself, and configure them to your needs.
|
|
|
785
800
|
lock: {
|
|
786
801
|
integrity: true,
|
|
787
802
|
selfDefending: true,
|
|
803
|
+
tamperProtection: true,
|
|
788
804
|
domainLock: ["mywebsite.com"],
|
|
789
805
|
osLock: ["windows", "linux"],
|
|
790
806
|
browserLock: ["firefox"],
|
|
@@ -813,7 +829,7 @@ These features are experimental or a security concern.
|
|
|
813
829
|
// set to false for web-related scripts
|
|
814
830
|
renameGlobals: false,
|
|
815
831
|
|
|
816
|
-
//
|
|
832
|
+
// custom implementation
|
|
817
833
|
identifierGenerator: function(){
|
|
818
834
|
return "myvar_" + (counter++);
|
|
819
835
|
},
|
package/dist/constants.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.reservedKeywords = exports.reservedIdentifiers = exports.predictableFunctionTag = exports.placeholderVariablePrefix = exports.noRenameVariablePrefix = exports.criticalFunctionTag = void 0;
|
|
6
|
+
exports.variableFunctionName = exports.reservedKeywords = exports.reservedIdentifiers = exports.predictableFunctionTag = exports.placeholderVariablePrefix = exports.noRenameVariablePrefix = exports.criticalFunctionTag = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* Keywords disallowed for variable names in ES5 and under.
|
|
9
9
|
*/
|
|
@@ -26,4 +26,9 @@ const predictableFunctionTag = exports.predictableFunctionTag = "__JS_PREDICT__"
|
|
|
26
26
|
* Tells the obfuscator this function is critical for the Obfuscated code.
|
|
27
27
|
* - Example: string decryption function
|
|
28
28
|
*/
|
|
29
|
-
const criticalFunctionTag = exports.criticalFunctionTag = "__JS_CRITICAL__";
|
|
29
|
+
const criticalFunctionTag = exports.criticalFunctionTag = "__JS_CRITICAL__";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Allows the user to grab the variable name of a renamed variable.
|
|
33
|
+
*/
|
|
34
|
+
const variableFunctionName = exports.variableFunctionName = "__JS_CONFUSER_VAR__";
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "Obfuscator", {
|
|
|
9
9
|
return _obfuscator.default;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(exports, "Template", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _template.default;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
12
18
|
Object.defineProperty(exports, "Transform", {
|
|
13
19
|
enumerable: true,
|
|
14
20
|
get: function () {
|
|
@@ -28,6 +34,7 @@ var _compiler = _interopRequireWildcard(require("./compiler"));
|
|
|
28
34
|
var _parser = _interopRequireWildcard(require("./parser"));
|
|
29
35
|
var _obfuscator = _interopRequireDefault(require("./obfuscator"));
|
|
30
36
|
var _transform = _interopRequireDefault(require("./transforms/transform"));
|
|
37
|
+
var _template = _interopRequireDefault(require("./templates/template"));
|
|
31
38
|
var _object = require("./util/object");
|
|
32
39
|
var _presets = _interopRequireDefault(require("./presets"));
|
|
33
40
|
var assert = _interopRequireWildcard(require("assert"));
|
|
@@ -156,6 +163,7 @@ JsConfuser.debugTransformations = debugTransformations;
|
|
|
156
163
|
JsConfuser.debugObfuscation = debugObfuscation;
|
|
157
164
|
JsConfuser.Obfuscator = _obfuscator.default;
|
|
158
165
|
JsConfuser.Transform = _transform.default;
|
|
166
|
+
JsConfuser.Template = _template.default;
|
|
159
167
|
if (typeof window !== "undefined") {
|
|
160
168
|
window["JsConfuser"] = JsConfuser;
|
|
161
169
|
}
|
package/dist/options.js
CHANGED
|
@@ -9,6 +9,7 @@ var _assert = require("assert");
|
|
|
9
9
|
var _presets = _interopRequireDefault(require("./presets"));
|
|
10
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
11
|
const validProperties = new Set(["preset", "target", "indent", "compact", "hexadecimalNumbers", "minify", "es5", "renameVariables", "renameGlobals", "identifierGenerator", "controlFlowFlattening", "globalConcealing", "stringCompression", "stringConcealing", "stringEncoding", "stringSplitting", "duplicateLiteralsRemoval", "dispatcher", "rgf", "objectExtraction", "flatten", "deadCode", "calculator", "lock", "movedDeclarations", "opaquePredicates", "shuffle", "stack", "verbose", "globalVariables", "debugComments", "preserveFunctionLength"]);
|
|
12
|
+
const validLockProperties = new Set(["selfDefending", "antiDebug", "context", "tamperProtection", "startDate", "endDate", "domainLock", "osLock", "browserLock", "integrity", "countermeasures"]);
|
|
12
13
|
const validOses = new Set(["windows", "linux", "osx", "ios", "android"]);
|
|
13
14
|
const validBrowsers = new Set(["firefox", "chrome", "iexplorer", "edge", "safari", "opera"]);
|
|
14
15
|
function validateOptions(options) {
|
|
@@ -31,6 +32,13 @@ function validateOptions(options) {
|
|
|
31
32
|
throw new TypeError('browserLock can only be used when target="browser"');
|
|
32
33
|
}
|
|
33
34
|
if (options.lock) {
|
|
35
|
+
(0, _assert.ok)(typeof options.lock === "object", "options.lock must be an object");
|
|
36
|
+
Object.keys(options.lock).forEach(key => {
|
|
37
|
+
if (!validLockProperties.has(key)) {
|
|
38
|
+
throw new TypeError("Invalid lock option: '" + key + "'");
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
34
42
|
// Validate browser-lock option
|
|
35
43
|
if (options.lock.browserLock && typeof options.lock.browserLock !== "undefined") {
|
|
36
44
|
(0, _assert.ok)(Array.isArray(options.lock.browserLock), "browserLock must be an array");
|
|
@@ -93,8 +101,10 @@ async function correctOptions(options) {
|
|
|
93
101
|
if (options.globalVariables && !(options.globalVariables instanceof Set)) {
|
|
94
102
|
options.globalVariables = new Set(Object.keys(options.globalVariables));
|
|
95
103
|
}
|
|
96
|
-
if (options.lock
|
|
97
|
-
options.
|
|
104
|
+
if (options.lock) {
|
|
105
|
+
if (options.lock.selfDefending) {
|
|
106
|
+
options.compact = true; // self defending forcibly enables this
|
|
107
|
+
}
|
|
98
108
|
}
|
|
99
109
|
|
|
100
110
|
// options.globalVariables outlines generic globals that should be present in the execution context
|
|
@@ -3,11 +3,33 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.createGetGlobalTemplate = exports.BufferToStringTemplate = void 0;
|
|
7
7
|
var _constants = require("../constants");
|
|
8
8
|
var _template = _interopRequireDefault(require("./template"));
|
|
9
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
-
const
|
|
10
|
+
const createGetGlobalTemplate = (transform, object, parents) => {
|
|
11
|
+
var _options$lock;
|
|
12
|
+
var options = transform.options;
|
|
13
|
+
if ((_options$lock = options.lock) !== null && _options$lock !== void 0 && _options$lock.tamperProtection) {
|
|
14
|
+
return new _template.default(`
|
|
15
|
+
function {getGlobalFnName}(){
|
|
16
|
+
var localVar = false;
|
|
17
|
+
eval(${transform.jsConfuserVar("localVar")} + " = true")
|
|
18
|
+
if (!localVar) {
|
|
19
|
+
{countermeasures}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const root = eval("this");
|
|
23
|
+
return root;
|
|
24
|
+
}
|
|
25
|
+
`).setDefaultVariables({
|
|
26
|
+
countermeasures: transform.lockTransform.getCounterMeasuresCode(object, parents)
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return GetGlobalTemplate;
|
|
30
|
+
};
|
|
31
|
+
exports.createGetGlobalTemplate = createGetGlobalTemplate;
|
|
32
|
+
const GetGlobalTemplate = new _template.default(`
|
|
11
33
|
function ${_constants.placeholderVariablePrefix}CFG__getGlobalThis${_constants.predictableFunctionTag}(){
|
|
12
34
|
return globalThis
|
|
13
35
|
}
|
|
@@ -51,9 +73,8 @@ const GetGlobalTemplate = exports.GetGlobalTemplate = (0, _template.default)(`
|
|
|
51
73
|
return bestMatch || this;
|
|
52
74
|
}
|
|
53
75
|
`);
|
|
54
|
-
const BufferToStringTemplate = exports.BufferToStringTemplate =
|
|
55
|
-
|
|
56
|
-
${GetGlobalTemplate.source}
|
|
76
|
+
const BufferToStringTemplate = exports.BufferToStringTemplate = new _template.default(`
|
|
77
|
+
{GetGlobalTemplate}
|
|
57
78
|
|
|
58
79
|
var __globalObject = {getGlobalFnName}() || {};
|
|
59
80
|
var __TextDecoder = __globalObject["TextDecoder"];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.IndexOfTemplate = void 0;
|
|
7
|
+
var _template = _interopRequireDefault(require("./template"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const IndexOfTemplate = exports.IndexOfTemplate = new _template.default(`
|
|
10
|
+
function indexOf(str, substr) {
|
|
11
|
+
const len = str.length;
|
|
12
|
+
const sublen = substr.length;
|
|
13
|
+
let count = 0;
|
|
14
|
+
|
|
15
|
+
if (sublen > len) {
|
|
16
|
+
return -1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i <= len - sublen; i++) {
|
|
20
|
+
for (let j = 0; j < sublen; j++) {
|
|
21
|
+
if (str[i + j] === substr[j]) {
|
|
22
|
+
count++;
|
|
23
|
+
if (count === sublen) {
|
|
24
|
+
return i;
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
count = 0;
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return -1;
|
|
34
|
+
}
|
|
35
|
+
`);
|
package/dist/templates/crash.js
CHANGED
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.CrashTemplate2 = exports.CrashTemplate1 = void 0;
|
|
7
7
|
var _template = _interopRequireDefault(require("./template"));
|
|
8
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
-
const CrashTemplate1 = exports.CrashTemplate1 =
|
|
10
|
-
var {var} = "
|
|
11
|
-
while(
|
|
12
|
-
{var} = {var}
|
|
9
|
+
const CrashTemplate1 = exports.CrashTemplate1 = new _template.default(`
|
|
10
|
+
var {var} = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_\`{|}~"';
|
|
11
|
+
while(true){
|
|
12
|
+
{var} = {var};
|
|
13
|
+
if(!{var}) break;
|
|
13
14
|
}
|
|
14
15
|
`);
|
|
15
|
-
const CrashTemplate2 = exports.CrashTemplate2 =
|
|
16
|
+
const CrashTemplate2 = exports.CrashTemplate2 = new _template.default(`
|
|
16
17
|
while(true) {
|
|
17
18
|
var {var} = 99;
|
|
18
19
|
for({var} = 99; {var} == {var}; {var} *= {var}) {
|
|
@@ -24,36 +25,4 @@ while(true) {
|
|
|
24
25
|
if({var} === 100) {
|
|
25
26
|
{var}--
|
|
26
27
|
}
|
|
27
|
-
};`);
|
|
28
|
-
const CrashTemplate3 = exports.CrashTemplate3 = (0, _template.default)(`
|
|
29
|
-
try {
|
|
30
|
-
function {$2}(y, x){
|
|
31
|
-
return x;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
var {$1} = {$2}(this, function () {
|
|
35
|
-
var {$3} = function () {
|
|
36
|
-
var regExp = {$3}
|
|
37
|
-
.constructor('return /" + this + "/')()
|
|
38
|
-
.constructor('^([^ ]+( +[^ ]+)+)+[^ ]}');
|
|
39
|
-
|
|
40
|
-
return !regExp.call({$1});
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
return {$3}();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
{$1}();
|
|
47
|
-
} catch ( {$1}e ) {
|
|
48
|
-
while({$1}e ? {$1}e : !{$1}e){
|
|
49
|
-
var {$1}b;
|
|
50
|
-
var {$1}c = 0;
|
|
51
|
-
({$1}e ? !{$1}e : {$1}e) ? (function({$1}e){
|
|
52
|
-
{$1}c = {$1}e ? 0 : !{$1}e ? 1 : 0;
|
|
53
|
-
})({$1}e) : {$1}b = 1;
|
|
54
|
-
|
|
55
|
-
if({$1}b&&{$1}c){break;}
|
|
56
|
-
if({$1}b){continue;}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
`);
|
|
28
|
+
};`);
|
package/dist/templates/es5.js
CHANGED
|
@@ -11,7 +11,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
11
11
|
*
|
|
12
12
|
* Source: https://vanillajstoolkit.com/polyfills/
|
|
13
13
|
*/
|
|
14
|
-
const ES5Template = exports.ES5Template =
|
|
14
|
+
const ES5Template = exports.ES5Template = new _template.default(`
|
|
15
15
|
if (!Array.prototype.forEach) {
|
|
16
16
|
Array.prototype.forEach = function forEach (callback, thisArg) {
|
|
17
17
|
if (typeof callback !== 'function') {
|
|
@@ -9,7 +9,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
9
9
|
/**
|
|
10
10
|
* Helper function to set `function.length` property.
|
|
11
11
|
*/
|
|
12
|
-
const FunctionLengthTemplate = exports.FunctionLengthTemplate =
|
|
12
|
+
const FunctionLengthTemplate = exports.FunctionLengthTemplate = new _template.default(`
|
|
13
13
|
function {name}(functionObject, functionLength){
|
|
14
14
|
{ObjectDefineProperty}(functionObject, "length", {
|
|
15
15
|
"value": functionLength,
|
|
@@ -6,4 +6,4 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.ObjectDefineProperty = void 0;
|
|
7
7
|
var _template = _interopRequireDefault(require("./template"));
|
|
8
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
-
const ObjectDefineProperty = exports.ObjectDefineProperty =
|
|
9
|
+
const ObjectDefineProperty = exports.ObjectDefineProperty = new _template.default(`Object["defineProperty"]`);
|
|
@@ -3,57 +3,135 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default =
|
|
6
|
+
exports.default = void 0;
|
|
7
7
|
var _parser = require("../parser");
|
|
8
8
|
var _assert = require("assert");
|
|
9
9
|
var _random = require("../util/random");
|
|
10
|
-
var
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
var _traverse = _interopRequireDefault(require("../traverse"));
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
13
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
14
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
15
|
+
/**
|
|
16
|
+
* Templates provides an easy way to parse code snippets into AST subtrees.
|
|
17
|
+
*
|
|
18
|
+
* These AST subtrees can added to the obfuscated code, tailored with variable names.
|
|
19
|
+
*
|
|
20
|
+
* 1. Basic string interpolation
|
|
21
|
+
*
|
|
22
|
+
* ```js
|
|
23
|
+
* var Base64Template = new Template(`
|
|
24
|
+
* function {name}(str){
|
|
25
|
+
* return btoa(str)
|
|
26
|
+
* }
|
|
27
|
+
* `);
|
|
28
|
+
*
|
|
29
|
+
* var functionDeclaration = Base64Template.single({ name: "atob" });
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* 2. AST subtree insertion
|
|
33
|
+
*
|
|
34
|
+
* ```js
|
|
35
|
+
* var Base64Template = new Template(`
|
|
36
|
+
* function {name}(str){
|
|
37
|
+
* {getWindow}
|
|
38
|
+
*
|
|
39
|
+
* return {getWindowName}btoa(str)
|
|
40
|
+
* }`)
|
|
41
|
+
*
|
|
42
|
+
* var functionDeclaration = Base64Template.single({
|
|
43
|
+
* name: "atob",
|
|
44
|
+
* getWindowName: "newWindow",
|
|
45
|
+
* getWindow: () => {
|
|
46
|
+
* return acorn.parse("var newWindow = {}").body[0];
|
|
47
|
+
* }
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* Here, the `getWindow` variable is a function that returns an AST subtree. This must be a `Node[]` array or Template.
|
|
52
|
+
* Optionally, the function can be replaced with just the `Node[]` array or Template if it's already computed.
|
|
53
|
+
*
|
|
54
|
+
* 3. Template subtree insertion
|
|
55
|
+
*
|
|
56
|
+
* ```js
|
|
57
|
+
* var NewWindowTemplate = new Template(`
|
|
58
|
+
* var newWindow = {};
|
|
59
|
+
* `);
|
|
60
|
+
*
|
|
61
|
+
* var Base64Template = new Template(`
|
|
62
|
+
* function {name}(str){
|
|
63
|
+
* {NewWindowTemplate}
|
|
64
|
+
*
|
|
65
|
+
* return newWindow.btoa(str)
|
|
66
|
+
* }`)
|
|
67
|
+
*
|
|
68
|
+
* var functionDeclaration = Base64Template.single({
|
|
69
|
+
* name: "atob",
|
|
70
|
+
* NewWindowTemplate: NewWindowTemplate
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
class Template {
|
|
75
|
+
constructor() {
|
|
76
|
+
_defineProperty(this, "templates", void 0);
|
|
77
|
+
_defineProperty(this, "defaultVariables", void 0);
|
|
78
|
+
_defineProperty(this, "requiredVariables", void 0);
|
|
79
|
+
for (var _len = arguments.length, templates = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
80
|
+
templates[_key] = arguments[_key];
|
|
81
|
+
}
|
|
82
|
+
this.templates = templates;
|
|
83
|
+
this.defaultVariables = Object.create(null);
|
|
84
|
+
this.requiredVariables = new Set();
|
|
85
|
+
this.findRequiredVariables();
|
|
14
86
|
}
|
|
15
|
-
(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
matches.forEach(variable => {
|
|
25
|
-
var name = variable.slice(1, -1);
|
|
87
|
+
setDefaultVariables(defaultVariables) {
|
|
88
|
+
this.defaultVariables = defaultVariables;
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
findRequiredVariables() {
|
|
92
|
+
var matches = this.templates[0].match(/{[$A-z0-9_]+}/g);
|
|
93
|
+
if (matches !== null) {
|
|
94
|
+
matches.forEach(variable => {
|
|
95
|
+
var name = variable.slice(1, -1);
|
|
26
96
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
97
|
+
// $ variables are for default variables
|
|
98
|
+
if (name.startsWith("$")) {
|
|
99
|
+
throw new Error("Default variables are no longer supported.");
|
|
100
|
+
} else {
|
|
101
|
+
this.requiredVariables.add(name);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
34
105
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Interpolates the template with the given variables.
|
|
109
|
+
*
|
|
110
|
+
* Prepares the template string for AST parsing.
|
|
111
|
+
*
|
|
112
|
+
* @param variables
|
|
113
|
+
*/
|
|
114
|
+
interpolateTemplate() {
|
|
115
|
+
let variables = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
116
|
+
var allVariables = {
|
|
117
|
+
...this.defaultVariables,
|
|
39
118
|
...variables
|
|
40
119
|
};
|
|
41
120
|
|
|
42
121
|
// Validate all variables were passed in
|
|
43
|
-
for (var requiredVariable of requiredVariables) {
|
|
44
|
-
if (typeof
|
|
45
|
-
throw new Error(templates[0] + " missing variable: " + requiredVariable + " from " + JSON.stringify(
|
|
122
|
+
for (var requiredVariable of this.requiredVariables) {
|
|
123
|
+
if (typeof allVariables[requiredVariable] === "undefined") {
|
|
124
|
+
throw new Error(this.templates[0] + " missing variable: " + requiredVariable + " from " + JSON.stringify(allVariables));
|
|
46
125
|
}
|
|
47
126
|
}
|
|
48
|
-
var template = (0, _random.choice)(templates);
|
|
127
|
+
var template = (0, _random.choice)(this.templates);
|
|
49
128
|
var output = template;
|
|
50
|
-
var allVariables = {
|
|
51
|
-
...defaultVariables,
|
|
52
|
-
...userVariables
|
|
53
|
-
};
|
|
54
129
|
Object.keys(allVariables).forEach(name => {
|
|
55
130
|
var bracketName = "{" + name.replace("$", "\\$") + "}";
|
|
56
131
|
var value = allVariables[name] + "";
|
|
132
|
+
if (typeof allVariables[name] !== "string") {
|
|
133
|
+
value = name;
|
|
134
|
+
}
|
|
57
135
|
var reg = new RegExp(bracketName, "g");
|
|
58
136
|
output = output.replace(reg, value);
|
|
59
137
|
});
|
|
@@ -62,45 +140,72 @@ function Template() {
|
|
|
62
140
|
template
|
|
63
141
|
};
|
|
64
142
|
}
|
|
65
|
-
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Finds the variables in the AST and replaces them with the given values.
|
|
146
|
+
*
|
|
147
|
+
* Note: Mutates the AST.
|
|
148
|
+
* @param ast
|
|
149
|
+
* @param variables
|
|
150
|
+
*/
|
|
151
|
+
interpolateAST(ast, variables) {
|
|
152
|
+
var allVariables = {
|
|
153
|
+
...this.defaultVariables,
|
|
154
|
+
...variables
|
|
155
|
+
};
|
|
156
|
+
var astNames = new Set(Object.keys(allVariables).filter(name => {
|
|
157
|
+
return typeof allVariables[name] !== "string";
|
|
158
|
+
}));
|
|
159
|
+
if (astNames.size === 0) return;
|
|
160
|
+
(0, _traverse.default)(ast, (o, p) => {
|
|
161
|
+
if (o.type === "Identifier" && allVariables[o.name]) {
|
|
162
|
+
return () => {
|
|
163
|
+
var value = allVariables[o.name];
|
|
164
|
+
(0, _assert.ok)(typeof value !== "string");
|
|
165
|
+
var insertNodes = typeof value === "function" ? value() : value;
|
|
166
|
+
if (insertNodes instanceof Template) {
|
|
167
|
+
insertNodes = insertNodes.compile(allVariables);
|
|
168
|
+
}
|
|
169
|
+
if (!Array.isArray(insertNodes)) {
|
|
170
|
+
// Replace with expression
|
|
171
|
+
|
|
172
|
+
Object.assign(o, insertNodes);
|
|
173
|
+
} else {
|
|
174
|
+
// Insert multiple statements/declarations
|
|
175
|
+
var expressionStatement = p[0];
|
|
176
|
+
var body = p[1];
|
|
177
|
+
(0, _assert.ok)(expressionStatement.type === "ExpressionStatement");
|
|
178
|
+
(0, _assert.ok)(Array.isArray(body));
|
|
179
|
+
var index = body.indexOf(expressionStatement);
|
|
180
|
+
body.splice(index, 1, ...insertNodes);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
compile() {
|
|
187
|
+
let variables = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
66
188
|
var {
|
|
67
189
|
output,
|
|
68
190
|
template
|
|
69
|
-
} =
|
|
191
|
+
} = this.interpolateTemplate(variables);
|
|
192
|
+
var program;
|
|
70
193
|
try {
|
|
71
|
-
|
|
72
|
-
return program.body;
|
|
194
|
+
program = (0, _parser.parseSnippet)(output);
|
|
73
195
|
} catch (e) {
|
|
74
|
-
|
|
75
|
-
console.error(template);
|
|
76
|
-
console.error({
|
|
77
|
-
...providedVariables,
|
|
78
|
-
...variables
|
|
79
|
-
});
|
|
80
|
-
throw new Error("Template failed to parse: OUTPUT= " + output + " SOURCE= " + template);
|
|
196
|
+
throw new Error(output + "\n" + "Template failed to parse: " + e.message);
|
|
81
197
|
}
|
|
198
|
+
this.interpolateAST(program, variables);
|
|
199
|
+
return program.body;
|
|
82
200
|
}
|
|
83
|
-
|
|
84
|
-
|
|
201
|
+
single() {
|
|
202
|
+
let variables = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
203
|
+
var nodes = this.compile(variables);
|
|
204
|
+
if (nodes.length !== 1) {
|
|
205
|
+
nodes = nodes.filter(node => node.type !== "EmptyStatement");
|
|
206
|
+
(0, _assert.ok)(nodes.length === 1, `Expected single node, got ${nodes.map(node => node.type).join(", ")}`);
|
|
207
|
+
}
|
|
85
208
|
return nodes[0];
|
|
86
209
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return obj;
|
|
90
|
-
}
|
|
91
|
-
function ignoreMissingVariables() {
|
|
92
|
-
defaultVariables = Object.create(null);
|
|
93
|
-
requiredVariables.clear();
|
|
94
|
-
return obj;
|
|
95
|
-
}
|
|
96
|
-
var obj = {
|
|
97
|
-
fill,
|
|
98
|
-
compile,
|
|
99
|
-
single,
|
|
100
|
-
templates,
|
|
101
|
-
variables,
|
|
102
|
-
ignoreMissingVariables,
|
|
103
|
-
source: templates[0]
|
|
104
|
-
};
|
|
105
|
-
return obj;
|
|
106
|
-
}
|
|
210
|
+
}
|
|
211
|
+
exports.default = Template;
|
|
@@ -23,7 +23,7 @@ class AntiTooling extends _transform.default {
|
|
|
23
23
|
apply(tree) {
|
|
24
24
|
super.apply(tree);
|
|
25
25
|
if (typeof this.fnName === "string") {
|
|
26
|
-
(0, _insert.prepend)(tree,
|
|
26
|
+
(0, _insert.prepend)(tree, new _template.default(`
|
|
27
27
|
function {fnName}(){
|
|
28
28
|
}
|
|
29
29
|
`).single({
|