js-confuser 1.7.3 → 2.0.0-alpha.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/ISSUE_TEMPLATE/bug_report.md +6 -4
- package/CHANGELOG.md +70 -0
- package/Migration.md +57 -0
- package/README.md +23 -929
- package/dist/constants.js +65 -14
- package/dist/index.js +108 -160
- package/dist/obfuscator.js +316 -118
- package/dist/options.js +1 -119
- package/dist/order.js +30 -30
- package/dist/presets.js +47 -45
- package/dist/probability.js +25 -32
- package/dist/templates/bufferToStringTemplate.js +9 -0
- package/dist/templates/deadCodeTemplates.js +9 -0
- package/dist/templates/getGlobalTemplate.js +19 -0
- package/dist/templates/integrityTemplate.js +30 -0
- package/dist/templates/setFunctionLengthTemplate.js +9 -0
- package/dist/templates/stringCompressionTemplate.js +10 -0
- package/dist/templates/tamperProtectionTemplates.js +21 -0
- package/dist/templates/template.js +199 -184
- package/dist/transforms/astScrambler.js +100 -0
- package/dist/transforms/calculator.js +70 -127
- package/dist/transforms/controlFlowFlattening.js +1182 -0
- package/dist/transforms/deadCode.js +62 -587
- package/dist/transforms/dispatcher.js +300 -313
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +88 -189
- package/dist/transforms/extraction/objectExtraction.js +131 -215
- package/dist/transforms/finalizer.js +56 -59
- package/dist/transforms/flatten.js +275 -276
- package/dist/transforms/functionOutlining.js +230 -0
- package/dist/transforms/identifier/globalConcealing.js +214 -135
- package/dist/transforms/identifier/movedDeclarations.js +167 -91
- package/dist/transforms/identifier/renameVariables.js +239 -193
- package/dist/transforms/lock/integrity.js +61 -184
- package/dist/transforms/lock/lock.js +261 -387
- package/dist/transforms/minify.js +431 -436
- package/dist/transforms/opaquePredicates.js +65 -118
- package/dist/transforms/pack.js +160 -0
- package/dist/transforms/plugin.js +179 -0
- package/dist/transforms/preparation.js +261 -173
- package/dist/transforms/renameLabels.js +132 -56
- package/dist/transforms/rgf.js +140 -267
- package/dist/transforms/shuffle.js +52 -145
- package/dist/transforms/string/encoding.js +44 -175
- package/dist/transforms/string/stringCompression.js +79 -155
- package/dist/transforms/string/stringConcealing.js +189 -225
- package/dist/transforms/string/stringEncoding.js +32 -40
- package/dist/transforms/string/stringSplitting.js +54 -55
- package/dist/transforms/variableMasking.js +232 -0
- package/dist/utils/ControlObject.js +125 -0
- package/dist/utils/IntGen.js +46 -0
- package/dist/utils/NameGen.js +106 -0
- package/dist/utils/ast-utils.js +560 -0
- package/dist/utils/function-utils.js +56 -0
- package/dist/utils/gen-utils.js +48 -0
- package/dist/utils/node.js +77 -0
- package/dist/utils/object-utils.js +21 -0
- package/dist/utils/random-utils.js +91 -0
- package/dist/utils/static-utils.js +64 -0
- package/dist/validateOptions.js +122 -0
- package/index.d.ts +1 -17
- package/package.json +27 -22
- package/src/constants.ts +139 -82
- package/src/index.ts +70 -165
- package/src/obfuscationResult.ts +43 -0
- package/src/obfuscator.ts +328 -135
- package/src/options.ts +149 -658
- package/src/order.ts +14 -14
- package/src/presets.ts +39 -34
- package/src/probability.ts +21 -36
- package/src/templates/bufferToStringTemplate.ts +57 -0
- package/src/templates/deadCodeTemplates.ts +1185 -0
- package/src/templates/getGlobalTemplate.ts +72 -0
- package/src/templates/integrityTemplate.ts +69 -0
- package/src/templates/setFunctionLengthTemplate.ts +11 -0
- package/src/templates/stringCompressionTemplate.ts +42 -0
- package/src/templates/tamperProtectionTemplates.ts +116 -0
- package/src/templates/template.ts +149 -157
- package/src/transforms/astScrambler.ts +99 -0
- package/src/transforms/calculator.ts +96 -226
- package/src/transforms/controlFlowFlattening.ts +1594 -0
- package/src/transforms/deadCode.ts +85 -676
- package/src/transforms/dispatcher.ts +431 -640
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +147 -295
- package/src/transforms/extraction/objectExtraction.ts +160 -333
- package/src/transforms/finalizer.ts +63 -64
- package/src/transforms/flatten.ts +439 -557
- package/src/transforms/functionOutlining.ts +225 -0
- package/src/transforms/identifier/globalConcealing.ts +255 -266
- package/src/transforms/identifier/movedDeclarations.ts +228 -142
- package/src/transforms/identifier/renameVariables.ts +250 -271
- package/src/transforms/lock/integrity.ts +85 -263
- package/src/transforms/lock/lock.ts +338 -579
- package/src/transforms/minify.ts +523 -663
- package/src/transforms/opaquePredicates.ts +90 -229
- package/src/transforms/pack.ts +195 -0
- package/src/transforms/plugin.ts +185 -0
- package/src/transforms/preparation.ts +337 -231
- package/src/transforms/renameLabels.ts +176 -77
- package/src/transforms/rgf.ts +293 -424
- package/src/transforms/shuffle.ts +80 -254
- package/src/transforms/string/encoding.ts +20 -126
- package/src/transforms/string/stringCompression.ts +117 -307
- package/src/transforms/string/stringConcealing.ts +254 -342
- package/src/transforms/string/stringEncoding.ts +28 -47
- package/src/transforms/string/stringSplitting.ts +61 -75
- package/src/transforms/variableMasking.ts +257 -0
- package/src/utils/ControlObject.ts +141 -0
- package/src/utils/IntGen.ts +33 -0
- package/src/utils/NameGen.ts +106 -0
- package/src/utils/ast-utils.ts +667 -0
- package/src/utils/function-utils.ts +50 -0
- package/src/utils/gen-utils.ts +48 -0
- package/src/utils/node.ts +78 -0
- package/src/utils/object-utils.ts +21 -0
- package/src/utils/random-utils.ts +79 -0
- package/src/utils/static-utils.ts +66 -0
- package/src/validateOptions.ts +256 -0
- package/tsconfig.json +13 -8
- package/babel.config.js +0 -12
- package/dev.js +0 -8
- package/dist/compiler.js +0 -34
- package/dist/parser.js +0 -59
- package/dist/precedence.js +0 -66
- package/dist/templates/bufferToString.js +0 -129
- package/dist/templates/core.js +0 -35
- package/dist/templates/crash.js +0 -28
- package/dist/templates/es5.js +0 -137
- package/dist/templates/functionLength.js +0 -34
- package/dist/templates/globals.js +0 -9
- package/dist/transforms/antiTooling.js +0 -88
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +0 -1287
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +0 -131
- package/dist/transforms/es5/antiClass.js +0 -164
- package/dist/transforms/es5/antiDestructuring.js +0 -193
- package/dist/transforms/es5/antiES6Object.js +0 -185
- package/dist/transforms/es5/antiSpreadOperator.js +0 -35
- package/dist/transforms/es5/antiTemplate.js +0 -66
- package/dist/transforms/es5/es5.js +0 -123
- package/dist/transforms/extraction/classExtraction.js +0 -83
- package/dist/transforms/identifier/globalAnalysis.js +0 -83
- package/dist/transforms/identifier/variableAnalysis.js +0 -104
- package/dist/transforms/lock/antiDebug.js +0 -76
- package/dist/transforms/stack.js +0 -349
- package/dist/transforms/transform.js +0 -372
- package/dist/traverse.js +0 -110
- package/dist/util/compare.js +0 -145
- package/dist/util/gen.js +0 -564
- package/dist/util/guard.js +0 -14
- package/dist/util/identifiers.js +0 -355
- package/dist/util/insert.js +0 -362
- package/dist/util/math.js +0 -19
- package/dist/util/object.js +0 -40
- package/dist/util/random.js +0 -156
- package/dist/util/scope.js +0 -20
- package/docs/ControlFlowFlattening.md +0 -595
- package/docs/Countermeasures.md +0 -70
- package/docs/ES5.md +0 -197
- package/docs/Integrity.md +0 -82
- package/docs/RGF.md +0 -424
- package/docs/RenameVariables.md +0 -116
- package/docs/TamperProtection.md +0 -100
- package/docs/Template.md +0 -117
- package/samples/example.js +0 -15
- package/samples/high.js +0 -1
- package/samples/input.js +0 -3
- package/samples/javascriptobfuscator.com.js +0 -8
- package/samples/jscrambler_advanced.js +0 -1894
- package/samples/jscrambler_light.js +0 -1134
- package/samples/low.js +0 -1
- package/samples/medium.js +0 -1
- package/samples/obfuscator.io.js +0 -1686
- package/samples/preemptive.com.js +0 -16
- package/src/compiler.ts +0 -35
- package/src/parser.ts +0 -49
- package/src/precedence.ts +0 -61
- package/src/templates/bufferToString.ts +0 -136
- package/src/templates/core.ts +0 -29
- package/src/templates/crash.ts +0 -23
- package/src/templates/es5.ts +0 -131
- package/src/templates/functionLength.ts +0 -32
- package/src/templates/globals.ts +0 -3
- package/src/transforms/antiTooling.ts +0 -102
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +0 -2153
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +0 -179
- package/src/transforms/es5/antiClass.ts +0 -276
- package/src/transforms/es5/antiDestructuring.ts +0 -294
- package/src/transforms/es5/antiES6Object.ts +0 -267
- package/src/transforms/es5/antiSpreadOperator.ts +0 -56
- package/src/transforms/es5/antiTemplate.ts +0 -98
- package/src/transforms/es5/es5.ts +0 -149
- package/src/transforms/extraction/classExtraction.ts +0 -168
- package/src/transforms/identifier/globalAnalysis.ts +0 -102
- package/src/transforms/identifier/variableAnalysis.ts +0 -118
- package/src/transforms/lock/antiDebug.ts +0 -112
- package/src/transforms/stack.ts +0 -557
- package/src/transforms/transform.ts +0 -441
- package/src/traverse.ts +0 -120
- package/src/types.ts +0 -133
- package/src/util/compare.ts +0 -181
- package/src/util/gen.ts +0 -651
- package/src/util/guard.ts +0 -17
- package/src/util/identifiers.ts +0 -494
- package/src/util/insert.ts +0 -419
- package/src/util/math.ts +0 -15
- package/src/util/object.ts +0 -39
- package/src/util/random.ts +0 -221
- package/src/util/scope.ts +0 -21
- package/test/code/Cash.src.js +0 -1011
- package/test/code/Cash.test.ts +0 -132
- package/test/code/Dynamic.src.js +0 -118
- package/test/code/Dynamic.test.ts +0 -49
- package/test/code/ES6.src.js +0 -235
- package/test/code/ES6.test.ts +0 -42
- package/test/code/NewFeatures.test.ts +0 -19
- package/test/code/StrictMode.src.js +0 -65
- package/test/code/StrictMode.test.js +0 -37
- package/test/compare.test.ts +0 -104
- package/test/index.test.ts +0 -249
- package/test/options.test.ts +0 -150
- package/test/presets.test.ts +0 -22
- package/test/probability.test.ts +0 -44
- package/test/templates/template.test.ts +0 -224
- package/test/transforms/antiTooling.test.ts +0 -52
- package/test/transforms/calculator.test.ts +0 -78
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +0 -1274
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +0 -192
- package/test/transforms/deadCode.test.ts +0 -85
- package/test/transforms/dispatcher.test.ts +0 -457
- package/test/transforms/es5/antiClass.test.ts +0 -427
- package/test/transforms/es5/antiDestructuring.test.ts +0 -157
- package/test/transforms/es5/antiES6Object.test.ts +0 -245
- package/test/transforms/es5/antiTemplate.test.ts +0 -116
- package/test/transforms/es5/es5.test.ts +0 -110
- package/test/transforms/extraction/classExtraction.test.ts +0 -86
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +0 -200
- package/test/transforms/extraction/objectExtraction.test.ts +0 -491
- package/test/transforms/flatten.test.ts +0 -721
- package/test/transforms/hexadecimalNumbers.test.ts +0 -62
- package/test/transforms/identifier/globalConcealing.test.ts +0 -142
- package/test/transforms/identifier/movedDeclarations.test.ts +0 -275
- package/test/transforms/identifier/renameVariables.test.ts +0 -695
- package/test/transforms/lock/antiDebug.test.ts +0 -66
- package/test/transforms/lock/browserLock.test.ts +0 -129
- package/test/transforms/lock/countermeasures.test.ts +0 -100
- package/test/transforms/lock/integrity.test.ts +0 -161
- package/test/transforms/lock/lock.test.ts +0 -204
- package/test/transforms/lock/osLock.test.ts +0 -312
- package/test/transforms/lock/selfDefending.test.ts +0 -68
- package/test/transforms/lock/tamperProtection.test.ts +0 -336
- package/test/transforms/minify.test.ts +0 -575
- package/test/transforms/opaquePredicates.test.ts +0 -43
- package/test/transforms/preparation.test.ts +0 -157
- package/test/transforms/renameLabels.test.ts +0 -95
- package/test/transforms/rgf.test.ts +0 -378
- package/test/transforms/shuffle.test.ts +0 -135
- package/test/transforms/stack.test.ts +0 -573
- package/test/transforms/string/stringCompression.test.ts +0 -120
- package/test/transforms/string/stringConcealing.test.ts +0 -299
- package/test/transforms/string/stringEncoding.test.ts +0 -95
- package/test/transforms/string/stringSplitting.test.ts +0 -135
- package/test/transforms/transform.test.ts +0 -66
- package/test/traverse.test.ts +0 -139
- package/test/util/compare.test.ts +0 -34
- package/test/util/gen.test.ts +0 -121
- package/test/util/identifiers.test.ts +0 -253
- package/test/util/insert.test.ts +0 -142
- package/test/util/math.test.ts +0 -5
- package/test/util/random.test.ts +0 -71
- /package/dist/{types.js → obfuscationResult.js} +0 -0
|
@@ -1,360 +1,187 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import {
|
|
1
|
+
import { NodePath } from "@babel/core";
|
|
2
|
+
import { PluginArg, PluginObject } from "../plugin";
|
|
3
|
+
import { Order } from "../../order";
|
|
4
|
+
import * as t from "@babel/types";
|
|
5
|
+
import {
|
|
6
|
+
getMemberExpressionPropertyAsString,
|
|
7
|
+
getObjectPropertyAsString,
|
|
8
|
+
getParentFunctionOrProgram,
|
|
9
|
+
} from "../../utils/ast-utils";
|
|
10
|
+
import { computeProbabilityMap } from "../../probability";
|
|
11
|
+
|
|
12
|
+
export default ({ Plugin }: PluginArg): PluginObject => {
|
|
13
|
+
const me = Plugin(Order.ObjectExtraction, {
|
|
14
|
+
changeData: {
|
|
15
|
+
objects: 0,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
visitor: {
|
|
21
|
+
Program: {
|
|
22
|
+
enter(path) {
|
|
23
|
+
path.scope.crawl();
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
VariableDeclaration(varDecPath) {
|
|
27
|
+
if (varDecPath.node.declarations.length !== 1) return;
|
|
28
|
+
const declaration = varDecPath.get(
|
|
29
|
+
"declarations.0"
|
|
30
|
+
) as NodePath<t.VariableDeclarator>;
|
|
31
|
+
|
|
32
|
+
// Must be simple variable declaration (No destructuring)
|
|
33
|
+
const identifier = declaration.get("id");
|
|
34
|
+
if (!identifier.isIdentifier()) return;
|
|
35
|
+
|
|
36
|
+
// Must be an object expression
|
|
37
|
+
const objectExpression = declaration.get("init");
|
|
38
|
+
if (!objectExpression.isObjectExpression()) return;
|
|
39
|
+
|
|
40
|
+
// Not allowed to reassign the object
|
|
41
|
+
const binding = varDecPath.scope.getBinding(identifier.node.name);
|
|
42
|
+
if (!binding || binding.constantViolations.length > 0) return;
|
|
43
|
+
|
|
44
|
+
var pendingReplacements: {
|
|
45
|
+
path: NodePath<t.MemberExpression>;
|
|
46
|
+
replaceWith: t.Expression;
|
|
47
|
+
}[] = [];
|
|
48
|
+
|
|
49
|
+
const newObjectName = me.getPlaceholder() + "_" + identifier.node.name;
|
|
50
|
+
const newPropertyMappings = new Map<string, string>();
|
|
51
|
+
|
|
52
|
+
// Create new property names from the original object properties
|
|
53
|
+
var newDeclarations: t.VariableDeclarator[] = [];
|
|
54
|
+
for (var property of objectExpression.get("properties")) {
|
|
55
|
+
if (!property.isObjectProperty()) return;
|
|
56
|
+
const propertyKey = getObjectPropertyAsString(property.node);
|
|
57
|
+
if (!propertyKey) {
|
|
58
|
+
// Property key is not a static string, not allowed
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
11
61
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* var utils_isString = x=>typeof x === "string";
|
|
26
|
-
* var utils_isBoolean = x=>typeof x === "boolean"
|
|
27
|
-
*
|
|
28
|
-
* if ( utils_isString("Hello") ) {
|
|
29
|
-
* ...
|
|
30
|
-
* }
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export default class ObjectExtraction extends Transform {
|
|
34
|
-
constructor(o) {
|
|
35
|
-
super(o, ObfuscateOrder.ObjectExtraction);
|
|
36
|
-
}
|
|
62
|
+
let newPropertyName = newPropertyMappings.get(propertyKey);
|
|
63
|
+
if (newPropertyName) {
|
|
64
|
+
// Duplicate property, not allowed
|
|
65
|
+
return;
|
|
66
|
+
} else {
|
|
67
|
+
newPropertyName =
|
|
68
|
+
newObjectName +
|
|
69
|
+
"_" +
|
|
70
|
+
(t.isValidIdentifier(propertyKey)
|
|
71
|
+
? propertyKey
|
|
72
|
+
: me.getPlaceholder());
|
|
73
|
+
newPropertyMappings.set(propertyKey, newPropertyName);
|
|
74
|
+
}
|
|
37
75
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
76
|
+
// Check function for referencing 'this'
|
|
77
|
+
const value = property.get("value");
|
|
78
|
+
if (value.isFunction()) {
|
|
79
|
+
var referencesThis = false;
|
|
41
80
|
|
|
42
|
-
|
|
43
|
-
|
|
81
|
+
value.traverse({
|
|
82
|
+
ThisExpression(thisPath) {
|
|
83
|
+
referencesThis = true;
|
|
84
|
+
},
|
|
85
|
+
});
|
|
44
86
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
87
|
+
if (referencesThis) {
|
|
88
|
+
// Function references 'this', not allowed
|
|
89
|
+
// When extracted, this will not refer to the original object
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
50
93
|
|
|
51
|
-
|
|
94
|
+
newDeclarations.push(
|
|
95
|
+
t.variableDeclarator(
|
|
96
|
+
t.identifier(newPropertyName),
|
|
97
|
+
value.node as t.Expression
|
|
98
|
+
)
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
var isObjectSafe = true;
|
|
52
103
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (name) {
|
|
63
|
-
if (getVarContext(object, parents) != context) {
|
|
64
|
-
illegal.add(name);
|
|
104
|
+
getParentFunctionOrProgram(varDecPath).traverse({
|
|
105
|
+
Identifier: {
|
|
106
|
+
exit(idPath) {
|
|
107
|
+
if (idPath.node.name !== identifier.node.name) return;
|
|
108
|
+
if (idPath === identifier) return; // Skip the original declaration
|
|
109
|
+
|
|
110
|
+
const memberExpression = idPath.parentPath;
|
|
111
|
+
if (!memberExpression || !memberExpression.isMemberExpression()) {
|
|
112
|
+
isObjectSafe = false;
|
|
65
113
|
return;
|
|
66
114
|
}
|
|
67
|
-
|
|
68
|
-
|
|
115
|
+
const property = getMemberExpressionPropertyAsString(
|
|
116
|
+
memberExpression.node
|
|
117
|
+
);
|
|
118
|
+
if (!property) {
|
|
119
|
+
isObjectSafe = false;
|
|
69
120
|
return;
|
|
70
121
|
}
|
|
71
122
|
|
|
72
|
-
//
|
|
73
|
-
if (
|
|
74
|
-
|
|
123
|
+
// Delete expression check
|
|
124
|
+
if (
|
|
125
|
+
memberExpression.parentPath.isUnaryExpression({
|
|
126
|
+
operator: "delete",
|
|
127
|
+
})
|
|
128
|
+
) {
|
|
129
|
+
// Deleting object properties is not allowed
|
|
130
|
+
isObjectSafe = false;
|
|
75
131
|
return;
|
|
76
132
|
}
|
|
77
133
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
prop.computed = false;
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
var nonInitOrComputed = object.properties.find(
|
|
87
|
-
(x) => x.kind !== "init" || x.computed
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
if (nonInitOrComputed) {
|
|
91
|
-
if (nonInitOrComputed.key) {
|
|
92
|
-
this.log(
|
|
93
|
-
name +
|
|
94
|
-
" has non-init/computed property: " +
|
|
95
|
-
nonInitOrComputed.key.name || nonInitOrComputed.key.value
|
|
96
|
-
);
|
|
97
|
-
} else {
|
|
98
|
-
this.log(
|
|
99
|
-
name + " has spread-element or other type of property"
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
illegal.add(name);
|
|
134
|
+
let newPropertyName = newPropertyMappings.get(property);
|
|
135
|
+
if (!newPropertyName) {
|
|
136
|
+
// Property added later on, not allowed
|
|
137
|
+
isObjectSafe = false;
|
|
104
138
|
return;
|
|
105
|
-
} else {
|
|
106
|
-
var illegalName = object.properties
|
|
107
|
-
.map((x) =>
|
|
108
|
-
x.computed ? x.key.value : x.key.name || x.key.value
|
|
109
|
-
)
|
|
110
|
-
.find((x) => !x || !isValidIdentifier(x));
|
|
111
|
-
|
|
112
|
-
if (illegalName) {
|
|
113
|
-
this.log(
|
|
114
|
-
name + " has an illegal property '" + illegalName + "'"
|
|
115
|
-
);
|
|
116
|
-
illegal.add(name);
|
|
117
|
-
return;
|
|
118
|
-
} else {
|
|
119
|
-
var isIllegal = false;
|
|
120
|
-
walk(object, parents, (o, p) => {
|
|
121
|
-
if (o.type == "ThisExpression" || o.type == "Super") {
|
|
122
|
-
isIllegal = true;
|
|
123
|
-
return "EXIT";
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
if (isIllegal) {
|
|
127
|
-
illegal.add(name);
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
objectDefs[name] = [object, parents];
|
|
132
|
-
objectDefiningIdentifiers[name] = [
|
|
133
|
-
parents[0].id,
|
|
134
|
-
[...parents],
|
|
135
|
-
];
|
|
136
|
-
}
|
|
137
139
|
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
illegal.forEach((name) => {
|
|
144
|
-
delete objectDefs[name];
|
|
145
|
-
delete objectDefiningIdentifiers[name];
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
// this.log("object defs", objectDefs);
|
|
149
|
-
// huge map of changes
|
|
150
|
-
var objectDefChanges: {
|
|
151
|
-
[name: string]: { key: string; object: Node; parents: Node[] }[];
|
|
152
|
-
} = {};
|
|
153
|
-
|
|
154
|
-
if (Object.keys(objectDefs).length) {
|
|
155
|
-
// A second pass through is only required when extracting object keys
|
|
156
|
-
|
|
157
|
-
// Second pass through the exclude the dynamic map (counting keys, re-assigning)
|
|
158
|
-
walk(context, contextParents, (object: any, parents: Node[]) => {
|
|
159
|
-
if (object.type == "Identifier") {
|
|
160
|
-
var info = getIdentifierInfo(object, parents);
|
|
161
|
-
if (!info.spec.isReferenced) {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
var def = objectDefs[object.name];
|
|
165
|
-
if (def) {
|
|
166
|
-
var isIllegal = false;
|
|
167
140
|
|
|
168
|
-
|
|
169
|
-
if (objectDefiningIdentifiers[object.name][0] !== object) {
|
|
170
|
-
this.log(object.name, "you can't redefine the object");
|
|
171
|
-
isIllegal = true;
|
|
172
|
-
}
|
|
173
|
-
} else {
|
|
174
|
-
var isMemberExpression =
|
|
175
|
-
parents[0].type == "MemberExpression" &&
|
|
176
|
-
parents[0].object == object;
|
|
141
|
+
const extractedIdentifier = t.identifier(newPropertyName);
|
|
177
142
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
) {
|
|
185
|
-
this.log(object.name, "you can't re-assign the object");
|
|
186
|
-
|
|
187
|
-
isIllegal = true;
|
|
188
|
-
} else if (isMemberExpression) {
|
|
189
|
-
var key =
|
|
190
|
-
parents[0].property.value || parents[0].property.name;
|
|
191
|
-
|
|
192
|
-
if (
|
|
193
|
-
parents[0].computed &&
|
|
194
|
-
parents[0].property.type !== "Literal"
|
|
195
|
-
) {
|
|
196
|
-
this.log(
|
|
197
|
-
object.name,
|
|
198
|
-
"object[expr] detected, only object['key'] is allowed"
|
|
199
|
-
);
|
|
200
|
-
|
|
201
|
-
isIllegal = true;
|
|
202
|
-
} else if (
|
|
203
|
-
!parents[0].computed &&
|
|
204
|
-
parents[0].property.type !== "Identifier"
|
|
205
|
-
) {
|
|
206
|
-
this.log(
|
|
207
|
-
object.name,
|
|
208
|
-
"object.<expr> detected, only object.key is allowed"
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
isIllegal = true;
|
|
212
|
-
} else if (
|
|
213
|
-
!key ||
|
|
214
|
-
!def[0].properties.some(
|
|
215
|
-
(x) => (x.key.value || x.key.name) == key
|
|
216
|
-
)
|
|
217
|
-
) {
|
|
218
|
-
// check if initialized property
|
|
219
|
-
// not in initialized object.
|
|
220
|
-
this.log(
|
|
221
|
-
object.name,
|
|
222
|
-
"not in initialized object.",
|
|
223
|
-
def[0].properties,
|
|
224
|
-
key
|
|
225
|
-
);
|
|
226
|
-
isIllegal = true;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (!isIllegal && key) {
|
|
230
|
-
// allowed.
|
|
231
|
-
// start the array if first time
|
|
232
|
-
if (!objectDefChanges[object.name]) {
|
|
233
|
-
objectDefChanges[object.name] = [];
|
|
234
|
-
}
|
|
235
|
-
// add to array
|
|
236
|
-
objectDefChanges[object.name].push({
|
|
237
|
-
key: key,
|
|
238
|
-
object: object,
|
|
239
|
-
parents: parents,
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
} else {
|
|
243
|
-
this.log(
|
|
244
|
-
object.name,
|
|
245
|
-
"you must access a property on the when referring to the identifier (accessors must be hard-coded literals), parent is " +
|
|
246
|
-
parents[0].type
|
|
247
|
-
);
|
|
248
|
-
|
|
249
|
-
isIllegal = true;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
if (isIllegal) {
|
|
254
|
-
// this is illegal, delete it from being moved and delete accessor changes from happening
|
|
255
|
-
this.log(object.name + " is illegal");
|
|
256
|
-
delete objectDefs[object.name];
|
|
257
|
-
delete objectDefChanges[object.name];
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
143
|
+
pendingReplacements.push({
|
|
144
|
+
path: memberExpression,
|
|
145
|
+
replaceWith: extractedIdentifier,
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
},
|
|
261
149
|
});
|
|
262
150
|
|
|
263
|
-
Object
|
|
264
|
-
|
|
265
|
-
!ComputeProbabilityMap(
|
|
266
|
-
this.options.objectExtraction,
|
|
267
|
-
(x) => x,
|
|
268
|
-
name
|
|
269
|
-
)
|
|
270
|
-
) {
|
|
271
|
-
//continue;
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
var [object, parents] = objectDefs[name];
|
|
276
|
-
var declarator = parents[0];
|
|
277
|
-
var declaration = parents[2];
|
|
278
|
-
|
|
279
|
-
ok(declarator.type === "VariableDeclarator");
|
|
280
|
-
ok(declaration.type === "VariableDeclaration");
|
|
281
|
-
|
|
282
|
-
var properties = object.properties;
|
|
283
|
-
// change the prop names while extracting
|
|
284
|
-
var newPropNames: { [key: string]: string } = {};
|
|
285
|
-
|
|
286
|
-
var variableDeclarators = [];
|
|
151
|
+
// Object references are too complex to safely extract
|
|
152
|
+
if (!isObjectSafe) return;
|
|
287
153
|
|
|
288
|
-
|
|
289
|
-
|
|
154
|
+
if (
|
|
155
|
+
!computeProbabilityMap(
|
|
156
|
+
me.options.objectExtraction,
|
|
157
|
+
identifier.node.name
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
return;
|
|
290
161
|
|
|
291
|
-
|
|
292
|
-
|
|
162
|
+
const newDeclarationKind =
|
|
163
|
+
varDecPath.node.kind === "const" ? "let" : varDecPath.node.kind;
|
|
293
164
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
)
|
|
165
|
+
varDecPath
|
|
166
|
+
.replaceWithMultiple(
|
|
167
|
+
newDeclarations.map((declaration) =>
|
|
168
|
+
t.variableDeclaration(newDeclarationKind, [declaration])
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
.forEach((path) => {
|
|
172
|
+
// Make sure to register the new declarations
|
|
173
|
+
path.scope.registerDeclaration(path);
|
|
299
174
|
});
|
|
300
175
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
);
|
|
306
|
-
|
|
307
|
-
// const can only be safely changed to let
|
|
308
|
-
if (declaration.kind === "const") {
|
|
309
|
-
declaration.kind = "let";
|
|
310
|
-
}
|
|
176
|
+
// Replace all references to new singular identifiers
|
|
177
|
+
for (const { path, replaceWith } of pendingReplacements) {
|
|
178
|
+
path.replaceWith(replaceWith);
|
|
179
|
+
}
|
|
311
180
|
|
|
312
|
-
|
|
313
|
-
objectDefChanges[name] &&
|
|
314
|
-
objectDefChanges[name].forEach((change) => {
|
|
315
|
-
if (!change.key) {
|
|
316
|
-
this.error(new Error("key is undefined"));
|
|
317
|
-
}
|
|
318
|
-
if (newPropNames[change.key]) {
|
|
319
|
-
var memberExpression = change.parents[0];
|
|
320
|
-
if (memberExpression.type == "MemberExpression") {
|
|
321
|
-
this.replace(
|
|
322
|
-
memberExpression,
|
|
323
|
-
this.addComment(
|
|
324
|
-
Identifier(newPropNames[change.key]),
|
|
325
|
-
`Original Accessor: ${name}.${change.key}`
|
|
326
|
-
)
|
|
327
|
-
);
|
|
328
|
-
} else {
|
|
329
|
-
// Provide error with more information:
|
|
330
|
-
console.log(memberExpression);
|
|
331
|
-
this.error(
|
|
332
|
-
new Error(
|
|
333
|
-
`should be MemberExpression, found type=${memberExpression.type}`
|
|
334
|
-
)
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
} else {
|
|
338
|
-
console.log(objectDefChanges[name], newPropNames);
|
|
339
|
-
this.error(
|
|
340
|
-
new Error(
|
|
341
|
-
`"${change.key}" not found in [${Object.keys(
|
|
342
|
-
newPropNames
|
|
343
|
-
).join(", ")}] while flattening ${name}.`
|
|
344
|
-
)
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
});
|
|
181
|
+
me.log("Extracted object", identifier.node.name);
|
|
348
182
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
} line(s) of code.`
|
|
355
|
-
);
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
}
|
|
183
|
+
me.changeData.objects++;
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
};
|
|
@@ -1,75 +1,74 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import { PluginArg, PluginObject } from "./plugin";
|
|
2
|
+
import * as t from "@babel/types";
|
|
3
|
+
import { Order } from "../order";
|
|
4
|
+
import stringEncoding from "./string/stringEncoding";
|
|
5
|
+
import { GEN_NODE, NodeSymbol, variableFunctionName } from "../constants";
|
|
6
|
+
import { ok } from "assert";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* Hexadecimal numbers:
|
|
11
|
-
* - Convert integer literals into `Identifier` nodes with the name being a hexadecimal number
|
|
12
|
-
*
|
|
13
|
-
* BigInt support:
|
|
14
|
-
* - Convert BigInt literals into `Identifier` nodes with the name being the raw BigInt string value + "n"
|
|
15
|
-
*
|
|
16
|
-
* String Encoding:
|
|
17
|
-
* - Convert String literals into `Identifier` nodes with the name being a unicode escaped string
|
|
18
|
-
*/
|
|
19
|
-
export default class Finalizer extends Transform {
|
|
20
|
-
stringEncoding: StringEncoding;
|
|
8
|
+
export default ({ Plugin }: PluginArg): PluginObject => {
|
|
9
|
+
const me = Plugin(Order.Finalizer);
|
|
10
|
+
const stringEncodingPlugin = stringEncoding(me);
|
|
21
11
|
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
return {
|
|
13
|
+
visitor: {
|
|
14
|
+
// String encoding
|
|
15
|
+
...stringEncodingPlugin.visitor,
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
// Backup __JS_CONFUSER_VAR__ replacement
|
|
18
|
+
// While done in Preparation, Rename Variables
|
|
19
|
+
// This accounts for when Rename Variables is disabled and an inserted Template adds __JS_CONFUSER_VAR__ calls
|
|
20
|
+
...(me.obfuscator.hasPlugin(Order.RenameVariables)
|
|
21
|
+
? {}
|
|
22
|
+
: {
|
|
23
|
+
CallExpression: {
|
|
24
|
+
exit(path) {
|
|
25
|
+
if (
|
|
26
|
+
path.get("callee").isIdentifier({
|
|
27
|
+
name: variableFunctionName,
|
|
28
|
+
})
|
|
29
|
+
) {
|
|
30
|
+
var args = path.get("arguments");
|
|
31
|
+
ok(args.length === 1);
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
object.type === "Literal" &&
|
|
31
|
-
typeof object.value === "number" &&
|
|
32
|
-
Math.floor(object.value) === object.value
|
|
33
|
-
);
|
|
34
|
-
}
|
|
33
|
+
var arg = args[0];
|
|
34
|
+
ok(arg.isIdentifier());
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
var name = arg.node.name;
|
|
37
|
+
path.replaceWith(t.stringLiteral(name));
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
}),
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
// Hexadecimal numbers
|
|
44
|
+
NumberLiteral: {
|
|
45
|
+
exit(path) {
|
|
46
|
+
if (me.options.hexadecimalNumbers) {
|
|
47
|
+
const { value } = path.node;
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
var hex = Math.abs(object.value).toString(16);
|
|
49
|
+
if (
|
|
50
|
+
Number.isNaN(value) ||
|
|
51
|
+
!Number.isFinite(value) ||
|
|
52
|
+
Math.floor(value) !== value
|
|
53
|
+
) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
// Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
|
|
58
|
+
// This code handles it regardless
|
|
59
|
+
var isNegative = value < 0;
|
|
60
|
+
var hex = Math.abs(value).toString(16);
|
|
54
61
|
|
|
55
|
-
|
|
56
|
-
};
|
|
57
|
-
}
|
|
62
|
+
var newStr = (isNegative ? "-" : "") + "0x" + hex;
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// https://github.com/MichaelXF/js-confuser/issues/79
|
|
62
|
-
return () => {
|
|
63
|
-
// Use an Identifier with the raw string
|
|
64
|
-
this.replace(object, Identifier(object.raw));
|
|
65
|
-
};
|
|
66
|
-
}
|
|
64
|
+
var id = t.identifier(newStr);
|
|
65
|
+
(id as NodeSymbol)[GEN_NODE] = true;
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
67
|
+
path.replaceWith(id);
|
|
68
|
+
path.skip();
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
};
|