js-confuser 1.5.9 → 1.7.0
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 +2 -2
- package/CHANGELOG.md +55 -0
- package/README.md +346 -165
- package/dist/constants.js +6 -2
- package/dist/index.js +9 -21
- package/dist/obfuscator.js +19 -31
- package/dist/options.js +5 -5
- package/dist/order.js +1 -3
- package/dist/presets.js +6 -7
- package/dist/probability.js +2 -4
- package/dist/templates/bufferToString.js +13 -0
- package/dist/templates/crash.js +3 -3
- package/dist/templates/es5.js +18 -0
- package/dist/templates/functionLength.js +16 -0
- package/dist/transforms/calculator.js +77 -21
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -1
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
- package/dist/transforms/deadCode.js +33 -25
- package/dist/transforms/dispatcher.js +8 -4
- package/dist/transforms/es5/antiDestructuring.js +2 -0
- package/dist/transforms/es5/es5.js +31 -34
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +92 -58
- package/dist/transforms/finalizer.js +82 -0
- package/dist/transforms/flatten.js +229 -148
- package/dist/transforms/identifier/globalAnalysis.js +88 -0
- package/dist/transforms/identifier/globalConcealing.js +10 -83
- package/dist/transforms/identifier/movedDeclarations.js +35 -88
- package/dist/transforms/identifier/renameVariables.js +124 -59
- package/dist/transforms/identifier/variableAnalysis.js +58 -62
- package/dist/transforms/lock/lock.js +0 -37
- package/dist/transforms/minify.js +60 -57
- package/dist/transforms/opaquePredicates.js +1 -1
- package/dist/transforms/preparation/preparation.js +2 -2
- package/dist/transforms/preparation.js +231 -0
- package/dist/transforms/renameLabels.js +1 -1
- package/dist/transforms/rgf.js +139 -247
- package/dist/transforms/stack.js +128 -26
- package/dist/transforms/string/encoding.js +150 -179
- package/dist/transforms/string/stringCompression.js +14 -15
- package/dist/transforms/string/stringConcealing.js +25 -8
- package/dist/transforms/string/stringEncoding.js +13 -24
- package/dist/transforms/transform.js +12 -19
- package/dist/traverse.js +24 -10
- package/dist/util/gen.js +17 -1
- package/dist/util/identifiers.js +37 -3
- package/dist/util/insert.js +35 -4
- package/dist/util/random.js +15 -0
- package/docs/ControlFlowFlattening.md +595 -0
- package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
- package/{Integrity.md → docs/Integrity.md} +2 -2
- package/docs/RGF.md +419 -0
- package/package.json +5 -5
- package/src/constants.ts +3 -0
- package/src/index.ts +2 -2
- package/src/obfuscator.ts +19 -31
- package/src/options.ts +14 -103
- package/src/order.ts +1 -5
- package/src/presets.ts +6 -7
- package/src/probability.ts +2 -3
- package/src/templates/bufferToString.ts +68 -0
- package/src/templates/crash.ts +15 -19
- package/src/templates/es5.ts +131 -0
- package/src/templates/functionLength.ts +14 -0
- package/src/transforms/calculator.ts +122 -59
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +4 -1
- package/src/transforms/deadCode.ts +383 -26
- package/src/transforms/dispatcher.ts +9 -4
- package/src/transforms/es5/antiDestructuring.ts +2 -0
- package/src/transforms/es5/es5.ts +32 -77
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +133 -129
- package/src/transforms/{hexadecimalNumbers.ts → finalizer.ts} +29 -13
- package/src/transforms/flatten.ts +357 -300
- package/src/transforms/identifier/globalAnalysis.ts +85 -0
- package/src/transforms/identifier/globalConcealing.ts +14 -103
- package/src/transforms/identifier/movedDeclarations.ts +49 -102
- package/src/transforms/identifier/renameVariables.ts +149 -78
- package/src/transforms/identifier/variableAnalysis.ts +66 -73
- package/src/transforms/lock/lock.ts +1 -42
- package/src/transforms/minify.ts +91 -75
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +238 -0
- package/src/transforms/renameLabels.ts +2 -2
- package/src/transforms/rgf.ts +213 -405
- package/src/transforms/stack.ts +156 -36
- package/src/transforms/string/encoding.ts +115 -212
- package/src/transforms/string/stringCompression.ts +27 -18
- package/src/transforms/string/stringConcealing.ts +39 -9
- package/src/transforms/string/stringEncoding.ts +18 -18
- package/src/transforms/transform.ts +21 -23
- package/src/traverse.ts +23 -4
- package/src/types.ts +2 -1
- package/src/util/gen.ts +28 -3
- package/src/util/identifiers.ts +43 -2
- package/src/util/insert.ts +38 -3
- package/src/util/random.ts +13 -0
- package/test/code/Cash.test.ts +1 -1
- package/test/code/Dynamic.test.ts +12 -10
- package/test/code/ES6.src.js +146 -0
- package/test/code/ES6.test.ts +28 -2
- package/test/index.test.ts +2 -1
- package/test/probability.test.ts +44 -0
- package/test/templates/template.test.ts +1 -1
- package/test/transforms/antiTooling.test.ts +22 -0
- package/test/transforms/calculator.test.ts +40 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +702 -160
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
- package/test/transforms/deadCode.test.ts +66 -15
- package/test/transforms/dispatcher.test.ts +20 -1
- package/test/transforms/es5/antiDestructuring.test.ts +16 -0
- package/test/transforms/flatten.test.ts +399 -86
- package/test/transforms/identifier/movedDeclarations.test.ts +63 -8
- package/test/transforms/identifier/renameVariables.test.ts +119 -0
- package/test/transforms/lock/antiDebug.test.ts +2 -2
- package/test/transforms/lock/lock.test.ts +1 -48
- package/test/transforms/minify.test.ts +104 -0
- package/test/transforms/preparation.test.ts +157 -0
- package/test/transforms/rgf.test.ts +261 -381
- package/test/transforms/stack.test.ts +143 -21
- package/test/transforms/string/stringCompression.test.ts +39 -0
- package/test/transforms/string/stringConcealing.test.ts +82 -0
- package/test/transforms/string/stringEncoding.test.ts +53 -2
- package/test/transforms/transform.test.ts +66 -0
- package/test/traverse.test.ts +139 -0
- package/test/util/identifiers.test.ts +113 -1
- package/test/util/insert.test.ts +57 -3
- package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
- package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
- package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
- package/src/transforms/eval.ts +0 -89
- package/src/transforms/hideInitializingCode.ts +0 -432
- package/src/transforms/identifier/nameRecycling.ts +0 -280
- package/src/transforms/label.ts +0 -64
- package/src/transforms/preparation/nameConflicts.ts +0 -102
- package/src/transforms/preparation/preparation.ts +0 -176
- package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
- package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
- package/test/transforms/eval.test.ts +0 -131
- package/test/transforms/hideInitializingCode.test.ts +0 -336
- package/test/transforms/identifier/nameRecycling.test.ts +0 -205
- package/test/transforms/preparation/nameConflicts.test.ts +0 -52
- package/test/transforms/preparation/preparation.test.ts +0 -62
package/dist/transforms/rgf.js
CHANGED
|
@@ -15,9 +15,7 @@ var _order = require("../order");
|
|
|
15
15
|
|
|
16
16
|
var _probability = require("../probability");
|
|
17
17
|
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
var _traverse = _interopRequireWildcard(require("../traverse"));
|
|
18
|
+
var _traverse = require("../traverse");
|
|
21
19
|
|
|
22
20
|
var _gen = require("../util/gen");
|
|
23
21
|
|
|
@@ -25,16 +23,12 @@ var _identifiers = require("../util/identifiers");
|
|
|
25
23
|
|
|
26
24
|
var _insert = require("../util/insert");
|
|
27
25
|
|
|
28
|
-
var _random = require("../util/random");
|
|
29
|
-
|
|
30
26
|
var _transform = _interopRequireDefault(require("./transform"));
|
|
31
27
|
|
|
32
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
33
|
-
|
|
34
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
35
|
-
|
|
36
28
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
37
29
|
|
|
30
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
31
|
+
|
|
38
32
|
/**
|
|
39
33
|
* Converts function to `new Function("..code..")` syntax as an alternative to `eval`. Eval is disabled in many environments.
|
|
40
34
|
*
|
|
@@ -43,286 +37,184 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
43
37
|
* Rigorous checks are in place to only include pure functions.
|
|
44
38
|
*
|
|
45
39
|
* `flatten` can attempt to make function reference-less. Recommended to have flatten enabled with RGF.
|
|
46
|
-
*
|
|
47
|
-
* | Mode | Description |
|
|
48
|
-
* | --- | --- |
|
|
49
|
-
* | `"all"` | Applies to all scopes |
|
|
50
|
-
* | `true` | Applies to the top level only |
|
|
51
|
-
* | `false` | Feature disabled |
|
|
52
40
|
*/
|
|
53
41
|
class RGF extends _transform.default {
|
|
42
|
+
// Array of all the `new Function` calls
|
|
43
|
+
// The name of the array holding all the `new Function` expressions
|
|
54
44
|
constructor(o) {
|
|
55
45
|
super(o, _order.ObfuscateOrder.RGF);
|
|
46
|
+
|
|
47
|
+
_defineProperty(this, "arrayExpressionElements", void 0);
|
|
48
|
+
|
|
49
|
+
_defineProperty(this, "arrayExpressionName", void 0);
|
|
50
|
+
|
|
51
|
+
this.arrayExpressionName = this.getPlaceholder() + "_rgf";
|
|
52
|
+
this.arrayExpressionElements = [];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
apply(tree) {
|
|
56
|
+
super.apply(tree); // Only add the array if there were converted functions
|
|
57
|
+
|
|
58
|
+
if (this.arrayExpressionElements.length > 0) {
|
|
59
|
+
(0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.Identifier)(this.arrayExpressionName), (0, _gen.ArrayExpression)(this.arrayExpressionElements))));
|
|
60
|
+
}
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
match(object, parents) {
|
|
59
|
-
return (
|
|
64
|
+
return (object.type === "FunctionDeclaration" || object.type === "FunctionExpression") && // Does not apply to Arrow functions
|
|
65
|
+
!object.async && // Does not apply to async/generator functions
|
|
66
|
+
!object.generator;
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
transform(
|
|
63
|
-
|
|
64
|
-
var isGlobal = contextObject.type == "Program";
|
|
65
|
-
var value = (0, _probability.ComputeProbabilityMap)(this.options.rgf, x => x, isGlobal);
|
|
69
|
+
transform(object, parents) {
|
|
70
|
+
var _this$options$lock, _object$id;
|
|
66
71
|
|
|
67
|
-
|
|
72
|
+
// Discard getter/setter methods
|
|
73
|
+
if (parents[0].type === "Property" && parents[0].value === object) {
|
|
74
|
+
if (parents[0].method || parents[0].kind === "get" || parents[0].kind === "set") {
|
|
68
75
|
return;
|
|
69
76
|
}
|
|
77
|
+
} // Discard class methods
|
|
70
78
|
|
|
71
|
-
var collect = [];
|
|
72
|
-
var queue = [];
|
|
73
|
-
var names = new Map();
|
|
74
|
-
var referenceSignatures = {};
|
|
75
|
-
var definingNodes = new Map();
|
|
76
|
-
(0, _traverse.walk)(contextObject, contextParents, (object, parents) => {
|
|
77
|
-
if (object !== contextObject && (0, _insert.isFunction)(object) && !object.$requiresEval && !object.async && !object.generator && (0, _insert.getVarContext)(parents[0], parents.slice(1)) === contextObject) {
|
|
78
|
-
var _this$options$lock;
|
|
79
|
-
|
|
80
|
-
// Discard getter/setter methods
|
|
81
|
-
if (parents[0].type === "Property" && parents[0].value === object) {
|
|
82
|
-
if (parents[0].method || parents[0].kind === "get" || parents[0].kind === "set") {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
} // Discard class methods
|
|
86
79
|
|
|
80
|
+
if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
|
|
81
|
+
return;
|
|
82
|
+
} // Avoid applying to the countermeasures function
|
|
87
83
|
|
|
88
|
-
if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
|
|
89
|
-
return;
|
|
90
|
-
} // Avoid applying to the countermeasures function
|
|
91
84
|
|
|
85
|
+
if (typeof ((_this$options$lock = this.options.lock) === null || _this$options$lock === void 0 ? void 0 : _this$options$lock.countermeasures) === "string") {
|
|
86
|
+
// function countermeasures(){...}
|
|
87
|
+
if (object.type === "FunctionDeclaration" && object.id.type === "Identifier" && object.id.name === this.options.lock.countermeasures) {
|
|
88
|
+
return;
|
|
89
|
+
} // var countermeasures = function(){...}
|
|
92
90
|
|
|
93
|
-
if (typeof ((_this$options$lock = this.options.lock) === null || _this$options$lock === void 0 ? void 0 : _this$options$lock.countermeasures) === "string") {
|
|
94
|
-
// function countermeasures(){...}
|
|
95
|
-
if (object.type === "FunctionDeclaration" && object.id.type === "Identifier" && object.id.name === this.options.lock.countermeasures) {
|
|
96
|
-
return;
|
|
97
|
-
} // var countermeasures = function(){...}
|
|
98
91
|
|
|
92
|
+
if (parents[0].type === "VariableDeclarator" && parents[0].init === object && parents[0].id.type === "Identifier" && parents[0].id.name === this.options.lock.countermeasures) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
} // Check user option
|
|
99
96
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
|
|
98
|
+
if (!(0, _probability.ComputeProbabilityMap)(this.options.rgf, x => x, object === null || object === void 0 ? void 0 : (_object$id = object.id) === null || _object$id === void 0 ? void 0 : _object$id.name)) return; // Discard functions that use 'eval' function
|
|
99
|
+
|
|
100
|
+
if (object.$requiresEval) return; // Check for 'this', 'arguments' (not allowed!)
|
|
101
|
+
|
|
102
|
+
var isIllegal = false;
|
|
103
|
+
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
104
|
+
if (o.type === "ThisExpression" || o.type === "Super" || o.type === "Identifier" && o.name === "arguments") {
|
|
105
|
+
isIllegal = true;
|
|
106
|
+
return "EXIT";
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
if (isIllegal) return;
|
|
110
|
+
return () => {
|
|
111
|
+
// Make sure function is 'reference-less'
|
|
112
|
+
var definedMap = new Map();
|
|
113
|
+
var isReferenceLess = true;
|
|
114
|
+
var identifierPreventingTransformation;
|
|
115
|
+
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
116
|
+
if (o.type === "Identifier" && !_constants.reservedIdentifiers.has(o.name) && !this.options.globalVariables.has(o.name)) {
|
|
117
|
+
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
118
|
+
|
|
119
|
+
if (!info.spec.isReferenced) {
|
|
120
|
+
return;
|
|
103
121
|
}
|
|
104
122
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* The fnTraverses serves two important purposes
|
|
110
|
-
*
|
|
111
|
-
* - Identify all the variables referenced and defined here
|
|
112
|
-
* - Identify is the 'this' keyword is used anywhere
|
|
113
|
-
*
|
|
114
|
-
* @param o
|
|
115
|
-
* @param p
|
|
116
|
-
* @returns
|
|
117
|
-
*/
|
|
118
|
-
|
|
119
|
-
const fnTraverser = (o, p) => {
|
|
120
|
-
if (o.type == "Identifier" && !_constants.reservedIdentifiers.has(o.name) && !this.options.globalVariables.has(o.name)) {
|
|
121
|
-
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
122
|
-
|
|
123
|
-
if (!info.spec.isReferenced) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
123
|
+
if (info.spec.isDefined) {
|
|
124
|
+
// Add to defined map
|
|
125
|
+
var definingContext = (0, _insert.getDefiningContext)(o, p);
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
if (!definedMap.has(definingContext)) {
|
|
128
|
+
definedMap.set(definingContext, new Set([o.name]));
|
|
129
|
+
} else {
|
|
130
|
+
definedMap.get(definingContext).add(o.name);
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
// This approach is dirty and does not account for hoisted FunctionDeclarations
|
|
134
|
+
var isDefinedAbove = false;
|
|
135
|
+
|
|
136
|
+
for (var pNode of p) {
|
|
137
|
+
if (definedMap.has(pNode)) {
|
|
138
|
+
if (definedMap.get(pNode).has(o.name)) {
|
|
139
|
+
isDefinedAbove = true;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
131
142
|
}
|
|
132
143
|
}
|
|
133
144
|
|
|
134
|
-
if (
|
|
135
|
-
|
|
145
|
+
if (!isDefinedAbove) {
|
|
146
|
+
isReferenceLess = false;
|
|
147
|
+
identifierPreventingTransformation = o.name;
|
|
148
|
+
return "EXIT";
|
|
136
149
|
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
(0, _traverse.walk)(object.params, [object, ...parents], fnTraverser);
|
|
140
|
-
(0, _traverse.walk)(object.body, [object, ...parents], fnTraverser);
|
|
141
|
-
|
|
142
|
-
if (!isBound) {
|
|
143
|
-
var _object$id;
|
|
144
|
-
|
|
145
|
-
defined.forEach(identifier => {
|
|
146
|
-
referenced.delete(identifier);
|
|
147
|
-
});
|
|
148
|
-
object.params.forEach(param => {
|
|
149
|
-
referenced.delete(param.name);
|
|
150
|
-
});
|
|
151
|
-
collect.push({
|
|
152
|
-
location: [object, parents],
|
|
153
|
-
references: referenced,
|
|
154
|
-
name: (_object$id = object.id) === null || _object$id === void 0 ? void 0 : _object$id.name
|
|
155
|
-
});
|
|
156
150
|
}
|
|
157
151
|
}
|
|
158
|
-
});
|
|
152
|
+
}); // This function is not 'reference-less', cannot be RGF'd
|
|
153
|
+
|
|
154
|
+
if (!isReferenceLess) {
|
|
155
|
+
if (object.id) {
|
|
156
|
+
var _object$id2;
|
|
157
|
+
|
|
158
|
+
this.log("".concat(object === null || object === void 0 ? void 0 : (_object$id2 = object.id) === null || _object$id2 === void 0 ? void 0 : _object$id2.name, "() cannot be transformed because of ").concat(identifierPreventingTransformation));
|
|
159
|
+
}
|
|
159
160
|
|
|
160
|
-
if (!collect.length) {
|
|
161
161
|
return;
|
|
162
|
-
}
|
|
162
|
+
} // Since `new Function` is completely isolated, create an entire new obfuscator and run remaining transformations.
|
|
163
|
+
// RGF runs early and needs completed code before converting to a string.
|
|
164
|
+
// (^ the variables haven't been renamed yet)
|
|
163
165
|
|
|
164
|
-
var miss = 0;
|
|
165
|
-
var start = collect.length * 2;
|
|
166
|
-
|
|
167
|
-
while (true) {
|
|
168
|
-
var hit = false;
|
|
169
|
-
collect.forEach(_ref => {
|
|
170
|
-
let {
|
|
171
|
-
name,
|
|
172
|
-
references: references1,
|
|
173
|
-
location: location1
|
|
174
|
-
} = _ref;
|
|
175
|
-
|
|
176
|
-
if (!references1.size && name) {
|
|
177
|
-
collect.forEach(o => {
|
|
178
|
-
if (o.location[0] !== location1[0] && o.references.size && o.references.delete(name)) {
|
|
179
|
-
// console.log(collect);
|
|
180
|
-
hit = true;
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
166
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
167
|
+
var obfuscator = new _obfuscator.default({ ...this.options,
|
|
168
|
+
stringEncoding: false,
|
|
169
|
+
compact: true
|
|
170
|
+
});
|
|
191
171
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
172
|
+
if (obfuscator.options.lock) {
|
|
173
|
+
delete obfuscator.options.lock.countermeasures;
|
|
195
174
|
}
|
|
196
175
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
176
|
+
var transforms = obfuscator.array.filter(x => x.priority > this.priority);
|
|
177
|
+
var embeddedFunctionName = this.getPlaceholder();
|
|
178
|
+
var embeddedFunction = {
|
|
179
|
+
type: "FunctionDeclaration",
|
|
180
|
+
id: (0, _gen.Identifier)(embeddedFunctionName),
|
|
181
|
+
body: (0, _gen.BlockStatement)([...object.body.body]),
|
|
182
|
+
params: object.params,
|
|
183
|
+
async: false,
|
|
184
|
+
generator: false
|
|
185
|
+
};
|
|
186
|
+
var tree = {
|
|
187
|
+
type: "Program",
|
|
188
|
+
body: [embeddedFunction, (0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(embeddedFunctionName), (0, _gen.Literal)("apply"), true), [(0, _gen.ThisExpression)(), (0, _gen.Identifier)("arguments")]))]
|
|
189
|
+
};
|
|
190
|
+
transforms.forEach(transform => {
|
|
191
|
+
transform.apply(tree);
|
|
210
192
|
});
|
|
193
|
+
var toString = (0, _compiler.compileJsSync)(tree, obfuscator.options); // new Function(code)
|
|
211
194
|
|
|
212
|
-
|
|
213
|
-
return;
|
|
214
|
-
} // An array containing all the function declarations
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
var referenceArray = "_" + (0, _random.getRandomString)(10);
|
|
218
|
-
(0, _traverse.walk)(contextObject, contextParents, (o, p) => {
|
|
219
|
-
if (o.type == "Identifier" && !_constants.reservedIdentifiers.has(o.name)) {
|
|
220
|
-
var index = names.get(o.name);
|
|
221
|
-
|
|
222
|
-
if (typeof index === "number") {
|
|
223
|
-
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
224
|
-
|
|
225
|
-
if (info.spec.isReferenced && !info.spec.isDefined) {
|
|
226
|
-
var location = (0, _identifiers.getDefiningIdentifier)(o, p);
|
|
227
|
-
|
|
228
|
-
if (location) {
|
|
229
|
-
var pointingTo = location[0];
|
|
230
|
-
var shouldBe = definingNodes.get(o.name); // console.log(pointingTo, shouldBe);
|
|
231
|
-
|
|
232
|
-
if (pointingTo == shouldBe) {
|
|
233
|
-
this.log(o.name, "->", "".concat(referenceArray, "[").concat(index, "]"));
|
|
234
|
-
var memberExpression = (0, _gen.MemberExpression)((0, _gen.Identifier)(referenceArray), (0, _gen.Literal)(index), true); // Allow re-assignment to the RGF function
|
|
235
|
-
|
|
236
|
-
if (p[0] && p[0].type === "AssignmentExpression" && p[0].left === o) {
|
|
237
|
-
// fn = ...
|
|
238
|
-
this.replace(o, memberExpression);
|
|
239
|
-
} else {
|
|
240
|
-
// fn()
|
|
241
|
-
// fn
|
|
242
|
-
// In most cases the identifier is being used like this (call expression, or referenced to be called later)
|
|
243
|
-
// Replace it with a simple wrapper function that will pass on the reference array
|
|
244
|
-
var conditionalExpression = (0, _gen.ConditionalExpression)((0, _template.default)("typeof ".concat(referenceArray, "[").concat(index, "] === \"function\" && ").concat(referenceArray, "[").concat(index, "][\"").concat(referenceSignatures[index] || "_", "\"]")).single().expression, (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)( // clone() is required!
|
|
245
|
-
(0, _gen.CallExpression)((0, _insert.clone)(memberExpression), [(0, _gen.Identifier)(referenceArray), (0, _gen.SpreadElement)((0, _gen.Identifier)("arguments"))]))]), memberExpression);
|
|
246
|
-
this.replace(o, conditionalExpression);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
var arrayExpression = (0, _gen.ArrayExpression)([]);
|
|
255
|
-
var variableDeclaration = (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)((0, _gen.Identifier)(referenceArray), arrayExpression)]);
|
|
256
|
-
(0, _insert.prepend)(contextObject, variableDeclaration);
|
|
257
|
-
queue.forEach(_ref2 => {
|
|
258
|
-
var _object$id2;
|
|
259
|
-
|
|
260
|
-
let [object, parents] = _ref2;
|
|
261
|
-
var name = object === null || object === void 0 ? void 0 : (_object$id2 = object.id) === null || _object$id2 === void 0 ? void 0 : _object$id2.name;
|
|
262
|
-
var signature = referenceSignatures[names.get(name)];
|
|
263
|
-
var embeddedName = name || this.getPlaceholder(); // Since `new Function` is completely isolated, create an entire new obfuscator and run remaining transformations.
|
|
264
|
-
// RGF runs early and needs completed code before converting to a string.
|
|
265
|
-
// (^ the variables haven't been renamed yet)
|
|
266
|
-
|
|
267
|
-
var obfuscator = new _obfuscator.default({ ...this.options,
|
|
268
|
-
rgf: false,
|
|
269
|
-
globalVariables: new Set([...this.options.globalVariables, referenceArray]),
|
|
270
|
-
lock: {
|
|
271
|
-
integrity: false
|
|
272
|
-
},
|
|
273
|
-
eval: false,
|
|
274
|
-
hideInitializingCode: false,
|
|
275
|
-
stringEncoding: false
|
|
276
|
-
});
|
|
277
|
-
var transforms = Object.values(obfuscator.transforms).filter(x => x.priority > this.priority);
|
|
278
|
-
var embeddedFunction = { ...object,
|
|
279
|
-
type: "FunctionDeclaration",
|
|
280
|
-
id: (0, _gen.Identifier)(embeddedName)
|
|
281
|
-
};
|
|
282
|
-
var tree = {
|
|
283
|
-
type: "Program",
|
|
284
|
-
body: [embeddedFunction, (0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(embeddedName), (0, _gen.Literal)("call"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.SpreadElement)((0, _template.default)("Array.prototype.slice.call(arguments, 1)").single().expression)]))]
|
|
285
|
-
};
|
|
286
|
-
tree.__hiddenDeclarations = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(referenceArray));
|
|
287
|
-
tree.__hiddenDeclarations.hidden = true;
|
|
288
|
-
tree.__hiddenDeclarations.declarations[0].id.hidden = true;
|
|
289
|
-
transforms.forEach(transform => {
|
|
290
|
-
transform.apply(tree);
|
|
291
|
-
}); // Find eval callbacks
|
|
292
|
-
|
|
293
|
-
(0, _traverse.default)(tree, (o, p) => {
|
|
294
|
-
if (o.$eval) {
|
|
295
|
-
return () => {
|
|
296
|
-
o.$eval(o, p);
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
var toString = (0, _compiler.compileJsSync)(tree, this.options);
|
|
301
|
-
var newFunction = (0, _gen.NewExpression)((0, _gen.Identifier)("Function"), [(0, _gen.Literal)(referenceArray), (0, _gen.Literal)(toString)]);
|
|
195
|
+
var newFunctionExpression = (0, _gen.NewExpression)((0, _gen.Identifier)("Function"), [(0, _gen.Literal)(toString)]); // The index where this function is placed in the array
|
|
302
196
|
|
|
303
|
-
|
|
304
|
-
if (!signature) {
|
|
305
|
-
return fn;
|
|
306
|
-
} // This code marks the function object with a unique property
|
|
197
|
+
var newFunctionExpressionIndex = this.arrayExpressionElements.length; // Add it to the array
|
|
307
198
|
|
|
199
|
+
this.arrayExpressionElements.push(newFunctionExpression); // The member expression to retrieve this function
|
|
308
200
|
|
|
309
|
-
|
|
310
|
-
|
|
201
|
+
var memberExpression = (0, _gen.MemberExpression)((0, _gen.Identifier)(this.arrayExpressionName), (0, _gen.Literal)(newFunctionExpressionIndex), true); // Replace based on type
|
|
202
|
+
// (1) Function Declaration:
|
|
203
|
+
// - Replace body with call to new function
|
|
311
204
|
|
|
312
|
-
|
|
313
|
-
|
|
205
|
+
if (object.type === "FunctionDeclaration") {
|
|
206
|
+
object.body = (0, _gen.BlockStatement)([(0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)(memberExpression, (0, _gen.Literal)("apply"), true), [(0, _gen.ThisExpression)(), (0, _gen.Identifier)("arguments")]))]); // The parameters are no longer needed ('arguments' is used to capture them)
|
|
314
207
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
});
|
|
208
|
+
object.params = [];
|
|
209
|
+
return;
|
|
210
|
+
} // (2) Function Expression:
|
|
211
|
+
// - Replace expression with member expression pointing to new function
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
if (object.type === "FunctionExpression") {
|
|
215
|
+
this.replace(object, memberExpression);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
326
218
|
};
|
|
327
219
|
}
|
|
328
220
|
|