js-confuser 1.5.8 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +2 -2
- package/CHANGELOG.md +69 -0
- package/README.md +143 -7
- package/dist/index.js +33 -4
- package/dist/obfuscator.js +30 -31
- package/dist/options.js +4 -5
- package/dist/order.js +4 -6
- package/dist/probability.js +2 -4
- package/dist/templates/bufferToString.js +13 -0
- package/dist/templates/crash.js +2 -2
- package/dist/templates/es5.js +18 -0
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/calculator.js +77 -21
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
- package/dist/transforms/deadCode.js +33 -25
- package/dist/transforms/dispatcher.js +7 -6
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +3 -1
- package/dist/transforms/es5/es5.js +31 -34
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/finalizer.js +82 -0
- package/dist/transforms/flatten.js +82 -55
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/globalAnalysis.js +88 -0
- package/dist/transforms/identifier/globalConcealing.js +10 -83
- package/dist/transforms/identifier/movedDeclarations.js +2 -8
- package/dist/transforms/identifier/renameVariables.js +39 -27
- package/dist/transforms/identifier/variableAnalysis.js +58 -62
- package/dist/transforms/minify.js +80 -61
- package/dist/transforms/opaquePredicates.js +1 -1
- package/dist/transforms/preparation/preparation.js +2 -2
- package/dist/transforms/preparation.js +231 -0
- package/dist/transforms/renameLabels.js +1 -1
- package/dist/transforms/rgf.js +4 -5
- package/dist/transforms/stack.js +87 -26
- package/dist/transforms/string/encoding.js +150 -179
- package/dist/transforms/string/stringCompression.js +14 -15
- package/dist/transforms/string/stringConcealing.js +25 -8
- package/dist/transforms/string/stringEncoding.js +13 -24
- package/dist/transforms/transform.js +11 -18
- package/dist/traverse.js +24 -18
- package/dist/util/compare.js +2 -2
- package/dist/util/gen.js +15 -0
- package/dist/util/insert.js +31 -7
- package/dist/util/random.js +15 -0
- package/package.json +5 -5
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +26 -29
- package/src/options.ts +17 -21
- package/src/order.ts +4 -8
- package/src/probability.ts +2 -3
- package/src/templates/bufferToString.ts +68 -0
- package/src/templates/crash.ts +5 -9
- package/src/templates/es5.ts +131 -0
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/calculator.ts +122 -59
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
- package/src/transforms/deadCode.ts +383 -26
- package/src/transforms/dispatcher.ts +8 -6
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +3 -1
- package/src/transforms/es5/es5.ts +32 -77
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/finalizer.ts +75 -0
- package/src/transforms/flatten.ts +194 -151
- package/src/transforms/identifier/globalAnalysis.ts +85 -0
- package/src/transforms/identifier/globalConcealing.ts +14 -103
- package/src/transforms/identifier/movedDeclarations.ts +4 -11
- package/src/transforms/identifier/renameVariables.ts +37 -30
- package/src/transforms/identifier/variableAnalysis.ts +66 -73
- package/src/transforms/minify.ts +116 -77
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +238 -0
- package/src/transforms/renameLabels.ts +2 -2
- package/src/transforms/rgf.ts +6 -7
- package/src/transforms/stack.ts +97 -37
- package/src/transforms/string/encoding.ts +115 -212
- package/src/transforms/string/stringCompression.ts +27 -18
- package/src/transforms/string/stringConcealing.ts +41 -11
- package/src/transforms/string/stringEncoding.ts +18 -18
- package/src/transforms/transform.ts +15 -21
- package/src/traverse.ts +24 -12
- package/src/types.ts +11 -2
- package/src/util/compare.ts +2 -2
- package/src/util/gen.ts +21 -1
- package/src/util/insert.ts +49 -9
- package/src/util/random.ts +13 -0
- package/test/code/Cash.test.ts +1 -1
- package/test/code/Dynamic.test.ts +12 -10
- package/test/code/ES6.src.js +136 -0
- package/test/code/ES6.test.ts +28 -2
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +15 -2
- package/test/probability.test.ts +44 -0
- package/test/templates/template.test.ts +1 -1
- package/test/transforms/antiTooling.test.ts +52 -0
- package/test/transforms/calculator.test.ts +40 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
- package/test/transforms/deadCode.test.ts +66 -15
- package/test/transforms/dispatcher.test.ts +44 -1
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/es5/antiDestructuring.test.ts +16 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +195 -3
- package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
- package/test/transforms/identifier/renameVariables.test.ts +108 -0
- package/test/transforms/lock/antiDebug.test.ts +2 -2
- package/test/transforms/minify.test.ts +151 -0
- package/test/transforms/preparation.test.ts +157 -0
- package/test/transforms/rgf.test.ts +56 -29
- package/test/transforms/stack.test.ts +91 -21
- package/test/transforms/string/stringCompression.test.ts +39 -0
- package/test/transforms/string/stringConcealing.test.ts +115 -0
- package/test/transforms/string/stringEncoding.test.ts +53 -2
- package/test/transforms/transform.test.ts +66 -0
- package/test/traverse.test.ts +139 -0
- package/test/util/compare.test.ts +23 -1
- package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
- package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
- package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
- package/src/transforms/hexadecimalNumbers.ts +0 -31
- package/src/transforms/hideInitializingCode.ts +0 -432
- package/src/transforms/label.ts +0 -64
- package/src/transforms/preparation/nameConflicts.ts +0 -102
- package/src/transforms/preparation/preparation.ts +0 -176
- package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
- package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
- package/test/transforms/hideInitializingCode.test.ts +0 -336
- package/test/transforms/preparation/nameConflicts.test.ts +0 -52
- package/test/transforms/preparation/preparation.test.ts +0 -62
|
@@ -16,88 +16,15 @@ import {
|
|
|
16
16
|
VariableDeclarator,
|
|
17
17
|
FunctionExpression,
|
|
18
18
|
ExpressionStatement,
|
|
19
|
-
SequenceExpression,
|
|
20
19
|
AssignmentExpression,
|
|
21
20
|
VariableDeclaration,
|
|
22
21
|
BreakStatement,
|
|
23
22
|
} from "../../util/gen";
|
|
24
23
|
import { append, prepend } from "../../util/insert";
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { reservedIdentifiers, reservedKeywords } from "../../constants";
|
|
24
|
+
import { chance, getRandomInteger } from "../../util/random";
|
|
25
|
+
import { reservedIdentifiers } from "../../constants";
|
|
28
26
|
import { ComputeProbabilityMap } from "../../probability";
|
|
29
|
-
|
|
30
|
-
class GlobalAnalysis extends Transform {
|
|
31
|
-
notGlobals: Set<string>;
|
|
32
|
-
globals: { [name: string]: Location[] };
|
|
33
|
-
|
|
34
|
-
constructor(o) {
|
|
35
|
-
super(o);
|
|
36
|
-
|
|
37
|
-
this.globals = Object.create(null);
|
|
38
|
-
this.notGlobals = new Set();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
match(object: Node, parents: Node[]) {
|
|
42
|
-
return object.type == "Identifier" && !reservedKeywords.has(object.name);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
transform(object: Node, parents: Node[]) {
|
|
46
|
-
// no touching `import()` or `import x from ...`
|
|
47
|
-
var importIndex = parents.findIndex(
|
|
48
|
-
(x) => x.type == "ImportExpression" || x.type == "ImportDeclaration"
|
|
49
|
-
);
|
|
50
|
-
if (importIndex !== -1) {
|
|
51
|
-
if (
|
|
52
|
-
parents[importIndex].source === (parents[importIndex - 1] || object)
|
|
53
|
-
) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
var info = getIdentifierInfo(object, parents);
|
|
59
|
-
if (!info.spec.isReferenced) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Add to globals
|
|
64
|
-
if (!this.notGlobals.has(object.name)) {
|
|
65
|
-
if (!this.globals[object.name]) {
|
|
66
|
-
this.globals[object.name] = [];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
this.globals[object.name].push([object, parents]);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (info.spec.isDefined || info.spec.isModified) {
|
|
73
|
-
delete this.globals[object.name];
|
|
74
|
-
|
|
75
|
-
this.notGlobals.add(object.name);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
var assignmentIndex = parents.findIndex(
|
|
79
|
-
(x) => x.type == "AssignmentExpression"
|
|
80
|
-
);
|
|
81
|
-
var updateIndex = parents.findIndex((x) => x.type == "UpdateExpression");
|
|
82
|
-
|
|
83
|
-
if (
|
|
84
|
-
(assignmentIndex != -1 &&
|
|
85
|
-
parents[assignmentIndex].left ===
|
|
86
|
-
(parents[assignmentIndex - 1] || object)) ||
|
|
87
|
-
updateIndex != -1
|
|
88
|
-
) {
|
|
89
|
-
var memberIndex = parents.findIndex((x) => x.type == "MemberExpression");
|
|
90
|
-
if (
|
|
91
|
-
memberIndex == -1 ||
|
|
92
|
-
memberIndex > (assignmentIndex == -1 ? assignmentIndex : updateIndex)
|
|
93
|
-
) {
|
|
94
|
-
delete this.globals[object.name];
|
|
95
|
-
|
|
96
|
-
this.notGlobals.add(object.name);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
27
|
+
import GlobalAnalysis from "./globalAnalysis";
|
|
101
28
|
|
|
102
29
|
/**
|
|
103
30
|
* Global Concealing hides global variables being accessed.
|
|
@@ -141,12 +68,10 @@ export default class GlobalConcealing extends Transform {
|
|
|
141
68
|
}
|
|
142
69
|
});
|
|
143
70
|
|
|
144
|
-
// this.log(Object.keys(globals).join(', '))
|
|
145
|
-
|
|
146
71
|
if (Object.keys(globals).length > 0) {
|
|
147
72
|
var used = new Set();
|
|
148
73
|
|
|
149
|
-
//
|
|
74
|
+
// Make getter function
|
|
150
75
|
|
|
151
76
|
// holds "window" or "global"
|
|
152
77
|
var globalVar = this.getPlaceholder();
|
|
@@ -157,6 +82,8 @@ export default class GlobalConcealing extends Transform {
|
|
|
157
82
|
// "window" or "global" in node
|
|
158
83
|
var global =
|
|
159
84
|
this.options.globalVariables.values().next().value || "window";
|
|
85
|
+
var alternateGlobal = global === "window" ? "global" : "window";
|
|
86
|
+
|
|
160
87
|
var getGlobalVariableFnName = this.getPlaceholder();
|
|
161
88
|
var getThisVariableFnName = this.getPlaceholder();
|
|
162
89
|
|
|
@@ -164,7 +91,7 @@ export default class GlobalConcealing extends Transform {
|
|
|
164
91
|
var getGlobalVariableFn = Template(`
|
|
165
92
|
var ${getGlobalVariableFnName} = function(){
|
|
166
93
|
try {
|
|
167
|
-
return ${global};
|
|
94
|
+
return ${global} || ${alternateGlobal} || (new Function("return this"))();
|
|
168
95
|
} catch (e){
|
|
169
96
|
return ${getThisVariableFnName}["call"](this);
|
|
170
97
|
}
|
|
@@ -182,7 +109,7 @@ export default class GlobalConcealing extends Transform {
|
|
|
182
109
|
// 2. Replace old accessors
|
|
183
110
|
var globalFn = this.getPlaceholder();
|
|
184
111
|
|
|
185
|
-
var newNames = Object.create(null);
|
|
112
|
+
var newNames: { [globalVarName: string]: number } = Object.create(null);
|
|
186
113
|
|
|
187
114
|
Object.keys(globals).forEach((name) => {
|
|
188
115
|
var locations: Location[] = globals[name];
|
|
@@ -195,26 +122,10 @@ export default class GlobalConcealing extends Transform {
|
|
|
195
122
|
newNames[name] = state;
|
|
196
123
|
|
|
197
124
|
locations.forEach(([node, parents]) => {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
parents[0].type == "ClassDeclaration" ||
|
|
203
|
-
parents[0].type == "ClassExpression" ||
|
|
204
|
-
parents[0].type == "FunctionExpression" ||
|
|
205
|
-
parents[0].type == "FunctionDeclaration"
|
|
206
|
-
) {
|
|
207
|
-
if (parents[0].id === node) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
this.replace(
|
|
214
|
-
node,
|
|
215
|
-
CallExpression(Identifier(globalFn), [Literal(state)])
|
|
216
|
-
);
|
|
217
|
-
}
|
|
125
|
+
this.replace(
|
|
126
|
+
node,
|
|
127
|
+
CallExpression(Identifier(globalFn), [Literal(state)])
|
|
128
|
+
);
|
|
218
129
|
});
|
|
219
130
|
});
|
|
220
131
|
|
|
@@ -224,7 +135,7 @@ export default class GlobalConcealing extends Transform {
|
|
|
224
135
|
var state;
|
|
225
136
|
do {
|
|
226
137
|
state = getRandomInteger(
|
|
227
|
-
|
|
138
|
+
0,
|
|
228
139
|
1000 + used.size + this.options.globalVariables.size * 100
|
|
229
140
|
);
|
|
230
141
|
} while (used.has(state));
|
|
@@ -259,7 +170,7 @@ export default class GlobalConcealing extends Transform {
|
|
|
259
170
|
)
|
|
260
171
|
),
|
|
261
172
|
];
|
|
262
|
-
if (
|
|
173
|
+
if (chance(50)) {
|
|
263
174
|
body = [
|
|
264
175
|
ExpressionStatement(
|
|
265
176
|
AssignmentExpression(
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import Transform from "../transform";
|
|
2
|
-
import { isBlock,
|
|
2
|
+
import { isBlock, walk } from "../../traverse";
|
|
3
3
|
import {
|
|
4
4
|
Location,
|
|
5
5
|
ExpressionStatement,
|
|
6
|
-
SequenceExpression,
|
|
7
6
|
AssignmentExpression,
|
|
8
7
|
Identifier,
|
|
9
8
|
Node,
|
|
10
9
|
VariableDeclarator,
|
|
11
10
|
VariableDeclaration,
|
|
12
11
|
} from "../../util/gen";
|
|
13
|
-
import {
|
|
12
|
+
import { isForInitialize, prepend } from "../../util/insert";
|
|
14
13
|
import { ok } from "assert";
|
|
15
14
|
import { ObfuscateOrder } from "../../order";
|
|
16
15
|
import { getIdentifierInfo } from "../../util/identifiers";
|
|
17
|
-
import { isLoop } from "../../util/compare";
|
|
18
|
-
import { reservedIdentifiers } from "../../constants";
|
|
19
16
|
import { isLexicalScope, getLexicalScope } from "../../util/scope";
|
|
20
17
|
|
|
21
18
|
/**
|
|
@@ -46,7 +43,7 @@ export default class MovedDeclarations extends Transform {
|
|
|
46
43
|
|
|
47
44
|
walk(object, parents, (o, p) => {
|
|
48
45
|
if (o.type == "Identifier") {
|
|
49
|
-
if (getLexicalScope(o, p) !== object) {
|
|
46
|
+
if (o.hidden || getLexicalScope(o, p) !== object) {
|
|
50
47
|
illegal.add(o.name);
|
|
51
48
|
} else {
|
|
52
49
|
var info = getIdentifierInfo(o, p);
|
|
@@ -125,11 +122,7 @@ export default class MovedDeclarations extends Transform {
|
|
|
125
122
|
})
|
|
126
123
|
);
|
|
127
124
|
|
|
128
|
-
|
|
129
|
-
prepend(object, variableDeclaration);
|
|
130
|
-
} else {
|
|
131
|
-
body.unshift(variableDeclaration);
|
|
132
|
-
}
|
|
125
|
+
prepend(object, variableDeclaration);
|
|
133
126
|
|
|
134
127
|
movingNames.forEach((name) => {
|
|
135
128
|
var { location, replace } = variableDeclarations[name];
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import { ok } from "assert";
|
|
2
2
|
import { ObfuscateOrder } from "../../order";
|
|
3
3
|
import { walk } from "../../traverse";
|
|
4
|
-
import {
|
|
4
|
+
import { Node } from "../../util/gen";
|
|
5
5
|
import { getIdentifierInfo } from "../../util/identifiers";
|
|
6
6
|
import {
|
|
7
|
-
getVarContext,
|
|
8
7
|
isVarContext,
|
|
9
|
-
getLexContext,
|
|
10
8
|
isContext,
|
|
11
9
|
isLexContext,
|
|
12
|
-
getDefiningContext,
|
|
13
10
|
clone,
|
|
14
11
|
} from "../../util/insert";
|
|
15
|
-
import { isValidIdentifier } from "../../util/compare";
|
|
16
12
|
import Transform from "../transform";
|
|
17
13
|
import { reservedIdentifiers } from "../../constants";
|
|
18
14
|
import { ComputeProbabilityMap } from "../../probability";
|
|
@@ -21,12 +17,13 @@ import VariableAnalysis from "./variableAnalysis";
|
|
|
21
17
|
/**
|
|
22
18
|
* Rename variables to randomly generated names.
|
|
23
19
|
*
|
|
24
|
-
* -
|
|
20
|
+
* - 1. First collect data on identifiers in all scope using 'VariableAnalysis'
|
|
21
|
+
* - 2. After 'VariableAnalysis' is finished start applying to each scope (top-down)
|
|
22
|
+
* - 3. Each scope, find the all names used here and exclude those names from being re-named
|
|
23
|
+
* - 4. Now loop through all the defined names in this scope and set it to a random name (or re-use previously generated name)
|
|
24
|
+
* - 5. Update all the Identifiers node's 'name' property to reflect this change
|
|
25
25
|
*/
|
|
26
26
|
export default class RenameVariables extends Transform {
|
|
27
|
-
// Generator object
|
|
28
|
-
gen: any;
|
|
29
|
-
|
|
30
27
|
// Names already used
|
|
31
28
|
generated: string[];
|
|
32
29
|
|
|
@@ -41,17 +38,18 @@ export default class RenameVariables extends Transform {
|
|
|
41
38
|
|
|
42
39
|
this.changed = new Map();
|
|
43
40
|
|
|
41
|
+
// 1.
|
|
44
42
|
this.variableAnalysis = new VariableAnalysis(o);
|
|
45
43
|
this.before.push(this.variableAnalysis);
|
|
46
|
-
this.gen = this.getGenerator();
|
|
47
44
|
this.generated = [];
|
|
48
45
|
}
|
|
49
46
|
|
|
50
|
-
match(object, parents) {
|
|
47
|
+
match(object: Node, parents: Node[]) {
|
|
51
48
|
return isContext(object);
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
transform(object, parents) {
|
|
51
|
+
transform(object: Node, parents: Node[]) {
|
|
52
|
+
// 2. Notice this is on 'onEnter' (top-down)
|
|
55
53
|
var isGlobal = object.type == "Program";
|
|
56
54
|
var type = isGlobal
|
|
57
55
|
? "root"
|
|
@@ -68,15 +66,18 @@ export default class RenameVariables extends Transform {
|
|
|
68
66
|
var defined = this.variableAnalysis.defined.get(object) || new Set();
|
|
69
67
|
var references = this.variableAnalysis.references.get(object) || new Set();
|
|
70
68
|
|
|
69
|
+
// No changes needed here
|
|
71
70
|
if (!defined && !this.changed.has(object)) {
|
|
72
71
|
this.changed.set(object, Object.create(null));
|
|
73
72
|
return;
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
// Names possible to be re-used here
|
|
76
|
+
var possible = new Set<string>();
|
|
77
77
|
|
|
78
|
+
// 3. Try to re-use names when possible
|
|
78
79
|
if (this.generated.length && !isGlobal) {
|
|
79
|
-
var allReferences = new Set(
|
|
80
|
+
var allReferences = new Set<string>();
|
|
80
81
|
var nope = new Set(defined);
|
|
81
82
|
walk(object, [], (o, p) => {
|
|
82
83
|
var ref = this.variableAnalysis.references.get(o);
|
|
@@ -90,14 +91,14 @@ export default class RenameVariables extends Transform {
|
|
|
90
91
|
}
|
|
91
92
|
});
|
|
92
93
|
|
|
93
|
-
var passed = new Set();
|
|
94
|
+
var passed = new Set<string>();
|
|
94
95
|
parents.forEach((p) => {
|
|
95
96
|
var changes = this.changed.get(p);
|
|
96
97
|
if (changes) {
|
|
97
98
|
Object.keys(changes).forEach((x) => {
|
|
98
99
|
var name = changes[x];
|
|
99
100
|
|
|
100
|
-
if (!allReferences.has(x)) {
|
|
101
|
+
if (!allReferences.has(x) && !references.has(x)) {
|
|
101
102
|
passed.add(name);
|
|
102
103
|
} else {
|
|
103
104
|
nope.add(name);
|
|
@@ -111,42 +112,48 @@ export default class RenameVariables extends Transform {
|
|
|
111
112
|
possible = passed;
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
// 4. Defined names to new names
|
|
116
|
+
for (var name of defined) {
|
|
115
117
|
if (
|
|
116
|
-
|
|
118
|
+
!name.startsWith("__NO_JS_CONFUSER_RENAME__") && // Variables prefixed with '__NO_JS_CONFUSER_RENAME__' are never renamed
|
|
119
|
+
(isGlobal && !name.startsWith("__p_") // Variables prefixed with '__p_' are created by the obfuscator, always renamed
|
|
117
120
|
? ComputeProbabilityMap(this.options.renameGlobals, (x) => x, name)
|
|
118
121
|
: true) &&
|
|
119
122
|
ComputeProbabilityMap(
|
|
123
|
+
// Check the user's option for renaming variables
|
|
120
124
|
this.options.renameVariables,
|
|
121
125
|
(x) => x,
|
|
122
126
|
name,
|
|
123
127
|
isGlobal
|
|
124
128
|
)
|
|
125
129
|
) {
|
|
126
|
-
//
|
|
127
|
-
var newName;
|
|
130
|
+
// Create a new name from (1) or (2) methods
|
|
131
|
+
var newName: string;
|
|
128
132
|
do {
|
|
129
133
|
if (possible.size) {
|
|
134
|
+
// (1) Re-use previously generated name
|
|
130
135
|
var first = possible.values().next().value;
|
|
131
136
|
possible.delete(first);
|
|
132
137
|
newName = first;
|
|
133
138
|
} else {
|
|
134
|
-
//
|
|
135
|
-
var
|
|
139
|
+
// (2) Create a new name with `generateIdentifier` function
|
|
140
|
+
var generatedName = this.generateIdentifier();
|
|
136
141
|
|
|
137
|
-
newName =
|
|
138
|
-
this.generated.push(
|
|
142
|
+
newName = generatedName;
|
|
143
|
+
this.generated.push(generatedName);
|
|
139
144
|
}
|
|
140
|
-
} while (this.variableAnalysis.globals.has(newName));
|
|
145
|
+
} while (this.variableAnalysis.globals.has(newName)); // Ensure global names aren't overridden
|
|
141
146
|
|
|
142
147
|
newNames[name] = newName;
|
|
143
148
|
} else {
|
|
149
|
+
// This variable name was deemed not to be renamed.
|
|
144
150
|
newNames[name] = name;
|
|
145
151
|
}
|
|
146
|
-
}
|
|
152
|
+
}
|
|
147
153
|
|
|
148
154
|
this.changed.set(object, newNames);
|
|
149
155
|
|
|
156
|
+
// 5. Update Identifier node's 'name' property
|
|
150
157
|
walk(object, parents, (o, p) => {
|
|
151
158
|
if (o.type == "Identifier") {
|
|
152
159
|
if (
|
|
@@ -156,6 +163,10 @@ export default class RenameVariables extends Transform {
|
|
|
156
163
|
return;
|
|
157
164
|
}
|
|
158
165
|
|
|
166
|
+
if (o.$renamed) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
159
170
|
var info = getIdentifierInfo(o, p);
|
|
160
171
|
|
|
161
172
|
if (info.spec.isExported) {
|
|
@@ -182,10 +193,6 @@ export default class RenameVariables extends Transform {
|
|
|
182
193
|
}
|
|
183
194
|
|
|
184
195
|
if (newName && typeof newName === "string") {
|
|
185
|
-
if (o.$renamed) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
196
|
// Strange behavior where the `local` and `imported` objects are the same
|
|
190
197
|
if (info.isImportSpecifier) {
|
|
191
198
|
var importSpecifierIndex = p.findIndex(
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { ok } from "assert";
|
|
2
2
|
import { reservedIdentifiers } from "../../constants";
|
|
3
|
-
import { walk } from "../../traverse";
|
|
4
3
|
import { isValidIdentifier } from "../../util/compare";
|
|
5
4
|
import { Node } from "../../util/gen";
|
|
6
5
|
import { getIdentifierInfo } from "../../util/identifiers";
|
|
7
6
|
import {
|
|
8
|
-
getDefiningContext,
|
|
9
|
-
getVarContext,
|
|
10
|
-
getLexContext,
|
|
11
|
-
isContext,
|
|
12
7
|
getReferencingContexts,
|
|
13
8
|
getAllDefiningContexts,
|
|
14
9
|
} from "../../util/insert";
|
|
@@ -30,11 +25,13 @@ export default class VariableAnalysis extends Transform {
|
|
|
30
25
|
|
|
31
26
|
/**
|
|
32
27
|
* Set of global identifiers to never be redefined
|
|
28
|
+
*
|
|
29
|
+
* - Used to not accidentally block access to a global variable
|
|
33
30
|
*/
|
|
34
31
|
globals: Set<string>;
|
|
35
32
|
|
|
36
33
|
/**
|
|
37
|
-
* Set of
|
|
34
|
+
* Set of identifiers that are defined within the program
|
|
38
35
|
*/
|
|
39
36
|
notGlobals: Set<string>;
|
|
40
37
|
|
|
@@ -48,77 +45,73 @@ export default class VariableAnalysis extends Transform {
|
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
match(object, parents) {
|
|
51
|
-
return
|
|
48
|
+
return object.type === "Identifier";
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
transform(object, parents) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
transform(object: Node, parents: Node[]) {
|
|
52
|
+
var name = object.name;
|
|
53
|
+
ok(typeof name === "string");
|
|
54
|
+
if (!isValidIdentifier(name)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (reservedIdentifiers.has(name)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (this.options.globalVariables.has(name)) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var info = getIdentifierInfo(object, parents);
|
|
66
|
+
if (!info.spec.isReferenced) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (info.spec.isExported) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var isDefined = info.spec.isDefined;
|
|
75
|
+
|
|
76
|
+
// Keep track of defined names within the program
|
|
77
|
+
if (isDefined) {
|
|
78
|
+
this.notGlobals.add(object.name);
|
|
79
|
+
this.globals.delete(object.name);
|
|
80
|
+
} else if (!this.notGlobals.has(object.name)) {
|
|
81
|
+
this.globals.add(object.name);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
var definingContexts = info.spec.isDefined
|
|
85
|
+
? getAllDefiningContexts(object, parents)
|
|
86
|
+
: getReferencingContexts(object, parents, info);
|
|
87
|
+
|
|
88
|
+
ok(definingContexts.length);
|
|
89
|
+
|
|
90
|
+
definingContexts.forEach((definingContext) => {
|
|
91
|
+
// ok(
|
|
92
|
+
// isContext(definingContext),
|
|
93
|
+
// `${definingContext.type} is not a context`
|
|
94
|
+
// );
|
|
95
|
+
|
|
96
|
+
if (isDefined) {
|
|
97
|
+
// Add to defined Map
|
|
98
|
+
if (!this.defined.has(definingContext)) {
|
|
99
|
+
this.defined.set(definingContext, new Set());
|
|
61
100
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (info.spec.isExported) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
var isDefined = info.spec.isDefined;
|
|
80
|
-
|
|
81
|
-
// Keep track of defined names within the program
|
|
82
|
-
if (isDefined) {
|
|
83
|
-
this.notGlobals.add(o.name);
|
|
84
|
-
this.globals.delete(o.name);
|
|
85
|
-
} else if (!this.notGlobals.has(o.name)) {
|
|
86
|
-
this.globals.add(o.name);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
var definingContexts = info.spec.isDefined
|
|
90
|
-
? getAllDefiningContexts(o, p)
|
|
91
|
-
: getReferencingContexts(o, p, info);
|
|
92
|
-
|
|
93
|
-
ok(definingContexts.length);
|
|
94
|
-
|
|
95
|
-
definingContexts.forEach((definingContext) => {
|
|
96
|
-
// ok(
|
|
97
|
-
// isContext(definingContext),
|
|
98
|
-
// `${definingContext.type} is not a context`
|
|
99
|
-
// );
|
|
100
|
-
|
|
101
|
-
if (isDefined) {
|
|
102
|
-
// Add to defined Map
|
|
103
|
-
if (!this.defined.has(definingContext)) {
|
|
104
|
-
this.defined.set(definingContext, new Set());
|
|
105
|
-
}
|
|
106
|
-
this.defined.get(definingContext).add(name);
|
|
107
|
-
this.references.has(definingContext) &&
|
|
108
|
-
this.references.get(definingContext).delete(name);
|
|
109
|
-
} else {
|
|
110
|
-
// Add to references Map
|
|
111
|
-
if (
|
|
112
|
-
!this.defined.has(definingContext) ||
|
|
113
|
-
!this.defined.get(definingContext).has(name)
|
|
114
|
-
) {
|
|
115
|
-
if (!this.references.has(definingContext)) {
|
|
116
|
-
this.references.set(definingContext, new Set());
|
|
117
|
-
}
|
|
118
|
-
this.references.get(definingContext).add(name);
|
|
119
|
-
}
|
|
101
|
+
this.defined.get(definingContext).add(name);
|
|
102
|
+
this.references.has(definingContext) &&
|
|
103
|
+
this.references.get(definingContext).delete(name);
|
|
104
|
+
} else {
|
|
105
|
+
// Add to references Map
|
|
106
|
+
if (
|
|
107
|
+
!this.defined.has(definingContext) ||
|
|
108
|
+
!this.defined.get(definingContext).has(name)
|
|
109
|
+
) {
|
|
110
|
+
if (!this.references.has(definingContext)) {
|
|
111
|
+
this.references.set(definingContext, new Set());
|
|
120
112
|
}
|
|
121
|
-
|
|
113
|
+
this.references.get(definingContext).add(name);
|
|
114
|
+
}
|
|
122
115
|
}
|
|
123
116
|
});
|
|
124
117
|
}
|