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,12 +1,11 @@
|
|
|
1
1
|
import { ok } from "assert";
|
|
2
2
|
import { ObfuscateOrder } from "../../order";
|
|
3
3
|
import Template from "../../templates/template";
|
|
4
|
-
import {
|
|
5
|
-
import { isDirective } from "../../util/compare";
|
|
4
|
+
import { getBlock } from "../../traverse";
|
|
5
|
+
import { isDirective, isModuleSource } from "../../util/compare";
|
|
6
6
|
import {
|
|
7
7
|
ArrayExpression,
|
|
8
8
|
CallExpression,
|
|
9
|
-
FunctionExpression,
|
|
10
9
|
Identifier,
|
|
11
10
|
Literal,
|
|
12
11
|
MemberExpression,
|
|
@@ -22,54 +21,39 @@ import {
|
|
|
22
21
|
choice,
|
|
23
22
|
getRandomInteger,
|
|
24
23
|
getRandomString,
|
|
24
|
+
shuffle,
|
|
25
25
|
} from "../../util/random";
|
|
26
26
|
import Transform from "../transform";
|
|
27
|
-
import
|
|
27
|
+
import {
|
|
28
|
+
EncodingImplementation,
|
|
29
|
+
EncodingImplementations,
|
|
30
|
+
createEncodingImplementation,
|
|
31
|
+
hasAllEncodings,
|
|
32
|
+
} from "./encoding";
|
|
28
33
|
import { ComputeProbabilityMap } from "../../probability";
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (parents[0].type == "ImportExpression" && parents[0].source == object) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (
|
|
45
|
-
parents[1] &&
|
|
46
|
-
parents[1].type == "CallExpression" &&
|
|
47
|
-
parents[1].arguments[0] === object &&
|
|
48
|
-
parents[1].callee.type == "Identifier"
|
|
49
|
-
) {
|
|
50
|
-
if (
|
|
51
|
-
parents[1].callee.name == "require" ||
|
|
52
|
-
parents[1].callee.name == "import"
|
|
53
|
-
) {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return false;
|
|
34
|
+
import {
|
|
35
|
+
BufferToStringTemplate,
|
|
36
|
+
createGetGlobalTemplate,
|
|
37
|
+
} from "../../templates/bufferToString";
|
|
38
|
+
import { criticalFunctionTag, predictableFunctionTag } from "../../constants";
|
|
39
|
+
|
|
40
|
+
interface FunctionObject {
|
|
41
|
+
block: Node;
|
|
42
|
+
fnName: string;
|
|
43
|
+
encodingImplementation: EncodingImplementation;
|
|
59
44
|
}
|
|
60
45
|
|
|
61
46
|
export default class StringConcealing extends Transform {
|
|
62
47
|
arrayExpression: Node;
|
|
63
48
|
set: Set<string>;
|
|
64
|
-
index: { [str: string]: [number, string] };
|
|
49
|
+
index: { [str: string]: [number, string, Node] }; // index, fnName, block
|
|
65
50
|
|
|
66
51
|
arrayName = this.getPlaceholder();
|
|
67
52
|
ignore = new Set<string>();
|
|
68
53
|
variablesMade = 1;
|
|
69
|
-
encoding: { [type: string]: string } = Object.create(null);
|
|
70
54
|
gen: ReturnType<Transform["getGenerator"]>;
|
|
71
55
|
|
|
72
|
-
|
|
56
|
+
functionObjects: FunctionObject[] = [];
|
|
73
57
|
|
|
74
58
|
constructor(o) {
|
|
75
59
|
super(o, ObfuscateOrder.StringConcealing);
|
|
@@ -77,84 +61,111 @@ export default class StringConcealing extends Transform {
|
|
|
77
61
|
this.set = new Set();
|
|
78
62
|
this.index = Object.create(null);
|
|
79
63
|
this.arrayExpression = ArrayExpression([]);
|
|
80
|
-
this.hasAllEncodings = false;
|
|
81
64
|
this.gen = this.getGenerator();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
apply(tree) {
|
|
68
|
+
super.apply(tree);
|
|
82
69
|
|
|
83
70
|
// Pad array with useless strings
|
|
84
|
-
var dead = getRandomInteger(
|
|
71
|
+
var dead = getRandomInteger(50, 200);
|
|
85
72
|
for (var i = 0; i < dead; i++) {
|
|
86
73
|
var str = getRandomString(getRandomInteger(5, 40));
|
|
87
|
-
var fn = this.transform(Literal(str), []);
|
|
74
|
+
var fn = this.transform(Literal(str), [tree]);
|
|
88
75
|
if (fn) {
|
|
89
76
|
fn();
|
|
90
77
|
}
|
|
91
78
|
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
apply(tree) {
|
|
95
|
-
super.apply(tree);
|
|
96
79
|
|
|
97
80
|
var cacheName = this.getPlaceholder();
|
|
98
|
-
var bufferToStringName = this.getPlaceholder();
|
|
81
|
+
var bufferToStringName = this.getPlaceholder() + predictableFunctionTag;
|
|
99
82
|
|
|
100
83
|
// This helper functions convert UInt8 Array to UTf-string
|
|
101
84
|
prepend(
|
|
102
85
|
tree,
|
|
103
|
-
...BufferToStringTemplate.compile({
|
|
86
|
+
...BufferToStringTemplate.compile({
|
|
87
|
+
name: bufferToStringName,
|
|
88
|
+
getGlobalFnName: this.getPlaceholder() + predictableFunctionTag,
|
|
89
|
+
GetGlobalTemplate: createGetGlobalTemplate(this, tree, []),
|
|
90
|
+
})
|
|
104
91
|
);
|
|
105
92
|
|
|
106
|
-
|
|
107
|
-
var {
|
|
108
|
-
|
|
109
|
-
|
|
93
|
+
for (var functionObject of this.functionObjects) {
|
|
94
|
+
var {
|
|
95
|
+
block,
|
|
96
|
+
fnName: getterFnName,
|
|
97
|
+
encodingImplementation,
|
|
98
|
+
} = functionObject;
|
|
99
|
+
|
|
100
|
+
var decodeFn =
|
|
101
|
+
this.getPlaceholder() + predictableFunctionTag + criticalFunctionTag;
|
|
110
102
|
|
|
111
103
|
append(
|
|
112
|
-
|
|
113
|
-
template.single({
|
|
104
|
+
block,
|
|
105
|
+
encodingImplementation.template.single({
|
|
106
|
+
__fnName__: decodeFn,
|
|
107
|
+
__bufferToString__: bufferToStringName,
|
|
108
|
+
})
|
|
114
109
|
);
|
|
110
|
+
// All these are fake and never ran
|
|
111
|
+
var ifStatements = new Template(`if ( z == x ) {
|
|
112
|
+
return y[${cacheName}[z]] = ${getterFnName}(x, y);
|
|
113
|
+
}
|
|
114
|
+
if ( y ) {
|
|
115
|
+
[b, y] = [a(b), x || z]
|
|
116
|
+
return ${getterFnName}(x, b, z)
|
|
117
|
+
}
|
|
118
|
+
if ( z && a !== ${decodeFn} ) {
|
|
119
|
+
${getterFnName} = ${decodeFn}
|
|
120
|
+
return ${getterFnName}(x, -1, z, a, b)
|
|
121
|
+
}
|
|
122
|
+
if ( a === ${getterFnName} ) {
|
|
123
|
+
${decodeFn} = y
|
|
124
|
+
return ${decodeFn}(z)
|
|
125
|
+
}
|
|
126
|
+
if( a === undefined ) {
|
|
127
|
+
${getterFnName} = b
|
|
128
|
+
}
|
|
129
|
+
if( z == a ) {
|
|
130
|
+
return y ? x[b[y]] : ${cacheName}[x] || (z=(b[x] || a), ${cacheName}[x] = z(${this.arrayName}[x]))
|
|
131
|
+
}
|
|
132
|
+
`).compile();
|
|
115
133
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return y ? x[b[y]] : ${cacheName}[x] || (z=(b[x], a), ${cacheName}[x] = z(${this.arrayName}[x]))
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
`).single()
|
|
134
|
+
// Not all fake if-statements are needed
|
|
135
|
+
ifStatements = ifStatements.filter(() => chance(50));
|
|
136
|
+
|
|
137
|
+
// This one is always used
|
|
138
|
+
ifStatements.push(
|
|
139
|
+
new Template(`
|
|
140
|
+
if ( x !== y ) {
|
|
141
|
+
return b[x] || (b[x] = a(${this.arrayName}[x]))
|
|
142
|
+
}
|
|
143
|
+
`).single()
|
|
131
144
|
);
|
|
132
|
-
});
|
|
133
145
|
|
|
134
|
-
|
|
146
|
+
shuffle(ifStatements);
|
|
147
|
+
|
|
148
|
+
var varDeclaration = new Template(`
|
|
149
|
+
var ${getterFnName} = (x, y, z, a, b)=>{
|
|
150
|
+
if(typeof a === "undefined") {
|
|
151
|
+
a = ${decodeFn}
|
|
152
|
+
}
|
|
153
|
+
if(typeof b === "undefined") {
|
|
154
|
+
b = ${cacheName}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
`).single();
|
|
158
|
+
|
|
159
|
+
varDeclaration.declarations[0].init.body.body.push(...ifStatements);
|
|
160
|
+
|
|
161
|
+
prepend(block, varDeclaration);
|
|
162
|
+
}
|
|
135
163
|
|
|
136
164
|
prepend(
|
|
137
165
|
tree,
|
|
138
166
|
VariableDeclaration([
|
|
139
167
|
VariableDeclarator(cacheName, ArrayExpression([])),
|
|
140
|
-
VariableDeclarator(
|
|
141
|
-
VariableDeclarator(
|
|
142
|
-
this.arrayName,
|
|
143
|
-
CallExpression(
|
|
144
|
-
FunctionExpression(
|
|
145
|
-
[],
|
|
146
|
-
[
|
|
147
|
-
VariableDeclaration(
|
|
148
|
-
VariableDeclarator("a", this.arrayExpression)
|
|
149
|
-
),
|
|
150
|
-
Template(
|
|
151
|
-
`return (${flowIntegrity} ? a["pop"]() : ${flowIntegrity}++, a)`
|
|
152
|
-
).single(),
|
|
153
|
-
]
|
|
154
|
-
),
|
|
155
|
-
[]
|
|
156
|
-
)
|
|
157
|
-
),
|
|
168
|
+
VariableDeclarator(this.arrayName, this.arrayExpression),
|
|
158
169
|
])
|
|
159
170
|
);
|
|
160
171
|
}
|
|
@@ -166,7 +177,7 @@ export default class StringConcealing extends Transform {
|
|
|
166
177
|
object.value.length >= 3 &&
|
|
167
178
|
!isModuleSource(object, parents) &&
|
|
168
179
|
!isDirective(object, parents) //&&
|
|
169
|
-
/*!parents.find((x) => x.$
|
|
180
|
+
/*!parents.find((x) => x.$multiTransformSkip)*/
|
|
170
181
|
);
|
|
171
182
|
}
|
|
172
183
|
|
|
@@ -192,48 +203,67 @@ export default class StringConcealing extends Transform {
|
|
|
192
203
|
return;
|
|
193
204
|
}
|
|
194
205
|
|
|
195
|
-
|
|
196
|
-
if (this.set.size > 1000 && !chance(this.set.size / 100)) return;
|
|
206
|
+
var currentBlock = getBlock(object, parents);
|
|
197
207
|
|
|
198
|
-
|
|
208
|
+
// Find created functions
|
|
209
|
+
var functionObjects: FunctionObject[] = parents
|
|
210
|
+
.filter((node) => node.$stringConcealingFunctionObject)
|
|
211
|
+
.map((item) => item.$stringConcealingFunctionObject);
|
|
199
212
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
213
|
+
// Choose random functionObject to use
|
|
214
|
+
var functionObject = choice(functionObjects);
|
|
215
|
+
|
|
216
|
+
if (
|
|
217
|
+
!functionObject ||
|
|
218
|
+
(!hasAllEncodings() &&
|
|
219
|
+
chance(25 / this.functionObjects.length) &&
|
|
220
|
+
!currentBlock.$stringConcealingFunctionObject)
|
|
221
|
+
) {
|
|
222
|
+
// No functions, create one
|
|
205
223
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
224
|
+
var newFunctionObject: FunctionObject = {
|
|
225
|
+
block: currentBlock,
|
|
226
|
+
encodingImplementation: createEncodingImplementation(),
|
|
227
|
+
fnName: this.getPlaceholder() + predictableFunctionTag,
|
|
228
|
+
};
|
|
211
229
|
|
|
212
|
-
|
|
213
|
-
|
|
230
|
+
this.functionObjects.push(newFunctionObject);
|
|
231
|
+
currentBlock.$stringConcealingFunctionObject = newFunctionObject;
|
|
232
|
+
functionObject = newFunctionObject;
|
|
214
233
|
}
|
|
215
234
|
|
|
216
|
-
var fnName =
|
|
217
|
-
var encoder = Encoding[type];
|
|
235
|
+
var { fnName, encodingImplementation } = functionObject;
|
|
218
236
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
this.
|
|
224
|
-
|
|
237
|
+
var index = -1;
|
|
238
|
+
|
|
239
|
+
// String already decoded?
|
|
240
|
+
if (this.set.has(object.value)) {
|
|
241
|
+
var row = this.index[object.value];
|
|
242
|
+
if (parents.includes(row[2])) {
|
|
243
|
+
[index, fnName] = row;
|
|
244
|
+
ok(typeof index === "number");
|
|
245
|
+
}
|
|
225
246
|
}
|
|
226
247
|
|
|
227
|
-
|
|
228
|
-
|
|
248
|
+
if (index == -1) {
|
|
249
|
+
// The decode function must return correct result
|
|
250
|
+
var encoded = encodingImplementation.encode(object.value);
|
|
251
|
+
if (encodingImplementation.decode(encoded) !== object.value) {
|
|
252
|
+
this.ignore.add(object.value);
|
|
253
|
+
this.warn(
|
|
254
|
+
encodingImplementation.identity,
|
|
255
|
+
object.value.slice(0, 100)
|
|
256
|
+
);
|
|
257
|
+
delete EncodingImplementations[encodingImplementation.identity];
|
|
258
|
+
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
229
262
|
this.arrayExpression.elements.push(Literal(encoded));
|
|
230
263
|
index = this.arrayExpression.elements.length - 1;
|
|
231
|
-
this.index[object.value] = [index, fnName];
|
|
264
|
+
this.index[object.value] = [index, fnName, currentBlock];
|
|
232
265
|
|
|
233
266
|
this.set.add(object.value);
|
|
234
|
-
} else {
|
|
235
|
-
[index, fnName] = this.index[object.value];
|
|
236
|
-
ok(typeof index === "number");
|
|
237
267
|
}
|
|
238
268
|
|
|
239
269
|
ok(index != -1, "index == -1");
|
|
@@ -269,7 +299,7 @@ export default class StringConcealing extends Transform {
|
|
|
269
299
|
|
|
270
300
|
var constantReferenceType = choice(["variable", "array", "object"]);
|
|
271
301
|
|
|
272
|
-
var place =
|
|
302
|
+
var place = currentBlock;
|
|
273
303
|
if (!place) {
|
|
274
304
|
this.error(new Error("No lexical block to insert code"));
|
|
275
305
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Transform from "../transform";
|
|
2
2
|
import { choice } from "../../util/random";
|
|
3
|
-
import { isDirective } from "../../util/compare";
|
|
4
|
-
import { isModuleSource } from "./stringConcealing";
|
|
3
|
+
import { isDirective, isModuleSource } from "../../util/compare";
|
|
5
4
|
import { ComputeProbabilityMap } from "../../probability";
|
|
6
5
|
import { Identifier } from "../../util/gen";
|
|
7
6
|
|
|
@@ -3,8 +3,7 @@ import { Node, Literal, BinaryExpression } from "../../util/gen";
|
|
|
3
3
|
import { clone } from "../../util/insert";
|
|
4
4
|
import { getRandomInteger, shuffle, splitIntoChunks } from "../../util/random";
|
|
5
5
|
import { ObfuscateOrder } from "../../order";
|
|
6
|
-
import { isModuleSource } from "
|
|
7
|
-
import { isDirective } from "../../util/compare";
|
|
6
|
+
import { isDirective, isModuleSource } from "../../util/compare";
|
|
8
7
|
import { ok } from "assert";
|
|
9
8
|
import { ComputeProbabilityMap } from "../../probability";
|
|
10
9
|
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import traverse, { ExitCallback } from "../traverse";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AddComment,
|
|
4
|
+
Node,
|
|
5
|
+
VariableDeclaration,
|
|
6
|
+
VariableDeclarator,
|
|
7
|
+
} from "../util/gen";
|
|
3
8
|
import {
|
|
4
9
|
alphabeticalGenerator,
|
|
5
10
|
choice,
|
|
11
|
+
createZeroWidthGenerator,
|
|
6
12
|
getRandomInteger,
|
|
13
|
+
shuffle,
|
|
7
14
|
} from "../util/random";
|
|
8
15
|
import { ok } from "assert";
|
|
9
16
|
import Obfuscator from "../obfuscator";
|
|
10
|
-
import { ObfuscateOptions } from "../options";
|
|
11
17
|
import { ComputeProbabilityMap } from "../probability";
|
|
12
18
|
import {
|
|
13
19
|
placeholderVariablePrefix,
|
|
@@ -15,6 +21,9 @@ import {
|
|
|
15
21
|
reservedKeywords,
|
|
16
22
|
} from "../constants";
|
|
17
23
|
import { ObfuscateOrder } from "../order";
|
|
24
|
+
import { prepend } from "../util/insert";
|
|
25
|
+
import Lock from "./lock/lock";
|
|
26
|
+
import Template from "../templates/template";
|
|
18
27
|
|
|
19
28
|
/**
|
|
20
29
|
* Base-class for all transformations.
|
|
@@ -61,7 +70,7 @@ export default class Transform {
|
|
|
61
70
|
/**
|
|
62
71
|
* The user's options.
|
|
63
72
|
*/
|
|
64
|
-
options:
|
|
73
|
+
options: Obfuscator["options"];
|
|
65
74
|
|
|
66
75
|
/**
|
|
67
76
|
* Only required for top-level transformations.
|
|
@@ -78,6 +87,10 @@ export default class Transform {
|
|
|
78
87
|
*/
|
|
79
88
|
after: Transform[];
|
|
80
89
|
|
|
90
|
+
initVariables = new Map<string, string>();
|
|
91
|
+
|
|
92
|
+
zeroWidthGenerator = createZeroWidthGenerator();
|
|
93
|
+
|
|
81
94
|
constructor(obfuscator, priority: number = -1) {
|
|
82
95
|
ok(obfuscator instanceof Obfuscator, "obfuscator should be an Obfuscator");
|
|
83
96
|
|
|
@@ -99,6 +112,32 @@ export default class Transform {
|
|
|
99
112
|
);
|
|
100
113
|
}
|
|
101
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Gets the `Lock` transformation.
|
|
117
|
+
*/
|
|
118
|
+
get lockTransform(): Lock {
|
|
119
|
+
var transform = this.obfuscator.transforms["Lock"] as Lock;
|
|
120
|
+
|
|
121
|
+
ok(transform, "Lock transform not created");
|
|
122
|
+
|
|
123
|
+
return transform;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Wraps the given name with the `__JS_CONFUSER_VAR__` function call.
|
|
128
|
+
*
|
|
129
|
+
* If `Rename Variables` is disabled, the name is returned as-is.
|
|
130
|
+
* @param name
|
|
131
|
+
* @returns
|
|
132
|
+
*/
|
|
133
|
+
jsConfuserVar(name: string) {
|
|
134
|
+
if (!this.obfuscator.transforms["RenameVariables"]) {
|
|
135
|
+
return `"${name}"`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return `__JS_CONFUSER_VAR__(${name})`;
|
|
139
|
+
}
|
|
140
|
+
|
|
102
141
|
/**
|
|
103
142
|
* Run an AST through the transformation (including `pre` and `post` transforms)
|
|
104
143
|
* @param tree
|
|
@@ -277,49 +316,7 @@ export default class Transform {
|
|
|
277
316
|
return "var_" + count;
|
|
278
317
|
|
|
279
318
|
case "zeroWidth":
|
|
280
|
-
|
|
281
|
-
"if",
|
|
282
|
-
"in",
|
|
283
|
-
"for",
|
|
284
|
-
"let",
|
|
285
|
-
"new",
|
|
286
|
-
"try",
|
|
287
|
-
"var",
|
|
288
|
-
"case",
|
|
289
|
-
"else",
|
|
290
|
-
"null",
|
|
291
|
-
"break",
|
|
292
|
-
"catch",
|
|
293
|
-
"class",
|
|
294
|
-
"const",
|
|
295
|
-
"super",
|
|
296
|
-
"throw",
|
|
297
|
-
"while",
|
|
298
|
-
"yield",
|
|
299
|
-
"delete",
|
|
300
|
-
"export",
|
|
301
|
-
"import",
|
|
302
|
-
"public",
|
|
303
|
-
"return",
|
|
304
|
-
"switch",
|
|
305
|
-
"default",
|
|
306
|
-
"finally",
|
|
307
|
-
"private",
|
|
308
|
-
"continue",
|
|
309
|
-
"debugger",
|
|
310
|
-
"function",
|
|
311
|
-
"arguments",
|
|
312
|
-
"protected",
|
|
313
|
-
"instanceof",
|
|
314
|
-
"function",
|
|
315
|
-
"await",
|
|
316
|
-
"async",
|
|
317
|
-
];
|
|
318
|
-
|
|
319
|
-
var safe = "\u200C".repeat(count + 1);
|
|
320
|
-
|
|
321
|
-
var base = choice(keyWords) + safe;
|
|
322
|
-
return base;
|
|
319
|
+
return this.zeroWidthGenerator.generate();
|
|
323
320
|
}
|
|
324
321
|
|
|
325
322
|
throw new Error("Invalid 'identifierGenerator' mode: " + mode);
|
|
@@ -336,6 +333,26 @@ export default class Transform {
|
|
|
336
333
|
return identifier;
|
|
337
334
|
}
|
|
338
335
|
|
|
336
|
+
createInitVariable = (value: Template, parents: Node[]) => {
|
|
337
|
+
var key = value.templates[0];
|
|
338
|
+
if (this.initVariables.has(key)) {
|
|
339
|
+
return this.initVariables.get(key);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
var root = parents[parents.length - 1];
|
|
343
|
+
ok(root.type === "Program");
|
|
344
|
+
|
|
345
|
+
var name = this.getPlaceholder();
|
|
346
|
+
this.initVariables.set(key, name);
|
|
347
|
+
|
|
348
|
+
prepend(
|
|
349
|
+
root,
|
|
350
|
+
VariableDeclaration(VariableDeclarator(name, value.single().expression))
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
return name;
|
|
354
|
+
};
|
|
355
|
+
|
|
339
356
|
/**
|
|
340
357
|
* Smartly appends a comment to a Node.
|
|
341
358
|
* - Includes the transformation's name.
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Obfuscator from "./obfuscator";
|
|
2
2
|
import { ObfuscateOptions } from "./options";
|
|
3
|
+
import Template from "./templates/template";
|
|
3
4
|
import Transform from "./transforms/transform";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -21,6 +22,7 @@ export interface IJsConfuser {
|
|
|
21
22
|
|
|
22
23
|
Transform: typeof Transform;
|
|
23
24
|
Obfuscator: typeof Obfuscator;
|
|
25
|
+
Template: typeof Template;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
/**
|
package/src/util/compare.ts
CHANGED
|
@@ -74,19 +74,52 @@ export function isDirective(object: Node, parents: Node[]) {
|
|
|
74
74
|
return parents[dIndex].expression == (parents[dIndex - 1] || object);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
export function isModuleSource(object: Node, parents: Node[]) {
|
|
78
|
+
if (!parents[0]) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (parents[0].type == "ImportDeclaration" && parents[0].source == object) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (parents[0].type == "ImportExpression" && parents[0].source == object) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (
|
|
91
|
+
parents[1] &&
|
|
92
|
+
parents[1].type == "CallExpression" &&
|
|
93
|
+
parents[1].arguments[0] === object &&
|
|
94
|
+
parents[1].callee.type == "Identifier"
|
|
95
|
+
) {
|
|
96
|
+
if (
|
|
97
|
+
parents[1].callee.name == "require" ||
|
|
98
|
+
parents[1].callee.name == "import"
|
|
99
|
+
) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function isMoveable(object: Node, parents: Node[]) {
|
|
108
|
+
return !isDirective(object, parents) && !isModuleSource(object, parents);
|
|
109
|
+
}
|
|
110
|
+
|
|
77
111
|
export function isIndependent(object: Node, parents: Node[]) {
|
|
78
112
|
if (object.type == "Literal") {
|
|
79
113
|
return true;
|
|
80
114
|
}
|
|
81
115
|
|
|
82
|
-
var parent = parents[0];
|
|
83
|
-
|
|
84
116
|
if (object.type == "Identifier") {
|
|
85
|
-
|
|
86
|
-
if (set.has(object.name)) {
|
|
117
|
+
if (primitiveIdentifiers.has(object.name)) {
|
|
87
118
|
return true;
|
|
88
119
|
}
|
|
89
|
-
|
|
120
|
+
|
|
121
|
+
var parent = parents[0];
|
|
122
|
+
if (parent && parent.type == "Property") {
|
|
90
123
|
if (!parent.computed && parent.key == object) {
|
|
91
124
|
return true;
|
|
92
125
|
}
|
|
@@ -105,6 +138,7 @@ export function isIndependent(object: Node, parents: Node[]) {
|
|
|
105
138
|
if (object != $object) {
|
|
106
139
|
if (!Array.isArray($object) && !isIndependent($object, $parents)) {
|
|
107
140
|
allowIt = false;
|
|
141
|
+
return "EXIT";
|
|
108
142
|
}
|
|
109
143
|
}
|
|
110
144
|
});
|
package/src/util/gen.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ok } from "assert";
|
|
2
|
+
import { predictableFunctionTag } from "../constants";
|
|
2
3
|
import { isValidIdentifier } from "./compare";
|
|
3
4
|
|
|
4
5
|
export type Type =
|
|
@@ -306,6 +307,7 @@ export function FunctionExpression(params: Node[], body: any[]) {
|
|
|
306
307
|
generator: false,
|
|
307
308
|
expression: false,
|
|
308
309
|
async: false,
|
|
310
|
+
[predictableFunctionTag]: true,
|
|
309
311
|
};
|
|
310
312
|
}
|
|
311
313
|
|
|
@@ -340,6 +342,7 @@ export function FunctionDeclaration(
|
|
|
340
342
|
generator: false,
|
|
341
343
|
expression: false,
|
|
342
344
|
async: false,
|
|
345
|
+
[predictableFunctionTag]: true,
|
|
343
346
|
};
|
|
344
347
|
}
|
|
345
348
|
|
|
@@ -529,16 +532,20 @@ export function AddComment(node: Node, text: string) {
|
|
|
529
532
|
return node;
|
|
530
533
|
}
|
|
531
534
|
|
|
535
|
+
export function Super() {
|
|
536
|
+
return { type: "Super" };
|
|
537
|
+
}
|
|
538
|
+
|
|
532
539
|
export function MethodDefinition(
|
|
533
|
-
|
|
540
|
+
key: Node,
|
|
534
541
|
functionExpression: Node,
|
|
535
542
|
kind: "method" | "constructor" | "get" | "set",
|
|
536
|
-
isStatic =
|
|
543
|
+
isStatic = false,
|
|
537
544
|
computed = false
|
|
538
545
|
) {
|
|
539
546
|
return {
|
|
540
547
|
type: "MethodDefinition",
|
|
541
|
-
key:
|
|
548
|
+
key: key,
|
|
542
549
|
computed: computed,
|
|
543
550
|
value: functionExpression,
|
|
544
551
|
kind: kind,
|
package/src/util/guard.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { variableFunctionName } from "../constants";
|
|
1
2
|
import { Node } from "./gen";
|
|
2
3
|
|
|
3
4
|
export function isStringLiteral(node: Node) {
|
|
@@ -5,3 +6,12 @@ export function isStringLiteral(node: Node) {
|
|
|
5
6
|
node.type === "Literal" && typeof node.value === "string" && !node.regex
|
|
6
7
|
);
|
|
7
8
|
}
|
|
9
|
+
|
|
10
|
+
export function isJSConfuserVar(p: Node[]) {
|
|
11
|
+
return p.find(
|
|
12
|
+
(x) =>
|
|
13
|
+
x.type === "CallExpression" &&
|
|
14
|
+
x.callee.type === "Identifier" &&
|
|
15
|
+
x.callee.name == variableFunctionName
|
|
16
|
+
);
|
|
17
|
+
}
|