js-confuser 1.7.3 → 2.0.0-alpha.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/ISSUE_TEMPLATE/bug_report.md +6 -4
- package/CHANGELOG.md +70 -0
- package/Migration.md +57 -0
- package/README.md +23 -929
- package/dist/constants.js +65 -14
- package/dist/index.js +108 -160
- package/dist/obfuscator.js +316 -118
- package/dist/options.js +1 -119
- package/dist/order.js +30 -30
- package/dist/presets.js +47 -45
- package/dist/probability.js +25 -32
- package/dist/templates/bufferToStringTemplate.js +9 -0
- package/dist/templates/deadCodeTemplates.js +9 -0
- package/dist/templates/getGlobalTemplate.js +19 -0
- package/dist/templates/integrityTemplate.js +30 -0
- package/dist/templates/setFunctionLengthTemplate.js +9 -0
- package/dist/templates/stringCompressionTemplate.js +10 -0
- package/dist/templates/tamperProtectionTemplates.js +21 -0
- package/dist/templates/template.js +199 -184
- package/dist/transforms/astScrambler.js +100 -0
- package/dist/transforms/calculator.js +70 -127
- package/dist/transforms/controlFlowFlattening.js +1182 -0
- package/dist/transforms/deadCode.js +62 -587
- package/dist/transforms/dispatcher.js +300 -313
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +88 -189
- package/dist/transforms/extraction/objectExtraction.js +131 -215
- package/dist/transforms/finalizer.js +56 -59
- package/dist/transforms/flatten.js +275 -276
- package/dist/transforms/functionOutlining.js +230 -0
- package/dist/transforms/identifier/globalConcealing.js +214 -135
- package/dist/transforms/identifier/movedDeclarations.js +167 -91
- package/dist/transforms/identifier/renameVariables.js +239 -193
- package/dist/transforms/lock/integrity.js +61 -184
- package/dist/transforms/lock/lock.js +261 -387
- package/dist/transforms/minify.js +431 -436
- package/dist/transforms/opaquePredicates.js +65 -118
- package/dist/transforms/pack.js +160 -0
- package/dist/transforms/plugin.js +179 -0
- package/dist/transforms/preparation.js +261 -173
- package/dist/transforms/renameLabels.js +132 -56
- package/dist/transforms/rgf.js +140 -267
- package/dist/transforms/shuffle.js +52 -145
- package/dist/transforms/string/encoding.js +44 -175
- package/dist/transforms/string/stringCompression.js +79 -155
- package/dist/transforms/string/stringConcealing.js +189 -225
- package/dist/transforms/string/stringEncoding.js +32 -40
- package/dist/transforms/string/stringSplitting.js +54 -55
- package/dist/transforms/variableMasking.js +232 -0
- package/dist/utils/ControlObject.js +125 -0
- package/dist/utils/IntGen.js +46 -0
- package/dist/utils/NameGen.js +106 -0
- package/dist/utils/ast-utils.js +560 -0
- package/dist/utils/function-utils.js +56 -0
- package/dist/utils/gen-utils.js +48 -0
- package/dist/utils/node.js +77 -0
- package/dist/utils/object-utils.js +21 -0
- package/dist/utils/random-utils.js +91 -0
- package/dist/utils/static-utils.js +64 -0
- package/dist/validateOptions.js +122 -0
- package/index.d.ts +1 -17
- package/package.json +27 -22
- package/src/constants.ts +139 -82
- package/src/index.ts +70 -165
- package/src/obfuscationResult.ts +43 -0
- package/src/obfuscator.ts +328 -135
- package/src/options.ts +149 -658
- package/src/order.ts +14 -14
- package/src/presets.ts +39 -34
- package/src/probability.ts +21 -36
- package/src/templates/bufferToStringTemplate.ts +57 -0
- package/src/templates/deadCodeTemplates.ts +1185 -0
- package/src/templates/getGlobalTemplate.ts +72 -0
- package/src/templates/integrityTemplate.ts +69 -0
- package/src/templates/setFunctionLengthTemplate.ts +11 -0
- package/src/templates/stringCompressionTemplate.ts +42 -0
- package/src/templates/tamperProtectionTemplates.ts +116 -0
- package/src/templates/template.ts +149 -157
- package/src/transforms/astScrambler.ts +99 -0
- package/src/transforms/calculator.ts +96 -226
- package/src/transforms/controlFlowFlattening.ts +1594 -0
- package/src/transforms/deadCode.ts +85 -676
- package/src/transforms/dispatcher.ts +431 -640
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +147 -295
- package/src/transforms/extraction/objectExtraction.ts +160 -333
- package/src/transforms/finalizer.ts +63 -64
- package/src/transforms/flatten.ts +439 -557
- package/src/transforms/functionOutlining.ts +225 -0
- package/src/transforms/identifier/globalConcealing.ts +255 -266
- package/src/transforms/identifier/movedDeclarations.ts +228 -142
- package/src/transforms/identifier/renameVariables.ts +250 -271
- package/src/transforms/lock/integrity.ts +85 -263
- package/src/transforms/lock/lock.ts +338 -579
- package/src/transforms/minify.ts +523 -663
- package/src/transforms/opaquePredicates.ts +90 -229
- package/src/transforms/pack.ts +195 -0
- package/src/transforms/plugin.ts +185 -0
- package/src/transforms/preparation.ts +337 -231
- package/src/transforms/renameLabels.ts +176 -77
- package/src/transforms/rgf.ts +293 -424
- package/src/transforms/shuffle.ts +80 -254
- package/src/transforms/string/encoding.ts +20 -126
- package/src/transforms/string/stringCompression.ts +117 -307
- package/src/transforms/string/stringConcealing.ts +254 -342
- package/src/transforms/string/stringEncoding.ts +28 -47
- package/src/transforms/string/stringSplitting.ts +61 -75
- package/src/transforms/variableMasking.ts +257 -0
- package/src/utils/ControlObject.ts +141 -0
- package/src/utils/IntGen.ts +33 -0
- package/src/utils/NameGen.ts +106 -0
- package/src/utils/ast-utils.ts +667 -0
- package/src/utils/function-utils.ts +50 -0
- package/src/utils/gen-utils.ts +48 -0
- package/src/utils/node.ts +78 -0
- package/src/utils/object-utils.ts +21 -0
- package/src/utils/random-utils.ts +79 -0
- package/src/utils/static-utils.ts +66 -0
- package/src/validateOptions.ts +256 -0
- package/tsconfig.json +13 -8
- package/babel.config.js +0 -12
- package/dev.js +0 -8
- package/dist/compiler.js +0 -34
- package/dist/parser.js +0 -59
- package/dist/precedence.js +0 -66
- package/dist/templates/bufferToString.js +0 -129
- package/dist/templates/core.js +0 -35
- package/dist/templates/crash.js +0 -28
- package/dist/templates/es5.js +0 -137
- package/dist/templates/functionLength.js +0 -34
- package/dist/templates/globals.js +0 -9
- package/dist/transforms/antiTooling.js +0 -88
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +0 -1287
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +0 -131
- package/dist/transforms/es5/antiClass.js +0 -164
- package/dist/transforms/es5/antiDestructuring.js +0 -193
- package/dist/transforms/es5/antiES6Object.js +0 -185
- package/dist/transforms/es5/antiSpreadOperator.js +0 -35
- package/dist/transforms/es5/antiTemplate.js +0 -66
- package/dist/transforms/es5/es5.js +0 -123
- package/dist/transforms/extraction/classExtraction.js +0 -83
- package/dist/transforms/identifier/globalAnalysis.js +0 -83
- package/dist/transforms/identifier/variableAnalysis.js +0 -104
- package/dist/transforms/lock/antiDebug.js +0 -76
- package/dist/transforms/stack.js +0 -349
- package/dist/transforms/transform.js +0 -372
- package/dist/traverse.js +0 -110
- package/dist/util/compare.js +0 -145
- package/dist/util/gen.js +0 -564
- package/dist/util/guard.js +0 -14
- package/dist/util/identifiers.js +0 -355
- package/dist/util/insert.js +0 -362
- package/dist/util/math.js +0 -19
- package/dist/util/object.js +0 -40
- package/dist/util/random.js +0 -156
- package/dist/util/scope.js +0 -20
- package/docs/ControlFlowFlattening.md +0 -595
- package/docs/Countermeasures.md +0 -70
- package/docs/ES5.md +0 -197
- package/docs/Integrity.md +0 -82
- package/docs/RGF.md +0 -424
- package/docs/RenameVariables.md +0 -116
- package/docs/TamperProtection.md +0 -100
- package/docs/Template.md +0 -117
- package/samples/example.js +0 -15
- package/samples/high.js +0 -1
- package/samples/input.js +0 -3
- package/samples/javascriptobfuscator.com.js +0 -8
- package/samples/jscrambler_advanced.js +0 -1894
- package/samples/jscrambler_light.js +0 -1134
- package/samples/low.js +0 -1
- package/samples/medium.js +0 -1
- package/samples/obfuscator.io.js +0 -1686
- package/samples/preemptive.com.js +0 -16
- package/src/compiler.ts +0 -35
- package/src/parser.ts +0 -49
- package/src/precedence.ts +0 -61
- package/src/templates/bufferToString.ts +0 -136
- package/src/templates/core.ts +0 -29
- package/src/templates/crash.ts +0 -23
- package/src/templates/es5.ts +0 -131
- package/src/templates/functionLength.ts +0 -32
- package/src/templates/globals.ts +0 -3
- package/src/transforms/antiTooling.ts +0 -102
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +0 -2153
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +0 -179
- package/src/transforms/es5/antiClass.ts +0 -276
- package/src/transforms/es5/antiDestructuring.ts +0 -294
- package/src/transforms/es5/antiES6Object.ts +0 -267
- package/src/transforms/es5/antiSpreadOperator.ts +0 -56
- package/src/transforms/es5/antiTemplate.ts +0 -98
- package/src/transforms/es5/es5.ts +0 -149
- package/src/transforms/extraction/classExtraction.ts +0 -168
- package/src/transforms/identifier/globalAnalysis.ts +0 -102
- package/src/transforms/identifier/variableAnalysis.ts +0 -118
- package/src/transforms/lock/antiDebug.ts +0 -112
- package/src/transforms/stack.ts +0 -557
- package/src/transforms/transform.ts +0 -441
- package/src/traverse.ts +0 -120
- package/src/types.ts +0 -133
- package/src/util/compare.ts +0 -181
- package/src/util/gen.ts +0 -651
- package/src/util/guard.ts +0 -17
- package/src/util/identifiers.ts +0 -494
- package/src/util/insert.ts +0 -419
- package/src/util/math.ts +0 -15
- package/src/util/object.ts +0 -39
- package/src/util/random.ts +0 -221
- package/src/util/scope.ts +0 -21
- package/test/code/Cash.src.js +0 -1011
- package/test/code/Cash.test.ts +0 -132
- package/test/code/Dynamic.src.js +0 -118
- package/test/code/Dynamic.test.ts +0 -49
- package/test/code/ES6.src.js +0 -235
- package/test/code/ES6.test.ts +0 -42
- package/test/code/NewFeatures.test.ts +0 -19
- package/test/code/StrictMode.src.js +0 -65
- package/test/code/StrictMode.test.js +0 -37
- package/test/compare.test.ts +0 -104
- package/test/index.test.ts +0 -249
- package/test/options.test.ts +0 -150
- package/test/presets.test.ts +0 -22
- package/test/probability.test.ts +0 -44
- package/test/templates/template.test.ts +0 -224
- package/test/transforms/antiTooling.test.ts +0 -52
- package/test/transforms/calculator.test.ts +0 -78
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +0 -1274
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +0 -192
- package/test/transforms/deadCode.test.ts +0 -85
- package/test/transforms/dispatcher.test.ts +0 -457
- package/test/transforms/es5/antiClass.test.ts +0 -427
- package/test/transforms/es5/antiDestructuring.test.ts +0 -157
- package/test/transforms/es5/antiES6Object.test.ts +0 -245
- package/test/transforms/es5/antiTemplate.test.ts +0 -116
- package/test/transforms/es5/es5.test.ts +0 -110
- package/test/transforms/extraction/classExtraction.test.ts +0 -86
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +0 -200
- package/test/transforms/extraction/objectExtraction.test.ts +0 -491
- package/test/transforms/flatten.test.ts +0 -721
- package/test/transforms/hexadecimalNumbers.test.ts +0 -62
- package/test/transforms/identifier/globalConcealing.test.ts +0 -142
- package/test/transforms/identifier/movedDeclarations.test.ts +0 -275
- package/test/transforms/identifier/renameVariables.test.ts +0 -695
- package/test/transforms/lock/antiDebug.test.ts +0 -66
- package/test/transforms/lock/browserLock.test.ts +0 -129
- package/test/transforms/lock/countermeasures.test.ts +0 -100
- package/test/transforms/lock/integrity.test.ts +0 -161
- package/test/transforms/lock/lock.test.ts +0 -204
- package/test/transforms/lock/osLock.test.ts +0 -312
- package/test/transforms/lock/selfDefending.test.ts +0 -68
- package/test/transforms/lock/tamperProtection.test.ts +0 -336
- package/test/transforms/minify.test.ts +0 -575
- package/test/transforms/opaquePredicates.test.ts +0 -43
- package/test/transforms/preparation.test.ts +0 -157
- package/test/transforms/renameLabels.test.ts +0 -95
- package/test/transforms/rgf.test.ts +0 -378
- package/test/transforms/shuffle.test.ts +0 -135
- package/test/transforms/stack.test.ts +0 -573
- package/test/transforms/string/stringCompression.test.ts +0 -120
- package/test/transforms/string/stringConcealing.test.ts +0 -299
- package/test/transforms/string/stringEncoding.test.ts +0 -95
- package/test/transforms/string/stringSplitting.test.ts +0 -135
- package/test/transforms/transform.test.ts +0 -66
- package/test/traverse.test.ts +0 -139
- package/test/util/compare.test.ts +0 -34
- package/test/util/gen.test.ts +0 -121
- package/test/util/identifiers.test.ts +0 -253
- package/test/util/insert.test.ts +0 -142
- package/test/util/math.test.ts +0 -5
- package/test/util/random.test.ts +0 -71
- /package/dist/{types.js → obfuscationResult.js} +0 -0
|
@@ -1,650 +1,409 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
ExpressionStatement,
|
|
6
|
-
AssignmentExpression,
|
|
7
|
-
Identifier,
|
|
8
|
-
BinaryExpression,
|
|
9
|
-
CallExpression,
|
|
10
|
-
MemberExpression,
|
|
11
|
-
Literal,
|
|
12
|
-
UnaryExpression,
|
|
13
|
-
NewExpression,
|
|
14
|
-
VariableDeclaration,
|
|
15
|
-
ThisExpression,
|
|
16
|
-
VariableDeclarator,
|
|
17
|
-
Location,
|
|
18
|
-
LogicalExpression,
|
|
19
|
-
SequenceExpression,
|
|
20
|
-
} from "../../util/gen";
|
|
21
|
-
import traverse, { getBlock, isBlock } from "../../traverse";
|
|
22
|
-
import { choice, getRandomInteger } from "../../util/random";
|
|
23
|
-
import { CrashTemplate1, CrashTemplate2 } from "../../templates/crash";
|
|
24
|
-
import { getBlockBody, getVarContext, prepend } from "../../util/insert";
|
|
1
|
+
import { NodePath } from "@babel/core";
|
|
2
|
+
import { PluginArg, PluginObject } from "../plugin";
|
|
3
|
+
import { Order } from "../../order";
|
|
4
|
+
import { chance, choice } from "../../utils/random-utils";
|
|
25
5
|
import Template from "../../templates/template";
|
|
26
|
-
import
|
|
27
|
-
import
|
|
28
|
-
import
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
var globalObject = typeof window !== "undefined" ? window : global;
|
|
75
|
-
var fn = globalObject;
|
|
76
|
-
for (var item of nameAndPropertyPath) {
|
|
77
|
-
fn = fn[item];
|
|
78
|
-
if (typeof fn === "undefined") return false;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
var hasNativeCode =
|
|
82
|
-
typeof fn === "function" && ("" + fn).includes("[native code]");
|
|
83
|
-
|
|
84
|
-
return hasNativeCode;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
constructor(o) {
|
|
88
|
-
super(o, ObfuscateOrder.Lock);
|
|
89
|
-
|
|
90
|
-
// Removed feature
|
|
91
|
-
// if (this.options.lock.startDate && this.options.lock.endDate) {
|
|
92
|
-
// this.before.push(new LockStrings(o));
|
|
93
|
-
// }
|
|
94
|
-
|
|
95
|
-
if (this.options.lock.integrity) {
|
|
96
|
-
this.before.push(new Integrity(o, this));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (this.options.lock.antiDebug) {
|
|
100
|
-
this.before.push(new AntiDebug(o, this));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
this.made = 0;
|
|
6
|
+
import * as t from "@babel/types";
|
|
7
|
+
import { CustomLock } from "../../options";
|
|
8
|
+
import {
|
|
9
|
+
getFunctionName,
|
|
10
|
+
getParentFunctionOrProgram,
|
|
11
|
+
isDefiningIdentifier,
|
|
12
|
+
isVariableIdentifier,
|
|
13
|
+
prependProgram,
|
|
14
|
+
} from "../../utils/ast-utils";
|
|
15
|
+
import { INTEGRITY, NodeIntegrity } from "./integrity";
|
|
16
|
+
import { HashTemplate } from "../../templates/integrityTemplate";
|
|
17
|
+
import {
|
|
18
|
+
MULTI_TRANSFORM,
|
|
19
|
+
NodeSymbol,
|
|
20
|
+
PREDICTABLE,
|
|
21
|
+
SKIP,
|
|
22
|
+
UNSAFE,
|
|
23
|
+
} from "../../constants";
|
|
24
|
+
import {
|
|
25
|
+
IndexOfTemplate,
|
|
26
|
+
NativeFunctionTemplate,
|
|
27
|
+
StrictModeTemplate,
|
|
28
|
+
} from "../../templates/tamperProtectionTemplates";
|
|
29
|
+
import { computeProbabilityMap } from "../../probability";
|
|
30
|
+
|
|
31
|
+
export default ({ Plugin }: PluginArg): PluginObject => {
|
|
32
|
+
const me = Plugin(Order.Lock, {
|
|
33
|
+
changeData: {
|
|
34
|
+
locksInserted: 0,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (me.options.lock.startDate instanceof Date) {
|
|
39
|
+
me.options.lock.customLocks.push({
|
|
40
|
+
code: [
|
|
41
|
+
`
|
|
42
|
+
if(Date.now()<${me.options.lock.startDate.getTime()}) {
|
|
43
|
+
{countermeasures}
|
|
44
|
+
}
|
|
45
|
+
`,
|
|
46
|
+
`
|
|
47
|
+
if((new Date()).getTime()<${me.options.lock.startDate.getTime()}) {
|
|
48
|
+
{countermeasures}
|
|
49
|
+
}
|
|
50
|
+
`,
|
|
51
|
+
],
|
|
52
|
+
percentagePerBlock: 0.5,
|
|
53
|
+
});
|
|
104
54
|
}
|
|
105
55
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (
|
|
113
|
-
object.type == "Identifier" &&
|
|
114
|
-
object.name === this.options.lock.countermeasures
|
|
115
|
-
) {
|
|
116
|
-
var info = getIdentifierInfo(object, parents);
|
|
117
|
-
if (info.spec.isDefined) {
|
|
118
|
-
if (this.counterMeasuresNode) {
|
|
119
|
-
throw new Error(
|
|
120
|
-
"Countermeasures function was already defined, it must have a unique name from the rest of your code"
|
|
121
|
-
);
|
|
122
|
-
} else {
|
|
123
|
-
var definingContext = getVarContext(parents[0], parents.slice(1));
|
|
124
|
-
if (definingContext != tree) {
|
|
125
|
-
throw new Error(
|
|
126
|
-
"Countermeasures function must be defined at the global level"
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
var chain: Location = [object, parents];
|
|
130
|
-
if (info.isFunctionDeclaration) {
|
|
131
|
-
chain = [parents[0], parents.slice(1)];
|
|
132
|
-
} else if (info.isVariableDeclaration) {
|
|
133
|
-
chain = [parents[1], parents.slice(2)];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
this.counterMeasuresNode = chain;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
if (!this.counterMeasuresNode) {
|
|
143
|
-
throw new Error(
|
|
144
|
-
"Countermeasures function named '" +
|
|
145
|
-
this.options.lock.countermeasures +
|
|
146
|
-
"' was not found."
|
|
147
|
-
);
|
|
56
|
+
if (me.options.lock.endDate instanceof Date) {
|
|
57
|
+
me.options.lock.customLocks.push({
|
|
58
|
+
code: [
|
|
59
|
+
`
|
|
60
|
+
if(Date.now()>${me.options.lock.endDate.getTime()}) {
|
|
61
|
+
{countermeasures}
|
|
148
62
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
63
|
+
`,
|
|
64
|
+
`
|
|
65
|
+
if((new Date()).getTime()>${me.options.lock.endDate.getTime()}) {
|
|
66
|
+
{countermeasures}
|
|
67
|
+
}
|
|
68
|
+
`,
|
|
69
|
+
],
|
|
70
|
+
percentagePerBlock: 0.5,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
158
73
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
var arr = []
|
|
164
|
-
delete arr["length"]
|
|
165
|
-
} catch(e) {
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
74
|
+
if (me.options.lock.domainLock) {
|
|
75
|
+
var domainArray = Array.isArray(me.options.lock.domainLock)
|
|
76
|
+
? me.options.lock.domainLock
|
|
77
|
+
: [me.options.lock.domainLock];
|
|
170
78
|
|
|
171
|
-
|
|
79
|
+
for (const regexString of domainArray) {
|
|
80
|
+
me.options.lock.customLocks.push({
|
|
81
|
+
code: new Template(`
|
|
82
|
+
if(!new RegExp({regexString}).test(window.location.href)) {
|
|
172
83
|
{countermeasures}
|
|
173
|
-
${this.nativeFunctionName} = undefined;
|
|
174
84
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
85
|
+
`).setDefaultVariables({
|
|
86
|
+
regexString: () => t.stringLiteral(regexString.toString()),
|
|
87
|
+
}),
|
|
88
|
+
percentagePerBlock: 0.5,
|
|
178
89
|
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
179
92
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
) {
|
|
93
|
+
if (me.options.lock.selfDefending) {
|
|
94
|
+
me.options.lock.customLocks.push({
|
|
95
|
+
code: `
|
|
96
|
+
(
|
|
97
|
+
function(){
|
|
98
|
+
// Breaks any code formatter
|
|
99
|
+
var namedFunction = function(){
|
|
100
|
+
const test = function(){
|
|
101
|
+
const regExp=new RegExp('\\n');
|
|
102
|
+
return regExp['test'](namedFunction)
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
if(test()) {
|
|
194
106
|
{countermeasures}
|
|
195
|
-
return undefined
|
|
196
107
|
}
|
|
197
|
-
|
|
198
|
-
return fn;
|
|
199
108
|
}
|
|
200
109
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
110
|
+
return namedFunction();
|
|
111
|
+
}
|
|
112
|
+
)();
|
|
113
|
+
`,
|
|
114
|
+
percentagePerBlock: 0.5,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (me.options.lock.antiDebug) {
|
|
119
|
+
me.options.lock.customLocks.push({
|
|
120
|
+
code: `
|
|
121
|
+
debugger;
|
|
122
|
+
`,
|
|
123
|
+
percentagePerBlock: 0.5,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
207
126
|
|
|
208
|
-
|
|
209
|
-
fn = checkFunction(fn);
|
|
127
|
+
const timesMap = new WeakMap<CustomLock, number>();
|
|
210
128
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}`).single({
|
|
214
|
-
IndexOfTemplate: IndexOfTemplate,
|
|
215
|
-
countermeasures: this.getCounterMeasuresCode(tree, []),
|
|
216
|
-
});
|
|
129
|
+
let countermeasuresNode: NodePath<t.Identifier>;
|
|
130
|
+
let invokeCountermeasuresFnName;
|
|
217
131
|
|
|
218
|
-
|
|
219
|
-
|
|
132
|
+
if (me.options.lock.countermeasures) {
|
|
133
|
+
invokeCountermeasuresFnName = me.getPlaceholder("invokeCountermeasures");
|
|
220
134
|
|
|
221
|
-
|
|
222
|
-
|
|
135
|
+
me.globalState.internals.invokeCountermeasuresFnName =
|
|
136
|
+
invokeCountermeasuresFnName;
|
|
223
137
|
}
|
|
224
138
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (opt === false) {
|
|
229
|
-
return null;
|
|
139
|
+
var createCountermeasuresCode = () => {
|
|
140
|
+
if (invokeCountermeasuresFnName) {
|
|
141
|
+
return new Template(`${invokeCountermeasuresFnName}()`).compile();
|
|
230
142
|
}
|
|
231
143
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (!this.counterMeasuresActivated) {
|
|
235
|
-
this.counterMeasuresActivated = this.getPlaceholder();
|
|
236
|
-
|
|
237
|
-
prepend(
|
|
238
|
-
parents[parents.length - 1] || object,
|
|
239
|
-
VariableDeclaration(VariableDeclarator(this.counterMeasuresActivated))
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Since Lock occurs before variable renaming, we are using the pre-obfuscated function name
|
|
244
|
-
return [
|
|
245
|
-
ExpressionStatement(
|
|
246
|
-
LogicalExpression(
|
|
247
|
-
"||",
|
|
248
|
-
Identifier(this.counterMeasuresActivated),
|
|
249
|
-
SequenceExpression([
|
|
250
|
-
AssignmentExpression(
|
|
251
|
-
"=",
|
|
252
|
-
Identifier(this.counterMeasuresActivated),
|
|
253
|
-
Literal(true)
|
|
254
|
-
),
|
|
255
|
-
CallExpression(new Template(opt).single().expression, []),
|
|
256
|
-
])
|
|
257
|
-
)
|
|
258
|
-
),
|
|
259
|
-
];
|
|
144
|
+
if (me.options.lock.countermeasures === false) {
|
|
145
|
+
return [];
|
|
260
146
|
}
|
|
261
147
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
var: varName,
|
|
266
|
-
});
|
|
267
|
-
}
|
|
148
|
+
return new Template(`while(true){}`).compile();
|
|
149
|
+
};
|
|
150
|
+
me.globalState.lock.createCountermeasuresCode = createCountermeasuresCode;
|
|
268
151
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
* @param object
|
|
272
|
-
*/
|
|
273
|
-
getTime(object: Date | number | false): number {
|
|
274
|
-
if (!object) {
|
|
275
|
-
return 0;
|
|
276
|
-
}
|
|
277
|
-
if (object instanceof Date) {
|
|
278
|
-
return this.getTime(object.getTime());
|
|
279
|
-
}
|
|
152
|
+
function applyLockToBlock(path: NodePath<t.Block>, customLock: CustomLock) {
|
|
153
|
+
let times = timesMap.get(customLock);
|
|
280
154
|
|
|
281
|
-
|
|
282
|
-
|
|
155
|
+
if (typeof times === "undefined") {
|
|
156
|
+
times = 0;
|
|
157
|
+
}
|
|
283
158
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
159
|
+
let maxCount = customLock.maxCount || 100; // 100 is default max count
|
|
160
|
+
let minCount = customLock.minCount || 1; // 1 is default min count
|
|
287
161
|
|
|
288
|
-
|
|
289
|
-
|
|
162
|
+
if (maxCount >= 0 && times > maxCount) {
|
|
163
|
+
// Limit creation, allowing -1 to disable the limit entirely
|
|
290
164
|
return;
|
|
291
165
|
}
|
|
292
166
|
|
|
293
|
-
//
|
|
167
|
+
// The Program always gets a lock
|
|
168
|
+
// Else based on the percentage
|
|
169
|
+
// Try to reach the minimum count
|
|
294
170
|
if (
|
|
295
|
-
|
|
296
|
-
(
|
|
297
|
-
|
|
171
|
+
!path.isProgram() &&
|
|
172
|
+
!chance(customLock.percentagePerBlock * 100) &&
|
|
173
|
+
times >= minCount
|
|
298
174
|
) {
|
|
299
175
|
return;
|
|
300
176
|
}
|
|
301
177
|
|
|
302
|
-
|
|
178
|
+
// Increment the times
|
|
179
|
+
timesMap.set(customLock, times + 1);
|
|
303
180
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
if (this.options.lock.endDate) {
|
|
309
|
-
choices.push("endDate");
|
|
310
|
-
}
|
|
311
|
-
if (this.options.lock.domainLock && this.options.lock.domainLock.length) {
|
|
312
|
-
choices.push("domainLock");
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (this.options.lock.context && this.options.lock.context.length) {
|
|
316
|
-
choices.push("context");
|
|
317
|
-
}
|
|
318
|
-
if (this.options.lock.browserLock && this.options.lock.browserLock.length) {
|
|
319
|
-
choices.push("browserLock");
|
|
320
|
-
}
|
|
321
|
-
if (this.options.lock.osLock && this.options.lock.osLock.length) {
|
|
322
|
-
choices.push("osLock");
|
|
323
|
-
}
|
|
324
|
-
if (this.options.lock.selfDefending) {
|
|
325
|
-
choices.push("selfDefending");
|
|
326
|
-
}
|
|
181
|
+
const lockCode = Array.isArray(customLock.code)
|
|
182
|
+
? choice(customLock.code)
|
|
183
|
+
: customLock.code;
|
|
327
184
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
185
|
+
const template =
|
|
186
|
+
typeof lockCode === "string" ? new Template(lockCode) : lockCode;
|
|
187
|
+
const lockNodes = template.compile({
|
|
188
|
+
countermeasures: () => createCountermeasuresCode(),
|
|
189
|
+
});
|
|
190
|
+
var p = path.unshiftContainer("body", lockNodes);
|
|
191
|
+
p.forEach((p) => p.skip());
|
|
331
192
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
if (this.made > 150) {
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
193
|
+
me.changeData.locksInserted++;
|
|
194
|
+
}
|
|
337
195
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
);
|
|
345
|
-
if (Math.random() > 0.5) {
|
|
346
|
-
dateNow = CallExpression(
|
|
347
|
-
MemberExpression(
|
|
348
|
-
NewExpression(Identifier("Date"), []),
|
|
349
|
-
Literal("getTime")
|
|
350
|
-
),
|
|
351
|
-
[]
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
if (Math.random() > 0.5) {
|
|
355
|
-
dateNow = CallExpression(
|
|
356
|
-
MemberExpression(
|
|
357
|
-
MemberExpression(
|
|
358
|
-
MemberExpression(Identifier("Date"), Literal("prototype"), true),
|
|
359
|
-
Literal("getTime"),
|
|
360
|
-
true
|
|
361
|
-
),
|
|
362
|
-
Literal("call"),
|
|
363
|
-
true
|
|
364
|
-
),
|
|
365
|
-
[NewExpression(Identifier("Date"), [])]
|
|
366
|
-
);
|
|
367
|
-
}
|
|
196
|
+
return {
|
|
197
|
+
visitor: {
|
|
198
|
+
BindingIdentifier(path) {
|
|
199
|
+
if (path.node.name !== me.options.lock.countermeasures) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
368
202
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
switch (type) {
|
|
373
|
-
case "selfDefending":
|
|
374
|
-
// A very simple mechanism inspired from https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/src/custom-code-helpers/self-defending/templates/SelfDefendingNoEvalTemplate.ts
|
|
375
|
-
// regExp checks for a newline, formatters add these
|
|
376
|
-
var callExpression = new Template(
|
|
377
|
-
`
|
|
378
|
-
(
|
|
379
|
-
function(){
|
|
380
|
-
// Breaks JSNice.org, beautifier.io
|
|
381
|
-
var namedFunction = function(){
|
|
382
|
-
const test = function(){
|
|
383
|
-
const regExp=new RegExp('\\n');
|
|
384
|
-
return regExp['test'](namedFunction)
|
|
385
|
-
};
|
|
386
|
-
return test()
|
|
387
|
-
}
|
|
203
|
+
// Exclude labels
|
|
204
|
+
if (!isVariableIdentifier(path)) return;
|
|
388
205
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
)()
|
|
392
|
-
`
|
|
393
|
-
).single().expression;
|
|
394
|
-
|
|
395
|
-
nodes.push(
|
|
396
|
-
IfStatement(
|
|
397
|
-
callExpression,
|
|
398
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
399
|
-
null
|
|
400
|
-
)
|
|
401
|
-
);
|
|
206
|
+
if (!isDefiningIdentifier(path)) {
|
|
207
|
+
// Reassignments are not allowed
|
|
402
208
|
|
|
403
|
-
|
|
209
|
+
me.error("Countermeasures function cannot be reassigned");
|
|
210
|
+
}
|
|
404
211
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
"<",
|
|
408
|
-
dateNow,
|
|
409
|
-
Literal(this.getTime(this.options.lock.startDate))
|
|
410
|
-
);
|
|
212
|
+
if (countermeasuresNode) {
|
|
213
|
+
// Disallow multiple countermeasures functions
|
|
411
214
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
test,
|
|
415
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
416
|
-
null
|
|
417
|
-
)
|
|
215
|
+
me.error(
|
|
216
|
+
"Countermeasures function was already defined, it must have a unique name from the rest of your code"
|
|
418
217
|
);
|
|
218
|
+
}
|
|
419
219
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
Literal(this.getTime(this.options.lock.endDate))
|
|
220
|
+
if (
|
|
221
|
+
path.scope.getBinding(path.node.name).scope !==
|
|
222
|
+
path.scope.getProgramParent()
|
|
223
|
+
) {
|
|
224
|
+
me.error(
|
|
225
|
+
"Countermeasures function must be defined at the global level"
|
|
427
226
|
);
|
|
227
|
+
}
|
|
428
228
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
test,
|
|
432
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
433
|
-
null
|
|
434
|
-
)
|
|
435
|
-
);
|
|
229
|
+
countermeasuresNode = path;
|
|
230
|
+
},
|
|
436
231
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
443
|
-
|
|
444
|
-
// Todo: Alternative to `this`
|
|
445
|
-
if (!this.globalVar) {
|
|
446
|
-
offset = 1;
|
|
447
|
-
this.globalVar = this.getPlaceholder();
|
|
448
|
-
prepend(
|
|
449
|
-
parents[parents.length - 1] || block,
|
|
450
|
-
VariableDeclaration(
|
|
451
|
-
VariableDeclarator(
|
|
452
|
-
this.globalVar,
|
|
453
|
-
LogicalExpression(
|
|
454
|
-
"||",
|
|
455
|
-
Identifier(
|
|
456
|
-
this.options.globalVariables.keys().next().value
|
|
457
|
-
),
|
|
458
|
-
ThisExpression()
|
|
459
|
-
)
|
|
460
|
-
)
|
|
461
|
-
)
|
|
462
|
-
);
|
|
232
|
+
Block: {
|
|
233
|
+
exit(path) {
|
|
234
|
+
var customLock = choice(me.options.lock.customLocks);
|
|
235
|
+
if (customLock) {
|
|
236
|
+
applyLockToBlock(path, customLock);
|
|
463
237
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
481
|
-
|
|
482
|
-
this.options.lock.osLock.forEach((osName) => {
|
|
483
|
-
var agentMatcher = {
|
|
484
|
-
windows: "Win",
|
|
485
|
-
linux: "Linux",
|
|
486
|
-
osx: "Mac",
|
|
487
|
-
android: "Android",
|
|
488
|
-
ios: "---",
|
|
489
|
-
}[osName];
|
|
490
|
-
var thisTest: Node = CallExpression(
|
|
491
|
-
MemberExpression(navigatorUserAgent, Literal("match"), true),
|
|
492
|
-
[Literal(agentMatcher.toLowerCase())]
|
|
493
|
-
);
|
|
494
|
-
if (osName == "ios" && this.options.target === "browser") {
|
|
495
|
-
if (!this.iosDetectFn) {
|
|
496
|
-
this.iosDetectFn = this.getPlaceholder();
|
|
497
|
-
prepend(
|
|
498
|
-
parents[parents.length - 1] || object,
|
|
499
|
-
new Template(`function ${this.iosDetectFn}() {
|
|
500
|
-
return [
|
|
501
|
-
'iPad Simulator',
|
|
502
|
-
'iPhone Simulator',
|
|
503
|
-
'iPod Simulator',
|
|
504
|
-
'iPad',
|
|
505
|
-
'iPhone',
|
|
506
|
-
'iPod'
|
|
507
|
-
].includes(navigator.platform)
|
|
508
|
-
// iPad on iOS 13 detection
|
|
509
|
-
|| (navigator.userAgent.includes("Mac") && "ontouchend" in document)
|
|
510
|
-
}`).single()
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
Program: {
|
|
242
|
+
exit(path) {
|
|
243
|
+
// Insert nativeFunctionCheck
|
|
244
|
+
if (me.options.lock.tamperProtection) {
|
|
245
|
+
// Disallow strict mode
|
|
246
|
+
// Tamper Protection uses non-strict mode features:
|
|
247
|
+
// - eval() with local scope assignments
|
|
248
|
+
const directives = path.get("directives");
|
|
249
|
+
for (var directive of directives) {
|
|
250
|
+
if (directive.node.value.value === "use strict") {
|
|
251
|
+
me.error(
|
|
252
|
+
"Tamper Protection cannot be applied to code in strict mode. Disable strict mode by removing the 'use strict' directive, or disable Tamper Protection."
|
|
511
253
|
);
|
|
512
254
|
}
|
|
513
|
-
|
|
514
|
-
thisTest = CallExpression(Identifier(this.iosDetectFn), []);
|
|
515
255
|
}
|
|
516
256
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
{ windows: "win32", osx: "darwin", ios: "darwin" }[osName] ||
|
|
520
|
-
osName;
|
|
521
|
-
thisTest = new Template(
|
|
522
|
-
`require('os').platform()==="${platformName}"`
|
|
523
|
-
).single().expression;
|
|
524
|
-
}
|
|
257
|
+
var nativeFunctionName =
|
|
258
|
+
me.getPlaceholder() + "_nativeFunctionCheck";
|
|
525
259
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
} else {
|
|
529
|
-
test = LogicalExpression("||", { ...test }, thisTest);
|
|
530
|
-
}
|
|
531
|
-
});
|
|
260
|
+
me.obfuscator.globalState.internals.nativeFunctionName =
|
|
261
|
+
nativeFunctionName;
|
|
532
262
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
ok(this.options.lock.browserLock);
|
|
543
|
-
|
|
544
|
-
this.options.lock.browserLock.forEach((browserName) => {
|
|
545
|
-
var thisTest: Node = CallExpression(
|
|
546
|
-
MemberExpression(navigatorUserAgent, Literal("match"), true),
|
|
547
|
-
[
|
|
548
|
-
Literal(
|
|
549
|
-
browserName == "iexplorer"
|
|
550
|
-
? "msie"
|
|
551
|
-
: browserName.toLowerCase()
|
|
552
|
-
),
|
|
553
|
-
]
|
|
263
|
+
// Ensure program is not in strict mode
|
|
264
|
+
// Tamper Protection forces non-strict mode
|
|
265
|
+
prependProgram(
|
|
266
|
+
path,
|
|
267
|
+
StrictModeTemplate.compile({
|
|
268
|
+
nativeFunctionName,
|
|
269
|
+
countermeasures: createCountermeasuresCode(),
|
|
270
|
+
})
|
|
554
271
|
);
|
|
555
272
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
if (!test) {
|
|
563
|
-
test = thisTest;
|
|
564
|
-
} else {
|
|
565
|
-
test = LogicalExpression("||", { ...test }, thisTest);
|
|
566
|
-
}
|
|
567
|
-
});
|
|
273
|
+
const nativeFunctionDeclaration = NativeFunctionTemplate.single({
|
|
274
|
+
nativeFunctionName,
|
|
275
|
+
countermeasures: createCountermeasuresCode(),
|
|
276
|
+
IndexOfTemplate: IndexOfTemplate,
|
|
277
|
+
});
|
|
568
278
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
test,
|
|
573
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
574
|
-
null
|
|
575
|
-
)
|
|
576
|
-
);
|
|
577
|
-
break;
|
|
279
|
+
// Checks function's toString() value for [native code] signature
|
|
280
|
+
prependProgram(path, nativeFunctionDeclaration);
|
|
281
|
+
}
|
|
578
282
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
283
|
+
// Insert invokeCountermeasures function
|
|
284
|
+
if (invokeCountermeasuresFnName) {
|
|
285
|
+
if (!countermeasuresNode) {
|
|
286
|
+
me.error(
|
|
287
|
+
"Countermeasures function named '" +
|
|
288
|
+
me.options.lock.countermeasures +
|
|
289
|
+
"' was not found."
|
|
290
|
+
);
|
|
291
|
+
}
|
|
583
292
|
|
|
584
|
-
|
|
585
|
-
|
|
293
|
+
var hasInvoked = me.getPlaceholder("hasInvoked");
|
|
294
|
+
var statements = new Template(`
|
|
295
|
+
var ${hasInvoked} = false;
|
|
296
|
+
function ${invokeCountermeasuresFnName}(){
|
|
297
|
+
if(${hasInvoked}) return;
|
|
298
|
+
${hasInvoked} = true;
|
|
299
|
+
${me.options.lock.countermeasures}();
|
|
300
|
+
}
|
|
301
|
+
`)
|
|
302
|
+
.addSymbols(MULTI_TRANSFORM)
|
|
303
|
+
.compile();
|
|
586
304
|
|
|
587
|
-
|
|
305
|
+
prependProgram(path, statements).forEach((p) => p.skip());
|
|
588
306
|
}
|
|
589
307
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
308
|
+
if (me.options.lock.integrity) {
|
|
309
|
+
const hashFnName = me.getPlaceholder() + "_hash";
|
|
310
|
+
const imulFnName = me.getPlaceholder() + "_imul";
|
|
311
|
+
|
|
312
|
+
const { sensitivityRegex } = me.globalState.lock.integrity;
|
|
313
|
+
me.globalState.internals.integrityHashName = hashFnName;
|
|
314
|
+
|
|
315
|
+
const hashCode = HashTemplate.compile({
|
|
316
|
+
imul: imulFnName,
|
|
317
|
+
name: hashFnName,
|
|
318
|
+
hashingUtilFnName: me.getPlaceholder(),
|
|
319
|
+
sensitivityRegex: () =>
|
|
320
|
+
t.newExpression(t.identifier("RegExp"), [
|
|
321
|
+
t.stringLiteral(sensitivityRegex.source),
|
|
322
|
+
t.stringLiteral(sensitivityRegex.flags),
|
|
323
|
+
]),
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
prependProgram(path, hashCode);
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
// Integrity first pass
|
|
332
|
+
// Functions are prepared for Integrity by simply extracting the function body
|
|
333
|
+
// The extracted function is hashed in the 'integrity' plugin
|
|
334
|
+
FunctionDeclaration: {
|
|
335
|
+
exit(funcDecPath) {
|
|
336
|
+
if (!me.options.lock.integrity) return;
|
|
337
|
+
|
|
338
|
+
// Mark functions for integrity
|
|
339
|
+
// Don't apply to async or generator functions
|
|
340
|
+
if (funcDecPath.node.async || funcDecPath.node.generator) return;
|
|
341
|
+
|
|
342
|
+
if (funcDecPath.find((p) => !!(p.node as NodeSymbol)[SKIP])) return;
|
|
343
|
+
|
|
344
|
+
var program = getParentFunctionOrProgram(funcDecPath);
|
|
345
|
+
// Only top-level functions
|
|
346
|
+
if (!program.isProgram()) return;
|
|
347
|
+
|
|
348
|
+
// Check user's custom implementation
|
|
349
|
+
const functionName = getFunctionName(funcDecPath);
|
|
350
|
+
// Don't apply to the countermeasures function (Intended)
|
|
351
|
+
if (
|
|
352
|
+
me.options.lock.countermeasures &&
|
|
353
|
+
functionName === me.options.lock.countermeasures
|
|
354
|
+
)
|
|
355
|
+
return;
|
|
356
|
+
// Don't apply to invokeCountermeasures function (Intended)
|
|
357
|
+
if (me.obfuscator.isInternalVariable(functionName)) return;
|
|
358
|
+
|
|
359
|
+
if (!computeProbabilityMap(me.options.lock.integrity, functionName))
|
|
360
|
+
return;
|
|
361
|
+
|
|
362
|
+
var newFnName = me.getPlaceholder();
|
|
363
|
+
var newFunctionDeclaration = t.functionDeclaration(
|
|
364
|
+
t.identifier(newFnName),
|
|
365
|
+
funcDecPath.node.params,
|
|
366
|
+
funcDecPath.node.body
|
|
594
367
|
);
|
|
595
368
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
{
|
|
602
|
-
type: "Literal",
|
|
603
|
-
regex: {
|
|
604
|
-
pattern:
|
|
605
|
-
random instanceof RegExp
|
|
606
|
-
? random.source
|
|
607
|
-
: removeSlashes(random + ""),
|
|
608
|
-
flags: random instanceof RegExp ? "" : "",
|
|
609
|
-
},
|
|
610
|
-
},
|
|
611
|
-
]
|
|
612
|
-
);
|
|
369
|
+
// Clone semantic symbols like (UNSAFE, PREDICTABLE, MULTI_TRANSFORM, etc)
|
|
370
|
+
const source = funcDecPath.node;
|
|
371
|
+
Object.getOwnPropertySymbols(source).forEach((symbol) => {
|
|
372
|
+
newFunctionDeclaration[symbol] = source[symbol];
|
|
373
|
+
});
|
|
613
374
|
|
|
614
|
-
|
|
615
|
-
if (Math.random() > 0.5) {
|
|
616
|
-
test = LogicalExpression(
|
|
617
|
-
"||",
|
|
618
|
-
BinaryExpression(
|
|
619
|
-
"==",
|
|
620
|
-
UnaryExpression("typeof", Identifier("location")),
|
|
621
|
-
Literal("undefined")
|
|
622
|
-
),
|
|
623
|
-
test
|
|
624
|
-
);
|
|
625
|
-
}
|
|
626
|
-
nodes.push(
|
|
627
|
-
IfStatement(
|
|
628
|
-
test,
|
|
629
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
630
|
-
null
|
|
631
|
-
)
|
|
632
|
-
);
|
|
633
|
-
}
|
|
375
|
+
(newFunctionDeclaration as NodeSymbol)[SKIP] = true;
|
|
634
376
|
|
|
635
|
-
|
|
636
|
-
|
|
377
|
+
var [newFnPath] = program.unshiftContainer(
|
|
378
|
+
"body",
|
|
379
|
+
newFunctionDeclaration
|
|
380
|
+
);
|
|
637
381
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
382
|
+
// Function simply calls the new function
|
|
383
|
+
// In the case Integrity cannot transform the function, the original behavior is preserved
|
|
384
|
+
funcDecPath.node.body = t.blockStatement(
|
|
385
|
+
new Template(`
|
|
386
|
+
return ${newFnName}(...arguments);
|
|
387
|
+
`).compile(),
|
|
388
|
+
funcDecPath.node.body.directives
|
|
389
|
+
);
|
|
641
390
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
391
|
+
// Parameters no longer needed, using 'arguments' instead
|
|
392
|
+
funcDecPath.node.params = [];
|
|
393
|
+
|
|
394
|
+
// Mark the function as unsafe - use of 'arguments' is unsafe
|
|
395
|
+
(funcDecPath.node as NodeSymbol)[UNSAFE] = true;
|
|
396
|
+
|
|
397
|
+
// Params changed - function is no longer predictable
|
|
398
|
+
(funcDecPath.node as NodeSymbol)[PREDICTABLE] = false;
|
|
399
|
+
|
|
400
|
+
// Mark the function for integrity
|
|
401
|
+
(funcDecPath.node as NodeIntegrity)[INTEGRITY] = {
|
|
402
|
+
fnPath: newFnPath,
|
|
403
|
+
fnName: newFnName,
|
|
404
|
+
};
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
};
|