js-confuser 1.7.2 → 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 +35 -0
- package/README.md +20 -4
- package/dist/constants.js +7 -2
- package/dist/index.js +8 -0
- package/dist/options.js +12 -2
- package/dist/templates/bufferToString.js +26 -5
- package/dist/templates/core.js +35 -0
- package/dist/templates/crash.js +8 -39
- package/dist/templates/es5.js +1 -1
- package/dist/templates/functionLength.js +1 -1
- package/dist/templates/globals.js +1 -1
- package/dist/templates/template.js +173 -68
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/calculator.js +2 -2
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +8 -2
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +1 -1
- package/dist/transforms/deadCode.js +34 -24
- package/dist/transforms/dispatcher.js +8 -4
- package/dist/transforms/es5/antiClass.js +11 -11
- package/dist/transforms/es5/antiDestructuring.js +1 -1
- package/dist/transforms/es5/antiES6Object.js +2 -2
- package/dist/transforms/es5/antiTemplate.js +1 -1
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +2 -2
- package/dist/transforms/identifier/globalAnalysis.js +13 -0
- package/dist/transforms/identifier/globalConcealing.js +41 -6
- package/dist/transforms/identifier/renameVariables.js +7 -0
- package/dist/transforms/lock/antiDebug.js +2 -2
- package/dist/transforms/lock/integrity.js +9 -9
- package/dist/transforms/lock/lock.js +106 -20
- package/dist/transforms/minify.js +1 -1
- package/dist/transforms/opaquePredicates.js +2 -2
- package/dist/transforms/preparation.js +12 -0
- package/dist/transforms/rgf.js +32 -3
- package/dist/transforms/shuffle.js +3 -3
- package/dist/transforms/stack.js +8 -2
- package/dist/transforms/string/encoding.js +6 -3
- package/dist/transforms/string/stringCompression.js +34 -3
- package/dist/transforms/string/stringConcealing.js +7 -6
- package/dist/transforms/transform.js +26 -4
- package/dist/util/guard.js +5 -0
- package/dist/util/random.js +26 -0
- 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 +1 -1
- package/src/constants.ts +5 -0
- package/src/index.ts +7 -5
- package/src/options.ts +47 -7
- package/src/templates/bufferToString.ts +34 -4
- 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 +1 -1
- package/src/templates/globals.ts +1 -1
- package/src/templates/template.ts +185 -86
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/calculator.ts +4 -2
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +10 -3
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +1 -1
- package/src/transforms/deadCode.ts +74 -26
- package/src/transforms/dispatcher.ts +9 -5
- package/src/transforms/es5/antiClass.ts +15 -11
- 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/duplicateLiteralsRemoval.ts +2 -6
- package/src/transforms/identifier/globalAnalysis.ts +18 -1
- package/src/transforms/identifier/globalConcealing.ts +94 -11
- 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 +1 -1
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +16 -0
- package/src/transforms/rgf.ts +46 -8
- package/src/transforms/shuffle.ts +3 -3
- package/src/transforms/stack.ts +9 -3
- package/src/transforms/string/encoding.ts +10 -7
- package/src/transforms/string/stringCompression.ts +81 -9
- package/src/transforms/string/stringConcealing.ts +10 -6
- package/src/transforms/transform.ts +35 -47
- package/src/types.ts +2 -0
- package/src/util/guard.ts +10 -0
- package/src/util/random.ts +81 -1
- package/test/code/Cash.test.ts +84 -1
- package/test/compare.test.ts +5 -5
- package/test/options.test.ts +18 -0
- package/test/templates/template.test.ts +211 -1
- package/test/transforms/identifier/globalConcealing.test.ts +70 -0
- package/test/transforms/identifier/renameVariables.test.ts +75 -1
- package/test/transforms/lock/tamperProtection.test.ts +336 -0
|
@@ -4,12 +4,18 @@ import { ComputeProbabilityMap } from "../../probability";
|
|
|
4
4
|
import Template from "../../templates/template";
|
|
5
5
|
import { isDirective, isModuleSource } from "../../util/compare";
|
|
6
6
|
import {
|
|
7
|
+
AssignmentExpression,
|
|
8
|
+
BinaryExpression,
|
|
7
9
|
CallExpression,
|
|
10
|
+
ExpressionStatement,
|
|
8
11
|
FunctionDeclaration,
|
|
9
12
|
FunctionExpression,
|
|
10
13
|
Identifier,
|
|
14
|
+
IfStatement,
|
|
11
15
|
Literal,
|
|
12
16
|
MemberExpression,
|
|
17
|
+
ObjectExpression,
|
|
18
|
+
Property,
|
|
13
19
|
ReturnStatement,
|
|
14
20
|
VariableDeclaration,
|
|
15
21
|
VariableDeclarator,
|
|
@@ -17,6 +23,14 @@ import {
|
|
|
17
23
|
import { append, prepend } from "../../util/insert";
|
|
18
24
|
import Transform from "../transform";
|
|
19
25
|
import { predictableFunctionTag } from "../../constants";
|
|
26
|
+
import {
|
|
27
|
+
chance,
|
|
28
|
+
choice,
|
|
29
|
+
getRandomFalseExpression,
|
|
30
|
+
getRandomInteger,
|
|
31
|
+
getRandomString,
|
|
32
|
+
splitIntoChunks,
|
|
33
|
+
} from "../../util/random";
|
|
20
34
|
|
|
21
35
|
function LZ_encode(c) {
|
|
22
36
|
ok(c);
|
|
@@ -58,7 +72,7 @@ function LZ_decode(b) {
|
|
|
58
72
|
return g.join("");
|
|
59
73
|
}
|
|
60
74
|
|
|
61
|
-
const DecodeTemplate = Template(
|
|
75
|
+
const DecodeTemplate = new Template(
|
|
62
76
|
`function {name}(b){
|
|
63
77
|
var o,
|
|
64
78
|
f,
|
|
@@ -141,15 +155,72 @@ export default class StringCompression extends Transform {
|
|
|
141
155
|
)
|
|
142
156
|
);
|
|
143
157
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
158
|
+
var keys = new Set<string>();
|
|
159
|
+
var keysToMake = getRandomInteger(4, 14);
|
|
160
|
+
for (var i = 0; i < keysToMake; i++) {
|
|
161
|
+
keys.add(getRandomString(getRandomInteger(4, 14)));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
var objectExpression = ObjectExpression(
|
|
165
|
+
Array.from(keys).map((key) => {
|
|
166
|
+
return Property(Literal(key), getRandomFalseExpression(), true);
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// Get string function
|
|
171
|
+
var getStringBody = [];
|
|
172
|
+
var splits = splitIntoChunks(
|
|
173
|
+
encoded,
|
|
174
|
+
Math.floor(encoded.length / getRandomInteger(3, 6))
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
getStringBody.push(
|
|
178
|
+
VariableDeclaration(VariableDeclarator("str", Literal(splits.shift())))
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
getStringBody.push(
|
|
182
|
+
VariableDeclaration(VariableDeclarator("objectToTest", objectExpression))
|
|
151
183
|
);
|
|
152
184
|
|
|
185
|
+
const addIfStatement = (testingFor, literalValueToBeAppended) => {
|
|
186
|
+
getStringBody.push(
|
|
187
|
+
IfStatement(
|
|
188
|
+
BinaryExpression(
|
|
189
|
+
"in",
|
|
190
|
+
Literal(testingFor),
|
|
191
|
+
Identifier("objectToTest")
|
|
192
|
+
),
|
|
193
|
+
[
|
|
194
|
+
ExpressionStatement(
|
|
195
|
+
AssignmentExpression(
|
|
196
|
+
"+=",
|
|
197
|
+
Identifier("str"),
|
|
198
|
+
Literal(literalValueToBeAppended)
|
|
199
|
+
)
|
|
200
|
+
),
|
|
201
|
+
]
|
|
202
|
+
)
|
|
203
|
+
);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
for (const split of splits) {
|
|
207
|
+
if (chance(50)) {
|
|
208
|
+
var fakeKey;
|
|
209
|
+
do {
|
|
210
|
+
fakeKey = getRandomString(getRandomInteger(4, 14));
|
|
211
|
+
} while (keys.has(fakeKey) || fakeKey in {});
|
|
212
|
+
|
|
213
|
+
addIfStatement(fakeKey, getRandomString(split.length));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
addIfStatement(choice(Array.from(keys)), split);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Return computed string
|
|
220
|
+
getStringBody.push(ReturnStatement(Identifier("str")));
|
|
221
|
+
|
|
222
|
+
append(tree, FunctionDeclaration(getStringName, [], getStringBody));
|
|
223
|
+
|
|
153
224
|
append(
|
|
154
225
|
tree,
|
|
155
226
|
FunctionDeclaration(
|
|
@@ -176,7 +247,8 @@ export default class StringCompression extends Transform {
|
|
|
176
247
|
object.value &&
|
|
177
248
|
object.value.length > 3 &&
|
|
178
249
|
!isDirective(object, parents) &&
|
|
179
|
-
!isModuleSource(object, parents)
|
|
250
|
+
!isModuleSource(object, parents) &&
|
|
251
|
+
!parents.find((x) => x.$multiTransformSkip)
|
|
180
252
|
);
|
|
181
253
|
}
|
|
182
254
|
|
|
@@ -31,7 +31,10 @@ import {
|
|
|
31
31
|
hasAllEncodings,
|
|
32
32
|
} from "./encoding";
|
|
33
33
|
import { ComputeProbabilityMap } from "../../probability";
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
BufferToStringTemplate,
|
|
36
|
+
createGetGlobalTemplate,
|
|
37
|
+
} from "../../templates/bufferToString";
|
|
35
38
|
import { criticalFunctionTag, predictableFunctionTag } from "../../constants";
|
|
36
39
|
|
|
37
40
|
interface FunctionObject {
|
|
@@ -65,7 +68,7 @@ export default class StringConcealing extends Transform {
|
|
|
65
68
|
super.apply(tree);
|
|
66
69
|
|
|
67
70
|
// Pad array with useless strings
|
|
68
|
-
var dead = getRandomInteger(
|
|
71
|
+
var dead = getRandomInteger(50, 200);
|
|
69
72
|
for (var i = 0; i < dead; i++) {
|
|
70
73
|
var str = getRandomString(getRandomInteger(5, 40));
|
|
71
74
|
var fn = this.transform(Literal(str), [tree]);
|
|
@@ -83,6 +86,7 @@ export default class StringConcealing extends Transform {
|
|
|
83
86
|
...BufferToStringTemplate.compile({
|
|
84
87
|
name: bufferToStringName,
|
|
85
88
|
getGlobalFnName: this.getPlaceholder() + predictableFunctionTag,
|
|
89
|
+
GetGlobalTemplate: createGetGlobalTemplate(this, tree, []),
|
|
86
90
|
})
|
|
87
91
|
);
|
|
88
92
|
|
|
@@ -104,7 +108,7 @@ export default class StringConcealing extends Transform {
|
|
|
104
108
|
})
|
|
105
109
|
);
|
|
106
110
|
// All these are fake and never ran
|
|
107
|
-
var ifStatements = Template(`if ( z == x ) {
|
|
111
|
+
var ifStatements = new Template(`if ( z == x ) {
|
|
108
112
|
return y[${cacheName}[z]] = ${getterFnName}(x, y);
|
|
109
113
|
}
|
|
110
114
|
if ( y ) {
|
|
@@ -132,7 +136,7 @@ export default class StringConcealing extends Transform {
|
|
|
132
136
|
|
|
133
137
|
// This one is always used
|
|
134
138
|
ifStatements.push(
|
|
135
|
-
Template(`
|
|
139
|
+
new Template(`
|
|
136
140
|
if ( x !== y ) {
|
|
137
141
|
return b[x] || (b[x] = a(${this.arrayName}[x]))
|
|
138
142
|
}
|
|
@@ -141,7 +145,7 @@ export default class StringConcealing extends Transform {
|
|
|
141
145
|
|
|
142
146
|
shuffle(ifStatements);
|
|
143
147
|
|
|
144
|
-
var varDeclaration = Template(`
|
|
148
|
+
var varDeclaration = new Template(`
|
|
145
149
|
var ${getterFnName} = (x, y, z, a, b)=>{
|
|
146
150
|
if(typeof a === "undefined") {
|
|
147
151
|
a = ${decodeFn}
|
|
@@ -173,7 +177,7 @@ export default class StringConcealing extends Transform {
|
|
|
173
177
|
object.value.length >= 3 &&
|
|
174
178
|
!isModuleSource(object, parents) &&
|
|
175
179
|
!isDirective(object, parents) //&&
|
|
176
|
-
/*!parents.find((x) => x.$
|
|
180
|
+
/*!parents.find((x) => x.$multiTransformSkip)*/
|
|
177
181
|
);
|
|
178
182
|
}
|
|
179
183
|
|
|
@@ -8,11 +8,12 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
alphabeticalGenerator,
|
|
10
10
|
choice,
|
|
11
|
+
createZeroWidthGenerator,
|
|
11
12
|
getRandomInteger,
|
|
13
|
+
shuffle,
|
|
12
14
|
} from "../util/random";
|
|
13
15
|
import { ok } from "assert";
|
|
14
16
|
import Obfuscator from "../obfuscator";
|
|
15
|
-
import { ObfuscateOptions } from "../options";
|
|
16
17
|
import { ComputeProbabilityMap } from "../probability";
|
|
17
18
|
import {
|
|
18
19
|
placeholderVariablePrefix,
|
|
@@ -20,8 +21,9 @@ import {
|
|
|
20
21
|
reservedKeywords,
|
|
21
22
|
} from "../constants";
|
|
22
23
|
import { ObfuscateOrder } from "../order";
|
|
23
|
-
import { ITemplate } from "../templates/template";
|
|
24
24
|
import { prepend } from "../util/insert";
|
|
25
|
+
import Lock from "./lock/lock";
|
|
26
|
+
import Template from "../templates/template";
|
|
25
27
|
|
|
26
28
|
/**
|
|
27
29
|
* Base-class for all transformations.
|
|
@@ -68,7 +70,7 @@ export default class Transform {
|
|
|
68
70
|
/**
|
|
69
71
|
* The user's options.
|
|
70
72
|
*/
|
|
71
|
-
options:
|
|
73
|
+
options: Obfuscator["options"];
|
|
72
74
|
|
|
73
75
|
/**
|
|
74
76
|
* Only required for top-level transformations.
|
|
@@ -87,6 +89,8 @@ export default class Transform {
|
|
|
87
89
|
|
|
88
90
|
initVariables = new Map<string, string>();
|
|
89
91
|
|
|
92
|
+
zeroWidthGenerator = createZeroWidthGenerator();
|
|
93
|
+
|
|
90
94
|
constructor(obfuscator, priority: number = -1) {
|
|
91
95
|
ok(obfuscator instanceof Obfuscator, "obfuscator should be an Obfuscator");
|
|
92
96
|
|
|
@@ -108,6 +112,32 @@ export default class Transform {
|
|
|
108
112
|
);
|
|
109
113
|
}
|
|
110
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
|
+
|
|
111
141
|
/**
|
|
112
142
|
* Run an AST through the transformation (including `pre` and `post` transforms)
|
|
113
143
|
* @param tree
|
|
@@ -286,49 +316,7 @@ export default class Transform {
|
|
|
286
316
|
return "var_" + count;
|
|
287
317
|
|
|
288
318
|
case "zeroWidth":
|
|
289
|
-
|
|
290
|
-
"if",
|
|
291
|
-
"in",
|
|
292
|
-
"for",
|
|
293
|
-
"let",
|
|
294
|
-
"new",
|
|
295
|
-
"try",
|
|
296
|
-
"var",
|
|
297
|
-
"case",
|
|
298
|
-
"else",
|
|
299
|
-
"null",
|
|
300
|
-
"break",
|
|
301
|
-
"catch",
|
|
302
|
-
"class",
|
|
303
|
-
"const",
|
|
304
|
-
"super",
|
|
305
|
-
"throw",
|
|
306
|
-
"while",
|
|
307
|
-
"yield",
|
|
308
|
-
"delete",
|
|
309
|
-
"export",
|
|
310
|
-
"import",
|
|
311
|
-
"public",
|
|
312
|
-
"return",
|
|
313
|
-
"switch",
|
|
314
|
-
"default",
|
|
315
|
-
"finally",
|
|
316
|
-
"private",
|
|
317
|
-
"continue",
|
|
318
|
-
"debugger",
|
|
319
|
-
"function",
|
|
320
|
-
"arguments",
|
|
321
|
-
"protected",
|
|
322
|
-
"instanceof",
|
|
323
|
-
"function",
|
|
324
|
-
"await",
|
|
325
|
-
"async",
|
|
326
|
-
];
|
|
327
|
-
|
|
328
|
-
var safe = "\u200C".repeat(count + 1);
|
|
329
|
-
|
|
330
|
-
var base = choice(keyWords) + safe;
|
|
331
|
-
return base;
|
|
319
|
+
return this.zeroWidthGenerator.generate();
|
|
332
320
|
}
|
|
333
321
|
|
|
334
322
|
throw new Error("Invalid 'identifierGenerator' mode: " + mode);
|
|
@@ -345,7 +333,7 @@ export default class Transform {
|
|
|
345
333
|
return identifier;
|
|
346
334
|
}
|
|
347
335
|
|
|
348
|
-
createInitVariable = (value:
|
|
336
|
+
createInitVariable = (value: Template, parents: Node[]) => {
|
|
349
337
|
var key = value.templates[0];
|
|
350
338
|
if (this.initVariables.has(key)) {
|
|
351
339
|
return this.initVariables.get(key);
|
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/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
|
+
}
|
package/src/util/random.ts
CHANGED
|
@@ -63,7 +63,7 @@ export function splitIntoChunks(str: string, size: number) {
|
|
|
63
63
|
ok(Math.floor(size) === size, "size must be integer");
|
|
64
64
|
|
|
65
65
|
const numChunks = Math.ceil(str.length / size);
|
|
66
|
-
const chunks = new Array(numChunks);
|
|
66
|
+
const chunks: string[] = new Array(numChunks);
|
|
67
67
|
|
|
68
68
|
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
|
|
69
69
|
chunks[i] = str.substr(o, size);
|
|
@@ -139,3 +139,83 @@ export function alphabeticalGenerator(index: number) {
|
|
|
139
139
|
}
|
|
140
140
|
return name;
|
|
141
141
|
}
|
|
142
|
+
|
|
143
|
+
export function createZeroWidthGenerator() {
|
|
144
|
+
var keywords = [
|
|
145
|
+
"if",
|
|
146
|
+
"in",
|
|
147
|
+
"for",
|
|
148
|
+
"let",
|
|
149
|
+
"new",
|
|
150
|
+
"try",
|
|
151
|
+
"var",
|
|
152
|
+
"case",
|
|
153
|
+
"else",
|
|
154
|
+
"null",
|
|
155
|
+
"break",
|
|
156
|
+
"catch",
|
|
157
|
+
"class",
|
|
158
|
+
"const",
|
|
159
|
+
"super",
|
|
160
|
+
"throw",
|
|
161
|
+
"while",
|
|
162
|
+
"yield",
|
|
163
|
+
"delete",
|
|
164
|
+
"export",
|
|
165
|
+
"import",
|
|
166
|
+
"public",
|
|
167
|
+
"return",
|
|
168
|
+
"switch",
|
|
169
|
+
"default",
|
|
170
|
+
"finally",
|
|
171
|
+
"private",
|
|
172
|
+
"continue",
|
|
173
|
+
"debugger",
|
|
174
|
+
"function",
|
|
175
|
+
"arguments",
|
|
176
|
+
"protected",
|
|
177
|
+
"instanceof",
|
|
178
|
+
"await",
|
|
179
|
+
"async",
|
|
180
|
+
|
|
181
|
+
// new key words and other fun stuff :P
|
|
182
|
+
"NaN",
|
|
183
|
+
"undefined",
|
|
184
|
+
"true",
|
|
185
|
+
"false",
|
|
186
|
+
"typeof",
|
|
187
|
+
"this",
|
|
188
|
+
"static",
|
|
189
|
+
"void",
|
|
190
|
+
"of",
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
var maxSize = 0;
|
|
194
|
+
var currentKeyWordsArray: string[] = [];
|
|
195
|
+
|
|
196
|
+
function generateArray() {
|
|
197
|
+
var result = keywords
|
|
198
|
+
.map(
|
|
199
|
+
(keyWord) =>
|
|
200
|
+
keyWord + "\u200C".repeat(Math.max(maxSize - keyWord.length, 1))
|
|
201
|
+
)
|
|
202
|
+
.filter((craftedVariableName) => craftedVariableName.length == maxSize);
|
|
203
|
+
|
|
204
|
+
if (!result.length) {
|
|
205
|
+
++maxSize;
|
|
206
|
+
return generateArray();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return shuffle(result);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function getNextVariable(): string {
|
|
213
|
+
if (!currentKeyWordsArray.length) {
|
|
214
|
+
++maxSize;
|
|
215
|
+
currentKeyWordsArray = generateArray();
|
|
216
|
+
}
|
|
217
|
+
return currentKeyWordsArray.pop();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return { generate: getNextVariable };
|
|
221
|
+
}
|
package/test/code/Cash.test.ts
CHANGED
|
@@ -6,7 +6,7 @@ var CASH_JS = readFileSync(join(__dirname, "./Cash.src.js"), "utf-8");
|
|
|
6
6
|
|
|
7
7
|
test("Variant #1: Cash.js on High Preset (Strict Mode)", async () => {
|
|
8
8
|
var output = await JsConfuser(CASH_JS, {
|
|
9
|
-
target: "
|
|
9
|
+
target: "node",
|
|
10
10
|
preset: "high",
|
|
11
11
|
});
|
|
12
12
|
|
|
@@ -33,6 +33,9 @@ test("Variant #1: Cash.js on High Preset (Strict Mode)", async () => {
|
|
|
33
33
|
} as any;
|
|
34
34
|
window.window = window;
|
|
35
35
|
global.window = window;
|
|
36
|
+
for (var key in window) {
|
|
37
|
+
global[key] = window[key];
|
|
38
|
+
}
|
|
36
39
|
|
|
37
40
|
try {
|
|
38
41
|
eval(output);
|
|
@@ -47,3 +50,83 @@ test("Variant #1: Cash.js on High Preset (Strict Mode)", async () => {
|
|
|
47
50
|
|
|
48
51
|
expect(window).toHaveProperty("cash");
|
|
49
52
|
});
|
|
53
|
+
|
|
54
|
+
test("Variant #2: Cash.js on High Preset + Integrity + Self Defending + RGF + Tamper Protection", async () => {
|
|
55
|
+
// Make the required document variables for initialization
|
|
56
|
+
var document = {
|
|
57
|
+
documentElement: {},
|
|
58
|
+
createElement: () => {
|
|
59
|
+
return { style: {} };
|
|
60
|
+
},
|
|
61
|
+
} as any as Document;
|
|
62
|
+
var window = {
|
|
63
|
+
document,
|
|
64
|
+
Array,
|
|
65
|
+
Object,
|
|
66
|
+
Symbol,
|
|
67
|
+
Number,
|
|
68
|
+
parseInt,
|
|
69
|
+
JSON,
|
|
70
|
+
setTimeout,
|
|
71
|
+
encodeURIComponent,
|
|
72
|
+
RegExp,
|
|
73
|
+
String,
|
|
74
|
+
$: false,
|
|
75
|
+
} as any;
|
|
76
|
+
window.window = window;
|
|
77
|
+
global.window = window;
|
|
78
|
+
for (var key in window) {
|
|
79
|
+
global[key] = window[key];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var output = await JsConfuser(CASH_JS, {
|
|
83
|
+
target: "node",
|
|
84
|
+
preset: "high",
|
|
85
|
+
rgf: true,
|
|
86
|
+
lock: {
|
|
87
|
+
integrity: true,
|
|
88
|
+
selfDefending: true,
|
|
89
|
+
tamperProtection: true,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
// new Function() runs in non-strict mode
|
|
95
|
+
new Function(output)();
|
|
96
|
+
} catch (e) {
|
|
97
|
+
var helperCode = `var document = {
|
|
98
|
+
documentElement: {},
|
|
99
|
+
createElement: () => {
|
|
100
|
+
return { style: {} };
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
var window = {
|
|
104
|
+
document,
|
|
105
|
+
Array,
|
|
106
|
+
Object,
|
|
107
|
+
Symbol,
|
|
108
|
+
Number,
|
|
109
|
+
parseInt,
|
|
110
|
+
JSON,
|
|
111
|
+
setTimeout,
|
|
112
|
+
encodeURIComponent,
|
|
113
|
+
RegExp,
|
|
114
|
+
String,
|
|
115
|
+
$: false,
|
|
116
|
+
};
|
|
117
|
+
window.window = window;
|
|
118
|
+
global.window = window;
|
|
119
|
+
for (var key in window) {
|
|
120
|
+
global[key] = window[key];
|
|
121
|
+
}`;
|
|
122
|
+
|
|
123
|
+
console.error(e);
|
|
124
|
+
writeFileSync("dev.output.js", helperCode + "\n" + output, {
|
|
125
|
+
encoding: "utf-8",
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
expect(true).toStrictEqual(false);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
expect(window).toHaveProperty("cash");
|
|
132
|
+
});
|
package/test/compare.test.ts
CHANGED
|
@@ -46,7 +46,7 @@ describe("isIndependent", () => {
|
|
|
46
46
|
it("various cases", () => {
|
|
47
47
|
expect(
|
|
48
48
|
isIndependent(
|
|
49
|
-
Template(`({
|
|
49
|
+
new Template(`({
|
|
50
50
|
x: 1,
|
|
51
51
|
y: 2,
|
|
52
52
|
z: 3,
|
|
@@ -57,7 +57,7 @@ describe("isIndependent", () => {
|
|
|
57
57
|
|
|
58
58
|
expect(
|
|
59
59
|
isIndependent(
|
|
60
|
-
Template(`({
|
|
60
|
+
new Template(`({
|
|
61
61
|
x: 1,
|
|
62
62
|
y: 2,
|
|
63
63
|
z: [3,4,5,6,7,"My String",undefined,null,NaN],
|
|
@@ -68,7 +68,7 @@ describe("isIndependent", () => {
|
|
|
68
68
|
|
|
69
69
|
expect(
|
|
70
70
|
isIndependent(
|
|
71
|
-
Template(`({
|
|
71
|
+
new Template(`({
|
|
72
72
|
x: 1,
|
|
73
73
|
y: 2,
|
|
74
74
|
z: 3,
|
|
@@ -80,7 +80,7 @@ describe("isIndependent", () => {
|
|
|
80
80
|
|
|
81
81
|
expect(
|
|
82
82
|
isIndependent(
|
|
83
|
-
Template(`({
|
|
83
|
+
new Template(`({
|
|
84
84
|
x: 1,
|
|
85
85
|
y: 2,
|
|
86
86
|
z: 3,
|
|
@@ -92,7 +92,7 @@ describe("isIndependent", () => {
|
|
|
92
92
|
|
|
93
93
|
expect(
|
|
94
94
|
isIndependent(
|
|
95
|
-
Template(`([
|
|
95
|
+
new Template(`([
|
|
96
96
|
{
|
|
97
97
|
x: value
|
|
98
98
|
}
|
package/test/options.test.ts
CHANGED
|
@@ -75,6 +75,24 @@ describe("options", () => {
|
|
|
75
75
|
|
|
76
76
|
expect(output).not.toContain("TEST_VARIABLE");
|
|
77
77
|
});
|
|
78
|
+
|
|
79
|
+
test("Variant #7: Error on invalid lock option", async () => {
|
|
80
|
+
expect(
|
|
81
|
+
JsConfuser(`var TEST_VARIABLE;`, {
|
|
82
|
+
target: "node",
|
|
83
|
+
lock: "invalid",
|
|
84
|
+
} as any)
|
|
85
|
+
).rejects.toThrow();
|
|
86
|
+
|
|
87
|
+
expect(
|
|
88
|
+
JsConfuser(`var TEST_VARIABLE;`, {
|
|
89
|
+
target: "node",
|
|
90
|
+
lock: {
|
|
91
|
+
invalidProperty: true,
|
|
92
|
+
},
|
|
93
|
+
} as any)
|
|
94
|
+
).rejects.toThrow();
|
|
95
|
+
});
|
|
78
96
|
});
|
|
79
97
|
|
|
80
98
|
describe("options.preserveFunctionLength", () => {
|