js-confuser 1.7.1 → 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 +73 -0
- package/README.md +32 -31
- package/dist/compiler.js +2 -8
- package/dist/constants.js +22 -10
- package/dist/index.js +15 -30
- package/dist/obfuscator.js +15 -62
- package/dist/options.js +33 -40
- package/dist/order.js +4 -7
- package/dist/parser.js +5 -13
- package/dist/precedence.js +6 -8
- package/dist/presets.js +4 -6
- package/dist/probability.js +13 -24
- package/dist/templates/bufferToString.js +121 -5
- package/dist/templates/core.js +35 -0
- package/dist/templates/crash.js +22 -11
- package/dist/templates/es5.js +125 -6
- package/dist/templates/functionLength.js +24 -6
- package/dist/templates/globals.js +9 -0
- package/dist/templates/template.js +189 -43
- package/dist/transforms/antiTooling.js +26 -22
- package/dist/transforms/calculator.js +19 -55
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +242 -333
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
- package/dist/transforms/deadCode.js +542 -31
- package/dist/transforms/dispatcher.js +112 -112
- package/dist/transforms/es5/antiClass.js +70 -44
- package/dist/transforms/es5/antiDestructuring.js +14 -38
- package/dist/transforms/es5/antiES6Object.js +39 -48
- package/dist/transforms/es5/antiSpreadOperator.js +5 -14
- package/dist/transforms/es5/antiTemplate.js +10 -19
- package/dist/transforms/es5/es5.js +7 -40
- package/dist/transforms/extraction/classExtraction.js +83 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +41 -80
- package/dist/transforms/extraction/objectExtraction.js +24 -56
- package/dist/transforms/finalizer.js +6 -20
- package/dist/transforms/flatten.js +51 -99
- package/dist/transforms/identifier/globalAnalysis.js +21 -26
- package/dist/transforms/identifier/globalConcealing.js +72 -56
- package/dist/transforms/identifier/movedDeclarations.js +66 -38
- package/dist/transforms/identifier/renameVariables.js +36 -68
- package/dist/transforms/identifier/variableAnalysis.js +21 -48
- package/dist/transforms/lock/antiDebug.js +20 -25
- package/dist/transforms/lock/integrity.js +53 -52
- package/dist/transforms/lock/lock.js +161 -126
- package/dist/transforms/minify.js +77 -108
- package/dist/transforms/opaquePredicates.js +12 -49
- package/dist/transforms/preparation.js +28 -49
- package/dist/transforms/renameLabels.js +5 -22
- package/dist/transforms/rgf.js +125 -72
- package/dist/transforms/shuffle.js +42 -47
- package/dist/transforms/stack.js +41 -98
- package/dist/transforms/string/encoding.js +76 -27
- package/dist/transforms/string/stringCompression.js +75 -68
- package/dist/transforms/string/stringConcealing.js +127 -135
- package/dist/transforms/string/stringEncoding.js +6 -26
- package/dist/transforms/string/stringSplitting.js +5 -30
- package/dist/transforms/transform.js +76 -104
- package/dist/traverse.js +11 -18
- package/dist/util/compare.js +27 -29
- package/dist/util/gen.js +32 -86
- package/dist/util/guard.js +5 -1
- package/dist/util/identifiers.js +9 -72
- package/dist/util/insert.js +27 -77
- package/dist/util/math.js +0 -3
- package/dist/util/object.js +3 -7
- package/dist/util/random.js +31 -36
- package/dist/util/scope.js +6 -3
- 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 +3 -3
- package/src/constants.ts +17 -0
- package/src/index.ts +7 -5
- package/src/options.ts +60 -7
- package/src/order.ts +2 -2
- package/src/templates/bufferToString.ts +79 -11
- 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 +21 -3
- package/src/templates/globals.ts +3 -0
- package/src/templates/template.ts +205 -46
- package/src/transforms/antiTooling.ts +33 -11
- package/src/transforms/calculator.ts +4 -2
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +12 -5
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
- package/src/transforms/deadCode.ts +74 -42
- package/src/transforms/dispatcher.ts +99 -73
- package/src/transforms/es5/antiClass.ts +25 -12
- 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/classExtraction.ts +168 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +11 -16
- package/src/transforms/extraction/objectExtraction.ts +4 -15
- package/src/transforms/flatten.ts +20 -5
- package/src/transforms/identifier/globalAnalysis.ts +18 -1
- package/src/transforms/identifier/globalConcealing.ts +119 -72
- package/src/transforms/identifier/movedDeclarations.ts +90 -24
- 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 +28 -13
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +16 -0
- package/src/transforms/rgf.ts +139 -12
- package/src/transforms/shuffle.ts +3 -3
- package/src/transforms/stack.ts +19 -4
- package/src/transforms/string/encoding.ts +88 -51
- package/src/transforms/string/stringCompression.ts +86 -17
- package/src/transforms/string/stringConcealing.ts +148 -118
- package/src/transforms/string/stringEncoding.ts +1 -2
- package/src/transforms/string/stringSplitting.ts +1 -2
- package/src/transforms/transform.ts +63 -46
- package/src/types.ts +2 -0
- package/src/util/compare.ts +39 -5
- package/src/util/gen.ts +10 -3
- package/src/util/guard.ts +10 -0
- package/src/util/insert.ts +17 -0
- package/src/util/random.ts +81 -1
- package/src/util/scope.ts +14 -2
- package/test/code/Cash.test.ts +94 -5
- package/test/code/StrictMode.src.js +65 -0
- package/test/code/StrictMode.test.js +37 -0
- package/test/compare.test.ts +62 -2
- package/test/options.test.ts +129 -55
- package/test/templates/template.test.ts +211 -1
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
- package/test/transforms/dispatcher.test.ts +55 -0
- package/test/transforms/extraction/classExtraction.test.ts +86 -0
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +8 -0
- package/test/transforms/extraction/objectExtraction.test.ts +2 -0
- package/test/transforms/identifier/globalConcealing.test.ts +89 -0
- package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
- package/test/transforms/identifier/renameVariables.test.ts +75 -1
- package/test/transforms/lock/tamperProtection.test.ts +336 -0
- package/test/transforms/minify.test.ts +37 -0
- package/test/transforms/rgf.test.ts +50 -0
- package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
- package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
- package/dist/transforms/eval.js +0 -84
- package/dist/transforms/hexadecimalNumbers.js +0 -63
- package/dist/transforms/hideInitializingCode.js +0 -270
- package/dist/transforms/identifier/nameRecycling.js +0 -218
- package/dist/transforms/label.js +0 -67
- package/dist/transforms/preparation/nameConflicts.js +0 -116
- package/dist/transforms/preparation/preparation.js +0 -188
package/dist/templates/es5.js
CHANGED
|
@@ -4,15 +4,134 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.ES5Template = void 0;
|
|
7
|
-
|
|
8
7
|
var _template = _interopRequireDefault(require("./template"));
|
|
9
|
-
|
|
10
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
9
|
/**
|
|
13
10
|
* Provides ES5 polyfills for Array methods
|
|
14
11
|
*
|
|
15
12
|
* Source: https://vanillajstoolkit.com/polyfills/
|
|
16
13
|
*/
|
|
17
|
-
const ES5Template =
|
|
18
|
-
|
|
14
|
+
const ES5Template = exports.ES5Template = new _template.default(`
|
|
15
|
+
if (!Array.prototype.forEach) {
|
|
16
|
+
Array.prototype.forEach = function forEach (callback, thisArg) {
|
|
17
|
+
if (typeof callback !== 'function') {
|
|
18
|
+
throw new TypeError(callback + ' is not a function');
|
|
19
|
+
}
|
|
20
|
+
var array = this;
|
|
21
|
+
thisArg = thisArg || this;
|
|
22
|
+
for (var i = 0, l = array.length; i !== l; ++i) {
|
|
23
|
+
callback.call(thisArg, array[i], i, array);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (!Array.prototype.filter)
|
|
28
|
+
Array.prototype.filter = function(func, thisArg) {
|
|
29
|
+
'use strict';
|
|
30
|
+
if ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )
|
|
31
|
+
throw new TypeError();
|
|
32
|
+
|
|
33
|
+
var len = this.length >>> 0,
|
|
34
|
+
res = new Array(len), // preallocate array
|
|
35
|
+
t = this, c = 0, i = -1;
|
|
36
|
+
if (thisArg === undefined)
|
|
37
|
+
while (++i !== len)
|
|
38
|
+
// checks to see if the key was set
|
|
39
|
+
if (i in this)
|
|
40
|
+
if (func(t[i], i, t))
|
|
41
|
+
res[c++] = t[i];
|
|
42
|
+
else
|
|
43
|
+
while (++i !== len)
|
|
44
|
+
// checks to see if the key was set
|
|
45
|
+
if (i in this)
|
|
46
|
+
if (func.call(thisArg, t[i], i, t))
|
|
47
|
+
res[c++] = t[i];
|
|
48
|
+
|
|
49
|
+
res.length = c; // shrink down array to proper size
|
|
50
|
+
return res;
|
|
51
|
+
};
|
|
52
|
+
if (!Array.prototype.map) {
|
|
53
|
+
Array.prototype.map = function(callback, thisArg) {
|
|
54
|
+
var T, A, k;
|
|
55
|
+
|
|
56
|
+
if (this == null) {
|
|
57
|
+
throw new TypeError('this is null or not defined');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 1. Let O be the result of calling ToObject passing the |this|
|
|
61
|
+
// value as the argument.
|
|
62
|
+
var O = Object(this);
|
|
63
|
+
|
|
64
|
+
// 2. Let lenValue be the result of calling the Get internal
|
|
65
|
+
// method of O with the argument "length".
|
|
66
|
+
// 3. Let len be ToUint32(lenValue).
|
|
67
|
+
var len = O.length >>> 0;
|
|
68
|
+
|
|
69
|
+
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
|
70
|
+
// See: http://es5.github.com/#x9.11
|
|
71
|
+
if (typeof callback !== 'function') {
|
|
72
|
+
throw new TypeError(callback + ' is not a function');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
|
76
|
+
if (arguments.length > 1) {
|
|
77
|
+
T = arguments[1];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 6. Let A be a new array created as if by the expression new Array(len)
|
|
81
|
+
// where Array is the standard built-in constructor with that name and
|
|
82
|
+
// len is the value of len.
|
|
83
|
+
A = new Array(len);
|
|
84
|
+
|
|
85
|
+
// 7. Let k be 0
|
|
86
|
+
k = 0;
|
|
87
|
+
|
|
88
|
+
// 8. Repeat, while k < len
|
|
89
|
+
while (k < len) {
|
|
90
|
+
|
|
91
|
+
var kValue, mappedValue;
|
|
92
|
+
|
|
93
|
+
// a. Let Pk be ToString(k).
|
|
94
|
+
// This is implicit for LHS operands of the in operator
|
|
95
|
+
// b. Let kPresent be the result of calling the HasProperty internal
|
|
96
|
+
// method of O with argument Pk.
|
|
97
|
+
// This step can be combined with c
|
|
98
|
+
// c. If kPresent is true, then
|
|
99
|
+
if (k in O) {
|
|
100
|
+
|
|
101
|
+
// i. Let kValue be the result of calling the Get internal
|
|
102
|
+
// method of O with argument Pk.
|
|
103
|
+
kValue = O[k];
|
|
104
|
+
|
|
105
|
+
// ii. Let mappedValue be the result of calling the Call internal
|
|
106
|
+
// method of callback with T as the this value and argument
|
|
107
|
+
// list containing kValue, k, and O.
|
|
108
|
+
mappedValue = callback.call(T, kValue, k, O);
|
|
109
|
+
|
|
110
|
+
// iii. Call the DefineOwnProperty internal method of A with arguments
|
|
111
|
+
// Pk, Property Descriptor
|
|
112
|
+
// { Value: mappedValue,
|
|
113
|
+
// Writable: true,
|
|
114
|
+
// Enumerable: true,
|
|
115
|
+
// Configurable: true },
|
|
116
|
+
// and false.
|
|
117
|
+
|
|
118
|
+
// In browsers that support Object.defineProperty, use the following:
|
|
119
|
+
// Object.defineProperty(A, k, {
|
|
120
|
+
// value: mappedValue,
|
|
121
|
+
// writable: true,
|
|
122
|
+
// enumerable: true,
|
|
123
|
+
// configurable: true
|
|
124
|
+
// });
|
|
125
|
+
|
|
126
|
+
// For best browser support, use the following:
|
|
127
|
+
A[k] = mappedValue;
|
|
128
|
+
}
|
|
129
|
+
// d. Increase k by 1.
|
|
130
|
+
k++;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 9. return A
|
|
134
|
+
return A;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
`);
|
|
@@ -4,13 +4,31 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.FunctionLengthTemplate = void 0;
|
|
7
|
-
|
|
8
7
|
var _template = _interopRequireDefault(require("./template"));
|
|
9
|
-
|
|
10
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
9
|
/**
|
|
13
10
|
* Helper function to set `function.length` property.
|
|
14
11
|
*/
|
|
15
|
-
const FunctionLengthTemplate =
|
|
16
|
-
|
|
12
|
+
const FunctionLengthTemplate = exports.FunctionLengthTemplate = new _template.default(`
|
|
13
|
+
function {name}(functionObject, functionLength){
|
|
14
|
+
{ObjectDefineProperty}(functionObject, "length", {
|
|
15
|
+
"value": functionLength,
|
|
16
|
+
"configurable": true
|
|
17
|
+
});
|
|
18
|
+
return functionObject;
|
|
19
|
+
}
|
|
20
|
+
`, `
|
|
21
|
+
function {name}(functionObject, functionLength){
|
|
22
|
+
return {ObjectDefineProperty}(functionObject, "length", {
|
|
23
|
+
"value": functionLength,
|
|
24
|
+
"configurable": true
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
`, `
|
|
28
|
+
function {name}(functionObject, functionLength){
|
|
29
|
+
return {ObjectDefineProperty}["call"](null, functionObject, "length", {
|
|
30
|
+
"value": functionLength,
|
|
31
|
+
"configurable": true
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
`);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ObjectDefineProperty = void 0;
|
|
7
|
+
var _template = _interopRequireDefault(require("./template"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const ObjectDefineProperty = exports.ObjectDefineProperty = new _template.default(`Object["defineProperty"]`);
|
|
@@ -3,63 +3,209 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default =
|
|
7
|
-
|
|
6
|
+
exports.default = void 0;
|
|
8
7
|
var _parser = require("../parser");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
var _assert = require("assert");
|
|
9
|
+
var _random = require("../util/random");
|
|
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();
|
|
15
86
|
}
|
|
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);
|
|
16
96
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
variables = Object.create(null);
|
|
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
|
+
});
|
|
25
104
|
}
|
|
105
|
+
}
|
|
26
106
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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,
|
|
118
|
+
...variables
|
|
30
119
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
120
|
+
|
|
121
|
+
// Validate all variables were passed in
|
|
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));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
var template = (0, _random.choice)(this.templates);
|
|
128
|
+
var output = template;
|
|
129
|
+
Object.keys(allVariables).forEach(name => {
|
|
130
|
+
var bracketName = "{" + name.replace("$", "\\$") + "}";
|
|
131
|
+
var value = allVariables[name] + "";
|
|
132
|
+
if (typeof allVariables[name] !== "string") {
|
|
133
|
+
value = name;
|
|
134
|
+
}
|
|
34
135
|
var reg = new RegExp(bracketName, "g");
|
|
35
|
-
|
|
136
|
+
output = output.replace(reg, value);
|
|
36
137
|
});
|
|
37
|
-
return
|
|
138
|
+
return {
|
|
139
|
+
output,
|
|
140
|
+
template
|
|
141
|
+
};
|
|
38
142
|
}
|
|
39
143
|
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
42
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] : {};
|
|
188
|
+
var {
|
|
189
|
+
output,
|
|
190
|
+
template
|
|
191
|
+
} = this.interpolateTemplate(variables);
|
|
192
|
+
var program;
|
|
43
193
|
try {
|
|
44
|
-
|
|
45
|
-
return program.body;
|
|
194
|
+
program = (0, _parser.parseSnippet)(output);
|
|
46
195
|
} catch (e) {
|
|
47
|
-
|
|
48
|
-
console.error(template);
|
|
49
|
-
throw new Error("Template failed to parse");
|
|
196
|
+
throw new Error(output + "\n" + "Template failed to parse: " + e.message);
|
|
50
197
|
}
|
|
198
|
+
this.interpolateAST(program, variables);
|
|
199
|
+
return program.body;
|
|
51
200
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
var nodes = compile(variables);
|
|
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
|
+
}
|
|
55
208
|
return nodes[0];
|
|
56
209
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
fill,
|
|
60
|
-
compile,
|
|
61
|
-
single,
|
|
62
|
-
source: template
|
|
63
|
-
};
|
|
64
|
-
return obj;
|
|
65
|
-
}
|
|
210
|
+
}
|
|
211
|
+
exports.default = Template;
|
|
@@ -4,35 +4,41 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _order = require("../order");
|
|
9
|
-
|
|
8
|
+
var _template = _interopRequireDefault(require("../templates/template"));
|
|
10
9
|
var _traverse = require("../traverse");
|
|
11
|
-
|
|
12
10
|
var _gen = require("../util/gen");
|
|
13
|
-
|
|
14
|
-
var _random = require("../util/random");
|
|
15
|
-
|
|
11
|
+
var _insert = require("../util/insert");
|
|
16
12
|
var _transform = _interopRequireDefault(require("./transform"));
|
|
17
|
-
|
|
18
|
-
function
|
|
19
|
-
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
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; }
|
|
15
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
16
|
+
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); }
|
|
20
17
|
// JsNice.org tries to separate sequence expressions into multiple lines, this stops that.
|
|
21
18
|
class AntiTooling extends _transform.default {
|
|
22
19
|
constructor(o) {
|
|
23
20
|
super(o, _order.ObfuscateOrder.AntiTooling);
|
|
21
|
+
_defineProperty(this, "fnName", void 0);
|
|
22
|
+
}
|
|
23
|
+
apply(tree) {
|
|
24
|
+
super.apply(tree);
|
|
25
|
+
if (typeof this.fnName === "string") {
|
|
26
|
+
(0, _insert.prepend)(tree, new _template.default(`
|
|
27
|
+
function {fnName}(){
|
|
28
|
+
}
|
|
29
|
+
`).single({
|
|
30
|
+
fnName: this.fnName
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
24
33
|
}
|
|
25
|
-
|
|
26
34
|
match(object, parents) {
|
|
27
35
|
return (0, _traverse.isBlock)(object) || object.type == "SwitchCase";
|
|
28
36
|
}
|
|
29
|
-
|
|
30
37
|
transform(object, parents) {
|
|
31
38
|
return () => {
|
|
32
39
|
var exprs = [];
|
|
33
40
|
var deleteExprs = [];
|
|
34
41
|
var body = object.type == "SwitchCase" ? object.consequent : object.body;
|
|
35
|
-
|
|
36
42
|
const end = () => {
|
|
37
43
|
function flatten(expr) {
|
|
38
44
|
if (expr.type == "ExpressionStatement") {
|
|
@@ -43,25 +49,26 @@ class AntiTooling extends _transform.default {
|
|
|
43
49
|
flattened.push(expr);
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
|
-
|
|
47
52
|
var flattened = [];
|
|
48
53
|
exprs.forEach(flatten);
|
|
49
|
-
|
|
50
54
|
if (flattened.length > 1) {
|
|
51
|
-
flattened[0] = {
|
|
55
|
+
flattened[0] = {
|
|
56
|
+
...flattened[0]
|
|
52
57
|
};
|
|
53
|
-
|
|
58
|
+
if (!this.fnName) {
|
|
59
|
+
this.fnName = this.getPlaceholder();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// (expr1,expr2,expr3) -> F(expr1, expr2, expr3)
|
|
63
|
+
this.replace(exprs[0], (0, _gen.ExpressionStatement)((0, _gen.CallExpression)((0, _gen.Identifier)(this.fnName), [...flattened])));
|
|
54
64
|
deleteExprs.push(...exprs.slice(1));
|
|
55
65
|
}
|
|
56
|
-
|
|
57
66
|
exprs = [];
|
|
58
67
|
};
|
|
59
|
-
|
|
60
68
|
body.forEach((stmt, i) => {
|
|
61
69
|
if (stmt.hidden || stmt.directive) {
|
|
62
70
|
return;
|
|
63
71
|
}
|
|
64
|
-
|
|
65
72
|
if (stmt.type == "ExpressionStatement") {
|
|
66
73
|
exprs.push(stmt);
|
|
67
74
|
} else {
|
|
@@ -71,14 +78,11 @@ class AntiTooling extends _transform.default {
|
|
|
71
78
|
end();
|
|
72
79
|
deleteExprs.forEach(expr => {
|
|
73
80
|
var index = body.indexOf(expr);
|
|
74
|
-
|
|
75
81
|
if (index !== -1) {
|
|
76
82
|
body.splice(index, 1);
|
|
77
83
|
}
|
|
78
84
|
});
|
|
79
85
|
};
|
|
80
86
|
}
|
|
81
|
-
|
|
82
87
|
}
|
|
83
|
-
|
|
84
88
|
exports.default = AntiTooling;
|