js-confuser 1.5.6 → 1.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/options.js +4 -4
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +16 -2
- package/dist/transforms/identifier/nameRecycling.js +8 -2
- package/dist/transforms/identifier/renameVariables.js +9 -0
- package/dist/transforms/lock/antiDebug.js +1 -1
- package/dist/transforms/lock/integrity.js +6 -2
- package/dist/transforms/lock/lock.js +40 -32
- package/dist/transforms/preparation/preparation.js +0 -7
- package/dist/transforms/rgf.js +32 -3
- package/dist/transforms/string/stringConcealing.js +77 -40
- package/dist/transforms/transform.js +1 -1
- package/package.json +2 -2
- package/src/options.ts +10 -4
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +16 -1
- package/src/transforms/identifier/nameRecycling.ts +14 -3
- package/src/transforms/identifier/renameVariables.ts +19 -0
- package/src/transforms/lock/antiDebug.ts +1 -1
- package/src/transforms/lock/integrity.ts +13 -1
- package/src/transforms/lock/lock.ts +81 -44
- package/src/transforms/preparation/preparation.ts +2 -21
- package/src/transforms/rgf.ts +39 -3
- package/src/transforms/string/stringConcealing.ts +120 -56
- package/src/transforms/transform.ts +1 -1
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +36 -0
- package/test/transforms/identifier/nameRecycling.test.ts +39 -0
- package/test/transforms/identifier/renameVariables.test.ts +38 -0
- package/test/transforms/lock/countermeasures.test.ts +18 -0
- package/test/transforms/rgf.test.ts +37 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js-confuser",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.8",
|
|
4
4
|
"description": "JavaScript Obfuscation Tool.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"author": "MichaelXF",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"acorn": "^8.
|
|
25
|
+
"acorn": "^8.8.2",
|
|
26
26
|
"escodegen": "^2.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
package/src/options.ts
CHANGED
|
@@ -770,7 +770,10 @@ export function validateOptions(options: ObfuscateOptions) {
|
|
|
770
770
|
|
|
771
771
|
if (options.lock) {
|
|
772
772
|
// Validate browser-lock option
|
|
773
|
-
if (
|
|
773
|
+
if (
|
|
774
|
+
options.lock.browserLock &&
|
|
775
|
+
typeof options.lock.browserLock !== "undefined"
|
|
776
|
+
) {
|
|
774
777
|
ok(
|
|
775
778
|
Array.isArray(options.lock.browserLock),
|
|
776
779
|
"browserLock must be an array"
|
|
@@ -783,7 +786,7 @@ export function validateOptions(options: ObfuscateOptions) {
|
|
|
783
786
|
);
|
|
784
787
|
}
|
|
785
788
|
// Validate os-lock option
|
|
786
|
-
if (typeof options.lock.osLock !== "undefined") {
|
|
789
|
+
if (options.lock.osLock && typeof options.lock.osLock !== "undefined") {
|
|
787
790
|
ok(Array.isArray(options.lock.osLock), "osLock must be an array");
|
|
788
791
|
ok(
|
|
789
792
|
!options.lock.osLock.find((osName) => !validOses.has(osName)),
|
|
@@ -791,12 +794,15 @@ export function validateOptions(options: ObfuscateOptions) {
|
|
|
791
794
|
);
|
|
792
795
|
}
|
|
793
796
|
// Validate domain-lock option
|
|
794
|
-
if (
|
|
797
|
+
if (
|
|
798
|
+
options.lock.domainLock &&
|
|
799
|
+
typeof options.lock.domainLock !== "undefined"
|
|
800
|
+
) {
|
|
795
801
|
ok(Array.isArray(options.lock.domainLock), "domainLock must be an array");
|
|
796
802
|
}
|
|
797
803
|
|
|
798
804
|
// Validate context option
|
|
799
|
-
if (typeof options.lock.context !== "undefined") {
|
|
805
|
+
if (options.lock.context && typeof options.lock.context !== "undefined") {
|
|
800
806
|
ok(Array.isArray(options.lock.context), "context must be an array");
|
|
801
807
|
}
|
|
802
808
|
|
|
@@ -47,6 +47,7 @@ import ChoiceFlowObfuscation from "./choiceFlowObfuscation";
|
|
|
47
47
|
import ControlFlowObfuscation from "./controlFlowObfuscation";
|
|
48
48
|
import ExpressionObfuscation from "./expressionObfuscation";
|
|
49
49
|
import SwitchCaseObfuscation from "./switchCaseObfuscation";
|
|
50
|
+
import { isModuleSource } from "../string/stringConcealing";
|
|
50
51
|
|
|
51
52
|
var flattenStructures = new Set([
|
|
52
53
|
"IfStatement",
|
|
@@ -226,6 +227,13 @@ export default class ControlFlowFlattening extends Transform {
|
|
|
226
227
|
fnNames.delete(illegal);
|
|
227
228
|
});
|
|
228
229
|
|
|
230
|
+
var importDeclarations = [];
|
|
231
|
+
for (var stmt of body) {
|
|
232
|
+
if (stmt.type === "ImportDeclaration") {
|
|
233
|
+
importDeclarations.push(stmt);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
229
237
|
var fraction = 0.9;
|
|
230
238
|
if (body.length > 20) {
|
|
231
239
|
fraction /= Math.max(1.2, body.length - 18);
|
|
@@ -285,6 +293,7 @@ export default class ControlFlowFlattening extends Transform {
|
|
|
285
293
|
if (
|
|
286
294
|
o.type == "Literal" &&
|
|
287
295
|
typeof o.value == "string" &&
|
|
296
|
+
!isModuleSource(o, p) &&
|
|
288
297
|
!o.regex &&
|
|
289
298
|
Math.random() / (Object.keys(stringBank).length / 2 + 1) > 0.5
|
|
290
299
|
) {
|
|
@@ -318,7 +327,10 @@ export default class ControlFlowFlattening extends Transform {
|
|
|
318
327
|
};
|
|
319
328
|
|
|
320
329
|
body.forEach((stmt, i) => {
|
|
321
|
-
if (
|
|
330
|
+
if (
|
|
331
|
+
functionDeclarations.has(stmt) ||
|
|
332
|
+
stmt.type === "ImportDeclaration"
|
|
333
|
+
) {
|
|
322
334
|
return;
|
|
323
335
|
}
|
|
324
336
|
|
|
@@ -1045,6 +1057,9 @@ export default class ControlFlowFlattening extends Transform {
|
|
|
1045
1057
|
var discriminant = Template(`${stateVars.join("+")}`).single().expression;
|
|
1046
1058
|
|
|
1047
1059
|
body.length = 0;
|
|
1060
|
+
for (var importDeclaration of importDeclarations) {
|
|
1061
|
+
body.push(importDeclaration);
|
|
1062
|
+
}
|
|
1048
1063
|
|
|
1049
1064
|
if (functionDeclarations.size) {
|
|
1050
1065
|
functionDeclarations.forEach((x) => {
|
|
@@ -97,8 +97,6 @@ export default class NameRecycling extends Transform {
|
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
lastReferenceMap.set(o.name, i);
|
|
101
|
-
|
|
102
100
|
var comparingContext = info.spec.isDefined
|
|
103
101
|
? getDefiningContext(o, p)
|
|
104
102
|
: getReferencingContexts(o, p).find((x) => isVarContext(x));
|
|
@@ -114,7 +112,18 @@ export default class NameRecycling extends Transform {
|
|
|
114
112
|
}
|
|
115
113
|
|
|
116
114
|
if (info.spec.isDefined) {
|
|
117
|
-
|
|
115
|
+
// Function Declarations can be used before they're defined, if so, don't change this
|
|
116
|
+
if (
|
|
117
|
+
info.isFunctionDeclaration &&
|
|
118
|
+
lastReferenceMap.has(o.name)
|
|
119
|
+
) {
|
|
120
|
+
illegal.add(o.name);
|
|
121
|
+
}
|
|
122
|
+
if (
|
|
123
|
+
defined.has(o.name) ||
|
|
124
|
+
getBlock(o, p) !== object ||
|
|
125
|
+
info.isImportSpecifier
|
|
126
|
+
) {
|
|
118
127
|
illegal.add(o.name);
|
|
119
128
|
}
|
|
120
129
|
defined.add(o.name);
|
|
@@ -123,6 +132,8 @@ export default class NameRecycling extends Transform {
|
|
|
123
132
|
referencedHere.add(o.name);
|
|
124
133
|
}
|
|
125
134
|
}
|
|
135
|
+
|
|
136
|
+
lastReferenceMap.set(o.name, i);
|
|
126
137
|
};
|
|
127
138
|
}
|
|
128
139
|
});
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
isContext,
|
|
11
11
|
isLexContext,
|
|
12
12
|
getDefiningContext,
|
|
13
|
+
clone,
|
|
13
14
|
} from "../../util/insert";
|
|
14
15
|
import { isValidIdentifier } from "../../util/compare";
|
|
15
16
|
import Transform from "../transform";
|
|
@@ -185,6 +186,24 @@ export default class RenameVariables extends Transform {
|
|
|
185
186
|
return;
|
|
186
187
|
}
|
|
187
188
|
|
|
189
|
+
// Strange behavior where the `local` and `imported` objects are the same
|
|
190
|
+
if (info.isImportSpecifier) {
|
|
191
|
+
var importSpecifierIndex = p.findIndex(
|
|
192
|
+
(x) => x.type === "ImportSpecifier"
|
|
193
|
+
);
|
|
194
|
+
if (
|
|
195
|
+
importSpecifierIndex != -1 &&
|
|
196
|
+
p[importSpecifierIndex].imported ===
|
|
197
|
+
(p[importSpecifierIndex - 1] || o) &&
|
|
198
|
+
p[importSpecifierIndex].imported &&
|
|
199
|
+
p[importSpecifierIndex].imported.type === "Identifier"
|
|
200
|
+
) {
|
|
201
|
+
p[importSpecifierIndex].imported = clone(
|
|
202
|
+
p[importSpecifierIndex - 1] || o
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
188
207
|
// console.log(o.name, "->", newName);
|
|
189
208
|
o.name = newName;
|
|
190
209
|
o.$renamed = true;
|
|
@@ -62,7 +62,7 @@ export default class AntiDebug extends Transform {
|
|
|
62
62
|
IfStatement(
|
|
63
63
|
Identifier(isDevName),
|
|
64
64
|
this.options.lock.countermeasures
|
|
65
|
-
? this.lock.getCounterMeasuresCode()
|
|
65
|
+
? this.lock.getCounterMeasuresCode(tree.body, [tree])
|
|
66
66
|
: [
|
|
67
67
|
WhileStatement(Identifier(isDevName), [
|
|
68
68
|
ExpressionStatement(
|
|
@@ -195,7 +195,10 @@ export default class Integrity extends Transform {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
return () => {
|
|
198
|
-
object.__hiddenCountermeasures = this.lock.getCounterMeasuresCode(
|
|
198
|
+
object.__hiddenCountermeasures = this.lock.getCounterMeasuresCode(
|
|
199
|
+
object,
|
|
200
|
+
parents
|
|
201
|
+
);
|
|
199
202
|
|
|
200
203
|
object.$eval = () => {
|
|
201
204
|
var functionName = this.generateIdentifier();
|
|
@@ -258,6 +261,15 @@ export default class Integrity extends Transform {
|
|
|
258
261
|
ifStatement,
|
|
259
262
|
]);
|
|
260
263
|
|
|
264
|
+
// Make sure the countermeasures activation variable is present
|
|
265
|
+
if (this.lock.counterMeasuresActivated) {
|
|
266
|
+
object.body.body.unshift(
|
|
267
|
+
VariableDeclaration(
|
|
268
|
+
VariableDeclarator(this.lock.counterMeasuresActivated)
|
|
269
|
+
)
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
261
273
|
if (object.type == "ArrowFunctionExpression") {
|
|
262
274
|
object.type = "FunctionExpression";
|
|
263
275
|
object.expression = false;
|
|
@@ -11,17 +11,12 @@ import {
|
|
|
11
11
|
Literal,
|
|
12
12
|
UnaryExpression,
|
|
13
13
|
NewExpression,
|
|
14
|
-
FunctionDeclaration,
|
|
15
|
-
ReturnStatement,
|
|
16
14
|
VariableDeclaration,
|
|
17
|
-
ObjectExpression,
|
|
18
|
-
Property,
|
|
19
|
-
ArrayExpression,
|
|
20
|
-
FunctionExpression,
|
|
21
15
|
ThisExpression,
|
|
22
16
|
VariableDeclarator,
|
|
23
17
|
Location,
|
|
24
18
|
LogicalExpression,
|
|
19
|
+
SequenceExpression,
|
|
25
20
|
} from "../../util/gen";
|
|
26
21
|
import traverse, { getBlock, isBlock } from "../../traverse";
|
|
27
22
|
import { choice, getRandomInteger } from "../../util/random";
|
|
@@ -47,6 +42,12 @@ export default class Lock extends Transform {
|
|
|
47
42
|
counterMeasuresNode: Location;
|
|
48
43
|
iosDetectFn: string;
|
|
49
44
|
|
|
45
|
+
/**
|
|
46
|
+
* This is a boolean variable injected into the source code determining wether the countermeasures function has been called.
|
|
47
|
+
* This is used to prevent infinite loops from happening
|
|
48
|
+
*/
|
|
49
|
+
counterMeasuresActivated: string;
|
|
50
|
+
|
|
50
51
|
made: number;
|
|
51
52
|
|
|
52
53
|
constructor(o) {
|
|
@@ -73,36 +74,32 @@ export default class Lock extends Transform {
|
|
|
73
74
|
typeof this.options.lock.countermeasures === "string" &&
|
|
74
75
|
isValidIdentifier(this.options.lock.countermeasures)
|
|
75
76
|
) {
|
|
76
|
-
var defined = new Set<string>();
|
|
77
77
|
traverse(tree, (object, parents) => {
|
|
78
|
-
if (
|
|
78
|
+
if (
|
|
79
|
+
object.type == "Identifier" &&
|
|
80
|
+
object.name === this.options.lock.countermeasures
|
|
81
|
+
) {
|
|
79
82
|
var info = getIdentifierInfo(object, parents);
|
|
80
83
|
if (info.spec.isDefined) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
if (this.counterMeasuresNode) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
"Countermeasures function was already defined, it must have a unique name from the rest of your code"
|
|
87
|
+
);
|
|
88
|
+
} else {
|
|
89
|
+
var definingContext = getVarContext(parents[0], parents.slice(1));
|
|
90
|
+
if (definingContext != tree) {
|
|
84
91
|
throw new Error(
|
|
85
|
-
"Countermeasures function
|
|
86
|
-
);
|
|
87
|
-
} else {
|
|
88
|
-
var definingContext = getVarContext(
|
|
89
|
-
parents[0],
|
|
90
|
-
parents.slice(1)
|
|
92
|
+
"Countermeasures function must be defined at the global level"
|
|
91
93
|
);
|
|
92
|
-
if (definingContext != tree) {
|
|
93
|
-
throw new Error(
|
|
94
|
-
"Countermeasures function must be defined at the global level"
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
var chain: Location = [object, parents];
|
|
98
|
-
if (info.isFunctionDeclaration) {
|
|
99
|
-
chain = [parents[0], parents.slice(1)];
|
|
100
|
-
} else if (info.isVariableDeclaration) {
|
|
101
|
-
chain = [parents[1], parents.slice(2)];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
this.counterMeasuresNode = chain;
|
|
105
94
|
}
|
|
95
|
+
var chain: Location = [object, parents];
|
|
96
|
+
if (info.isFunctionDeclaration) {
|
|
97
|
+
chain = [parents[0], parents.slice(1)];
|
|
98
|
+
} else if (info.isVariableDeclaration) {
|
|
99
|
+
chain = [parents[1], parents.slice(2)];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.counterMeasuresNode = chain;
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
}
|
|
@@ -120,7 +117,7 @@ export default class Lock extends Transform {
|
|
|
120
117
|
super.apply(tree);
|
|
121
118
|
}
|
|
122
119
|
|
|
123
|
-
getCounterMeasuresCode(): Node[] {
|
|
120
|
+
getCounterMeasuresCode(object: Node, parents: Node[]): Node[] {
|
|
124
121
|
var opt = this.options.lock.countermeasures;
|
|
125
122
|
|
|
126
123
|
if (opt === false) {
|
|
@@ -129,10 +126,30 @@ export default class Lock extends Transform {
|
|
|
129
126
|
|
|
130
127
|
// Call function
|
|
131
128
|
if (typeof opt === "string") {
|
|
129
|
+
if (!this.counterMeasuresActivated) {
|
|
130
|
+
this.counterMeasuresActivated = this.getPlaceholder();
|
|
131
|
+
|
|
132
|
+
prepend(
|
|
133
|
+
parents[parents.length - 1] || object,
|
|
134
|
+
VariableDeclaration(VariableDeclarator(this.counterMeasuresActivated))
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
132
138
|
// Since Lock occurs before variable renaming, we are using the pre-obfuscated function name
|
|
133
139
|
return [
|
|
134
140
|
ExpressionStatement(
|
|
135
|
-
|
|
141
|
+
LogicalExpression(
|
|
142
|
+
"||",
|
|
143
|
+
Identifier(this.counterMeasuresActivated),
|
|
144
|
+
SequenceExpression([
|
|
145
|
+
AssignmentExpression(
|
|
146
|
+
"=",
|
|
147
|
+
Identifier(this.counterMeasuresActivated),
|
|
148
|
+
Literal(true)
|
|
149
|
+
),
|
|
150
|
+
CallExpression(Template(opt).single().expression, []),
|
|
151
|
+
])
|
|
152
|
+
)
|
|
136
153
|
),
|
|
137
154
|
];
|
|
138
155
|
}
|
|
@@ -288,7 +305,7 @@ export default class Lock extends Transform {
|
|
|
288
305
|
nodes.push(
|
|
289
306
|
IfStatement(
|
|
290
307
|
callExpression,
|
|
291
|
-
this.getCounterMeasuresCode() || [],
|
|
308
|
+
this.getCounterMeasuresCode(object, parents) || [],
|
|
292
309
|
null
|
|
293
310
|
)
|
|
294
311
|
);
|
|
@@ -324,7 +341,11 @@ export default class Lock extends Transform {
|
|
|
324
341
|
}
|
|
325
342
|
|
|
326
343
|
nodes.push(
|
|
327
|
-
IfStatement(
|
|
344
|
+
IfStatement(
|
|
345
|
+
test,
|
|
346
|
+
this.getCounterMeasuresCode(object, parents) || [],
|
|
347
|
+
null
|
|
348
|
+
)
|
|
328
349
|
);
|
|
329
350
|
}
|
|
330
351
|
|
|
@@ -338,7 +359,11 @@ export default class Lock extends Transform {
|
|
|
338
359
|
);
|
|
339
360
|
|
|
340
361
|
nodes.push(
|
|
341
|
-
IfStatement(
|
|
362
|
+
IfStatement(
|
|
363
|
+
test,
|
|
364
|
+
this.getCounterMeasuresCode(object, parents) || [],
|
|
365
|
+
null
|
|
366
|
+
)
|
|
342
367
|
);
|
|
343
368
|
|
|
344
369
|
break;
|
|
@@ -351,7 +376,11 @@ export default class Lock extends Transform {
|
|
|
351
376
|
);
|
|
352
377
|
|
|
353
378
|
nodes.push(
|
|
354
|
-
IfStatement(
|
|
379
|
+
IfStatement(
|
|
380
|
+
test,
|
|
381
|
+
this.getCounterMeasuresCode(object, parents) || [],
|
|
382
|
+
null
|
|
383
|
+
)
|
|
355
384
|
);
|
|
356
385
|
|
|
357
386
|
break;
|
|
@@ -359,6 +388,8 @@ export default class Lock extends Transform {
|
|
|
359
388
|
case "context":
|
|
360
389
|
var prop = choice(this.options.lock.context);
|
|
361
390
|
|
|
391
|
+
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
392
|
+
|
|
362
393
|
// Todo: Alternative to `this`
|
|
363
394
|
if (!this.globalVar) {
|
|
364
395
|
offset = 1;
|
|
@@ -384,9 +415,7 @@ export default class Lock extends Transform {
|
|
|
384
415
|
"!",
|
|
385
416
|
MemberExpression(Identifier(this.globalVar), Literal(prop), true)
|
|
386
417
|
);
|
|
387
|
-
nodes.push(
|
|
388
|
-
IfStatement(test, this.getCounterMeasuresCode() || [], null)
|
|
389
|
-
);
|
|
418
|
+
nodes.push(IfStatement(test, code, null));
|
|
390
419
|
|
|
391
420
|
break;
|
|
392
421
|
|
|
@@ -397,6 +426,8 @@ export default class Lock extends Transform {
|
|
|
397
426
|
|
|
398
427
|
ok(this.options.lock.osLock);
|
|
399
428
|
|
|
429
|
+
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
430
|
+
|
|
400
431
|
this.options.lock.osLock.forEach((osName) => {
|
|
401
432
|
var agentMatcher = {
|
|
402
433
|
windows: "Win",
|
|
@@ -449,9 +480,7 @@ export default class Lock extends Transform {
|
|
|
449
480
|
});
|
|
450
481
|
|
|
451
482
|
test = UnaryExpression("!", { ...test });
|
|
452
|
-
nodes.push(
|
|
453
|
-
IfStatement(test, this.getCounterMeasuresCode() || [], null)
|
|
454
|
-
);
|
|
483
|
+
nodes.push(IfStatement(test, code, null));
|
|
455
484
|
break;
|
|
456
485
|
|
|
457
486
|
case "browserLock":
|
|
@@ -488,7 +517,11 @@ export default class Lock extends Transform {
|
|
|
488
517
|
|
|
489
518
|
test = UnaryExpression("!", { ...test });
|
|
490
519
|
nodes.push(
|
|
491
|
-
IfStatement(
|
|
520
|
+
IfStatement(
|
|
521
|
+
test,
|
|
522
|
+
this.getCounterMeasuresCode(object, parents) || [],
|
|
523
|
+
null
|
|
524
|
+
)
|
|
492
525
|
);
|
|
493
526
|
break;
|
|
494
527
|
|
|
@@ -540,7 +573,11 @@ export default class Lock extends Transform {
|
|
|
540
573
|
);
|
|
541
574
|
}
|
|
542
575
|
nodes.push(
|
|
543
|
-
IfStatement(
|
|
576
|
+
IfStatement(
|
|
577
|
+
test,
|
|
578
|
+
this.getCounterMeasuresCode(object, parents) || [],
|
|
579
|
+
null
|
|
580
|
+
)
|
|
544
581
|
);
|
|
545
582
|
}
|
|
546
583
|
|
|
@@ -3,24 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import Transform from "../transform";
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
BlockStatement,
|
|
8
|
-
Identifier,
|
|
9
|
-
LabeledStatement,
|
|
10
|
-
Literal,
|
|
11
|
-
Location,
|
|
12
|
-
Node,
|
|
13
|
-
ReturnStatement,
|
|
14
|
-
} from "../../util/gen";
|
|
6
|
+
import { BlockStatement, Literal, ReturnStatement } from "../../util/gen";
|
|
15
7
|
import { ObfuscateOrder } from "../../order";
|
|
16
|
-
import {
|
|
17
|
-
import { ok } from "assert";
|
|
8
|
+
import { clone, getFunction } from "../../util/insert";
|
|
18
9
|
import { getIdentifierInfo } from "../../util/identifiers";
|
|
19
|
-
import { walk } from "../../traverse";
|
|
20
10
|
import Label from "../label";
|
|
21
|
-
import NameConflicts from "./nameConflicts";
|
|
22
|
-
import AntiDestructuring from "../es5/antiDestructuring";
|
|
23
|
-
import { OPERATOR_PRECEDENCE } from "../../precedence";
|
|
24
11
|
import { isLoop } from "../../util/compare";
|
|
25
12
|
|
|
26
13
|
/**
|
|
@@ -181,12 +168,6 @@ export default class Preparation extends Transform {
|
|
|
181
168
|
this.before.push(new Label(o));
|
|
182
169
|
this.before.push(new ExplicitIdentifiers(o));
|
|
183
170
|
this.before.push(new ExplicitDeclarations(o));
|
|
184
|
-
|
|
185
|
-
if (this.options.es5) {
|
|
186
|
-
this.before.push(new AntiDestructuring(o));
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// this.before.push(new NameConflicts(o));
|
|
190
171
|
}
|
|
191
172
|
|
|
192
173
|
match() {
|
package/src/transforms/rgf.ts
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
isVarContext,
|
|
31
31
|
isFunction,
|
|
32
32
|
prepend,
|
|
33
|
+
getDefiningContext,
|
|
33
34
|
} from "../util/insert";
|
|
34
35
|
import { getRandomString } from "../util/random";
|
|
35
36
|
import Transform from "./transform";
|
|
@@ -106,12 +107,44 @@ export default class RGF extends Transform {
|
|
|
106
107
|
return;
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
// Avoid applying to the countermeasures function
|
|
111
|
+
if (typeof this.options.lock?.countermeasures === "string") {
|
|
112
|
+
// function countermeasures(){...}
|
|
113
|
+
if (
|
|
114
|
+
object.type === "FunctionDeclaration" &&
|
|
115
|
+
object.id.type === "Identifier" &&
|
|
116
|
+
object.id.name === this.options.lock.countermeasures
|
|
117
|
+
) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// var countermeasures = function(){...}
|
|
122
|
+
if (
|
|
123
|
+
parents[0].type === "VariableDeclarator" &&
|
|
124
|
+
parents[0].init === object &&
|
|
125
|
+
parents[0].id.type === "Identifier" &&
|
|
126
|
+
parents[0].id.name === this.options.lock.countermeasures
|
|
127
|
+
) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
109
132
|
var defined = new Set<string>(),
|
|
110
133
|
referenced = new Set<string>();
|
|
111
134
|
|
|
112
135
|
var isBound = false;
|
|
113
136
|
|
|
114
|
-
|
|
137
|
+
/**
|
|
138
|
+
* The fnTraverses serves two important purposes
|
|
139
|
+
*
|
|
140
|
+
* - Identify all the variables referenced and defined here
|
|
141
|
+
* - Identify is the 'this' keyword is used anywhere
|
|
142
|
+
*
|
|
143
|
+
* @param o
|
|
144
|
+
* @param p
|
|
145
|
+
* @returns
|
|
146
|
+
*/
|
|
147
|
+
const fnTraverser = (o, p) => {
|
|
115
148
|
if (
|
|
116
149
|
o.type == "Identifier" &&
|
|
117
150
|
!reservedIdentifiers.has(o.name) &&
|
|
@@ -121,7 +154,7 @@ export default class RGF extends Transform {
|
|
|
121
154
|
if (!info.spec.isReferenced) {
|
|
122
155
|
return;
|
|
123
156
|
}
|
|
124
|
-
if (info.spec.isDefined) {
|
|
157
|
+
if (info.spec.isDefined && getDefiningContext(o, p) === object) {
|
|
125
158
|
defined.add(o.name);
|
|
126
159
|
} else {
|
|
127
160
|
referenced.add(o.name);
|
|
@@ -131,7 +164,10 @@ export default class RGF extends Transform {
|
|
|
131
164
|
if (o.type == "ThisExpression" || o.type == "Super") {
|
|
132
165
|
isBound = true;
|
|
133
166
|
}
|
|
134
|
-
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
walk(object.params, [object, ...parents], fnTraverser);
|
|
170
|
+
walk(object.body, [object, ...parents], fnTraverser);
|
|
135
171
|
|
|
136
172
|
if (!isBound) {
|
|
137
173
|
defined.forEach((identifier) => {
|