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
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _assert = require("assert");
|
|
8
|
+
var _traverse = require("../../traverse");
|
|
9
|
+
var _gen = require("../../util/gen");
|
|
10
|
+
var _guard = require("../../util/guard");
|
|
11
|
+
var _insert = require("../../util/insert");
|
|
12
|
+
var _scope = require("../../util/scope");
|
|
13
|
+
var _transform = _interopRequireDefault(require("../transform"));
|
|
14
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
+
class ClassExtraction extends _transform.default {
|
|
16
|
+
constructor(o) {
|
|
17
|
+
super(o);
|
|
18
|
+
}
|
|
19
|
+
match(object, parents) {
|
|
20
|
+
return object.type === "ClassDeclaration" || object.type === "ClassExpression";
|
|
21
|
+
}
|
|
22
|
+
extractKeyString(property) {
|
|
23
|
+
if (property.key.type === "Identifier" && !property.key.computed) {
|
|
24
|
+
return property.key.name;
|
|
25
|
+
}
|
|
26
|
+
if ((0, _guard.isStringLiteral)(property.key)) {
|
|
27
|
+
return property.key.value;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
transform(object, parents) {
|
|
32
|
+
return () => {
|
|
33
|
+
var _object$id, _object$id2;
|
|
34
|
+
var classBody = object.body;
|
|
35
|
+
var className = ((_object$id = object.id) === null || _object$id === void 0 ? void 0 : _object$id.type) === "Identifier" && ((_object$id2 = object.id) === null || _object$id2 === void 0 ? void 0 : _object$id2.name);
|
|
36
|
+
if (!className) className = this.getPlaceholder();
|
|
37
|
+
var lexicalScope = (0, _scope.getLexicalScope)(object, parents);
|
|
38
|
+
var superMethodName;
|
|
39
|
+
for (var methodDefinition of classBody.body) {
|
|
40
|
+
if (methodDefinition.type === "MethodDefinition" && methodDefinition.value.type === "FunctionExpression") {
|
|
41
|
+
// Don't change constructors calling super()
|
|
42
|
+
if (methodDefinition.kind === "constructor" && object.superClass) continue;
|
|
43
|
+
var functionExpression = methodDefinition.value;
|
|
44
|
+
var fnName = className + "_" + methodDefinition.kind + "_" + this.extractKeyString(methodDefinition) || this.getPlaceholder();
|
|
45
|
+
(0, _traverse.walk)(functionExpression, [methodDefinition, object, ...parents], (o, p) => {
|
|
46
|
+
if (o.type === "Super") {
|
|
47
|
+
var classContext = p.find(node => (0, _insert.isClass)(node));
|
|
48
|
+
if (classContext !== object) return;
|
|
49
|
+
return () => {
|
|
50
|
+
if (!superMethodName) {
|
|
51
|
+
superMethodName = this.getGenerator("randomized").generate();
|
|
52
|
+
}
|
|
53
|
+
var memberExpression = p[0];
|
|
54
|
+
if (memberExpression.type === "CallExpression") {
|
|
55
|
+
throw new Error("Failed to detect super() usage");
|
|
56
|
+
}
|
|
57
|
+
(0, _assert.ok)(memberExpression.type === "MemberExpression");
|
|
58
|
+
var propertyArg = memberExpression.computed ? memberExpression.property : ((0, _assert.ok)(memberExpression.property.type === "Identifier"), (0, _gen.Literal)(memberExpression.property.name));
|
|
59
|
+
var getSuperExpression = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.ThisExpression)(), (0, _gen.Literal)(superMethodName), true), [propertyArg]);
|
|
60
|
+
if (p[1].type === "CallExpression" && p[1].callee === p[0]) {
|
|
61
|
+
getSuperExpression = (0, _gen.CallExpression)((0, _gen.MemberExpression)(getSuperExpression, (0, _gen.Literal)("bind"), true), [(0, _gen.ThisExpression)()]);
|
|
62
|
+
}
|
|
63
|
+
this.replace(p[0], getSuperExpression);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
var originalParams = functionExpression.params;
|
|
68
|
+
var originalBody = functionExpression.body.body;
|
|
69
|
+
functionExpression.body.body = [(0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Literal)("apply"), true), [(0, _gen.ThisExpression)(), (0, _gen.Identifier)("arguments")]))];
|
|
70
|
+
functionExpression.params = [];
|
|
71
|
+
if (methodDefinition.kind === "set") {
|
|
72
|
+
functionExpression.params = [(0, _gen.Identifier)(this.getPlaceholder())];
|
|
73
|
+
}
|
|
74
|
+
(0, _insert.prepend)(lexicalScope, (0, _gen.FunctionDeclaration)(fnName, [...originalParams], [...originalBody]));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (superMethodName) {
|
|
78
|
+
classBody.body.push((0, _gen.MethodDefinition)((0, _gen.Literal)(superMethodName), (0, _gen.FunctionExpression)([(0, _gen.Identifier)("key")], [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Super)(), (0, _gen.Identifier)("key"), true))]), "method", false, true));
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.default = ClassExtraction;
|
|
@@ -4,33 +4,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _transform = _interopRequireDefault(require("../transform"));
|
|
9
|
-
|
|
10
8
|
var _gen = require("../../util/gen");
|
|
11
|
-
|
|
12
9
|
var _insert = require("../../util/insert");
|
|
13
|
-
|
|
14
10
|
var _compare = require("../../util/compare");
|
|
15
|
-
|
|
16
11
|
var _order = require("../../order");
|
|
17
|
-
|
|
18
|
-
var _stringConcealing = require("../string/stringConcealing");
|
|
19
|
-
|
|
20
12
|
var _probability = require("../../probability");
|
|
21
|
-
|
|
22
13
|
var _assert = require("assert");
|
|
23
|
-
|
|
24
14
|
var _random = require("../../util/random");
|
|
25
|
-
|
|
26
15
|
var _traverse = require("../../traverse");
|
|
27
|
-
|
|
28
16
|
var _identifiers = require("../../util/identifiers");
|
|
29
|
-
|
|
30
|
-
function _interopRequireDefault(
|
|
31
|
-
|
|
32
|
-
function
|
|
33
|
-
|
|
17
|
+
var _constants = require("../../constants");
|
|
18
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
|
+
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; }
|
|
20
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
21
|
+
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); }
|
|
34
22
|
/**
|
|
35
23
|
* [Duplicate Literals Removal](https://docs.jscrambler.com/code-integrity/documentation/transformations/duplicate-literals-removal) replaces duplicate literals with a variable name.
|
|
36
24
|
*
|
|
@@ -50,58 +38,49 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
50
38
|
* ```
|
|
51
39
|
*/
|
|
52
40
|
class DuplicateLiteralsRemoval extends _transform.default {
|
|
53
|
-
// The array holding all the duplicate literals
|
|
54
|
-
// The array expression node to be inserted into the program
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Literals in the array
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Literals are saved here the first time they are seen.
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Block -> { functionName, indexShift }
|
|
66
|
-
*/
|
|
67
41
|
constructor(o) {
|
|
68
42
|
super(o, _order.ObfuscateOrder.DuplicateLiteralsRemoval);
|
|
69
|
-
|
|
43
|
+
// The array holding all the duplicate literals
|
|
70
44
|
_defineProperty(this, "arrayName", void 0);
|
|
71
|
-
|
|
45
|
+
// The array expression node to be inserted into the program
|
|
72
46
|
_defineProperty(this, "arrayExpression", void 0);
|
|
73
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Literals in the array
|
|
49
|
+
*/
|
|
74
50
|
_defineProperty(this, "map", void 0);
|
|
75
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Literals are saved here the first time they are seen.
|
|
53
|
+
*/
|
|
76
54
|
_defineProperty(this, "first", void 0);
|
|
77
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Block -> { functionName, indexShift }
|
|
57
|
+
*/
|
|
78
58
|
_defineProperty(this, "functions", void 0);
|
|
79
|
-
|
|
80
59
|
this.map = new Map();
|
|
81
60
|
this.first = new Map();
|
|
82
61
|
this.functions = new Map();
|
|
83
62
|
}
|
|
84
|
-
|
|
85
63
|
apply(tree) {
|
|
86
64
|
super.apply(tree);
|
|
87
|
-
|
|
88
65
|
if (this.arrayName && this.arrayExpression.elements.length > 0) {
|
|
89
66
|
// This function simply returns the array
|
|
90
67
|
var getArrayFn = this.getPlaceholder();
|
|
91
|
-
(0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(getArrayFn, [], [(0, _gen.ReturnStatement)(this.arrayExpression)]));
|
|
68
|
+
(0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(getArrayFn, [], [(0, _gen.ReturnStatement)(this.arrayExpression)]));
|
|
92
69
|
|
|
93
|
-
|
|
70
|
+
// This variable holds the array
|
|
71
|
+
(0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.arrayName, (0, _gen.CallExpression)((0, _gen.Identifier)(getArrayFn), []))));
|
|
94
72
|
|
|
73
|
+
// Create all the functions needed
|
|
95
74
|
for (var blockNode of this.functions.keys()) {
|
|
96
75
|
var {
|
|
97
76
|
functionName,
|
|
98
77
|
indexShift
|
|
99
78
|
} = this.functions.get(blockNode);
|
|
100
79
|
var propertyNode = (0, _gen.BinaryExpression)("-", (0, _gen.Identifier)("index_param"), (0, _gen.Literal)(indexShift));
|
|
101
|
-
var indexRangeInclusive = [0 + indexShift - 1, this.map.size + indexShift];
|
|
102
|
-
|
|
103
|
-
var mangleCount = (0, _random.getRandomInteger)(1, 10);
|
|
80
|
+
var indexRangeInclusive = [0 + indexShift - 1, this.map.size + indexShift];
|
|
104
81
|
|
|
82
|
+
// The function uses mangling to hide the index being accessed
|
|
83
|
+
var mangleCount = (0, _random.getRandomInteger)(1, 5);
|
|
105
84
|
for (var i = 0; i < mangleCount; i++) {
|
|
106
85
|
var operator = (0, _random.choice)([">", "<"]);
|
|
107
86
|
var compareValue = (0, _random.choice)(indexRangeInclusive);
|
|
@@ -110,86 +89,74 @@ class DuplicateLiteralsRemoval extends _transform.default {
|
|
|
110
89
|
var testValue = operator === ">" && compareValue === indexRangeInclusive[0] || operator === "<" && compareValue === indexRangeInclusive[1];
|
|
111
90
|
propertyNode = (0, _gen.ConditionalExpression)(test, testValue ? propertyNode : alternate, !testValue ? propertyNode : alternate);
|
|
112
91
|
}
|
|
113
|
-
|
|
114
92
|
var returnArgument = (0, _gen.MemberExpression)((0, _gen.Identifier)(this.arrayName), propertyNode, true);
|
|
115
93
|
(0, _insert.prepend)(blockNode, (0, _gen.FunctionDeclaration)(functionName, [(0, _gen.Identifier)("index_param")], [(0, _gen.ReturnStatement)(returnArgument)]));
|
|
116
94
|
}
|
|
117
95
|
}
|
|
118
96
|
}
|
|
119
|
-
|
|
120
97
|
match(object, parents) {
|
|
121
|
-
return (0, _compare.isPrimitive)(object) && !(0, _compare.isDirective)(object, parents) && !(0,
|
|
98
|
+
return (0, _compare.isPrimitive)(object) && !(0, _compare.isDirective)(object, parents) && !(0, _compare.isModuleSource)(object, parents) && !parents.find(x => x.$multiTransformSkip);
|
|
122
99
|
}
|
|
100
|
+
|
|
123
101
|
/**
|
|
124
102
|
* Converts ordinary literal to go through a getter function.
|
|
125
103
|
* @param object
|
|
126
104
|
* @param parents
|
|
127
105
|
* @param index
|
|
128
106
|
*/
|
|
129
|
-
|
|
130
|
-
|
|
131
107
|
transformLiteral(object, parents, index) {
|
|
132
|
-
var blockNode = (0, _random.choice)(parents.filter(x => this.functions.has(x)));
|
|
108
|
+
var blockNode = (0, _random.choice)(parents.filter(x => this.functions.has(x)));
|
|
133
109
|
|
|
110
|
+
// Create initial function if none exist
|
|
134
111
|
if (this.functions.size === 0) {
|
|
135
112
|
var root = parents[parents.length - 1];
|
|
136
113
|
var rootFunctionName = this.getPlaceholder() + "_dLR_0";
|
|
137
114
|
this.functions.set(root, {
|
|
138
|
-
functionName: rootFunctionName,
|
|
115
|
+
functionName: rootFunctionName + _constants.predictableFunctionTag,
|
|
139
116
|
indexShift: (0, _random.getRandomInteger)(-100, 100)
|
|
140
117
|
});
|
|
141
118
|
blockNode = root;
|
|
142
|
-
}
|
|
143
|
-
|
|
119
|
+
}
|
|
144
120
|
|
|
121
|
+
// If no function here exist, possibly create new chained function
|
|
145
122
|
var block = (0, _traverse.getBlock)(object, parents);
|
|
146
|
-
|
|
147
123
|
if (!this.functions.has(block) && (0, _random.chance)(50 - this.functions.size)) {
|
|
148
|
-
var newFunctionName = this.getPlaceholder() + "_dLR_" + this.functions.size;
|
|
124
|
+
var newFunctionName = this.getPlaceholder() + "_dLR_" + this.functions.size + _constants.predictableFunctionTag;
|
|
149
125
|
this.functions.set(block, {
|
|
150
126
|
functionName: newFunctionName,
|
|
151
127
|
indexShift: (0, _random.getRandomInteger)(-100, 100)
|
|
152
128
|
});
|
|
153
129
|
blockNode = block;
|
|
154
|
-
}
|
|
155
|
-
|
|
130
|
+
}
|
|
156
131
|
|
|
132
|
+
// Derive the function to call from the selected blockNode
|
|
157
133
|
var {
|
|
158
134
|
functionName,
|
|
159
135
|
indexShift
|
|
160
|
-
} = this.functions.get(blockNode);
|
|
136
|
+
} = this.functions.get(blockNode);
|
|
161
137
|
|
|
138
|
+
// Call the function given it's indexShift
|
|
162
139
|
var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(functionName), [(0, _gen.Literal)(index + indexShift)]);
|
|
163
140
|
this.replaceIdentifierOrLiteral(object, callExpression, parents);
|
|
164
141
|
}
|
|
165
|
-
|
|
166
142
|
transform(object, parents) {
|
|
167
143
|
return () => {
|
|
168
144
|
if (object.type === "Identifier") {
|
|
169
145
|
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
170
|
-
if (info.isLabel || info.spec.isDefined) return;
|
|
146
|
+
if (info.isLabel || info.spec.isDefined || info.spec.isModified) return;
|
|
171
147
|
}
|
|
172
|
-
|
|
173
148
|
if (object.regex) {
|
|
174
149
|
return;
|
|
175
150
|
}
|
|
176
|
-
|
|
177
151
|
if (!(0, _probability.ComputeProbabilityMap)(this.options.duplicateLiteralsRemoval)) {
|
|
178
152
|
return;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (this.map.size > 1000 && (0, _random.chance)(this.map.size / 100)) return;
|
|
183
|
-
|
|
153
|
+
}
|
|
184
154
|
if (this.arrayName && parents[0].object && parents[0].object.name == this.arrayName) {
|
|
185
155
|
return;
|
|
186
156
|
}
|
|
187
|
-
|
|
188
157
|
var stringValue;
|
|
189
|
-
|
|
190
158
|
if (object.type == "Literal") {
|
|
191
159
|
stringValue = typeof object.value + ":" + object.value;
|
|
192
|
-
|
|
193
160
|
if (object.value === null) {
|
|
194
161
|
stringValue = "null:null";
|
|
195
162
|
} else {
|
|
@@ -203,19 +170,16 @@ class DuplicateLiteralsRemoval extends _transform.default {
|
|
|
203
170
|
} else {
|
|
204
171
|
throw new Error("Unsupported primitive type: " + object.type);
|
|
205
172
|
}
|
|
206
|
-
|
|
207
173
|
(0, _assert.ok)(stringValue);
|
|
208
|
-
|
|
209
174
|
if (this.map.has(stringValue) || this.first.has(stringValue)) {
|
|
210
175
|
// Create the array if not already made
|
|
211
176
|
if (!this.arrayName) {
|
|
212
177
|
this.arrayName = this.getPlaceholder();
|
|
213
178
|
this.arrayExpression = (0, _gen.ArrayExpression)([]);
|
|
214
|
-
}
|
|
215
|
-
|
|
179
|
+
}
|
|
216
180
|
|
|
181
|
+
// Delete with first location
|
|
217
182
|
var firstLocation = this.first.get(stringValue);
|
|
218
|
-
|
|
219
183
|
if (firstLocation) {
|
|
220
184
|
var index = this.map.size;
|
|
221
185
|
(0, _assert.ok)(!this.map.has(stringValue));
|
|
@@ -226,18 +190,15 @@ class DuplicateLiteralsRemoval extends _transform.default {
|
|
|
226
190
|
(0, _assert.ok)(this.arrayExpression.elements[index] === pushing);
|
|
227
191
|
this.transformLiteral(firstLocation[0], firstLocation[1], index);
|
|
228
192
|
}
|
|
229
|
-
|
|
230
193
|
var index = this.map.get(stringValue);
|
|
231
194
|
(0, _assert.ok)(typeof index === "number");
|
|
232
195
|
this.transformLiteral(object, parents, index);
|
|
233
196
|
return;
|
|
234
|
-
}
|
|
235
|
-
|
|
197
|
+
}
|
|
236
198
|
|
|
199
|
+
// Save this, maybe a duplicate will be found.
|
|
237
200
|
this.first.set(stringValue, [object, parents]);
|
|
238
201
|
};
|
|
239
202
|
}
|
|
240
|
-
|
|
241
203
|
}
|
|
242
|
-
|
|
243
204
|
exports.default = DuplicateLiteralsRemoval;
|
|
@@ -4,29 +4,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _transform = _interopRequireDefault(require("../transform"));
|
|
9
|
-
|
|
10
8
|
var _traverse = require("../../traverse");
|
|
11
|
-
|
|
12
9
|
var _gen = require("../../util/gen");
|
|
13
|
-
|
|
14
10
|
var _insert = require("../../util/insert");
|
|
15
|
-
|
|
16
11
|
var _order = require("../../order");
|
|
17
|
-
|
|
18
12
|
var _identifiers = require("../../util/identifiers");
|
|
19
|
-
|
|
20
13
|
var _compare = require("../../util/compare");
|
|
21
|
-
|
|
22
14
|
var _probability = require("../../probability");
|
|
23
|
-
|
|
24
15
|
var _assert = require("assert");
|
|
25
|
-
|
|
26
16
|
var _guard = require("../../util/guard");
|
|
27
|
-
|
|
28
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
29
|
-
|
|
17
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
30
18
|
/**
|
|
31
19
|
* Extracts keys out of an object if possible.
|
|
32
20
|
* ```js
|
|
@@ -52,13 +40,12 @@ class ObjectExtraction extends _transform.default {
|
|
|
52
40
|
constructor(o) {
|
|
53
41
|
super(o, _order.ObfuscateOrder.ObjectExtraction);
|
|
54
42
|
}
|
|
55
|
-
|
|
56
43
|
match(object, parents) {
|
|
57
44
|
return (0, _insert.isVarContext)(object);
|
|
58
45
|
}
|
|
59
|
-
|
|
60
46
|
transform(context, contextParents) {
|
|
61
47
|
// ObjectExpression Extractor
|
|
48
|
+
|
|
62
49
|
return () => {
|
|
63
50
|
// First pass through to find the maps
|
|
64
51
|
var objectDefs = Object.create(null);
|
|
@@ -69,45 +56,40 @@ class ObjectExtraction extends _transform.default {
|
|
|
69
56
|
// this.log(object, parents);
|
|
70
57
|
if (parents[0].type == "VariableDeclarator" && parents[0].init == object && parents[0].id.type == "Identifier") {
|
|
71
58
|
var name = parents[0].id.name;
|
|
72
|
-
|
|
73
59
|
if (name) {
|
|
74
60
|
if ((0, _insert.getVarContext)(object, parents) != context) {
|
|
75
61
|
illegal.add(name);
|
|
76
62
|
return;
|
|
77
63
|
}
|
|
78
|
-
|
|
79
64
|
if (!object.properties.length) {
|
|
80
65
|
illegal.add(name);
|
|
81
66
|
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
67
|
+
}
|
|
84
68
|
|
|
69
|
+
// duplicate name
|
|
85
70
|
if (objectDefiningIdentifiers[name]) {
|
|
86
71
|
illegal.add(name);
|
|
87
72
|
return;
|
|
88
|
-
}
|
|
89
|
-
// Change String literals to non-computed
|
|
90
|
-
|
|
73
|
+
}
|
|
91
74
|
|
|
75
|
+
// check for computed properties
|
|
76
|
+
// Change String literals to non-computed
|
|
92
77
|
object.properties.forEach(prop => {
|
|
93
78
|
if (prop.computed && (0, _guard.isStringLiteral)(prop.key)) {
|
|
94
79
|
prop.computed = false;
|
|
95
80
|
}
|
|
96
81
|
});
|
|
97
82
|
var nonInitOrComputed = object.properties.find(x => x.kind !== "init" || x.computed);
|
|
98
|
-
|
|
99
83
|
if (nonInitOrComputed) {
|
|
100
84
|
if (nonInitOrComputed.key) {
|
|
101
85
|
this.log(name + " has non-init/computed property: " + nonInitOrComputed.key.name || nonInitOrComputed.key.value);
|
|
102
86
|
} else {
|
|
103
87
|
this.log(name + " has spread-element or other type of property");
|
|
104
88
|
}
|
|
105
|
-
|
|
106
89
|
illegal.add(name);
|
|
107
90
|
return;
|
|
108
91
|
} else {
|
|
109
92
|
var illegalName = object.properties.map(x => x.computed ? x.key.value : x.key.name || x.key.value).find(x => !x || !(0, _compare.isValidIdentifier)(x));
|
|
110
|
-
|
|
111
93
|
if (illegalName) {
|
|
112
94
|
this.log(name + " has an illegal property '" + illegalName + "'");
|
|
113
95
|
illegal.add(name);
|
|
@@ -120,12 +102,10 @@ class ObjectExtraction extends _transform.default {
|
|
|
120
102
|
return "EXIT";
|
|
121
103
|
}
|
|
122
104
|
});
|
|
123
|
-
|
|
124
105
|
if (isIllegal) {
|
|
125
106
|
illegal.add(name);
|
|
126
107
|
return;
|
|
127
108
|
}
|
|
128
|
-
|
|
129
109
|
objectDefs[name] = [object, parents];
|
|
130
110
|
objectDefiningIdentifiers[name] = [parents[0].id, [...parents]];
|
|
131
111
|
}
|
|
@@ -137,27 +117,24 @@ class ObjectExtraction extends _transform.default {
|
|
|
137
117
|
illegal.forEach(name => {
|
|
138
118
|
delete objectDefs[name];
|
|
139
119
|
delete objectDefiningIdentifiers[name];
|
|
140
|
-
});
|
|
141
|
-
// huge map of changes
|
|
120
|
+
});
|
|
142
121
|
|
|
122
|
+
// this.log("object defs", objectDefs);
|
|
123
|
+
// huge map of changes
|
|
143
124
|
var objectDefChanges = {};
|
|
144
|
-
|
|
145
125
|
if (Object.keys(objectDefs).length) {
|
|
146
126
|
// A second pass through is only required when extracting object keys
|
|
127
|
+
|
|
147
128
|
// Second pass through the exclude the dynamic map (counting keys, re-assigning)
|
|
148
129
|
(0, _traverse.walk)(context, contextParents, (object, parents) => {
|
|
149
130
|
if (object.type == "Identifier") {
|
|
150
131
|
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
151
|
-
|
|
152
132
|
if (!info.spec.isReferenced) {
|
|
153
133
|
return;
|
|
154
134
|
}
|
|
155
|
-
|
|
156
135
|
var def = objectDefs[object.name];
|
|
157
|
-
|
|
158
136
|
if (def) {
|
|
159
137
|
var isIllegal = false;
|
|
160
|
-
|
|
161
138
|
if (info.spec.isDefined) {
|
|
162
139
|
if (objectDefiningIdentifiers[object.name][0] !== object) {
|
|
163
140
|
this.log(object.name, "you can't redefine the object");
|
|
@@ -165,13 +142,11 @@ class ObjectExtraction extends _transform.default {
|
|
|
165
142
|
}
|
|
166
143
|
} else {
|
|
167
144
|
var isMemberExpression = parents[0].type == "MemberExpression" && parents[0].object == object;
|
|
168
|
-
|
|
169
145
|
if (parents.find(x => x.type == "AssignmentExpression") && !isMemberExpression || parents.find(x => x.type == "UnaryExpression" && x.operator == "delete")) {
|
|
170
146
|
this.log(object.name, "you can't re-assign the object");
|
|
171
147
|
isIllegal = true;
|
|
172
148
|
} else if (isMemberExpression) {
|
|
173
149
|
var key = parents[0].property.value || parents[0].property.name;
|
|
174
|
-
|
|
175
150
|
if (parents[0].computed && parents[0].property.type !== "Literal") {
|
|
176
151
|
this.log(object.name, "object[expr] detected, only object['key'] is allowed");
|
|
177
152
|
isIllegal = true;
|
|
@@ -184,15 +159,13 @@ class ObjectExtraction extends _transform.default {
|
|
|
184
159
|
this.log(object.name, "not in initialized object.", def[0].properties, key);
|
|
185
160
|
isIllegal = true;
|
|
186
161
|
}
|
|
187
|
-
|
|
188
162
|
if (!isIllegal && key) {
|
|
189
163
|
// allowed.
|
|
190
164
|
// start the array if first time
|
|
191
165
|
if (!objectDefChanges[object.name]) {
|
|
192
166
|
objectDefChanges[object.name] = [];
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
167
|
+
}
|
|
168
|
+
// add to array
|
|
196
169
|
objectDefChanges[object.name].push({
|
|
197
170
|
key: key,
|
|
198
171
|
object: object,
|
|
@@ -204,7 +177,6 @@ class ObjectExtraction extends _transform.default {
|
|
|
204
177
|
isIllegal = true;
|
|
205
178
|
}
|
|
206
179
|
}
|
|
207
|
-
|
|
208
180
|
if (isIllegal) {
|
|
209
181
|
// this is illegal, delete it from being moved and delete accessor changes from happening
|
|
210
182
|
this.log(object.name + " is illegal");
|
|
@@ -219,14 +191,13 @@ class ObjectExtraction extends _transform.default {
|
|
|
219
191
|
//continue;
|
|
220
192
|
return;
|
|
221
193
|
}
|
|
222
|
-
|
|
223
194
|
var [object, parents] = objectDefs[name];
|
|
224
195
|
var declarator = parents[0];
|
|
225
196
|
var declaration = parents[2];
|
|
226
197
|
(0, _assert.ok)(declarator.type === "VariableDeclarator");
|
|
227
198
|
(0, _assert.ok)(declaration.type === "VariableDeclaration");
|
|
228
|
-
var properties = object.properties;
|
|
229
|
-
|
|
199
|
+
var properties = object.properties;
|
|
200
|
+
// change the prop names while extracting
|
|
230
201
|
var newPropNames = {};
|
|
231
202
|
var variableDeclarators = [];
|
|
232
203
|
properties.forEach(property => {
|
|
@@ -234,41 +205,38 @@ class ObjectExtraction extends _transform.default {
|
|
|
234
205
|
var nn = name + "_" + keyName;
|
|
235
206
|
newPropNames[keyName] = nn;
|
|
236
207
|
var v = property.value;
|
|
237
|
-
variableDeclarators.push((0, _gen.VariableDeclarator)(nn, this.addComment(v,
|
|
208
|
+
variableDeclarators.push((0, _gen.VariableDeclarator)(nn, this.addComment(v, `${name}.${keyName}`)));
|
|
238
209
|
});
|
|
239
210
|
declaration.declarations.splice(declaration.declarations.indexOf(declarator), 1, ...variableDeclarators);
|
|
240
211
|
|
|
212
|
+
// const can only be safely changed to let
|
|
241
213
|
if (declaration.kind === "const") {
|
|
242
|
-
declaration.kind = "
|
|
243
|
-
}
|
|
244
|
-
|
|
214
|
+
declaration.kind = "let";
|
|
215
|
+
}
|
|
245
216
|
|
|
217
|
+
// update all identifiers that pointed to the old object
|
|
246
218
|
objectDefChanges[name] && objectDefChanges[name].forEach(change => {
|
|
247
219
|
if (!change.key) {
|
|
248
220
|
this.error(new Error("key is undefined"));
|
|
249
221
|
}
|
|
250
|
-
|
|
251
222
|
if (newPropNames[change.key]) {
|
|
252
223
|
var memberExpression = change.parents[0];
|
|
253
|
-
|
|
254
224
|
if (memberExpression.type == "MemberExpression") {
|
|
255
|
-
this.replace(memberExpression, this.addComment((0, _gen.Identifier)(newPropNames[change.key]),
|
|
225
|
+
this.replace(memberExpression, this.addComment((0, _gen.Identifier)(newPropNames[change.key]), `Original Accessor: ${name}.${change.key}`));
|
|
256
226
|
} else {
|
|
257
227
|
// Provide error with more information:
|
|
258
228
|
console.log(memberExpression);
|
|
259
|
-
this.error(new Error(
|
|
229
|
+
this.error(new Error(`should be MemberExpression, found type=${memberExpression.type}`));
|
|
260
230
|
}
|
|
261
231
|
} else {
|
|
262
232
|
console.log(objectDefChanges[name], newPropNames);
|
|
263
|
-
this.error(new Error("
|
|
233
|
+
this.error(new Error(`"${change.key}" not found in [${Object.keys(newPropNames).join(", ")}] while flattening ${name}.`));
|
|
264
234
|
}
|
|
265
235
|
});
|
|
266
|
-
this.log(
|
|
236
|
+
this.log(`Extracted ${Object.keys(newPropNames).length} properties from ${name}, affecting ${Object.keys(objectDefChanges[name] || {}).length} line(s) of code.`);
|
|
267
237
|
});
|
|
268
238
|
}
|
|
269
239
|
};
|
|
270
240
|
}
|
|
271
|
-
|
|
272
241
|
}
|
|
273
|
-
|
|
274
242
|
exports.default = ObjectExtraction;
|
|
@@ -4,19 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _order = require("../order");
|
|
9
|
-
|
|
10
8
|
var _gen = require("../util/gen");
|
|
11
|
-
|
|
12
9
|
var _stringEncoding = _interopRequireDefault(require("./string/stringEncoding"));
|
|
13
|
-
|
|
14
10
|
var _transform = _interopRequireDefault(require("./transform"));
|
|
15
|
-
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
function
|
|
19
|
-
|
|
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); }
|
|
20
15
|
/**
|
|
21
16
|
* The Finalizer is the last transformation before the code is ready to be generated.
|
|
22
17
|
*
|
|
@@ -32,24 +27,18 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
32
27
|
class Finalizer extends _transform.default {
|
|
33
28
|
constructor(o) {
|
|
34
29
|
super(o, _order.ObfuscateOrder.Finalizer);
|
|
35
|
-
|
|
36
30
|
_defineProperty(this, "stringEncoding", void 0);
|
|
37
|
-
|
|
38
31
|
this.stringEncoding = new _stringEncoding.default(o);
|
|
39
32
|
}
|
|
40
|
-
|
|
41
33
|
isNumberLiteral(object) {
|
|
42
34
|
return object.type === "Literal" && typeof object.value === "number" && Math.floor(object.value) === object.value;
|
|
43
35
|
}
|
|
44
|
-
|
|
45
36
|
isBigIntLiteral(object) {
|
|
46
37
|
return object.type === "Literal" && typeof object.value === "bigint";
|
|
47
38
|
}
|
|
48
|
-
|
|
49
39
|
match(object, parents) {
|
|
50
40
|
return object.type === "Literal";
|
|
51
41
|
}
|
|
52
|
-
|
|
53
42
|
transform(object, parents) {
|
|
54
43
|
// Hexadecimal Numbers
|
|
55
44
|
if (this.options.hexadecimalNumbers && this.isNumberLiteral(object)) {
|
|
@@ -61,9 +50,9 @@ class Finalizer extends _transform.default {
|
|
|
61
50
|
var newStr = (isNegative ? "-" : "") + "0x" + hex;
|
|
62
51
|
this.replace(object, (0, _gen.Identifier)(newStr));
|
|
63
52
|
};
|
|
64
|
-
}
|
|
65
|
-
|
|
53
|
+
}
|
|
66
54
|
|
|
55
|
+
// BigInt support
|
|
67
56
|
if (this.isBigIntLiteral(object)) {
|
|
68
57
|
// https://github.com/MichaelXF/js-confuser/issues/79
|
|
69
58
|
return () => {
|
|
@@ -71,12 +60,9 @@ class Finalizer extends _transform.default {
|
|
|
71
60
|
this.replace(object, (0, _gen.Identifier)(object.raw));
|
|
72
61
|
};
|
|
73
62
|
}
|
|
74
|
-
|
|
75
63
|
if (this.options.stringEncoding && this.stringEncoding.match(object, parents)) {
|
|
76
64
|
return this.stringEncoding.transform(object, parents);
|
|
77
65
|
}
|
|
78
66
|
}
|
|
79
|
-
|
|
80
67
|
}
|
|
81
|
-
|
|
82
68
|
exports.default = Finalizer;
|