js-confuser 1.7.2 → 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/.github/workflows/node.js.yml +1 -1
- package/CHANGELOG.md +105 -0
- package/Migration.md +57 -0
- package/README.md +23 -913
- package/dist/constants.js +69 -13
- package/dist/index.js +108 -152
- package/dist/obfuscator.js +316 -118
- package/dist/options.js +1 -109
- 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 +213 -93
- 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 -577
- package/dist/transforms/dispatcher.js +300 -309
- 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 +217 -103
- package/dist/transforms/identifier/movedDeclarations.js +167 -91
- package/dist/transforms/identifier/renameVariables.js +240 -187
- package/dist/transforms/lock/integrity.js +61 -184
- package/dist/transforms/lock/lock.js +263 -303
- 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 +263 -163
- package/dist/transforms/renameLabels.js +132 -56
- package/dist/transforms/rgf.js +142 -240
- package/dist/transforms/shuffle.js +52 -145
- package/dist/transforms/string/encoding.js +45 -173
- package/dist/transforms/string/stringCompression.js +81 -126
- package/dist/transforms/string/stringConcealing.js +189 -224
- 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 -77
- package/src/index.ts +70 -163
- package/src/obfuscationResult.ts +43 -0
- package/src/obfuscator.ts +328 -135
- package/src/options.ts +154 -623
- package/src/order.ts +14 -14
- package/src/presets.ts +39 -34
- package/src/probability.ts +21 -36
- package/src/templates/{bufferToString.ts → bufferToStringTemplate.ts} +5 -54
- 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 +183 -92
- package/src/transforms/astScrambler.ts +99 -0
- package/src/transforms/calculator.ts +96 -224
- package/src/transforms/controlFlowFlattening.ts +1594 -0
- package/src/transforms/deadCode.ts +85 -628
- package/src/transforms/dispatcher.ts +431 -636
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +147 -299
- 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 +261 -189
- package/src/transforms/identifier/movedDeclarations.ts +228 -142
- package/src/transforms/identifier/renameVariables.ts +252 -258
- package/src/transforms/lock/integrity.ts +84 -260
- package/src/transforms/lock/lock.ts +342 -491
- 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 -215
- package/src/transforms/renameLabels.ts +176 -77
- package/src/transforms/rgf.ts +293 -386
- package/src/transforms/shuffle.ts +80 -254
- package/src/transforms/string/encoding.ts +26 -129
- package/src/transforms/string/stringCompression.ts +118 -236
- package/src/transforms/string/stringConcealing.ts +255 -339
- 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 -108
- package/dist/templates/crash.js +0 -59
- 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 -1281
- 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 -70
- package/dist/transforms/identifier/variableAnalysis.js +0 -104
- package/dist/transforms/lock/antiDebug.js +0 -76
- package/dist/transforms/stack.js +0 -343
- package/dist/transforms/transform.js +0 -350
- 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 -9
- 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 -130
- package/dist/util/scope.js +0 -20
- package/docs/ControlFlowFlattening.md +0 -595
- package/docs/Countermeasures.md +0 -63
- package/docs/ES5.md +0 -197
- package/docs/Integrity.md +0 -75
- package/docs/RGF.md +0 -419
- 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/crash.ts +0 -55
- 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 -2146
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +0 -179
- package/src/transforms/es5/antiClass.ts +0 -272
- 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 -85
- package/src/transforms/identifier/variableAnalysis.ts +0 -118
- package/src/transforms/lock/antiDebug.ts +0 -112
- package/src/transforms/stack.ts +0 -551
- package/src/transforms/transform.ts +0 -453
- package/src/traverse.ts +0 -120
- package/src/types.ts +0 -131
- package/src/util/compare.ts +0 -181
- package/src/util/gen.ts +0 -651
- package/src/util/guard.ts +0 -7
- 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 -141
- package/src/util/scope.ts +0 -21
- package/test/code/Cash.src.js +0 -1011
- package/test/code/Cash.test.ts +0 -49
- 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 -132
- package/test/presets.test.ts +0 -22
- package/test/probability.test.ts +0 -44
- package/test/templates/template.test.ts +0 -14
- 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 -72
- package/test/transforms/identifier/movedDeclarations.test.ts +0 -275
- package/test/transforms/identifier/renameVariables.test.ts +0 -621
- 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/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,558 +1,409 @@
|
|
|
1
|
-
import
|
|
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";
|
|
5
|
+
import Template from "../../templates/template";
|
|
6
|
+
import * as t from "@babel/types";
|
|
7
|
+
import { CustomLock } from "../../options";
|
|
2
8
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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";
|
|
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";
|
|
23
17
|
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
import {
|
|
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
|
-
if (this.options.lock.integrity) {
|
|
62
|
-
this.before.push(new Integrity(o, this));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (this.options.lock.antiDebug) {
|
|
66
|
-
this.before.push(new AntiDebug(o, this));
|
|
67
|
-
}
|
|
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
|
+
});
|
|
54
|
+
}
|
|
68
55
|
|
|
69
|
-
|
|
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}
|
|
62
|
+
}
|
|
63
|
+
`,
|
|
64
|
+
`
|
|
65
|
+
if((new Date()).getTime()>${me.options.lock.endDate.getTime()}) {
|
|
66
|
+
{countermeasures}
|
|
67
|
+
}
|
|
68
|
+
`,
|
|
69
|
+
],
|
|
70
|
+
percentagePerBlock: 0.5,
|
|
71
|
+
});
|
|
70
72
|
}
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
) {
|
|
77
|
-
traverse(tree, (object, parents) => {
|
|
78
|
-
if (
|
|
79
|
-
object.type == "Identifier" &&
|
|
80
|
-
object.name === this.options.lock.countermeasures
|
|
81
|
-
) {
|
|
82
|
-
var info = getIdentifierInfo(object, parents);
|
|
83
|
-
if (info.spec.isDefined) {
|
|
84
|
-
if (this.counterMeasuresNode) {
|
|
85
|
-
throw new Error(
|
|
86
|
-
"Countermeasures function was already defined, it must have a unique name from the rest of your code"
|
|
87
|
-
);
|
|
88
|
-
} else {
|
|
89
|
-
var definingContext = getVarContext(parents[0], parents.slice(1));
|
|
90
|
-
if (definingContext != tree) {
|
|
91
|
-
throw new Error(
|
|
92
|
-
"Countermeasures function must be defined at the global level"
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
var chain: Location = [object, parents];
|
|
96
|
-
if (info.isFunctionDeclaration) {
|
|
97
|
-
chain = [parents[0], parents.slice(1)];
|
|
98
|
-
} else if (info.isVariableDeclaration) {
|
|
99
|
-
chain = [parents[1], parents.slice(2)];
|
|
100
|
-
}
|
|
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];
|
|
101
78
|
|
|
102
|
-
|
|
103
|
-
|
|
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)) {
|
|
83
|
+
{countermeasures}
|
|
104
84
|
}
|
|
105
|
-
|
|
85
|
+
`).setDefaultVariables({
|
|
86
|
+
regexString: () => t.stringLiteral(regexString.toString()),
|
|
87
|
+
}),
|
|
88
|
+
percentagePerBlock: 0.5,
|
|
106
89
|
});
|
|
107
|
-
|
|
108
|
-
if (!this.counterMeasuresNode) {
|
|
109
|
-
throw new Error(
|
|
110
|
-
"Countermeasures function named '" +
|
|
111
|
-
this.options.lock.countermeasures +
|
|
112
|
-
"' was not found."
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
90
|
}
|
|
116
|
-
|
|
117
|
-
super.apply(tree);
|
|
118
91
|
}
|
|
119
92
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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()) {
|
|
106
|
+
{countermeasures}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
131
109
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
110
|
+
return namedFunction();
|
|
111
|
+
}
|
|
112
|
+
)();
|
|
113
|
+
`,
|
|
114
|
+
percentagePerBlock: 0.5,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
137
117
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
"=",
|
|
147
|
-
Identifier(this.counterMeasuresActivated),
|
|
148
|
-
Literal(true)
|
|
149
|
-
),
|
|
150
|
-
CallExpression(Template(opt).single().expression, []),
|
|
151
|
-
])
|
|
152
|
-
)
|
|
153
|
-
),
|
|
154
|
-
];
|
|
155
|
-
}
|
|
118
|
+
if (me.options.lock.antiDebug) {
|
|
119
|
+
me.options.lock.customLocks.push({
|
|
120
|
+
code: `
|
|
121
|
+
debugger;
|
|
122
|
+
`,
|
|
123
|
+
percentagePerBlock: 0.5,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
156
126
|
|
|
157
|
-
|
|
127
|
+
const timesMap = new WeakMap<CustomLock, number>();
|
|
158
128
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
var varName = this.getPlaceholder();
|
|
162
|
-
return choice([CrashTemplate1, CrashTemplate2, CrashTemplate3]).compile(
|
|
163
|
-
{
|
|
164
|
-
var: varName,
|
|
165
|
-
}
|
|
166
|
-
);
|
|
129
|
+
let countermeasuresNode: NodePath<t.Identifier>;
|
|
130
|
+
let invokeCountermeasuresFnName;
|
|
167
131
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return Template("document.documentElement.innerHTML = '';").compile();
|
|
171
|
-
}
|
|
132
|
+
if (me.options.lock.countermeasures) {
|
|
133
|
+
invokeCountermeasuresFnName = me.getPlaceholder("invokeCountermeasures");
|
|
172
134
|
|
|
173
|
-
|
|
174
|
-
|
|
135
|
+
me.globalState.internals.invokeCountermeasuresFnName =
|
|
136
|
+
invokeCountermeasuresFnName;
|
|
175
137
|
}
|
|
176
138
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
*/
|
|
181
|
-
getTime(object: Date | number | false): number {
|
|
182
|
-
if (!object) {
|
|
183
|
-
return 0;
|
|
139
|
+
var createCountermeasuresCode = () => {
|
|
140
|
+
if (invokeCountermeasuresFnName) {
|
|
141
|
+
return new Template(`${invokeCountermeasuresFnName}()`).compile();
|
|
184
142
|
}
|
|
185
|
-
|
|
186
|
-
|
|
143
|
+
|
|
144
|
+
if (me.options.lock.countermeasures === false) {
|
|
145
|
+
return [];
|
|
187
146
|
}
|
|
188
147
|
|
|
189
|
-
return
|
|
190
|
-
}
|
|
148
|
+
return new Template(`while(true){}`).compile();
|
|
149
|
+
};
|
|
150
|
+
me.globalState.lock.createCountermeasuresCode = createCountermeasuresCode;
|
|
191
151
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
152
|
+
function applyLockToBlock(path: NodePath<t.Block>, customLock: CustomLock) {
|
|
153
|
+
let times = timesMap.get(customLock);
|
|
154
|
+
|
|
155
|
+
if (typeof times === "undefined") {
|
|
156
|
+
times = 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let maxCount = customLock.maxCount || 100; // 100 is default max count
|
|
160
|
+
let minCount = customLock.minCount || 1; // 1 is default min count
|
|
195
161
|
|
|
196
|
-
|
|
197
|
-
|
|
162
|
+
if (maxCount >= 0 && times > maxCount) {
|
|
163
|
+
// Limit creation, allowing -1 to disable the limit entirely
|
|
198
164
|
return;
|
|
199
165
|
}
|
|
200
166
|
|
|
201
|
-
//
|
|
167
|
+
// The Program always gets a lock
|
|
168
|
+
// Else based on the percentage
|
|
169
|
+
// Try to reach the minimum count
|
|
202
170
|
if (
|
|
203
|
-
|
|
204
|
-
(
|
|
205
|
-
|
|
171
|
+
!path.isProgram() &&
|
|
172
|
+
!chance(customLock.percentagePerBlock * 100) &&
|
|
173
|
+
times >= minCount
|
|
206
174
|
) {
|
|
207
175
|
return;
|
|
208
176
|
}
|
|
209
177
|
|
|
210
|
-
|
|
178
|
+
// Increment the times
|
|
179
|
+
timesMap.set(customLock, times + 1);
|
|
211
180
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
if (this.options.lock.endDate) {
|
|
217
|
-
choices.push("endDate");
|
|
218
|
-
}
|
|
219
|
-
if (this.options.lock.domainLock && this.options.lock.domainLock.length) {
|
|
220
|
-
choices.push("domainLock");
|
|
221
|
-
}
|
|
181
|
+
const lockCode = Array.isArray(customLock.code)
|
|
182
|
+
? choice(customLock.code)
|
|
183
|
+
: customLock.code;
|
|
222
184
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
choices.push("osLock");
|
|
231
|
-
}
|
|
232
|
-
if (this.options.lock.selfDefending) {
|
|
233
|
-
choices.push("selfDefending");
|
|
234
|
-
}
|
|
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());
|
|
235
192
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return () => {
|
|
241
|
-
this.made++;
|
|
242
|
-
if (this.made > 150) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
193
|
+
me.changeData.locksInserted++;
|
|
194
|
+
}
|
|
245
195
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
);
|
|
253
|
-
if (Math.random() > 0.5) {
|
|
254
|
-
dateNow = CallExpression(
|
|
255
|
-
MemberExpression(
|
|
256
|
-
NewExpression(Identifier("Date"), []),
|
|
257
|
-
Literal("getTime")
|
|
258
|
-
),
|
|
259
|
-
[]
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
if (Math.random() > 0.5) {
|
|
263
|
-
dateNow = CallExpression(
|
|
264
|
-
MemberExpression(
|
|
265
|
-
MemberExpression(
|
|
266
|
-
MemberExpression(Identifier("Date"), Literal("prototype"), true),
|
|
267
|
-
Literal("getTime"),
|
|
268
|
-
true
|
|
269
|
-
),
|
|
270
|
-
Literal("call"),
|
|
271
|
-
true
|
|
272
|
-
),
|
|
273
|
-
[NewExpression(Identifier("Date"), [])]
|
|
274
|
-
);
|
|
275
|
-
}
|
|
196
|
+
return {
|
|
197
|
+
visitor: {
|
|
198
|
+
BindingIdentifier(path) {
|
|
199
|
+
if (path.node.name !== me.options.lock.countermeasures) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
276
202
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
switch (type) {
|
|
281
|
-
case "selfDefending":
|
|
282
|
-
// A very simple mechanism inspired from https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/src/custom-code-helpers/self-defending/templates/SelfDefendingNoEvalTemplate.ts
|
|
283
|
-
// regExp checks for a newline, formatters add these
|
|
284
|
-
var callExpression = Template(
|
|
285
|
-
`
|
|
286
|
-
(
|
|
287
|
-
function(){
|
|
288
|
-
// Breaks JSNice.org, beautifier.io
|
|
289
|
-
var namedFunction = function(){
|
|
290
|
-
const test = function(){
|
|
291
|
-
const regExp=new RegExp('\\n');
|
|
292
|
-
return regExp['test'](namedFunction)
|
|
293
|
-
};
|
|
294
|
-
return test()
|
|
295
|
-
}
|
|
203
|
+
// Exclude labels
|
|
204
|
+
if (!isVariableIdentifier(path)) return;
|
|
296
205
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
)()
|
|
300
|
-
`
|
|
301
|
-
).single().expression;
|
|
302
|
-
|
|
303
|
-
nodes.push(
|
|
304
|
-
IfStatement(
|
|
305
|
-
callExpression,
|
|
306
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
307
|
-
null
|
|
308
|
-
)
|
|
309
|
-
);
|
|
206
|
+
if (!isDefiningIdentifier(path)) {
|
|
207
|
+
// Reassignments are not allowed
|
|
310
208
|
|
|
311
|
-
|
|
209
|
+
me.error("Countermeasures function cannot be reassigned");
|
|
210
|
+
}
|
|
312
211
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
"<",
|
|
316
|
-
dateNow,
|
|
317
|
-
Literal(this.getTime(this.options.lock.startDate))
|
|
318
|
-
);
|
|
212
|
+
if (countermeasuresNode) {
|
|
213
|
+
// Disallow multiple countermeasures functions
|
|
319
214
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
test,
|
|
323
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
324
|
-
null
|
|
325
|
-
)
|
|
215
|
+
me.error(
|
|
216
|
+
"Countermeasures function was already defined, it must have a unique name from the rest of your code"
|
|
326
217
|
);
|
|
218
|
+
}
|
|
327
219
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
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"
|
|
335
226
|
);
|
|
227
|
+
}
|
|
336
228
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
test,
|
|
340
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
341
|
-
null
|
|
342
|
-
)
|
|
343
|
-
);
|
|
229
|
+
countermeasuresNode = path;
|
|
230
|
+
},
|
|
344
231
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
351
|
-
|
|
352
|
-
// Todo: Alternative to `this`
|
|
353
|
-
if (!this.globalVar) {
|
|
354
|
-
offset = 1;
|
|
355
|
-
this.globalVar = this.getPlaceholder();
|
|
356
|
-
prepend(
|
|
357
|
-
parents[parents.length - 1] || block,
|
|
358
|
-
VariableDeclaration(
|
|
359
|
-
VariableDeclarator(
|
|
360
|
-
this.globalVar,
|
|
361
|
-
LogicalExpression(
|
|
362
|
-
"||",
|
|
363
|
-
Identifier(
|
|
364
|
-
this.options.globalVariables.keys().next().value
|
|
365
|
-
),
|
|
366
|
-
ThisExpression()
|
|
367
|
-
)
|
|
368
|
-
)
|
|
369
|
-
)
|
|
370
|
-
);
|
|
232
|
+
Block: {
|
|
233
|
+
exit(path) {
|
|
234
|
+
var customLock = choice(me.options.lock.customLocks);
|
|
235
|
+
if (customLock) {
|
|
236
|
+
applyLockToBlock(path, customLock);
|
|
371
237
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
var code = this.getCounterMeasuresCode(object, parents) || [];
|
|
389
|
-
|
|
390
|
-
this.options.lock.osLock.forEach((osName) => {
|
|
391
|
-
var agentMatcher = {
|
|
392
|
-
windows: "Win",
|
|
393
|
-
linux: "Linux",
|
|
394
|
-
osx: "Mac",
|
|
395
|
-
android: "Android",
|
|
396
|
-
ios: "---",
|
|
397
|
-
}[osName];
|
|
398
|
-
var thisTest: Node = CallExpression(
|
|
399
|
-
MemberExpression(navigatorUserAgent, Literal("match"), true),
|
|
400
|
-
[Literal(agentMatcher.toLowerCase())]
|
|
401
|
-
);
|
|
402
|
-
if (osName == "ios" && this.options.target === "browser") {
|
|
403
|
-
if (!this.iosDetectFn) {
|
|
404
|
-
this.iosDetectFn = this.getPlaceholder();
|
|
405
|
-
prepend(
|
|
406
|
-
parents[parents.length - 1] || object,
|
|
407
|
-
Template(`function ${this.iosDetectFn}() {
|
|
408
|
-
return [
|
|
409
|
-
'iPad Simulator',
|
|
410
|
-
'iPhone Simulator',
|
|
411
|
-
'iPod Simulator',
|
|
412
|
-
'iPad',
|
|
413
|
-
'iPhone',
|
|
414
|
-
'iPod'
|
|
415
|
-
].includes(navigator.platform)
|
|
416
|
-
// iPad on iOS 13 detection
|
|
417
|
-
|| (navigator.userAgent.includes("Mac") && "ontouchend" in document)
|
|
418
|
-
}`).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."
|
|
419
253
|
);
|
|
420
254
|
}
|
|
421
|
-
|
|
422
|
-
thisTest = CallExpression(Identifier(this.iosDetectFn), []);
|
|
423
255
|
}
|
|
424
256
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
{ windows: "win32", osx: "darwin", ios: "darwin" }[osName] ||
|
|
428
|
-
osName;
|
|
429
|
-
thisTest = Template(
|
|
430
|
-
`require('os').platform()==="${platformName}"`
|
|
431
|
-
).single().expression;
|
|
432
|
-
}
|
|
257
|
+
var nativeFunctionName =
|
|
258
|
+
me.getPlaceholder() + "_nativeFunctionCheck";
|
|
433
259
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
} else {
|
|
437
|
-
test = LogicalExpression("||", { ...test }, thisTest);
|
|
438
|
-
}
|
|
439
|
-
});
|
|
260
|
+
me.obfuscator.globalState.internals.nativeFunctionName =
|
|
261
|
+
nativeFunctionName;
|
|
440
262
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
ok(this.options.lock.browserLock);
|
|
451
|
-
|
|
452
|
-
this.options.lock.browserLock.forEach((browserName) => {
|
|
453
|
-
var thisTest: Node = CallExpression(
|
|
454
|
-
MemberExpression(navigatorUserAgent, Literal("match"), true),
|
|
455
|
-
[
|
|
456
|
-
Literal(
|
|
457
|
-
browserName == "iexplorer"
|
|
458
|
-
? "msie"
|
|
459
|
-
: browserName.toLowerCase()
|
|
460
|
-
),
|
|
461
|
-
]
|
|
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
|
+
})
|
|
462
271
|
);
|
|
463
272
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}
|
|
273
|
+
const nativeFunctionDeclaration = NativeFunctionTemplate.single({
|
|
274
|
+
nativeFunctionName,
|
|
275
|
+
countermeasures: createCountermeasuresCode(),
|
|
276
|
+
IndexOfTemplate: IndexOfTemplate,
|
|
277
|
+
});
|
|
469
278
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
test = LogicalExpression("||", { ...test }, thisTest);
|
|
474
|
-
}
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
test = UnaryExpression("!", { ...test });
|
|
478
|
-
nodes.push(
|
|
479
|
-
IfStatement(
|
|
480
|
-
test,
|
|
481
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
482
|
-
null
|
|
483
|
-
)
|
|
484
|
-
);
|
|
485
|
-
break;
|
|
279
|
+
// Checks function's toString() value for [native code] signature
|
|
280
|
+
prependProgram(path, nativeFunctionDeclaration);
|
|
281
|
+
}
|
|
486
282
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
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
|
+
}
|
|
491
292
|
|
|
492
|
-
|
|
493
|
-
|
|
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();
|
|
494
304
|
|
|
495
|
-
|
|
305
|
+
prependProgram(path, statements).forEach((p) => p.skip());
|
|
496
306
|
}
|
|
497
307
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
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
|
|
502
367
|
);
|
|
503
368
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
{
|
|
510
|
-
type: "Literal",
|
|
511
|
-
regex: {
|
|
512
|
-
pattern:
|
|
513
|
-
random instanceof RegExp
|
|
514
|
-
? random.source
|
|
515
|
-
: removeSlashes(random + ""),
|
|
516
|
-
flags: random instanceof RegExp ? "" : "",
|
|
517
|
-
},
|
|
518
|
-
},
|
|
519
|
-
]
|
|
520
|
-
);
|
|
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
|
+
});
|
|
521
374
|
|
|
522
|
-
|
|
523
|
-
if (Math.random() > 0.5) {
|
|
524
|
-
test = LogicalExpression(
|
|
525
|
-
"||",
|
|
526
|
-
BinaryExpression(
|
|
527
|
-
"==",
|
|
528
|
-
UnaryExpression("typeof", Identifier("location")),
|
|
529
|
-
Literal("undefined")
|
|
530
|
-
),
|
|
531
|
-
test
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
nodes.push(
|
|
535
|
-
IfStatement(
|
|
536
|
-
test,
|
|
537
|
-
this.getCounterMeasuresCode(object, parents) || [],
|
|
538
|
-
null
|
|
539
|
-
)
|
|
540
|
-
);
|
|
541
|
-
}
|
|
375
|
+
(newFunctionDeclaration as NodeSymbol)[SKIP] = true;
|
|
542
376
|
|
|
543
|
-
|
|
544
|
-
|
|
377
|
+
var [newFnPath] = program.unshiftContainer(
|
|
378
|
+
"body",
|
|
379
|
+
newFunctionDeclaration
|
|
380
|
+
);
|
|
545
381
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
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
|
+
);
|
|
549
390
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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
|
+
};
|