js-confuser 1.7.1 → 1.7.2
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 +38 -0
- package/README.md +12 -27
- package/dist/compiler.js +2 -8
- package/dist/constants.js +17 -10
- package/dist/index.js +7 -30
- package/dist/obfuscator.js +15 -62
- package/dist/options.js +21 -38
- 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 +100 -5
- package/dist/templates/crash.js +51 -9
- 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 +71 -30
- package/dist/transforms/antiTooling.js +26 -22
- package/dist/transforms/calculator.js +18 -54
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +236 -333
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
- package/dist/transforms/deadCode.js +528 -27
- package/dist/transforms/dispatcher.js +106 -110
- 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 +8 -26
- package/dist/transforms/identifier/globalConcealing.js +35 -54
- package/dist/transforms/identifier/movedDeclarations.js +66 -38
- package/dist/transforms/identifier/renameVariables.js +29 -68
- package/dist/transforms/identifier/variableAnalysis.js +21 -48
- package/dist/transforms/lock/antiDebug.js +20 -25
- package/dist/transforms/lock/integrity.js +48 -47
- package/dist/transforms/lock/lock.js +62 -113
- package/dist/transforms/minify.js +77 -108
- package/dist/transforms/opaquePredicates.js +11 -48
- package/dist/transforms/preparation.js +17 -50
- package/dist/transforms/renameLabels.js +5 -22
- package/dist/transforms/rgf.js +93 -69
- package/dist/transforms/shuffle.js +41 -46
- package/dist/transforms/stack.js +35 -98
- package/dist/transforms/string/encoding.js +73 -27
- package/dist/transforms/string/stringCompression.js +44 -68
- package/dist/transforms/string/stringConcealing.js +125 -134
- package/dist/transforms/string/stringEncoding.js +6 -26
- package/dist/transforms/string/stringSplitting.js +5 -30
- package/dist/transforms/transform.js +50 -100
- 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 +0 -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 +5 -36
- package/dist/util/scope.js +6 -3
- package/package.json +3 -3
- package/src/constants.ts +12 -0
- package/src/options.ts +13 -0
- package/src/order.ts +2 -2
- package/src/templates/bufferToString.ts +49 -11
- package/src/templates/functionLength.ts +21 -3
- package/src/templates/globals.ts +3 -0
- package/src/templates/template.ts +85 -25
- package/src/transforms/antiTooling.ts +33 -11
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +2 -2
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
- package/src/transforms/deadCode.ts +0 -16
- package/src/transforms/dispatcher.ts +91 -69
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/extraction/classExtraction.ts +168 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -10
- package/src/transforms/extraction/objectExtraction.ts +4 -15
- package/src/transforms/flatten.ts +20 -5
- package/src/transforms/identifier/globalConcealing.ts +29 -65
- package/src/transforms/identifier/movedDeclarations.ts +90 -24
- package/src/transforms/minify.ts +27 -12
- package/src/transforms/rgf.ts +94 -5
- package/src/transforms/stack.ts +12 -3
- package/src/transforms/string/encoding.ts +85 -51
- package/src/transforms/string/stringCompression.ts +5 -8
- package/src/transforms/string/stringConcealing.ts +139 -113
- package/src/transforms/string/stringEncoding.ts +1 -2
- package/src/transforms/string/stringSplitting.ts +1 -2
- package/src/transforms/transform.ts +30 -1
- package/src/util/compare.ts +39 -5
- package/src/util/gen.ts +10 -3
- package/src/util/insert.ts +17 -0
- package/src/util/scope.ts +14 -2
- package/test/code/Cash.test.ts +10 -4
- 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 +111 -55
- 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 +19 -0
- package/test/transforms/identifier/movedDeclarations.test.ts +61 -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,16 +1,47 @@
|
|
|
1
|
-
import Template from "../../templates/template";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import Template, { ITemplate } from "../../templates/template";
|
|
2
|
+
import { choice, shuffle } from "../../util/random";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Defines an encoding implementation the Obfuscator
|
|
6
|
+
*/
|
|
7
|
+
export interface EncodingImplementation {
|
|
8
|
+
identity: string;
|
|
9
|
+
|
|
10
|
+
encode(s): string;
|
|
11
|
+
decode(s): string;
|
|
12
|
+
template: ITemplate;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let _hasAllEncodings = false;
|
|
16
|
+
export function hasAllEncodings() {
|
|
17
|
+
return _hasAllEncodings;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createEncodingImplementation(): EncodingImplementation {
|
|
21
|
+
if (_hasAllEncodings) {
|
|
22
|
+
return EncodingImplementations[
|
|
23
|
+
choice(Object.keys(EncodingImplementations))
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// create base91 encoding
|
|
28
|
+
let strTable =
|
|
29
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"';
|
|
30
|
+
|
|
31
|
+
// shuffle table
|
|
32
|
+
strTable = shuffle(strTable.split("")).join("");
|
|
33
|
+
|
|
34
|
+
let identity = "base91_" + strTable;
|
|
35
|
+
|
|
36
|
+
if (EncodingImplementations.hasOwnProperty(identity)) {
|
|
37
|
+
_hasAllEncodings = true;
|
|
38
|
+
return EncodingImplementations[identity];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var encodingImplementation = {
|
|
42
|
+
identity,
|
|
11
43
|
encode(str) {
|
|
12
|
-
const table =
|
|
13
|
-
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"';
|
|
44
|
+
const table = strTable;
|
|
14
45
|
|
|
15
46
|
const raw = Buffer.from(str, "utf-8");
|
|
16
47
|
const len = raw.length;
|
|
@@ -45,8 +76,7 @@ const Encoding: {
|
|
|
45
76
|
return ret;
|
|
46
77
|
},
|
|
47
78
|
decode(str) {
|
|
48
|
-
const table =
|
|
49
|
-
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"';
|
|
79
|
+
const table = strTable;
|
|
50
80
|
|
|
51
81
|
const raw = "" + (str || "");
|
|
52
82
|
const len = raw.length;
|
|
@@ -81,45 +111,51 @@ const Encoding: {
|
|
|
81
111
|
return Buffer.from(ret).toString("utf-8");
|
|
82
112
|
},
|
|
83
113
|
template: Template(`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
n
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
function {__fnName__}(str){
|
|
115
|
+
var table = '${strTable}';
|
|
116
|
+
|
|
117
|
+
var raw = "" + (str || "");
|
|
118
|
+
var len = raw.length;
|
|
119
|
+
var ret = [];
|
|
120
|
+
|
|
121
|
+
var b = 0;
|
|
122
|
+
var n = 0;
|
|
123
|
+
var v = -1;
|
|
124
|
+
|
|
125
|
+
for (var i = 0; i < len; i++) {
|
|
126
|
+
var p = table.indexOf(raw[i]);
|
|
127
|
+
if (p === -1) continue;
|
|
128
|
+
if (v < 0) {
|
|
129
|
+
v = p;
|
|
130
|
+
} else {
|
|
131
|
+
v += p * 91;
|
|
132
|
+
b |= v << n;
|
|
133
|
+
n += (v & 8191) > 88 ? 13 : 14;
|
|
134
|
+
do {
|
|
135
|
+
ret.push(b & 0xff);
|
|
136
|
+
b >>= 8;
|
|
137
|
+
n -= 8;
|
|
138
|
+
} while (n > 7);
|
|
139
|
+
v = -1;
|
|
140
|
+
}
|
|
111
141
|
}
|
|
142
|
+
|
|
143
|
+
if (v > -1) {
|
|
144
|
+
ret.push((b | (v << n)) & 0xff);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return {__bufferToString__}(ret);
|
|
112
148
|
}
|
|
149
|
+
`).ignoreMissingVariables(),
|
|
150
|
+
};
|
|
113
151
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return {bufferToString}(ret);
|
|
119
|
-
}
|
|
120
|
-
`),
|
|
121
|
-
},
|
|
152
|
+
EncodingImplementations[identity] = encodingImplementation;
|
|
153
|
+
return encodingImplementation;
|
|
154
|
+
}
|
|
122
155
|
|
|
156
|
+
export const EncodingImplementations: {
|
|
157
|
+
[encodingIdentity: string]: EncodingImplementation;
|
|
158
|
+
} = {
|
|
123
159
|
/* ascii85: { This implementation is flaky and causes decoding errors
|
|
124
160
|
encode(a) {
|
|
125
161
|
var b, c, d, e, f, g, h, i, j, k;
|
|
@@ -209,5 +245,3 @@ const Encoding: {
|
|
|
209
245
|
`),
|
|
210
246
|
}, */
|
|
211
247
|
};
|
|
212
|
-
|
|
213
|
-
export default Encoding;
|
|
@@ -2,7 +2,7 @@ import { ok } from "assert";
|
|
|
2
2
|
import { ObfuscateOrder } from "../../order";
|
|
3
3
|
import { ComputeProbabilityMap } from "../../probability";
|
|
4
4
|
import Template from "../../templates/template";
|
|
5
|
-
import { isDirective } from "../../util/compare";
|
|
5
|
+
import { isDirective, isModuleSource } from "../../util/compare";
|
|
6
6
|
import {
|
|
7
7
|
CallExpression,
|
|
8
8
|
FunctionDeclaration,
|
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
} from "../../util/gen";
|
|
17
17
|
import { append, prepend } from "../../util/insert";
|
|
18
18
|
import Transform from "../transform";
|
|
19
|
-
import {
|
|
20
|
-
|
|
19
|
+
import { predictableFunctionTag } from "../../constants";
|
|
20
|
+
|
|
21
21
|
function LZ_encode(c) {
|
|
22
22
|
ok(c);
|
|
23
23
|
var x = "charCodeAt",
|
|
@@ -94,7 +94,7 @@ export default class StringCompression extends Transform {
|
|
|
94
94
|
this.map = new Map();
|
|
95
95
|
this.ignore = new Set();
|
|
96
96
|
this.string = "";
|
|
97
|
-
this.fnName = this.getPlaceholder();
|
|
97
|
+
this.fnName = this.getPlaceholder() + predictableFunctionTag;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
apply(tree) {
|
|
@@ -107,7 +107,7 @@ export default class StringCompression extends Transform {
|
|
|
107
107
|
|
|
108
108
|
var split = this.getPlaceholder();
|
|
109
109
|
var decoder = this.getPlaceholder();
|
|
110
|
-
var getStringName = this.getPlaceholder();
|
|
110
|
+
var getStringName = this.getPlaceholder() + predictableFunctionTag; // Returns the string payload
|
|
111
111
|
|
|
112
112
|
var encoded = LZ_encode(this.string);
|
|
113
113
|
if (LZ_decode(encoded) !== this.string) {
|
|
@@ -210,9 +210,6 @@ export default class StringCompression extends Transform {
|
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
// HARD CODED LIMIT of 10,000 (after 1,000 elements)
|
|
214
|
-
if (this.map.size > 1000 && !chance(this.map.size / 100)) return;
|
|
215
|
-
|
|
216
213
|
var index = this.map.get(object.value);
|
|
217
214
|
|
|
218
215
|
// New string, add it!
|
|
@@ -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,36 @@ 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
34
|
import { BufferToStringTemplate } from "../../templates/bufferToString";
|
|
35
|
+
import { criticalFunctionTag, predictableFunctionTag } from "../../constants";
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (parents[0].type == "ImportDeclaration" && parents[0].source == object) {
|
|
37
|
-
return true;
|
|
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;
|
|
37
|
+
interface FunctionObject {
|
|
38
|
+
block: Node;
|
|
39
|
+
fnName: string;
|
|
40
|
+
encodingImplementation: EncodingImplementation;
|
|
59
41
|
}
|
|
60
42
|
|
|
61
43
|
export default class StringConcealing extends Transform {
|
|
62
44
|
arrayExpression: Node;
|
|
63
45
|
set: Set<string>;
|
|
64
|
-
index: { [str: string]: [number, string] };
|
|
46
|
+
index: { [str: string]: [number, string, Node] }; // index, fnName, block
|
|
65
47
|
|
|
66
48
|
arrayName = this.getPlaceholder();
|
|
67
49
|
ignore = new Set<string>();
|
|
68
50
|
variablesMade = 1;
|
|
69
|
-
encoding: { [type: string]: string } = Object.create(null);
|
|
70
51
|
gen: ReturnType<Transform["getGenerator"]>;
|
|
71
52
|
|
|
72
|
-
|
|
53
|
+
functionObjects: FunctionObject[] = [];
|
|
73
54
|
|
|
74
55
|
constructor(o) {
|
|
75
56
|
super(o, ObfuscateOrder.StringConcealing);
|
|
@@ -77,84 +58,110 @@ export default class StringConcealing extends Transform {
|
|
|
77
58
|
this.set = new Set();
|
|
78
59
|
this.index = Object.create(null);
|
|
79
60
|
this.arrayExpression = ArrayExpression([]);
|
|
80
|
-
this.hasAllEncodings = false;
|
|
81
61
|
this.gen = this.getGenerator();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
apply(tree) {
|
|
65
|
+
super.apply(tree);
|
|
82
66
|
|
|
83
67
|
// Pad array with useless strings
|
|
84
68
|
var dead = getRandomInteger(5, 15);
|
|
85
69
|
for (var i = 0; i < dead; i++) {
|
|
86
70
|
var str = getRandomString(getRandomInteger(5, 40));
|
|
87
|
-
var fn = this.transform(Literal(str), []);
|
|
71
|
+
var fn = this.transform(Literal(str), [tree]);
|
|
88
72
|
if (fn) {
|
|
89
73
|
fn();
|
|
90
74
|
}
|
|
91
75
|
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
apply(tree) {
|
|
95
|
-
super.apply(tree);
|
|
96
76
|
|
|
97
77
|
var cacheName = this.getPlaceholder();
|
|
98
|
-
var bufferToStringName = this.getPlaceholder();
|
|
78
|
+
var bufferToStringName = this.getPlaceholder() + predictableFunctionTag;
|
|
99
79
|
|
|
100
80
|
// This helper functions convert UInt8 Array to UTf-string
|
|
101
81
|
prepend(
|
|
102
82
|
tree,
|
|
103
|
-
...BufferToStringTemplate.compile({
|
|
83
|
+
...BufferToStringTemplate.compile({
|
|
84
|
+
name: bufferToStringName,
|
|
85
|
+
getGlobalFnName: this.getPlaceholder() + predictableFunctionTag,
|
|
86
|
+
})
|
|
104
87
|
);
|
|
105
88
|
|
|
106
|
-
|
|
107
|
-
var {
|
|
108
|
-
|
|
109
|
-
|
|
89
|
+
for (var functionObject of this.functionObjects) {
|
|
90
|
+
var {
|
|
91
|
+
block,
|
|
92
|
+
fnName: getterFnName,
|
|
93
|
+
encodingImplementation,
|
|
94
|
+
} = functionObject;
|
|
95
|
+
|
|
96
|
+
var decodeFn =
|
|
97
|
+
this.getPlaceholder() + predictableFunctionTag + criticalFunctionTag;
|
|
110
98
|
|
|
111
99
|
append(
|
|
112
|
-
|
|
113
|
-
template.single({
|
|
100
|
+
block,
|
|
101
|
+
encodingImplementation.template.single({
|
|
102
|
+
__fnName__: decodeFn,
|
|
103
|
+
__bufferToString__: bufferToStringName,
|
|
104
|
+
})
|
|
114
105
|
);
|
|
106
|
+
// All these are fake and never ran
|
|
107
|
+
var ifStatements = Template(`if ( z == x ) {
|
|
108
|
+
return y[${cacheName}[z]] = ${getterFnName}(x, y);
|
|
109
|
+
}
|
|
110
|
+
if ( y ) {
|
|
111
|
+
[b, y] = [a(b), x || z]
|
|
112
|
+
return ${getterFnName}(x, b, z)
|
|
113
|
+
}
|
|
114
|
+
if ( z && a !== ${decodeFn} ) {
|
|
115
|
+
${getterFnName} = ${decodeFn}
|
|
116
|
+
return ${getterFnName}(x, -1, z, a, b)
|
|
117
|
+
}
|
|
118
|
+
if ( a === ${getterFnName} ) {
|
|
119
|
+
${decodeFn} = y
|
|
120
|
+
return ${decodeFn}(z)
|
|
121
|
+
}
|
|
122
|
+
if( a === undefined ) {
|
|
123
|
+
${getterFnName} = b
|
|
124
|
+
}
|
|
125
|
+
if( z == a ) {
|
|
126
|
+
return y ? x[b[y]] : ${cacheName}[x] || (z=(b[x] || a), ${cacheName}[x] = z(${this.arrayName}[x]))
|
|
127
|
+
}
|
|
128
|
+
`).compile();
|
|
115
129
|
|
|
116
|
-
|
|
117
|
-
|
|
130
|
+
// Not all fake if-statements are needed
|
|
131
|
+
ifStatements = ifStatements.filter(() => chance(50));
|
|
132
|
+
|
|
133
|
+
// This one is always used
|
|
134
|
+
ifStatements.push(
|
|
118
135
|
Template(`
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
} else if ( y ) {
|
|
124
|
-
[b, y] = [a(b), x || z]
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return y ? x[b[y]] : ${cacheName}[x] || (z=(b[x], a), ${cacheName}[x] = z(${this.arrayName}[x]))
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
`).single()
|
|
136
|
+
if ( x !== y ) {
|
|
137
|
+
return b[x] || (b[x] = a(${this.arrayName}[x]))
|
|
138
|
+
}
|
|
139
|
+
`).single()
|
|
131
140
|
);
|
|
132
|
-
});
|
|
133
141
|
|
|
134
|
-
|
|
142
|
+
shuffle(ifStatements);
|
|
143
|
+
|
|
144
|
+
var varDeclaration = Template(`
|
|
145
|
+
var ${getterFnName} = (x, y, z, a, b)=>{
|
|
146
|
+
if(typeof a === "undefined") {
|
|
147
|
+
a = ${decodeFn}
|
|
148
|
+
}
|
|
149
|
+
if(typeof b === "undefined") {
|
|
150
|
+
b = ${cacheName}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
`).single();
|
|
154
|
+
|
|
155
|
+
varDeclaration.declarations[0].init.body.body.push(...ifStatements);
|
|
156
|
+
|
|
157
|
+
prepend(block, varDeclaration);
|
|
158
|
+
}
|
|
135
159
|
|
|
136
160
|
prepend(
|
|
137
161
|
tree,
|
|
138
162
|
VariableDeclaration([
|
|
139
163
|
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
|
-
),
|
|
164
|
+
VariableDeclarator(this.arrayName, this.arrayExpression),
|
|
158
165
|
])
|
|
159
166
|
);
|
|
160
167
|
}
|
|
@@ -192,48 +199,67 @@ export default class StringConcealing extends Transform {
|
|
|
192
199
|
return;
|
|
193
200
|
}
|
|
194
201
|
|
|
195
|
-
|
|
196
|
-
if (this.set.size > 1000 && !chance(this.set.size / 100)) return;
|
|
202
|
+
var currentBlock = getBlock(object, parents);
|
|
197
203
|
|
|
198
|
-
|
|
204
|
+
// Find created functions
|
|
205
|
+
var functionObjects: FunctionObject[] = parents
|
|
206
|
+
.filter((node) => node.$stringConcealingFunctionObject)
|
|
207
|
+
.map((item) => item.$stringConcealingFunctionObject);
|
|
199
208
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
209
|
+
// Choose random functionObject to use
|
|
210
|
+
var functionObject = choice(functionObjects);
|
|
211
|
+
|
|
212
|
+
if (
|
|
213
|
+
!functionObject ||
|
|
214
|
+
(!hasAllEncodings() &&
|
|
215
|
+
chance(25 / this.functionObjects.length) &&
|
|
216
|
+
!currentBlock.$stringConcealingFunctionObject)
|
|
217
|
+
) {
|
|
218
|
+
// No functions, create one
|
|
205
219
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
220
|
+
var newFunctionObject: FunctionObject = {
|
|
221
|
+
block: currentBlock,
|
|
222
|
+
encodingImplementation: createEncodingImplementation(),
|
|
223
|
+
fnName: this.getPlaceholder() + predictableFunctionTag,
|
|
224
|
+
};
|
|
211
225
|
|
|
212
|
-
|
|
213
|
-
|
|
226
|
+
this.functionObjects.push(newFunctionObject);
|
|
227
|
+
currentBlock.$stringConcealingFunctionObject = newFunctionObject;
|
|
228
|
+
functionObject = newFunctionObject;
|
|
214
229
|
}
|
|
215
230
|
|
|
216
|
-
var fnName =
|
|
217
|
-
var encoder = Encoding[type];
|
|
231
|
+
var { fnName, encodingImplementation } = functionObject;
|
|
218
232
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
this.
|
|
224
|
-
|
|
233
|
+
var index = -1;
|
|
234
|
+
|
|
235
|
+
// String already decoded?
|
|
236
|
+
if (this.set.has(object.value)) {
|
|
237
|
+
var row = this.index[object.value];
|
|
238
|
+
if (parents.includes(row[2])) {
|
|
239
|
+
[index, fnName] = row;
|
|
240
|
+
ok(typeof index === "number");
|
|
241
|
+
}
|
|
225
242
|
}
|
|
226
243
|
|
|
227
|
-
|
|
228
|
-
|
|
244
|
+
if (index == -1) {
|
|
245
|
+
// The decode function must return correct result
|
|
246
|
+
var encoded = encodingImplementation.encode(object.value);
|
|
247
|
+
if (encodingImplementation.decode(encoded) !== object.value) {
|
|
248
|
+
this.ignore.add(object.value);
|
|
249
|
+
this.warn(
|
|
250
|
+
encodingImplementation.identity,
|
|
251
|
+
object.value.slice(0, 100)
|
|
252
|
+
);
|
|
253
|
+
delete EncodingImplementations[encodingImplementation.identity];
|
|
254
|
+
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
229
258
|
this.arrayExpression.elements.push(Literal(encoded));
|
|
230
259
|
index = this.arrayExpression.elements.length - 1;
|
|
231
|
-
this.index[object.value] = [index, fnName];
|
|
260
|
+
this.index[object.value] = [index, fnName, currentBlock];
|
|
232
261
|
|
|
233
262
|
this.set.add(object.value);
|
|
234
|
-
} else {
|
|
235
|
-
[index, fnName] = this.index[object.value];
|
|
236
|
-
ok(typeof index === "number");
|
|
237
263
|
}
|
|
238
264
|
|
|
239
265
|
ok(index != -1, "index == -1");
|
|
@@ -269,7 +295,7 @@ export default class StringConcealing extends Transform {
|
|
|
269
295
|
|
|
270
296
|
var constantReferenceType = choice(["variable", "array", "object"]);
|
|
271
297
|
|
|
272
|
-
var place =
|
|
298
|
+
var place = currentBlock;
|
|
273
299
|
if (!place) {
|
|
274
300
|
this.error(new Error("No lexical block to insert code"));
|
|
275
301
|
}
|
|
@@ -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,5 +1,10 @@
|
|
|
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,
|
|
@@ -15,6 +20,8 @@ import {
|
|
|
15
20
|
reservedKeywords,
|
|
16
21
|
} from "../constants";
|
|
17
22
|
import { ObfuscateOrder } from "../order";
|
|
23
|
+
import { ITemplate } from "../templates/template";
|
|
24
|
+
import { prepend } from "../util/insert";
|
|
18
25
|
|
|
19
26
|
/**
|
|
20
27
|
* Base-class for all transformations.
|
|
@@ -78,6 +85,8 @@ export default class Transform {
|
|
|
78
85
|
*/
|
|
79
86
|
after: Transform[];
|
|
80
87
|
|
|
88
|
+
initVariables = new Map<string, string>();
|
|
89
|
+
|
|
81
90
|
constructor(obfuscator, priority: number = -1) {
|
|
82
91
|
ok(obfuscator instanceof Obfuscator, "obfuscator should be an Obfuscator");
|
|
83
92
|
|
|
@@ -336,6 +345,26 @@ export default class Transform {
|
|
|
336
345
|
return identifier;
|
|
337
346
|
}
|
|
338
347
|
|
|
348
|
+
createInitVariable = (value: ITemplate, parents: Node[]) => {
|
|
349
|
+
var key = value.templates[0];
|
|
350
|
+
if (this.initVariables.has(key)) {
|
|
351
|
+
return this.initVariables.get(key);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
var root = parents[parents.length - 1];
|
|
355
|
+
ok(root.type === "Program");
|
|
356
|
+
|
|
357
|
+
var name = this.getPlaceholder();
|
|
358
|
+
this.initVariables.set(key, name);
|
|
359
|
+
|
|
360
|
+
prepend(
|
|
361
|
+
root,
|
|
362
|
+
VariableDeclaration(VariableDeclarator(name, value.single().expression))
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
return name;
|
|
366
|
+
};
|
|
367
|
+
|
|
339
368
|
/**
|
|
340
369
|
* Smartly appends a comment to a Node.
|
|
341
370
|
* - Includes the transformation's name.
|