js-confuser 1.5.8 → 1.5.9
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/CHANGELOG.md +37 -0
- package/dist/index.js +45 -4
- package/dist/obfuscator.js +10 -5
- package/dist/options.js +2 -3
- package/dist/order.js +3 -3
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -2
- package/dist/transforms/dispatcher.js +3 -3
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +1 -1
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +4 -4
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/flatten.js +73 -50
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/movedDeclarations.js +1 -1
- package/dist/transforms/minify.js +22 -6
- package/dist/transforms/rgf.js +4 -4
- package/dist/transforms/stack.js +1 -1
- package/dist/transforms/string/stringConcealing.js +2 -2
- package/dist/traverse.js +0 -8
- package/dist/util/compare.js +2 -2
- package/dist/util/insert.js +20 -6
- package/package.json +1 -1
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +6 -1
- package/src/options.ts +10 -2
- package/src/order.ts +3 -3
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +14 -2
- package/src/transforms/dispatcher.ts +4 -3
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +1 -1
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +5 -5
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/flatten.ts +181 -128
- package/src/transforms/hexadecimalNumbers.ts +37 -9
- package/src/transforms/identifier/movedDeclarations.ts +1 -1
- package/src/transforms/minify.ts +37 -5
- package/src/transforms/rgf.ts +4 -3
- package/src/transforms/stack.ts +3 -1
- package/src/transforms/string/stringConcealing.ts +2 -2
- package/src/traverse.ts +1 -8
- package/src/types.ts +9 -1
- package/src/util/compare.ts +2 -2
- package/src/util/insert.ts +37 -8
- package/test/code/ES6.src.js +14 -0
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +13 -1
- package/test/transforms/antiTooling.test.ts +30 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +22 -0
- package/test/transforms/dispatcher.test.ts +24 -0
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +146 -3
- package/test/transforms/identifier/renameVariables.test.ts +26 -0
- package/test/transforms/minify.test.ts +66 -0
- package/test/transforms/rgf.test.ts +56 -0
- package/test/transforms/string/stringConcealing.test.ts +33 -0
- package/test/util/compare.test.ts +23 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
# `1.5.9`
|
|
2
|
+
Big update
|
|
3
|
+
|
|
4
|
+
This updates comes with many bug fixes:
|
|
5
|
+
|
|
6
|
+
- Fixed [#72](https://github.com/MichaelXF/js-confuser/issues/72)
|
|
7
|
+
- - ES5 to handle Class Fields
|
|
8
|
+
|
|
9
|
+
Note: The `ES5` option is not meant to replace Babel. It is only intended to undo ES6 features the obfuscator may have added to your code.
|
|
10
|
+
|
|
11
|
+
- Fixed [#74](https://github.com/MichaelXF/js-confuser/issues/74)
|
|
12
|
+
- - Anti Tooling to not break Symbols
|
|
13
|
+
|
|
14
|
+
- Fixed [#75](https://github.com/MichaelXF/js-confuser/issues/75)
|
|
15
|
+
- - Minify to properly handle Object constructors
|
|
16
|
+
|
|
17
|
+
- Fixed [#76](https://github.com/MichaelXF/js-confuser/issues/76)
|
|
18
|
+
- - Minify to not cause syntax errors when objects used `^`, `` ` ``, `[`, `]` as property keys
|
|
19
|
+
|
|
20
|
+
- Fixed [#77](https://github.com/MichaelXF/js-confuser/issues/77)
|
|
21
|
+
- - Dispatcher to not break code that uses generic names like `toString` and `hasOwnProperty`
|
|
22
|
+
|
|
23
|
+
- Fixed [#78](https://github.com/MichaelXF/js-confuser/issues/78)
|
|
24
|
+
- - Object Extraction to not error on objects with spread elements
|
|
25
|
+
|
|
26
|
+
- Fixed [#79](https://github.com/MichaelXF/js-confuser/issues/79)
|
|
27
|
+
- - JsConfuser now supports `BigInt` literals
|
|
28
|
+
|
|
29
|
+
- Fixed [#80](https://github.com/MichaelXF/js-confuser/issues/80)
|
|
30
|
+
- - Rename Variables to not break code that had `var` and `let` variables in the same scope
|
|
31
|
+
|
|
32
|
+
- Fixed [#81](https://github.com/MichaelXF/js-confuser/issues/81)
|
|
33
|
+
- - Control Flow Flattening to not break `typeof` expressions
|
|
34
|
+
|
|
35
|
+
- Fixed [#82](https://github.com/MichaelXF/js-confuser/issues/82)
|
|
36
|
+
- - String Concealing to not break class constructors
|
|
37
|
+
|
|
1
38
|
# `1.5.8`
|
|
2
39
|
Several fixes
|
|
3
40
|
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,8 @@ var _object = require("./util/object");
|
|
|
37
37
|
|
|
38
38
|
var _presets = _interopRequireDefault(require("./presets"));
|
|
39
39
|
|
|
40
|
+
var _perf_hooks = require("perf_hooks");
|
|
41
|
+
|
|
40
42
|
var assert = _interopRequireWildcard(require("assert"));
|
|
41
43
|
|
|
42
44
|
var _options = require("./options");
|
|
@@ -103,7 +105,7 @@ var JsConfuser = async function (code, options) {
|
|
|
103
105
|
return result;
|
|
104
106
|
};
|
|
105
107
|
|
|
106
|
-
|
|
108
|
+
const debugTransformations = async function (code, options) {
|
|
107
109
|
(0, _options.validateOptions)(options);
|
|
108
110
|
options = await (0, _options.correctOptions)(options);
|
|
109
111
|
var frames = [];
|
|
@@ -121,21 +123,60 @@ var debugTransformations = async function debugTransformations(code, options) {
|
|
|
121
123
|
await obfuscator.apply(tree, true);
|
|
122
124
|
return frames;
|
|
123
125
|
};
|
|
126
|
+
/**
|
|
127
|
+
* This method is used by the obfuscator website to display a progress bar and additional information
|
|
128
|
+
* about the obfuscation.
|
|
129
|
+
*
|
|
130
|
+
* @param code - Source code to obfuscate
|
|
131
|
+
* @param options - Options
|
|
132
|
+
* @param callback - Progress callback, called after each transformation
|
|
133
|
+
* @returns
|
|
134
|
+
*/
|
|
135
|
+
|
|
124
136
|
|
|
125
137
|
exports.debugTransformations = debugTransformations;
|
|
126
138
|
|
|
127
|
-
|
|
139
|
+
const debugObfuscation = async function (code, options, callback) {
|
|
140
|
+
const startTime = _perf_hooks.performance.now();
|
|
141
|
+
|
|
128
142
|
(0, _options.validateOptions)(options);
|
|
129
143
|
options = await (0, _options.correctOptions)(options);
|
|
144
|
+
|
|
145
|
+
const beforeParseTime = _perf_hooks.performance.now();
|
|
146
|
+
|
|
130
147
|
var tree = (0, _parser.parseSync)(code);
|
|
148
|
+
const parseTime = _perf_hooks.performance.now() - beforeParseTime;
|
|
131
149
|
var obfuscator = new _obfuscator.default(options);
|
|
132
150
|
var totalTransforms = obfuscator.array.length;
|
|
151
|
+
var transformationTimes = Object.create(null);
|
|
152
|
+
|
|
153
|
+
var currentTransformTime = _perf_hooks.performance.now();
|
|
154
|
+
|
|
133
155
|
obfuscator.on("debug", (name, tree, i) => {
|
|
156
|
+
var nowTime = _perf_hooks.performance.now();
|
|
157
|
+
|
|
158
|
+
transformationTimes[name] = nowTime - currentTransformTime;
|
|
159
|
+
currentTransformTime = nowTime;
|
|
134
160
|
callback(name, i, totalTransforms);
|
|
135
161
|
});
|
|
136
162
|
await obfuscator.apply(tree, true);
|
|
137
|
-
|
|
138
|
-
|
|
163
|
+
|
|
164
|
+
const beforeCompileTime = _perf_hooks.performance.now();
|
|
165
|
+
|
|
166
|
+
var output = await (0, _compiler.default)(tree, options);
|
|
167
|
+
const compileTime = _perf_hooks.performance.now() - beforeCompileTime;
|
|
168
|
+
|
|
169
|
+
const endTime = _perf_hooks.performance.now();
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
obfuscated: output,
|
|
173
|
+
transformationTimes: transformationTimes,
|
|
174
|
+
obfuscationTime: endTime - startTime,
|
|
175
|
+
parseTime: parseTime,
|
|
176
|
+
compileTime: compileTime,
|
|
177
|
+
totalTransforms: totalTransforms,
|
|
178
|
+
totalPossibleTransforms: obfuscator.totalPossibleTransforms
|
|
179
|
+
};
|
|
139
180
|
};
|
|
140
181
|
|
|
141
182
|
exports.debugObfuscation = debugObfuscation;
|
package/dist/obfuscator.js
CHANGED
|
@@ -94,18 +94,23 @@ class Obfuscator extends _events.EventEmitter {
|
|
|
94
94
|
|
|
95
95
|
_defineProperty(this, "generated", void 0);
|
|
96
96
|
|
|
97
|
+
_defineProperty(this, "totalPossibleTransforms", void 0);
|
|
98
|
+
|
|
97
99
|
this.varCount = 0;
|
|
98
100
|
this.transforms = Object.create(null);
|
|
99
101
|
this.generated = new Set();
|
|
102
|
+
this.totalPossibleTransforms = 0;
|
|
100
103
|
this.push(new _preparation.default(this));
|
|
101
104
|
this.push(new _renameLabels.default(this));
|
|
102
105
|
|
|
103
106
|
const test = function (map) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
107
|
+
for (var _len = arguments.length, transformers = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
108
|
+
transformers[_key - 1] = arguments[_key];
|
|
109
|
+
}
|
|
108
110
|
|
|
111
|
+
_this.totalPossibleTransforms += transformers.length;
|
|
112
|
+
|
|
113
|
+
if ((0, _probability.isProbabilityMapProbable)(map)) {
|
|
109
114
|
// options.verbose && console.log("+ Added " + transformer.name);
|
|
110
115
|
transformers.forEach(Transformer => _this.push(new Transformer(_this)));
|
|
111
116
|
} else {// options.verbose && console.log("- Skipped adding " + transformer.name);
|
|
@@ -137,7 +142,7 @@ class Obfuscator extends _events.EventEmitter {
|
|
|
137
142
|
test(options.stack, _stack.default);
|
|
138
143
|
test(true, _antiTooling.default);
|
|
139
144
|
test(options.hideInitializingCode, _hideInitializingCode.default);
|
|
140
|
-
test(
|
|
145
|
+
test(true, _hexadecimalNumbers.default); // BigInt support is included
|
|
141
146
|
|
|
142
147
|
if (options.lock && Object.keys(options.lock).filter(x => x == "domainLock" ? options.lock.domainLock && options.lock.domainLock.length : options.lock[x]).length) {
|
|
143
148
|
test(true, _lock.default);
|
package/dist/options.js
CHANGED
|
@@ -109,8 +109,7 @@ async function correctOptions(options) {
|
|
|
109
109
|
|
|
110
110
|
if (options.lock && options.lock.selfDefending) {
|
|
111
111
|
options.compact = true; // self defending forcibly enables this
|
|
112
|
-
} // options.globalVariables
|
|
113
|
-
// GlobalConcealing implicitly determines a global to be a variable referenced but never defined or modified.
|
|
112
|
+
} // options.globalVariables outlines generic globals that should be present in the execution context
|
|
114
113
|
|
|
115
114
|
|
|
116
115
|
if (!options.hasOwnProperty("globalVariables")) {
|
|
@@ -124,7 +123,7 @@ async function correctOptions(options) {
|
|
|
124
123
|
["global", "Buffer", "require", "process", "__dirname", "__filename"].forEach(x => options.globalVariables.add(x));
|
|
125
124
|
}
|
|
126
125
|
|
|
127
|
-
["globalThis", "console", "parseInt", "parseFloat", "Math", "Promise", "String", "Boolean", "Function", "Object", "Array", "Proxy", "Error", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate", "queueMicrotask", "exports", "module", "isNaN", "isFinite"].forEach(x => options.globalVariables.add(x));
|
|
126
|
+
["globalThis", "console", "parseInt", "parseFloat", "Math", "Promise", "String", "Boolean", "Function", "Object", "Array", "Proxy", "Error", "TypeError", "ReferenceError", "RangeError", "EvalError", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate", "queueMicrotask", "exports", "module", "isNaN", "isFinite", "Set", "Map", "WeakSet", "WeakMap", "Symbol"].forEach(x => options.globalVariables.add(x));
|
|
128
127
|
}
|
|
129
128
|
|
|
130
129
|
return options;
|
package/dist/order.js
CHANGED
|
@@ -33,9 +33,9 @@ exports.ObfuscateOrder = ObfuscateOrder;
|
|
|
33
33
|
ObfuscateOrder[ObfuscateOrder["Shuffle"] = 24] = "Shuffle";
|
|
34
34
|
ObfuscateOrder[ObfuscateOrder["NameRecycling"] = 25] = "NameRecycling";
|
|
35
35
|
ObfuscateOrder[ObfuscateOrder["MovedDeclarations"] = 26] = "MovedDeclarations";
|
|
36
|
-
ObfuscateOrder[ObfuscateOrder["
|
|
37
|
-
ObfuscateOrder[ObfuscateOrder["
|
|
38
|
-
ObfuscateOrder[ObfuscateOrder["
|
|
36
|
+
ObfuscateOrder[ObfuscateOrder["RenameLabels"] = 27] = "RenameLabels";
|
|
37
|
+
ObfuscateOrder[ObfuscateOrder["Minify"] = 28] = "Minify";
|
|
38
|
+
ObfuscateOrder[ObfuscateOrder["RenameVariables"] = 30] = "RenameVariables";
|
|
39
39
|
ObfuscateOrder[ObfuscateOrder["ES5"] = 31] = "ES5";
|
|
40
40
|
ObfuscateOrder[ObfuscateOrder["StringEncoding"] = 32] = "StringEncoding";
|
|
41
41
|
ObfuscateOrder[ObfuscateOrder["AntiTooling"] = 34] = "AntiTooling";
|
|
@@ -50,7 +50,7 @@ class AntiTooling extends _transform.default {
|
|
|
50
50
|
if (flattened.length > 1) {
|
|
51
51
|
flattened[0] = { ...flattened[0]
|
|
52
52
|
};
|
|
53
|
-
this.replace(exprs[0], (0, _gen.ExpressionStatement)((0, _gen.UnaryExpression)((0, _random.choice)(["typeof", "void", "
|
|
53
|
+
this.replace(exprs[0], (0, _gen.ExpressionStatement)((0, _gen.UnaryExpression)((0, _random.choice)(["typeof", "void", "!"]), (0, _gen.SequenceExpression)(flattened))));
|
|
54
54
|
deleteExprs.push(...exprs.slice(1));
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -30,7 +30,8 @@ class ExpressionObfuscation extends _transform.default {
|
|
|
30
30
|
if (stmt.type == "ExpressionStatement") {
|
|
31
31
|
var expr = stmt.expression;
|
|
32
32
|
|
|
33
|
-
if (expr.type == "UnaryExpression" && exprs.length
|
|
33
|
+
if (expr.type == "UnaryExpression" && !(expr.operator === "typeof" && expr.argument.type === "Identifier") && exprs.length // typeof is special
|
|
34
|
+
) {
|
|
34
35
|
expr.argument = (0, _gen.SequenceExpression)([...exprs, { ...expr.argument
|
|
35
36
|
}]);
|
|
36
37
|
deleteExprs.push(...exprs);
|
|
@@ -42,7 +43,8 @@ class ExpressionObfuscation extends _transform.default {
|
|
|
42
43
|
if (exprs.length) {
|
|
43
44
|
if (stmt.type == "IfStatement") {
|
|
44
45
|
if (stmt.test.type == "BinaryExpression" && stmt.test.operator !== "**") {
|
|
45
|
-
if (stmt.test.left.type == "UnaryExpression")
|
|
46
|
+
if (stmt.test.left.type == "UnaryExpression" && !(stmt.test.left.operator === "typeof" && stmt.test.left.argument.type === "Identifier") // typeof is special
|
|
47
|
+
) {
|
|
46
48
|
stmt.test.left.argument = (0, _gen.SequenceExpression)([...exprs, { ...stmt.test.left.argument
|
|
47
49
|
}]);
|
|
48
50
|
} else {
|
|
@@ -80,12 +80,12 @@ class Dispatcher extends _transform.default {
|
|
|
80
80
|
} // Map of FunctionDeclarations
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
var functionDeclarations =
|
|
83
|
+
var functionDeclarations = Object.create(null); // Array of Identifier nodes
|
|
84
84
|
|
|
85
85
|
var identifiers = [];
|
|
86
86
|
var illegalFnNames = new Set(); // New Names for Functions
|
|
87
87
|
|
|
88
|
-
var newFnNames =
|
|
88
|
+
var newFnNames = Object.create(null); // [old name]: randomized name
|
|
89
89
|
|
|
90
90
|
var context = (0, _insert.isVarContext)(object) ? object : (0, _insert.getVarContext)(object, parents);
|
|
91
91
|
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
@@ -264,7 +264,7 @@ class Dispatcher extends _transform.default {
|
|
|
264
264
|
|
|
265
265
|
var newName = newFnNames[o.name];
|
|
266
266
|
|
|
267
|
-
if (!newName) {
|
|
267
|
+
if (!newName || typeof newName !== "string") {
|
|
268
268
|
return;
|
|
269
269
|
}
|
|
270
270
|
|
|
@@ -85,9 +85,13 @@ class AntiClass extends _transform.default {
|
|
|
85
85
|
this.replace(o, (0, _gen.Identifier)(superName));
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
|
-
}
|
|
88
|
+
} // Support class fields
|
|
89
|
+
|
|
89
90
|
|
|
90
|
-
if (methodDefinition.
|
|
91
|
+
if (methodDefinition.type === "PropertyDefinition") {
|
|
92
|
+
var assignmentExpression = (0, _gen.AssignmentExpression)("=", key, value || (0, _gen.Identifier)("undefined"));
|
|
93
|
+
pushingTo.push((0, _gen.ExpressionStatement)(assignmentExpression));
|
|
94
|
+
} else if (methodDefinition.kind == "constructor" || methodDefinition.kind == "method") {
|
|
91
95
|
pushingTo.push((0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", key, value)));
|
|
92
96
|
} else if (methodDefinition.kind == "get" || methodDefinition.kind == "set") {
|
|
93
97
|
var id = (0, _gen.Identifier)(methodDefinition.kind == "get" ? "getters" : "setters");
|
|
@@ -189,7 +189,7 @@ class AntiDestructuring extends _transform.default {
|
|
|
189
189
|
var seq = (0, _gen.SequenceExpression)([(0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(temp), (0, _insert.clone)(extracting) || (0, _gen.Identifier)("undefined")), ...exprs]);
|
|
190
190
|
|
|
191
191
|
if (object.type == "VariableDeclarator") {
|
|
192
|
-
var i = (0, _insert.getIndexDirect)(object, parents);
|
|
192
|
+
var i = (0, _insert.getIndexDirect)(object, parents[0]);
|
|
193
193
|
var extra = Array.from(names).map(x => {
|
|
194
194
|
return {
|
|
195
195
|
type: "VariableDeclarator",
|
package/dist/transforms/eval.js
CHANGED
|
@@ -31,6 +31,17 @@ class Eval extends _transform.default {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
transform(object, parents) {
|
|
34
|
+
// Don't apply to getter/setters or class methods
|
|
35
|
+
if (parents[0]) {
|
|
36
|
+
if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (parents[0].type === "Property" && parents[0].value === object && (parents[0].kind !== "init" || parents[0].method)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
34
45
|
if (!(0, _probability.ComputeProbabilityMap)(this.options.eval, x => x, object.id && object.id.name)) {
|
|
35
46
|
return;
|
|
36
47
|
}
|
|
@@ -113,7 +113,7 @@ class DuplicateLiteralsRemoval extends _transform.default {
|
|
|
113
113
|
var body = [];
|
|
114
114
|
var thisShift = (0, _random.getRandomInteger)(-250, 250); // the name of the getter
|
|
115
115
|
|
|
116
|
-
getterName = this.getPlaceholder();
|
|
116
|
+
getterName = this.getPlaceholder() + "_dLR_" + this.fnGetters.size;
|
|
117
117
|
|
|
118
118
|
if (basedOn) {
|
|
119
119
|
var shift = this.fnShifts.get(basedOn);
|
|
@@ -179,17 +179,17 @@ class DuplicateLiteralsRemoval extends _transform.default {
|
|
|
179
179
|
this.arrayExpression = (0, _gen.ArrayExpression)([]);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
var
|
|
182
|
+
var firstLocation = this.first.get(value);
|
|
183
183
|
|
|
184
|
-
if (
|
|
184
|
+
if (firstLocation) {
|
|
185
185
|
this.first.set(value, null);
|
|
186
186
|
var index = this.map.size;
|
|
187
187
|
(0, _assert.ok)(!this.map.has(value));
|
|
188
188
|
this.map.set(value, index);
|
|
189
|
-
this.toCaller(first[0], first[1], index);
|
|
190
189
|
var pushing = (0, _insert.clone)(object);
|
|
191
190
|
this.arrayExpression.elements.push(pushing);
|
|
192
191
|
(0, _assert.ok)(this.arrayExpression.elements[index] === pushing);
|
|
192
|
+
this.toCaller(firstLocation[0], firstLocation[1], index);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
var index = this.map.get(value);
|
|
@@ -97,7 +97,12 @@ class ObjectExtraction extends _transform.default {
|
|
|
97
97
|
var nonInitOrComputed = object.properties.find(x => x.kind !== "init" || x.computed);
|
|
98
98
|
|
|
99
99
|
if (nonInitOrComputed) {
|
|
100
|
-
|
|
100
|
+
if (nonInitOrComputed.key) {
|
|
101
|
+
this.log(name + " has non-init/computed property: " + nonInitOrComputed.key.name || nonInitOrComputed.key.value);
|
|
102
|
+
} else {
|
|
103
|
+
this.log(name + " has spread-element or other type of property");
|
|
104
|
+
}
|
|
105
|
+
|
|
101
106
|
illegal.add(name);
|
|
102
107
|
return;
|
|
103
108
|
} else {
|
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
+
var _assert = require("assert");
|
|
9
|
+
|
|
8
10
|
var _constants = require("../constants");
|
|
9
11
|
|
|
10
12
|
var _order = require("../order");
|
|
@@ -39,6 +41,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
39
41
|
* return [ref1, ref2, refN, returnValue];
|
|
40
42
|
* }
|
|
41
43
|
* ```
|
|
44
|
+
*
|
|
45
|
+
* Flatten is used to make functions eligible for the RGF transformation.
|
|
42
46
|
*/
|
|
43
47
|
class Flatten extends _transform.default {
|
|
44
48
|
constructor(o) {
|
|
@@ -46,15 +50,12 @@ class Flatten extends _transform.default {
|
|
|
46
50
|
|
|
47
51
|
_defineProperty(this, "definedNames", void 0);
|
|
48
52
|
|
|
49
|
-
_defineProperty(this, "
|
|
50
|
-
|
|
51
|
-
_defineProperty(this, "flatNode", void 0);
|
|
53
|
+
_defineProperty(this, "flattenedFns", void 0);
|
|
52
54
|
|
|
53
55
|
_defineProperty(this, "gen", void 0);
|
|
54
56
|
|
|
55
57
|
this.definedNames = new Map();
|
|
56
|
-
this.
|
|
57
|
-
this.flatNode = null;
|
|
58
|
+
this.flattenedFns = [];
|
|
58
59
|
this.gen = this.getGenerator();
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -79,19 +80,43 @@ class Flatten extends _transform.default {
|
|
|
79
80
|
}
|
|
80
81
|
});
|
|
81
82
|
super.apply(tree);
|
|
83
|
+
|
|
84
|
+
if (this.flattenedFns.length) {
|
|
85
|
+
(0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)(this.flattenedFns));
|
|
86
|
+
}
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
match(object, parents) {
|
|
85
|
-
return object.type == "FunctionDeclaration" && object.body.type == "BlockStatement" && !object.generator && !object.
|
|
90
|
+
return (object.type == "FunctionDeclaration" || object.type === "FunctionExpression") && object.body.type == "BlockStatement" && !object.generator && !object.params.find(x => x.type !== "Identifier");
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
transform(object, parents) {
|
|
89
94
|
return () => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
95
|
+
var _object$id, _parents$, _parents$0$id, _parents$0$id2, _parents$2, _parents$3;
|
|
96
|
+
|
|
97
|
+
if (parents[0]) {
|
|
98
|
+
// Don't change class methods
|
|
99
|
+
if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
|
|
100
|
+
return;
|
|
101
|
+
} // Don't change getter/setter methods
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if (parents[0].type === "Property" && parents[0].value === object && parents[0].kind !== "init") {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
93
107
|
}
|
|
94
108
|
|
|
109
|
+
(0, _assert.ok)(object.type === "FunctionDeclaration" || object.type === "FunctionExpression"); // The name is purely for debugging purposes
|
|
110
|
+
|
|
111
|
+
var currentFnName = object.type === "FunctionDeclaration" ? (_object$id = object.id) === null || _object$id === void 0 ? void 0 : _object$id.name : ((_parents$ = parents[0]) === null || _parents$ === void 0 ? void 0 : _parents$.type) === "VariableDeclarator" && ((_parents$0$id = parents[0].id) === null || _parents$0$id === void 0 ? void 0 : _parents$0$id.type) === "Identifier" && ((_parents$0$id2 = parents[0].id) === null || _parents$0$id2 === void 0 ? void 0 : _parents$0$id2.name);
|
|
112
|
+
|
|
113
|
+
if (((_parents$2 = parents[0]) === null || _parents$2 === void 0 ? void 0 : _parents$2.type) === "Property" && (_parents$3 = parents[0]) !== null && _parents$3 !== void 0 && _parents$3.key) {
|
|
114
|
+
var _parents$4, _parents$4$key, _parents$5, _parents$5$key;
|
|
115
|
+
|
|
116
|
+
currentFnName = currentFnName || String(((_parents$4 = parents[0]) === null || _parents$4 === void 0 ? void 0 : (_parents$4$key = _parents$4.key) === null || _parents$4$key === void 0 ? void 0 : _parents$4$key.name) || ((_parents$5 = parents[0]) === null || _parents$5 === void 0 ? void 0 : (_parents$5$key = _parents$5.key) === null || _parents$5$key === void 0 ? void 0 : _parents$5$key.value));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!currentFnName) currentFnName = "unnamed";
|
|
95
120
|
var defined = new Set();
|
|
96
121
|
var references = new Set();
|
|
97
122
|
var modified = new Set();
|
|
@@ -119,9 +144,7 @@ class Flatten extends _transform.default {
|
|
|
119
144
|
|
|
120
145
|
if (o.hidden) {
|
|
121
146
|
illegal.add(o.name);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (info.spec.isDefined) {
|
|
147
|
+
} else if (info.spec.isDefined) {
|
|
125
148
|
defined.add(o.name);
|
|
126
149
|
} else if (info.spec.isModified) {
|
|
127
150
|
modified.add(o.name);
|
|
@@ -171,9 +194,6 @@ class Flatten extends _transform.default {
|
|
|
171
194
|
return;
|
|
172
195
|
}
|
|
173
196
|
|
|
174
|
-
illegal.forEach(name => {
|
|
175
|
-
defined.delete(name);
|
|
176
|
-
});
|
|
177
197
|
defined.forEach(name => {
|
|
178
198
|
references.delete(name);
|
|
179
199
|
modified.delete(name);
|
|
@@ -186,65 +206,68 @@ class Flatten extends _transform.default {
|
|
|
186
206
|
}
|
|
187
207
|
|
|
188
208
|
var output = Array.from(modified);
|
|
189
|
-
var newName = this.
|
|
190
|
-
var valName = this.getPlaceholder();
|
|
209
|
+
var newName = this.getPlaceholder() + "_flat_" + currentFnName;
|
|
191
210
|
var resultName = this.getPlaceholder();
|
|
192
211
|
var propName = this.gen.generate();
|
|
212
|
+
var newOutputNames = Object.create(null);
|
|
213
|
+
output.forEach(name => {
|
|
214
|
+
newOutputNames[name] = this.gen.generate();
|
|
215
|
+
});
|
|
216
|
+
var returnOutputName = this.gen.generate();
|
|
193
217
|
(0, _insert.getBlockBody)(object.body).push((0, _gen.ReturnStatement)());
|
|
194
218
|
(0, _traverse.walk)(object.body, [object, ...parents], (o, p) => {
|
|
195
219
|
return () => {
|
|
220
|
+
// Change return statements from
|
|
221
|
+
// return (argument)
|
|
222
|
+
// to
|
|
223
|
+
// return [ [modifiedRefs], ]
|
|
196
224
|
if (o.type == "ReturnStatement" && (0, _insert.getVarContext)(o, p) === object) {
|
|
197
|
-
var
|
|
225
|
+
var returnObject = (0, _gen.ObjectExpression)(output.map(outputName => (0, _gen.Property)((0, _gen.Literal)(newOutputNames[outputName]), (0, _gen.Identifier)(outputName), true)));
|
|
198
226
|
|
|
199
227
|
if (o.argument && !(o.argument.type == "Identifier" && o.argument.name == "undefined")) {
|
|
200
|
-
|
|
228
|
+
returnObject.properties.push((0, _gen.Property)((0, _gen.Literal)(returnOutputName), (0, _insert.clone)(o.argument), true));
|
|
201
229
|
}
|
|
202
230
|
|
|
203
|
-
o.argument = (0, _gen.
|
|
204
|
-
o.argument = (0, _gen.AssignmentExpression)("=", (0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(propName), false), o.argument);
|
|
231
|
+
o.argument = (0, _gen.AssignmentExpression)("=", (0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(propName), false), returnObject);
|
|
205
232
|
}
|
|
206
233
|
};
|
|
207
234
|
});
|
|
208
235
|
var newBody = (0, _insert.getBlockBody)(object.body);
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (!this.flatMapName) {
|
|
212
|
-
this.flatMapName = this.getPlaceholder();
|
|
213
|
-
(0, _insert.prepend)(parents[parents.length - 1], (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.flatMapName, this.flatNode = (0, _gen.ObjectExpression)([]))));
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
var newFunctionExpression = (0, _gen.FunctionExpression)([(0, _gen.Identifier)(valName)], newBody);
|
|
236
|
+
var newFunctionExpression = (0, _gen.FunctionExpression)([(0, _gen.ArrayPattern)(input.map(_gen.Identifier)), (0, _gen.ArrayPattern)((0, _insert.clone)(object.params)), (0, _gen.Identifier)(resultName)], newBody);
|
|
217
237
|
newFunctionExpression.async = !!object.async;
|
|
218
238
|
newFunctionExpression.generator = !!object.generator;
|
|
219
239
|
var property = (0, _gen.Property)((0, _gen.Identifier)(newName), newFunctionExpression, false);
|
|
220
240
|
property.kind = "set";
|
|
221
|
-
this.
|
|
222
|
-
var
|
|
223
|
-
var newParamNodes = object.params.map(() => (0, _gen.Identifier)(this.getPlaceholder())); // var result = newFn.call([...refs], ...arguments)
|
|
241
|
+
this.flattenedFns.push((0, _gen.VariableDeclarator)(newName, newFunctionExpression));
|
|
242
|
+
var newParamNodes = object.params.map(() => (0, _gen.Identifier)(this.getPlaceholder())); // result.pop()
|
|
224
243
|
|
|
225
|
-
var
|
|
244
|
+
var getOutputMemberExpression = outputName => (0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(propName), true), (0, _gen.Literal)(outputName), true); // newFn.call([...refs], ...arguments, resultObject)
|
|
226
245
|
|
|
227
|
-
var pop = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Identifier)(propName), false), (0, _gen.Literal)("pop"), true), []); // var result = newFn.call([...refs], ...arguments)
|
|
228
|
-
// modified1 = result.pop();
|
|
229
|
-
// modified2 = result.pop();
|
|
230
|
-
// ...modifiedN = result.pop();...
|
|
231
|
-
//
|
|
232
|
-
// return result.pop()
|
|
233
246
|
|
|
234
|
-
var
|
|
235
|
-
var
|
|
247
|
+
var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(newName), [(0, _gen.ArrayExpression)(input.map(_gen.Identifier)), (0, _gen.ArrayExpression)([...newParamNodes]), (0, _gen.Identifier)(resultName)]);
|
|
248
|
+
var newObjectBody = [// var resultObject = {};
|
|
249
|
+
(0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(resultName, (0, _gen.ObjectExpression)([]))]), (0, _gen.ExpressionStatement)(newFunctionExpression.async ? (0, _gen.AwaitExpression)(callExpression) : callExpression)];
|
|
250
|
+
var outputReversed = [...output].reverse(); // realVar
|
|
251
|
+
|
|
252
|
+
outputReversed.forEach(outputName => {
|
|
253
|
+
newObjectBody.push((0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(outputName), getOutputMemberExpression(newOutputNames[outputName]))));
|
|
254
|
+
}); // DECOY STATEMENTS
|
|
236
255
|
|
|
237
256
|
var decoyKey = this.gen.generate();
|
|
238
|
-
var decoyNodes = [
|
|
257
|
+
var decoyNodes = [// if (result.random) throw result.prop.random
|
|
258
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ThrowStatement)((0, _gen.NewExpression)((0, _gen.Identifier)("Error"), [getOutputMemberExpression(this.gen.generate())]))]), // if (result.random) return true;
|
|
259
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ReturnStatement)((0, _gen.Literal)(true))]), // if (result.random) return result;
|
|
260
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ReturnStatement)((0, _gen.Identifier)(resultName))]), // if (result.random) return result.random;
|
|
261
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(decoyKey), true), [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(decoyKey), true))]), // if(result.random1) return result.random2;
|
|
262
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true))]), // if(result.random) return flatFn;
|
|
263
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ReturnStatement)((0, _gen.Identifier)(newName))]), // if(result.random) flatFn = undefined;
|
|
264
|
+
(0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(this.gen.generate()), true), [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(newName), (0, _gen.Identifier)("undefined")))]), // if(!result) return;
|
|
265
|
+
(0, _gen.IfStatement)((0, _gen.UnaryExpression)("!", (0, _gen.Identifier)(resultName)), [(0, _gen.ReturnStatement)()])].filter(() => Math.random() > 0.25); // if (result.output) return result.output.returnValue;
|
|
266
|
+
// this is the real return statement, it is always added
|
|
267
|
+
|
|
268
|
+
decoyNodes.push((0, _gen.IfStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(resultName), (0, _gen.Literal)(propName), true), [(0, _gen.ReturnStatement)(getOutputMemberExpression(returnOutputName))]));
|
|
239
269
|
(0, _random.shuffle)(decoyNodes);
|
|
240
|
-
|
|
241
|
-
if (Math.random() < 0.5) {
|
|
242
|
-
newObjectBody.push(decoyNode);
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
newObjectBody.push(...outputReversed.map(name => {
|
|
246
|
-
return (0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(name), (0, _insert.clone)(pop)));
|
|
247
|
-
}), (0, _gen.ReturnStatement)((0, _insert.clone)(pop)));
|
|
270
|
+
newObjectBody.push(...decoyNodes);
|
|
248
271
|
object.body = (0, _gen.BlockStatement)(newObjectBody);
|
|
249
272
|
object.params = newParamNodes;
|
|
250
273
|
};
|
|
@@ -13,24 +13,49 @@ var _gen = require("../util/gen");
|
|
|
13
13
|
|
|
14
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* The HexadecimalNumbers transformation converts number literals into the hexadecimal form.
|
|
18
|
+
*
|
|
19
|
+
* This is done by replacing the number literal with an Identifier to ensure escodegen properly outputs it as such
|
|
20
|
+
*
|
|
21
|
+
* This transformation also handles BigInt support, so its always enabled for this reason.
|
|
22
|
+
*/
|
|
16
23
|
class HexadecimalNumbers extends _transform.default {
|
|
17
24
|
constructor(o) {
|
|
18
25
|
super(o, _order.ObfuscateOrder.HexadecimalNumbers);
|
|
19
26
|
}
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
isNumberLiteral(object) {
|
|
22
29
|
return object.type === "Literal" && typeof object.value === "number" && Math.floor(object.value) === object.value;
|
|
23
30
|
}
|
|
24
31
|
|
|
32
|
+
isBigIntLiteral(object) {
|
|
33
|
+
return object.type === "Literal" && typeof object.value === "bigint";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
match(object, parents) {
|
|
37
|
+
return this.options.hexadecimalNumbers && this.isNumberLiteral(object) || this.isBigIntLiteral(object);
|
|
38
|
+
}
|
|
39
|
+
|
|
25
40
|
transform(object, parents) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
if (this.isNumberLiteral(object)) {
|
|
42
|
+
return () => {
|
|
43
|
+
// Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
|
|
44
|
+
// This code handles it regardless
|
|
45
|
+
var isNegative = object.value < 0;
|
|
46
|
+
var hex = Math.abs(object.value).toString(16);
|
|
47
|
+
var newStr = (isNegative ? "-" : "") + "0x" + hex;
|
|
48
|
+
this.replace(object, (0, _gen.Identifier)(newStr));
|
|
49
|
+
};
|
|
50
|
+
} // https://github.com/MichaelXF/js-confuser/issues/79
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if (this.isBigIntLiteral(object)) {
|
|
54
|
+
return () => {
|
|
55
|
+
// Use an Identifier with the raw string
|
|
56
|
+
this.replace(object, (0, _gen.Identifier)(object.raw));
|
|
57
|
+
};
|
|
58
|
+
}
|
|
34
59
|
}
|
|
35
60
|
|
|
36
61
|
}
|
|
@@ -44,7 +44,7 @@ class MovedDeclarations extends _transform.default {
|
|
|
44
44
|
var variableDeclarations = Object.create(null);
|
|
45
45
|
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
46
46
|
if (o.type == "Identifier") {
|
|
47
|
-
if ((0, _scope.getLexicalScope)(o, p) !== object) {
|
|
47
|
+
if (o.hidden || (0, _scope.getLexicalScope)(o, p) !== object) {
|
|
48
48
|
illegal.add(o.name);
|
|
49
49
|
} else {
|
|
50
50
|
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|