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
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
import Transform from "../transform";
|
|
2
2
|
import { walk } from "../../traverse";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
Location,
|
|
6
|
-
Identifier,
|
|
7
|
-
VariableDeclaration,
|
|
8
|
-
VariableDeclarator,
|
|
9
|
-
} from "../../util/gen";
|
|
10
|
-
import {
|
|
11
|
-
clone,
|
|
12
|
-
deleteDeclaration,
|
|
13
|
-
getVarContext,
|
|
14
|
-
isVarContext,
|
|
15
|
-
prepend,
|
|
16
|
-
} from "../../util/insert";
|
|
3
|
+
import { Node, Location, Identifier, VariableDeclarator } from "../../util/gen";
|
|
4
|
+
import { getVarContext, isVarContext } from "../../util/insert";
|
|
17
5
|
import { ObfuscateOrder } from "../../order";
|
|
18
6
|
import { getIdentifierInfo } from "../../util/identifiers";
|
|
19
7
|
import { isValidIdentifier } from "../../util/compare";
|
|
@@ -316,8 +304,9 @@ export default class ObjectExtraction extends Transform {
|
|
|
316
304
|
...variableDeclarators
|
|
317
305
|
);
|
|
318
306
|
|
|
307
|
+
// const can only be safely changed to let
|
|
319
308
|
if (declaration.kind === "const") {
|
|
320
|
-
declaration.kind = "
|
|
309
|
+
declaration.kind = "let";
|
|
321
310
|
}
|
|
322
311
|
|
|
323
312
|
// update all identifiers that pointed to the old object
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ok } from "assert";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
noRenameVariablePrefix,
|
|
4
|
+
predictableFunctionTag,
|
|
5
|
+
reservedIdentifiers,
|
|
6
|
+
} from "../constants";
|
|
3
7
|
import { ObfuscateOrder } from "../order";
|
|
4
8
|
import { walk } from "../traverse";
|
|
5
9
|
import {
|
|
@@ -35,6 +39,7 @@ import {
|
|
|
35
39
|
import { shuffle } from "../util/random";
|
|
36
40
|
import Transform from "./transform";
|
|
37
41
|
import { FunctionLengthTemplate } from "../templates/functionLength";
|
|
42
|
+
import { ObjectDefineProperty } from "../templates/globals";
|
|
38
43
|
|
|
39
44
|
/**
|
|
40
45
|
* Flatten takes functions and isolates them from their original scope, and brings it to the top level of the program.
|
|
@@ -235,7 +240,11 @@ export default class Flatten extends Transform {
|
|
|
235
240
|
return;
|
|
236
241
|
}
|
|
237
242
|
|
|
238
|
-
var newFnName =
|
|
243
|
+
var newFnName =
|
|
244
|
+
this.getPlaceholder() +
|
|
245
|
+
"_flat_" +
|
|
246
|
+
currentFnName +
|
|
247
|
+
predictableFunctionTag;
|
|
239
248
|
var flatObjectName = this.getPlaceholder() + "_flat_object";
|
|
240
249
|
|
|
241
250
|
const getFlatObjectMember = (propertyName: string) => {
|
|
@@ -498,15 +507,21 @@ export default class Flatten extends Transform {
|
|
|
498
507
|
// Preserve function.length property
|
|
499
508
|
var originalFunctionLength = computeFunctionLength(object.params);
|
|
500
509
|
|
|
501
|
-
object.params = [
|
|
510
|
+
object.params = [RestElement(Identifier(argumentsName))];
|
|
502
511
|
|
|
503
|
-
if (originalFunctionLength !== 0) {
|
|
512
|
+
if (this.options.preserveFunctionLength && originalFunctionLength !== 0) {
|
|
504
513
|
if (!this.functionLengthName) {
|
|
505
514
|
this.functionLengthName = this.getPlaceholder();
|
|
506
515
|
|
|
507
516
|
prepend(
|
|
508
517
|
parents[parents.length - 1] || object,
|
|
509
|
-
FunctionLengthTemplate.single({
|
|
518
|
+
FunctionLengthTemplate.single({
|
|
519
|
+
name: this.functionLengthName,
|
|
520
|
+
ObjectDefineProperty: this.createInitVariable(
|
|
521
|
+
ObjectDefineProperty,
|
|
522
|
+
parents
|
|
523
|
+
),
|
|
524
|
+
})
|
|
510
525
|
);
|
|
511
526
|
}
|
|
512
527
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { reservedKeywords } from "../../constants";
|
|
2
2
|
import { Location, Node } from "../../util/gen";
|
|
3
|
+
import { isJSConfuserVar } from "../../util/guard";
|
|
3
4
|
import { getIdentifierInfo } from "../../util/identifiers";
|
|
4
5
|
import Transform from "../transform";
|
|
5
6
|
|
|
@@ -43,10 +44,26 @@ export default class GlobalAnalysis extends Transform {
|
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
if (isJSConfuserVar(parents)) {
|
|
48
|
+
delete this.globals[object.name];
|
|
49
|
+
this.notGlobals.add(object.name);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
46
53
|
// Cannot be defined or overridden
|
|
47
54
|
if (info.spec.isDefined || info.spec.isModified) {
|
|
48
|
-
|
|
55
|
+
if (info.spec.isModified) {
|
|
56
|
+
// Only direct overwrites should be considered
|
|
57
|
+
// Changing object properties is allowed
|
|
58
|
+
if (
|
|
59
|
+
parents[0].type === "MemberExpression" &&
|
|
60
|
+
parents[0].object === object
|
|
61
|
+
) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
49
65
|
|
|
66
|
+
delete this.globals[object.name];
|
|
50
67
|
this.notGlobals.add(object.name);
|
|
51
68
|
return;
|
|
52
69
|
}
|
|
@@ -22,9 +22,15 @@ import {
|
|
|
22
22
|
} from "../../util/gen";
|
|
23
23
|
import { append, prepend } from "../../util/insert";
|
|
24
24
|
import { chance, getRandomInteger } from "../../util/random";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
predictableFunctionTag,
|
|
27
|
+
reservedIdentifiers,
|
|
28
|
+
variableFunctionName,
|
|
29
|
+
} from "../../constants";
|
|
26
30
|
import { ComputeProbabilityMap } from "../../probability";
|
|
27
31
|
import GlobalAnalysis from "./globalAnalysis";
|
|
32
|
+
import { createGetGlobalTemplate } from "../../templates/bufferToString";
|
|
33
|
+
import { isJSConfuserVar } from "../../util/guard";
|
|
28
34
|
|
|
29
35
|
/**
|
|
30
36
|
* Global Concealing hides global variables being accessed.
|
|
@@ -33,6 +39,12 @@ import GlobalAnalysis from "./globalAnalysis";
|
|
|
33
39
|
*/
|
|
34
40
|
export default class GlobalConcealing extends Transform {
|
|
35
41
|
globalAnalysis: GlobalAnalysis;
|
|
42
|
+
ignoreGlobals = new Set([
|
|
43
|
+
"require",
|
|
44
|
+
"__dirname",
|
|
45
|
+
"eval",
|
|
46
|
+
variableFunctionName,
|
|
47
|
+
]);
|
|
36
48
|
|
|
37
49
|
constructor(o) {
|
|
38
50
|
super(o, ObfuscateOrder.GlobalConcealing);
|
|
@@ -52,7 +64,9 @@ export default class GlobalConcealing extends Transform {
|
|
|
52
64
|
delete globals[del];
|
|
53
65
|
});
|
|
54
66
|
|
|
55
|
-
|
|
67
|
+
for (var varName of this.ignoreGlobals) {
|
|
68
|
+
delete globals[varName];
|
|
69
|
+
}
|
|
56
70
|
|
|
57
71
|
reservedIdentifiers.forEach((x) => {
|
|
58
72
|
delete globals[x];
|
|
@@ -69,63 +83,114 @@ export default class GlobalConcealing extends Transform {
|
|
|
69
83
|
});
|
|
70
84
|
|
|
71
85
|
if (Object.keys(globals).length > 0) {
|
|
72
|
-
var
|
|
86
|
+
var usedStates = new Set<number>();
|
|
73
87
|
|
|
74
88
|
// Make getter function
|
|
75
89
|
|
|
76
90
|
// holds "window" or "global"
|
|
77
91
|
var globalVar = this.getPlaceholder();
|
|
78
92
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// "window" or "global" in node
|
|
83
|
-
var global =
|
|
84
|
-
this.options.globalVariables.values().next().value || "window";
|
|
85
|
-
var alternateGlobal = global === "window" ? "global" : "window";
|
|
86
|
-
|
|
87
|
-
var getGlobalVariableFnName = this.getPlaceholder();
|
|
88
|
-
var getThisVariableFnName = this.getPlaceholder();
|
|
93
|
+
var getGlobalVariableFnName =
|
|
94
|
+
this.getPlaceholder() + predictableFunctionTag;
|
|
89
95
|
|
|
90
96
|
// Returns global variable or fall backs to `this`
|
|
91
|
-
var getGlobalVariableFn =
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}`).single();
|
|
99
|
-
|
|
100
|
-
var getThisVariableFn = Template(`
|
|
101
|
-
var ${getThisVariableFnName} = function(){
|
|
102
|
-
try {
|
|
103
|
-
return this;
|
|
104
|
-
} catch (e){
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
}`).single();
|
|
97
|
+
var getGlobalVariableFn = createGetGlobalTemplate(
|
|
98
|
+
this,
|
|
99
|
+
object,
|
|
100
|
+
parents
|
|
101
|
+
).compile({
|
|
102
|
+
getGlobalFnName: getGlobalVariableFnName,
|
|
103
|
+
});
|
|
108
104
|
|
|
109
105
|
// 2. Replace old accessors
|
|
110
|
-
var globalFn = this.getPlaceholder();
|
|
106
|
+
var globalFn = this.getPlaceholder() + predictableFunctionTag;
|
|
111
107
|
|
|
112
108
|
var newNames: { [globalVarName: string]: number } = Object.create(null);
|
|
113
109
|
|
|
114
110
|
Object.keys(globals).forEach((name) => {
|
|
115
111
|
var locations: Location[] = globals[name];
|
|
116
|
-
var state;
|
|
112
|
+
var state: number;
|
|
117
113
|
do {
|
|
118
|
-
state = getRandomInteger(-1000, 1000 +
|
|
119
|
-
} while (
|
|
120
|
-
|
|
114
|
+
state = getRandomInteger(-1000, 1000 + usedStates.size);
|
|
115
|
+
} while (usedStates.has(state));
|
|
116
|
+
usedStates.add(state);
|
|
121
117
|
|
|
122
118
|
newNames[name] = state;
|
|
123
119
|
|
|
124
|
-
locations.forEach(([node,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
120
|
+
locations.forEach(([node, p]) => {
|
|
121
|
+
if (p.find((x) => x.$multiTransformSkip)) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
var newExpression = CallExpression(Identifier(globalFn), [
|
|
126
|
+
Literal(state),
|
|
127
|
+
]);
|
|
128
|
+
|
|
129
|
+
this.replace(node, newExpression);
|
|
130
|
+
|
|
131
|
+
if (
|
|
132
|
+
this.options.lock?.tamperProtection &&
|
|
133
|
+
this.lockTransform.nativeFunctionName
|
|
134
|
+
) {
|
|
135
|
+
var isMemberExpression = false;
|
|
136
|
+
var nameAndPropertyPath = [name];
|
|
137
|
+
var callExpression: Node;
|
|
138
|
+
|
|
139
|
+
var index = 0;
|
|
140
|
+
do {
|
|
141
|
+
if (p[index].type === "CallExpression") {
|
|
142
|
+
callExpression = p[index];
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
var memberExpression = p[index];
|
|
147
|
+
if (memberExpression.type !== "MemberExpression") return;
|
|
148
|
+
var property = memberExpression.property;
|
|
149
|
+
var stringValue =
|
|
150
|
+
property.type === "Literal"
|
|
151
|
+
? property.value
|
|
152
|
+
: memberExpression.computed
|
|
153
|
+
? null
|
|
154
|
+
: property.type === "Identifier"
|
|
155
|
+
? property.name
|
|
156
|
+
: null;
|
|
157
|
+
|
|
158
|
+
if (!stringValue) return;
|
|
159
|
+
|
|
160
|
+
isMemberExpression = true;
|
|
161
|
+
nameAndPropertyPath.push(stringValue);
|
|
162
|
+
index++;
|
|
163
|
+
} while (index < p.length);
|
|
164
|
+
|
|
165
|
+
if (
|
|
166
|
+
!this.lockTransform.shouldTransformNativeFunction(
|
|
167
|
+
nameAndPropertyPath
|
|
168
|
+
)
|
|
169
|
+
)
|
|
170
|
+
return;
|
|
171
|
+
|
|
172
|
+
if (callExpression && callExpression.type === "CallExpression") {
|
|
173
|
+
if (isMemberExpression) {
|
|
174
|
+
callExpression.callee = CallExpression(
|
|
175
|
+
Identifier(this.lockTransform.nativeFunctionName),
|
|
176
|
+
[
|
|
177
|
+
callExpression.callee.object,
|
|
178
|
+
callExpression.callee.computed
|
|
179
|
+
? callExpression.callee.property
|
|
180
|
+
: Literal(
|
|
181
|
+
callExpression.callee.property.name ||
|
|
182
|
+
callExpression.callee.property.value
|
|
183
|
+
),
|
|
184
|
+
]
|
|
185
|
+
);
|
|
186
|
+
} else {
|
|
187
|
+
callExpression.callee = CallExpression(
|
|
188
|
+
Identifier(this.lockTransform.nativeFunctionName),
|
|
189
|
+
[{ ...callExpression.callee }]
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
129
194
|
});
|
|
130
195
|
});
|
|
131
196
|
|
|
@@ -136,10 +201,10 @@ export default class GlobalConcealing extends Transform {
|
|
|
136
201
|
do {
|
|
137
202
|
state = getRandomInteger(
|
|
138
203
|
0,
|
|
139
|
-
1000 +
|
|
204
|
+
1000 + usedStates.size + this.options.globalVariables.size * 100
|
|
140
205
|
);
|
|
141
|
-
} while (
|
|
142
|
-
|
|
206
|
+
} while (usedStates.has(state));
|
|
207
|
+
usedStates.add(state);
|
|
143
208
|
|
|
144
209
|
newNames[name] = state;
|
|
145
210
|
}
|
|
@@ -159,15 +224,7 @@ export default class GlobalConcealing extends Transform {
|
|
|
159
224
|
var code = newNames[name];
|
|
160
225
|
var body: Node[] = [
|
|
161
226
|
ReturnStatement(
|
|
162
|
-
|
|
163
|
-
"||",
|
|
164
|
-
MemberExpression(
|
|
165
|
-
Identifier(globalVar),
|
|
166
|
-
Literal(name),
|
|
167
|
-
true
|
|
168
|
-
),
|
|
169
|
-
MemberExpression(Identifier(thisVar), Literal(name), true)
|
|
170
|
-
)
|
|
227
|
+
MemberExpression(Identifier(globalVar), Literal(name), true)
|
|
171
228
|
),
|
|
172
229
|
];
|
|
173
230
|
if (chance(50)) {
|
|
@@ -180,7 +237,7 @@ export default class GlobalConcealing extends Transform {
|
|
|
180
237
|
"||",
|
|
181
238
|
Literal(name),
|
|
182
239
|
MemberExpression(
|
|
183
|
-
Identifier(
|
|
240
|
+
Identifier(globalVar),
|
|
184
241
|
Literal(name),
|
|
185
242
|
true
|
|
186
243
|
)
|
|
@@ -195,18 +252,10 @@ export default class GlobalConcealing extends Transform {
|
|
|
195
252
|
})
|
|
196
253
|
),
|
|
197
254
|
ReturnStatement(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
Identifier(returnName),
|
|
203
|
-
true
|
|
204
|
-
),
|
|
205
|
-
MemberExpression(
|
|
206
|
-
Identifier(thisVar),
|
|
207
|
-
Identifier(returnName),
|
|
208
|
-
true
|
|
209
|
-
)
|
|
255
|
+
MemberExpression(
|
|
256
|
+
Identifier(globalVar),
|
|
257
|
+
Identifier(returnName),
|
|
258
|
+
true
|
|
210
259
|
)
|
|
211
260
|
),
|
|
212
261
|
]
|
|
@@ -214,8 +263,8 @@ export default class GlobalConcealing extends Transform {
|
|
|
214
263
|
|
|
215
264
|
var tempVar = this.getPlaceholder();
|
|
216
265
|
|
|
217
|
-
var variableDeclaration = Template(`
|
|
218
|
-
var ${globalVar}
|
|
266
|
+
var variableDeclaration = new Template(`
|
|
267
|
+
var ${globalVar};
|
|
219
268
|
`).single();
|
|
220
269
|
|
|
221
270
|
variableDeclaration.declarations.push(
|
|
@@ -226,11 +275,9 @@ export default class GlobalConcealing extends Transform {
|
|
|
226
275
|
FunctionExpression(
|
|
227
276
|
[],
|
|
228
277
|
[
|
|
229
|
-
getGlobalVariableFn,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
Template(
|
|
233
|
-
`return ${thisVar} = ${getThisVariableFnName}["call"](this, ${globalFn}), ${globalVar} = ${getGlobalVariableFnName}["call"](this)`
|
|
278
|
+
...getGlobalVariableFn,
|
|
279
|
+
new Template(
|
|
280
|
+
`return ${globalVar} = ${getGlobalVariableFnName}["call"](this)`
|
|
234
281
|
).single(),
|
|
235
282
|
]
|
|
236
283
|
),
|
|
@@ -6,10 +6,21 @@ import {
|
|
|
6
6
|
Identifier,
|
|
7
7
|
Node,
|
|
8
8
|
VariableDeclarator,
|
|
9
|
+
AssignmentPattern,
|
|
9
10
|
} from "../../util/gen";
|
|
10
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
isForInitialize,
|
|
13
|
+
isFunction,
|
|
14
|
+
isStrictModeFunction,
|
|
15
|
+
prepend,
|
|
16
|
+
} from "../../util/insert";
|
|
11
17
|
import { ok } from "assert";
|
|
12
18
|
import { ObfuscateOrder } from "../../order";
|
|
19
|
+
import { choice } from "../../util/random";
|
|
20
|
+
import { predictableFunctionTag } from "../../constants";
|
|
21
|
+
import { isIndependent, isMoveable } from "../../util/compare";
|
|
22
|
+
import { getFunctionParameters } from "../../util/identifiers";
|
|
23
|
+
import { isLexicalScope } from "../../util/scope";
|
|
13
24
|
|
|
14
25
|
/**
|
|
15
26
|
* Defines all the names at the top of every lexical block.
|
|
@@ -33,35 +44,86 @@ export default class MovedDeclarations extends Transform {
|
|
|
33
44
|
var forInitializeType = isForInitialize(object, parents);
|
|
34
45
|
|
|
35
46
|
// Get the block statement or Program node
|
|
36
|
-
var blockIndex = parents.findIndex((x) =>
|
|
47
|
+
var blockIndex = parents.findIndex((x) => isLexicalScope(x));
|
|
37
48
|
var block = parents[blockIndex];
|
|
38
|
-
var body =
|
|
39
|
-
|
|
49
|
+
var body: Node[] =
|
|
50
|
+
block.type === "SwitchCase" ? block.consequent : block.body;
|
|
51
|
+
ok(Array.isArray(body), "No body array found.");
|
|
40
52
|
|
|
41
|
-
|
|
53
|
+
var bodyObject = parents[blockIndex - 2] || object;
|
|
42
54
|
var index = body.indexOf(bodyObject);
|
|
43
|
-
if (index === -1 || index === 0) return;
|
|
44
55
|
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
var varName = object.declarations[0].id.name;
|
|
57
|
+
ok(typeof varName === "string");
|
|
58
|
+
|
|
59
|
+
var predictableFunctionIndex = parents.findIndex((x) => isFunction(x));
|
|
60
|
+
var predictableFunction = parents[predictableFunctionIndex];
|
|
61
|
+
|
|
62
|
+
var deleteStatement = false;
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
predictableFunction &&
|
|
66
|
+
((predictableFunction.id &&
|
|
67
|
+
predictableFunction.id.name.includes(predictableFunctionTag)) ||
|
|
68
|
+
predictableFunction[predictableFunctionTag]) && // Must have predictableFunctionTag in the name, or on object
|
|
69
|
+
predictableFunction[predictableFunctionTag] !== false && // If === false, the function is deemed not predictable
|
|
70
|
+
predictableFunction.params.length < 1000 && // Max 1,000 parameters
|
|
71
|
+
!predictableFunction.params.find((x) => x.type === "RestElement") && // Cannot add parameters after spread operator
|
|
72
|
+
!(
|
|
73
|
+
["Property", "MethodDefinition"].includes(
|
|
74
|
+
parents[predictableFunctionIndex + 1]?.type
|
|
75
|
+
) && parents[predictableFunctionIndex + 1]?.kind !== "init"
|
|
76
|
+
) && // Preserve getter/setter methods
|
|
77
|
+
!getFunctionParameters(
|
|
78
|
+
predictableFunction,
|
|
79
|
+
parents.slice(predictableFunctionIndex)
|
|
80
|
+
).find((entry) => entry[0].name === varName) // Ensure not duplicate param name
|
|
81
|
+
) {
|
|
82
|
+
// Use function f(..., x, y, z) to declare name
|
|
83
|
+
|
|
84
|
+
var value = object.declarations[0].init;
|
|
85
|
+
var isPredictablyComputed =
|
|
86
|
+
predictableFunction.body === block &&
|
|
87
|
+
!isStrictModeFunction(predictableFunction) &&
|
|
88
|
+
value &&
|
|
89
|
+
isIndependent(value, []) &&
|
|
90
|
+
isMoveable(value, [object.declarations[0], object, ...parents]);
|
|
91
|
+
|
|
92
|
+
var defineWithValue = isPredictablyComputed;
|
|
93
|
+
|
|
94
|
+
if (defineWithValue) {
|
|
95
|
+
predictableFunction.params.push(
|
|
96
|
+
AssignmentPattern(Identifier(varName), value)
|
|
97
|
+
);
|
|
98
|
+
object.declarations[0].init = null;
|
|
99
|
+
deleteStatement = true;
|
|
100
|
+
} else {
|
|
101
|
+
predictableFunction.params.push(Identifier(varName));
|
|
102
|
+
}
|
|
48
103
|
} else {
|
|
49
|
-
|
|
50
|
-
type: "VariableDeclaration",
|
|
51
|
-
declarations: [],
|
|
52
|
-
kind: "var",
|
|
53
|
-
};
|
|
104
|
+
// Use 'var x, y, z' to declare name
|
|
54
105
|
|
|
55
|
-
|
|
56
|
-
|
|
106
|
+
// Make sure in the block statement, and not already at the top of it
|
|
107
|
+
if (index === -1 || index === 0) return;
|
|
57
108
|
|
|
58
|
-
|
|
59
|
-
|
|
109
|
+
var topVariableDeclaration;
|
|
110
|
+
if (body[0].type === "VariableDeclaration" && body[0].kind === "var") {
|
|
111
|
+
topVariableDeclaration = body[0];
|
|
112
|
+
} else {
|
|
113
|
+
topVariableDeclaration = {
|
|
114
|
+
type: "VariableDeclaration",
|
|
115
|
+
declarations: [],
|
|
116
|
+
kind: "var",
|
|
117
|
+
};
|
|
60
118
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
119
|
+
prepend(block, topVariableDeclaration);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Add `var x` at the top of the block
|
|
123
|
+
topVariableDeclaration.declarations.push(
|
|
124
|
+
VariableDeclarator(Identifier(varName))
|
|
125
|
+
);
|
|
126
|
+
}
|
|
65
127
|
|
|
66
128
|
var assignmentExpression = AssignmentExpression(
|
|
67
129
|
"=",
|
|
@@ -79,8 +141,12 @@ export default class MovedDeclarations extends Transform {
|
|
|
79
141
|
this.replace(object, Identifier(varName));
|
|
80
142
|
}
|
|
81
143
|
} else {
|
|
82
|
-
|
|
83
|
-
|
|
144
|
+
if (deleteStatement && index !== -1) {
|
|
145
|
+
body.splice(index, 1);
|
|
146
|
+
} else {
|
|
147
|
+
// Replace `var x = value` to `x = value`
|
|
148
|
+
this.replace(object, ExpressionStatement(assignmentExpression));
|
|
149
|
+
}
|
|
84
150
|
}
|
|
85
151
|
};
|
|
86
152
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ok } from "assert";
|
|
2
2
|
import { ObfuscateOrder } from "../../order";
|
|
3
3
|
import { walk } from "../../traverse";
|
|
4
|
-
import { Node } from "../../util/gen";
|
|
4
|
+
import { Literal, Node } from "../../util/gen";
|
|
5
5
|
import { getIdentifierInfo } from "../../util/identifiers";
|
|
6
6
|
import {
|
|
7
7
|
isVarContext,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
noRenameVariablePrefix,
|
|
16
16
|
placeholderVariablePrefix,
|
|
17
17
|
reservedIdentifiers,
|
|
18
|
+
variableFunctionName,
|
|
18
19
|
} from "../../constants";
|
|
19
20
|
import { ComputeProbabilityMap } from "../../probability";
|
|
20
21
|
import VariableAnalysis from "./variableAnalysis";
|
|
@@ -267,6 +268,20 @@ export default class RenameVariables extends Transform {
|
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
270
|
|
|
271
|
+
if (
|
|
272
|
+
parents[1] &&
|
|
273
|
+
parents[1].type === "CallExpression" &&
|
|
274
|
+
parents[1].arguments === parents[0]
|
|
275
|
+
) {
|
|
276
|
+
if (
|
|
277
|
+
parents[1].callee.type === "Identifier" &&
|
|
278
|
+
parents[1].callee.name === variableFunctionName
|
|
279
|
+
) {
|
|
280
|
+
this.replace(parents[1], Literal(newName));
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
270
285
|
// console.log(o.name, "->", newName);
|
|
271
286
|
// 5. Update Identifier node's 'name' property
|
|
272
287
|
object.name = newName;
|
|
@@ -16,7 +16,7 @@ import { getRandomInteger } from "../../util/random";
|
|
|
16
16
|
import Transform from "../transform";
|
|
17
17
|
import Lock from "./lock";
|
|
18
18
|
|
|
19
|
-
var DevToolsDetection = Template(
|
|
19
|
+
var DevToolsDetection = new Template(
|
|
20
20
|
`
|
|
21
21
|
try {
|
|
22
22
|
if ( setInterval ) {
|
|
@@ -52,7 +52,7 @@ export default class AntiDebug extends Transform {
|
|
|
52
52
|
fnName,
|
|
53
53
|
[],
|
|
54
54
|
[
|
|
55
|
-
...Template(`
|
|
55
|
+
...new Template(`
|
|
56
56
|
var ${startTimeName} = new Date();
|
|
57
57
|
debugger;
|
|
58
58
|
var ${endTimeName} = new Date();
|