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
|
@@ -7,14 +7,10 @@ import {
|
|
|
7
7
|
BlockStatement,
|
|
8
8
|
ReturnStatement,
|
|
9
9
|
CallExpression,
|
|
10
|
-
ObjectExpression,
|
|
11
|
-
ArrayExpression,
|
|
12
10
|
ThisExpression,
|
|
13
|
-
Property,
|
|
14
11
|
} from "../../util/gen";
|
|
15
|
-
import { clone,
|
|
16
|
-
import { isBlock,
|
|
17
|
-
import Template from "../../templates/template";
|
|
12
|
+
import { clone, prepend } from "../../util/insert";
|
|
13
|
+
import { isBlock, walk } from "../../traverse";
|
|
18
14
|
import { ObfuscateOrder } from "../../order";
|
|
19
15
|
import { ok } from "assert";
|
|
20
16
|
import { reservedKeywords } from "../../constants";
|
|
@@ -23,6 +19,7 @@ import AntiTemplate from "./antiTemplate";
|
|
|
23
19
|
import AntiClass from "./antiClass";
|
|
24
20
|
import AntiES6Object from "./antiES6Object";
|
|
25
21
|
import AntiSpreadOperator from "./antiSpreadOperator";
|
|
22
|
+
import { ES5Template } from "../../templates/es5";
|
|
26
23
|
|
|
27
24
|
/**
|
|
28
25
|
* `Const` and `Let` are not allowed in ES5.
|
|
@@ -96,24 +93,40 @@ export class AntiArrowFunction extends Transform {
|
|
|
96
93
|
}
|
|
97
94
|
}
|
|
98
95
|
|
|
99
|
-
|
|
96
|
+
/**
|
|
97
|
+
* The ES5 options aims to convert ES6 and up features down to ES5-compatible code.
|
|
98
|
+
*
|
|
99
|
+
* The obfuscator regularly adds ES6 code (variable destructuring, spread element, etc.)
|
|
100
|
+
* This transformations goal is undo only these things.
|
|
101
|
+
*/
|
|
102
|
+
export default class ES5 extends Transform {
|
|
100
103
|
constructor(o) {
|
|
101
|
-
super(o);
|
|
104
|
+
super(o, ObfuscateOrder.ES5);
|
|
105
|
+
|
|
106
|
+
this.before.push(new AntiClass(o));
|
|
107
|
+
this.before.push(new AntiTemplate(o));
|
|
108
|
+
this.before.push(new AntiSpreadOperator(o));
|
|
109
|
+
this.before.push(new AntiES6Object(o));
|
|
110
|
+
this.before.push(new AntiArrowFunction(o));
|
|
111
|
+
this.before.push(new AntiDestructuring(o));
|
|
112
|
+
this.before.push(new AntiConstLet(o));
|
|
102
113
|
}
|
|
103
114
|
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
apply(tree: Node) {
|
|
116
|
+
super.apply(tree);
|
|
117
|
+
|
|
118
|
+
var nodesToAdd = ES5Template.compile();
|
|
119
|
+
prepend(tree, ...nodesToAdd);
|
|
106
120
|
}
|
|
107
121
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
object.init.type == "ExpressionStatement"
|
|
113
|
-
) {
|
|
114
|
-
object.init = object.init.expression;
|
|
115
|
-
}
|
|
122
|
+
// FixedExpressions
|
|
123
|
+
match(object: Node, parents: Node[]) {
|
|
124
|
+
return !!object.type;
|
|
125
|
+
}
|
|
116
126
|
|
|
127
|
+
transform(object: Node, parents: Node[]) {
|
|
128
|
+
return () => {
|
|
129
|
+
// Object.keyword -> Object["keyword"]
|
|
117
130
|
if (object.type == "MemberExpression") {
|
|
118
131
|
if (!object.computed && object.property.type == "Identifier") {
|
|
119
132
|
if (reservedKeywords.has(object.property.name)) {
|
|
@@ -123,6 +136,7 @@ class FixedExpressions extends Transform {
|
|
|
123
136
|
}
|
|
124
137
|
}
|
|
125
138
|
|
|
139
|
+
// { keyword: ... } -> { "keyword": ... }
|
|
126
140
|
if (object.type == "Property") {
|
|
127
141
|
if (!object.computed && object.key.type == "Identifier") {
|
|
128
142
|
if (reservedKeywords.has(object.key.name)) {
|
|
@@ -133,62 +147,3 @@ class FixedExpressions extends Transform {
|
|
|
133
147
|
};
|
|
134
148
|
}
|
|
135
149
|
}
|
|
136
|
-
|
|
137
|
-
export default class ES5 extends Transform {
|
|
138
|
-
constructor(o) {
|
|
139
|
-
super(o, ObfuscateOrder.ES5);
|
|
140
|
-
|
|
141
|
-
this.before.push(new AntiClass(o));
|
|
142
|
-
this.before.push(new AntiTemplate(o));
|
|
143
|
-
this.before.push(new AntiSpreadOperator(o));
|
|
144
|
-
this.before.push(new AntiES6Object(o));
|
|
145
|
-
this.before.push(new AntiArrowFunction(o));
|
|
146
|
-
this.before.push(new AntiDestructuring(o));
|
|
147
|
-
this.before.push(new AntiConstLet(o));
|
|
148
|
-
|
|
149
|
-
this.concurrent.push(new FixedExpressions(o));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
match(object: Node, parents: Node[]) {
|
|
153
|
-
return object.type == "Program";
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
transform(object: Node, parents: Node[]) {
|
|
157
|
-
var block = getBlock(object, parents);
|
|
158
|
-
|
|
159
|
-
getBlockBody(block).splice(
|
|
160
|
-
0,
|
|
161
|
-
0,
|
|
162
|
-
...Template(`
|
|
163
|
-
!Array.prototype.forEach ? Array.prototype.forEach = function (callback, thisArg) {
|
|
164
|
-
thisArg = thisArg;
|
|
165
|
-
for (var i = 0; i < this.length; i++) {
|
|
166
|
-
callback.call(thisArg, this[i], i, this);
|
|
167
|
-
}
|
|
168
|
-
} : 0;
|
|
169
|
-
|
|
170
|
-
!Array.prototype.map ? Array.prototype.map = function (callback, thisArg) {
|
|
171
|
-
thisArg = thisArg;
|
|
172
|
-
var array=[];
|
|
173
|
-
for (var i = 0; i < this.length; i++) {
|
|
174
|
-
array.push( callback.call(thisArg, this[i], i, this) );
|
|
175
|
-
}
|
|
176
|
-
return array;
|
|
177
|
-
} : 0;
|
|
178
|
-
|
|
179
|
-
!Array.prototype.reduce ? Array.prototype.reduce = function(fn, initial) {
|
|
180
|
-
var values = this;
|
|
181
|
-
if ( typeof initial === "undefined" ) {
|
|
182
|
-
initial = 0;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
values.forEach(function(item, index){
|
|
186
|
-
initial = fn(initial, item, index, this);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
return initial;
|
|
190
|
-
} : 0;
|
|
191
|
-
`).compile()
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
}
|
package/src/transforms/eval.ts
CHANGED
|
@@ -28,6 +28,24 @@ export default class Eval extends Transform {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
transform(object, parents) {
|
|
31
|
+
// Don't apply to getter/setters or class methods
|
|
32
|
+
if (parents[0]) {
|
|
33
|
+
if (
|
|
34
|
+
parents[0].type === "MethodDefinition" &&
|
|
35
|
+
parents[0].value === object
|
|
36
|
+
) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (
|
|
41
|
+
parents[0].type === "Property" &&
|
|
42
|
+
parents[0].value === object &&
|
|
43
|
+
(parents[0].kind !== "init" || parents[0].method)
|
|
44
|
+
) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
31
49
|
if (
|
|
32
50
|
!ComputeProbabilityMap(
|
|
33
51
|
this.options.eval,
|
|
@@ -28,7 +28,7 @@ import { ObfuscateOrder } from "../../order";
|
|
|
28
28
|
import { isModuleSource } from "../string/stringConcealing";
|
|
29
29
|
import { ComputeProbabilityMap } from "../../probability";
|
|
30
30
|
import { ok } from "assert";
|
|
31
|
-
import { choice, getRandomInteger } from "../../util/random";
|
|
31
|
+
import { chance, choice, getRandomInteger } from "../../util/random";
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* [Duplicate Literals Removal](https://docs.jscrambler.com/code-integrity/documentation/transformations/duplicate-literals-removal) replaces duplicate literals with a variable name.
|
|
@@ -159,7 +159,7 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
159
159
|
var body = [];
|
|
160
160
|
var thisShift = getRandomInteger(-250, 250);
|
|
161
161
|
// the name of the getter
|
|
162
|
-
getterName = this.getPlaceholder();
|
|
162
|
+
getterName = this.getPlaceholder() + "_dLR_" + this.fnGetters.size;
|
|
163
163
|
|
|
164
164
|
if (basedOn) {
|
|
165
165
|
var shift = this.fnShifts.get(basedOn);
|
|
@@ -233,6 +233,9 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
233
233
|
return;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
+
// HARD CODED LIMIT of 10,000 (after 1,000 elements)
|
|
237
|
+
if (this.map.size > 1000 && !chance(this.map.size / 100)) return;
|
|
238
|
+
|
|
236
239
|
if (
|
|
237
240
|
this.arrayName &&
|
|
238
241
|
parents[0].object &&
|
|
@@ -268,20 +271,20 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
268
271
|
this.arrayExpression = ArrayExpression([]);
|
|
269
272
|
}
|
|
270
273
|
|
|
271
|
-
var
|
|
272
|
-
if (
|
|
274
|
+
var firstLocation = this.first.get(value);
|
|
275
|
+
if (firstLocation) {
|
|
273
276
|
this.first.set(value, null);
|
|
274
277
|
var index = this.map.size;
|
|
275
278
|
|
|
276
279
|
ok(!this.map.has(value));
|
|
277
280
|
this.map.set(value, index);
|
|
278
281
|
|
|
279
|
-
this.toCaller(first[0], first[1], index);
|
|
280
|
-
|
|
281
282
|
var pushing = clone(object);
|
|
282
283
|
this.arrayExpression.elements.push(pushing);
|
|
283
284
|
|
|
284
285
|
ok(this.arrayExpression.elements[index] === pushing);
|
|
286
|
+
|
|
287
|
+
this.toCaller(firstLocation[0], firstLocation[1], index);
|
|
285
288
|
}
|
|
286
289
|
|
|
287
290
|
var index = this.map.get(value);
|
|
@@ -100,11 +100,18 @@ export default class ObjectExtraction extends Transform {
|
|
|
100
100
|
);
|
|
101
101
|
|
|
102
102
|
if (nonInitOrComputed) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
if (nonInitOrComputed.key) {
|
|
104
|
+
this.log(
|
|
105
|
+
name +
|
|
106
|
+
" has non-init/computed property: " +
|
|
107
|
+
nonInitOrComputed.key.name || nonInitOrComputed.key.value
|
|
108
|
+
);
|
|
109
|
+
} else {
|
|
110
|
+
this.log(
|
|
111
|
+
name + " has spread-element or other type of property"
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
108
115
|
illegal.add(name);
|
|
109
116
|
return;
|
|
110
117
|
} else {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ObfuscateOrder } from "../order";
|
|
2
|
+
import { ExitCallback } from "../traverse";
|
|
3
|
+
import { Identifier, Node } from "../util/gen";
|
|
4
|
+
import StringEncoding from "./string/stringEncoding";
|
|
5
|
+
import Transform from "./transform";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The Finalizer is the last transformation before the code is ready to be generated.
|
|
9
|
+
*
|
|
10
|
+
* Hexadecimal numbers:
|
|
11
|
+
* - Convert integer literals into `Identifier` nodes with the name being a hexadecimal number
|
|
12
|
+
*
|
|
13
|
+
* BigInt support:
|
|
14
|
+
* - Convert BigInt literals into `Identifier` nodes with the name being the raw BigInt string value + "n"
|
|
15
|
+
*
|
|
16
|
+
* String Encoding:
|
|
17
|
+
* - Convert String literals into `Identifier` nodes with the name being a unicode escaped string
|
|
18
|
+
*/
|
|
19
|
+
export default class Finalizer extends Transform {
|
|
20
|
+
stringEncoding: StringEncoding;
|
|
21
|
+
|
|
22
|
+
constructor(o) {
|
|
23
|
+
super(o, ObfuscateOrder.Finalizer);
|
|
24
|
+
|
|
25
|
+
this.stringEncoding = new StringEncoding(o);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
isNumberLiteral(object: Node) {
|
|
29
|
+
return (
|
|
30
|
+
object.type === "Literal" &&
|
|
31
|
+
typeof object.value === "number" &&
|
|
32
|
+
Math.floor(object.value) === object.value
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
isBigIntLiteral(object: Node) {
|
|
37
|
+
return object.type === "Literal" && typeof object.value === "bigint";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
match(object, parents) {
|
|
41
|
+
return object.type === "Literal";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
transform(object: Node, parents: Node[]): void | ExitCallback {
|
|
45
|
+
// Hexadecimal Numbers
|
|
46
|
+
if (this.options.hexadecimalNumbers && this.isNumberLiteral(object)) {
|
|
47
|
+
return () => {
|
|
48
|
+
// Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
|
|
49
|
+
// This code handles it regardless
|
|
50
|
+
var isNegative = object.value < 0;
|
|
51
|
+
var hex = Math.abs(object.value).toString(16);
|
|
52
|
+
|
|
53
|
+
var newStr = (isNegative ? "-" : "") + "0x" + hex;
|
|
54
|
+
|
|
55
|
+
this.replace(object, Identifier(newStr));
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// BigInt support
|
|
60
|
+
if (this.isBigIntLiteral(object)) {
|
|
61
|
+
// https://github.com/MichaelXF/js-confuser/issues/79
|
|
62
|
+
return () => {
|
|
63
|
+
// Use an Identifier with the raw string
|
|
64
|
+
this.replace(object, Identifier(object.raw));
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
this.options.stringEncoding &&
|
|
70
|
+
this.stringEncoding.match(object, parents)
|
|
71
|
+
) {
|
|
72
|
+
return this.stringEncoding.transform(object, parents);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|