js-confuser 2.0.0-alpha.2 → 2.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -6
- package/dist/constants.js +6 -2
- package/dist/index.js +12 -0
- package/dist/obfuscator.js +117 -6
- package/dist/order.js +0 -1
- package/dist/probability.js +1 -96
- package/dist/templates/getGlobalTemplate.js +4 -1
- package/dist/templates/stringCompressionTemplate.js +3 -3
- package/dist/templates/tamperProtectionTemplates.js +1 -1
- package/dist/templates/template.js +17 -12
- package/dist/transforms/controlFlowFlattening.js +2 -6
- package/dist/transforms/deadCode.js +8 -15
- package/dist/transforms/dispatcher.js +1 -2
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +5 -0
- package/dist/transforms/extraction/objectExtraction.js +1 -2
- package/dist/transforms/finalizer.js +1 -1
- package/dist/transforms/flatten.js +2 -19
- package/dist/transforms/identifier/globalConcealing.js +1 -2
- package/dist/transforms/identifier/movedDeclarations.js +12 -5
- package/dist/transforms/identifier/renameVariables.js +7 -6
- package/dist/transforms/lock/lock.js +9 -2
- package/dist/transforms/minify.js +14 -1
- package/dist/transforms/opaquePredicates.js +5 -6
- package/dist/transforms/pack.js +5 -0
- package/dist/transforms/plugin.js +20 -39
- package/dist/transforms/renameLabels.js +1 -2
- package/dist/transforms/rgf.js +29 -11
- package/dist/transforms/shuffle.js +10 -11
- package/dist/transforms/string/stringCompression.js +14 -10
- package/dist/transforms/string/stringConcealing.js +4 -4
- package/dist/transforms/string/stringEncoding.js +4 -2
- package/dist/transforms/string/stringSplitting.js +4 -2
- package/dist/transforms/variableMasking.js +1 -2
- package/dist/utils/NameGen.js +3 -2
- package/dist/utils/PredicateGen.js +62 -0
- package/dist/utils/ast-utils.js +24 -9
- package/dist/validateOptions.js +2 -2
- package/package.json +2 -2
- package/src/constants.ts +6 -5
- package/src/index.ts +1 -0
- package/src/obfuscator.ts +148 -7
- package/src/options.ts +14 -6
- package/src/order.ts +0 -2
- package/src/probability.ts +0 -110
- package/src/templates/getGlobalTemplate.ts +5 -1
- package/src/templates/stringCompressionTemplate.ts +4 -28
- package/src/templates/tamperProtectionTemplates.ts +7 -3
- package/src/templates/template.ts +5 -3
- package/src/transforms/controlFlowFlattening.ts +2 -7
- package/src/transforms/deadCode.ts +11 -23
- package/src/transforms/dispatcher.ts +1 -2
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +10 -1
- package/src/transforms/extraction/objectExtraction.ts +1 -2
- package/src/transforms/finalizer.ts +1 -1
- package/src/transforms/flatten.ts +3 -22
- package/src/transforms/identifier/globalConcealing.ts +4 -2
- package/src/transforms/identifier/movedDeclarations.ts +18 -6
- package/src/transforms/identifier/renameVariables.ts +10 -6
- package/src/transforms/lock/lock.ts +14 -3
- package/src/transforms/minify.ts +24 -2
- package/src/transforms/opaquePredicates.ts +5 -8
- package/src/transforms/pack.ts +6 -0
- package/src/transforms/plugin.ts +47 -69
- package/src/transforms/renameLabels.ts +1 -2
- package/src/transforms/rgf.ts +39 -14
- package/src/transforms/shuffle.ts +28 -26
- package/src/transforms/string/encoding.ts +1 -1
- package/src/transforms/string/stringCompression.ts +22 -13
- package/src/transforms/string/stringConcealing.ts +11 -7
- package/src/transforms/string/stringEncoding.ts +6 -2
- package/src/transforms/string/stringSplitting.ts +9 -4
- package/src/transforms/variableMasking.ts +1 -2
- package/src/utils/NameGen.ts +4 -2
- package/src/utils/PredicateGen.ts +61 -0
- package/src/utils/ast-utils.ts +16 -9
- package/src/validateOptions.ts +7 -4
- package/src/transforms/functionOutlining.ts +0 -225
- package/src/utils/ControlObject.ts +0 -141
|
@@ -4,7 +4,6 @@ import * as t from "@babel/types";
|
|
|
4
4
|
import Template from "../templates/template";
|
|
5
5
|
import { ok } from "assert";
|
|
6
6
|
import { chance, getRandomString } from "../utils/random-utils";
|
|
7
|
-
import { computeProbabilityMap } from "../probability";
|
|
8
7
|
import { Order } from "../order";
|
|
9
8
|
import { NodeSymbol, PREDICTABLE, UNSAFE } from "../constants";
|
|
10
9
|
import {
|
|
@@ -146,7 +145,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
146
145
|
}
|
|
147
146
|
|
|
148
147
|
for (var name of functionPaths.keys()) {
|
|
149
|
-
if (!computeProbabilityMap(me.options.dispatcher, name)) {
|
|
148
|
+
if (!me.computeProbabilityMap(me.options.dispatcher, name)) {
|
|
150
149
|
functionPaths.delete(name);
|
|
151
150
|
}
|
|
152
151
|
}
|
|
@@ -2,7 +2,11 @@ import * as t from "@babel/types";
|
|
|
2
2
|
import { ok } from "assert";
|
|
3
3
|
import { PluginArg, PluginObject } from "../plugin";
|
|
4
4
|
import { Order } from "../../order";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ensureComputedExpression,
|
|
7
|
+
isModuleImport,
|
|
8
|
+
prepend,
|
|
9
|
+
} from "../../utils/ast-utils";
|
|
6
10
|
import { createLiteral, LiteralValue, numericLiteral } from "../../utils/node";
|
|
7
11
|
import { NodePath } from "@babel/traverse";
|
|
8
12
|
|
|
@@ -49,6 +53,11 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
49
53
|
t.Literal | t.Identifier
|
|
50
54
|
>;
|
|
51
55
|
|
|
56
|
+
// Don't change module imports
|
|
57
|
+
if (literalPath.isStringLiteral()) {
|
|
58
|
+
if (isModuleImport(literalPath)) return;
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
let node = literalPath.node;
|
|
53
62
|
var isUndefined = false;
|
|
54
63
|
if (literalPath.isIdentifier()) {
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
getObjectPropertyAsString,
|
|
8
8
|
getParentFunctionOrProgram,
|
|
9
9
|
} from "../../utils/ast-utils";
|
|
10
|
-
import { computeProbabilityMap } from "../../probability";
|
|
11
10
|
|
|
12
11
|
export default ({ Plugin }: PluginArg): PluginObject => {
|
|
13
12
|
const me = Plugin(Order.ObjectExtraction, {
|
|
@@ -152,7 +151,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
152
151
|
if (!isObjectSafe) return;
|
|
153
152
|
|
|
154
153
|
if (
|
|
155
|
-
!computeProbabilityMap(
|
|
154
|
+
!me.computeProbabilityMap(
|
|
156
155
|
me.options.objectExtraction,
|
|
157
156
|
identifier.node.name
|
|
158
157
|
)
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
prependProgram,
|
|
12
12
|
} from "../utils/ast-utils";
|
|
13
13
|
import { PluginArg, PluginObject } from "./plugin";
|
|
14
|
-
import { computeProbabilityMap } from "../probability";
|
|
15
14
|
import { Order } from "../order";
|
|
16
15
|
import { NodeSymbol, PREDICTABLE, UNSAFE } from "../constants";
|
|
17
16
|
import {
|
|
@@ -58,7 +57,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
58
57
|
functionName = "anonymous";
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
if (!computeProbabilityMap(me.options.flatten, functionName)) {
|
|
60
|
+
if (!me.computeProbabilityMap(me.options.flatten, functionName)) {
|
|
62
61
|
return;
|
|
63
62
|
}
|
|
64
63
|
|
|
@@ -117,26 +116,8 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
117
116
|
return;
|
|
118
117
|
}
|
|
119
118
|
|
|
120
|
-
var
|
|
121
|
-
|
|
122
|
-
if (definedLocal.hasOwnBinding(identifierName)) return;
|
|
123
|
-
if (definedLocal === fnPath.scope) break;
|
|
124
|
-
|
|
125
|
-
definedLocal = definedLocal.parent;
|
|
126
|
-
if (definedLocal === program.scope)
|
|
127
|
-
ok(functionName + ":" + identifierName);
|
|
128
|
-
} while (definedLocal);
|
|
129
|
-
|
|
130
|
-
var cursor: Scope = fnPath.scope.parent;
|
|
131
|
-
var isOutsideVariable = false;
|
|
132
|
-
|
|
133
|
-
do {
|
|
134
|
-
if (cursor.hasBinding(identifierName)) {
|
|
135
|
-
isOutsideVariable = true;
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
cursor = cursor.parent;
|
|
139
|
-
} while (cursor);
|
|
119
|
+
var isOutsideVariable =
|
|
120
|
+
fnPath.scope.parent.getBinding(identifierName) === binding;
|
|
140
121
|
|
|
141
122
|
if (!isOutsideVariable) {
|
|
142
123
|
return;
|
|
@@ -4,7 +4,6 @@ import { NameGen } from "../../utils/NameGen";
|
|
|
4
4
|
import Template from "../../templates/template";
|
|
5
5
|
import { PluginArg, PluginObject } from "../plugin";
|
|
6
6
|
import { Order } from "../../order";
|
|
7
|
-
import { computeProbabilityMap } from "../../probability";
|
|
8
7
|
import {
|
|
9
8
|
MULTI_TRANSFORM,
|
|
10
9
|
reservedIdentifiers,
|
|
@@ -132,7 +131,10 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
132
131
|
if (!mapping) {
|
|
133
132
|
// Allow user to disable custom global variables
|
|
134
133
|
if (
|
|
135
|
-
!computeProbabilityMap(
|
|
134
|
+
!me.computeProbabilityMap(
|
|
135
|
+
me.options.globalConcealing,
|
|
136
|
+
globalName
|
|
137
|
+
)
|
|
136
138
|
)
|
|
137
139
|
continue;
|
|
138
140
|
|
|
@@ -65,8 +65,12 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
65
65
|
if (!functionPath || !(functionPath.node as NodeSymbol)[PREDICTABLE])
|
|
66
66
|
return;
|
|
67
67
|
|
|
68
|
+
var fnBody = functionPath.get("body");
|
|
69
|
+
|
|
70
|
+
if (!fnBody.isBlockStatement()) return;
|
|
71
|
+
|
|
68
72
|
// Must be direct child of the function
|
|
69
|
-
if (path.parentPath !==
|
|
73
|
+
if (path.parentPath !== fnBody) return;
|
|
70
74
|
|
|
71
75
|
const functionName = path.node.id.name;
|
|
72
76
|
|
|
@@ -99,7 +103,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
prepend(
|
|
102
|
-
|
|
106
|
+
fnBody,
|
|
103
107
|
new Template(`
|
|
104
108
|
if(!${functionName}) {
|
|
105
109
|
${functionName} = {functionExpression};
|
|
@@ -113,6 +117,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
113
117
|
},
|
|
114
118
|
VariableDeclaration: {
|
|
115
119
|
exit(path) {
|
|
120
|
+
if (me.isSkipped(path)) return;
|
|
116
121
|
if (path.node.kind !== "var") return;
|
|
117
122
|
if (path.node.declarations.length !== 1) return;
|
|
118
123
|
|
|
@@ -150,7 +155,11 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
150
155
|
let isDefinedAtTop = false;
|
|
151
156
|
const parentPath = path.parentPath;
|
|
152
157
|
if (parentPath.isBlock()) {
|
|
153
|
-
isDefinedAtTop =
|
|
158
|
+
isDefinedAtTop =
|
|
159
|
+
parentPath
|
|
160
|
+
.get("body")
|
|
161
|
+
.filter((x) => x.type !== "ImportDeclaration")
|
|
162
|
+
.indexOf(path) === 0;
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
// Already at the top - nothing will change
|
|
@@ -214,7 +223,9 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
214
223
|
path.isBlock()
|
|
215
224
|
) as NodePath<t.Block>;
|
|
216
225
|
|
|
217
|
-
var topNode = block.node.body
|
|
226
|
+
var topNode = block.node.body.filter(
|
|
227
|
+
(x) => x.type !== "ImportDeclaration"
|
|
228
|
+
)[0];
|
|
218
229
|
const variableDeclarator = t.variableDeclarator(
|
|
219
230
|
t.identifier(name)
|
|
220
231
|
);
|
|
@@ -223,8 +234,9 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
223
234
|
topNode.declarations.push(variableDeclarator);
|
|
224
235
|
break;
|
|
225
236
|
} else {
|
|
226
|
-
|
|
227
|
-
|
|
237
|
+
prepend(
|
|
238
|
+
block,
|
|
239
|
+
me.skip(t.variableDeclaration("var", [variableDeclarator]))
|
|
228
240
|
);
|
|
229
241
|
}
|
|
230
242
|
|
|
@@ -6,9 +6,7 @@ import { Order } from "../../order";
|
|
|
6
6
|
import {
|
|
7
7
|
noRenameVariablePrefix,
|
|
8
8
|
placeholderVariablePrefix,
|
|
9
|
-
variableFunctionName,
|
|
10
9
|
} from "../../constants";
|
|
11
|
-
import { computeProbabilityMap } from "../../probability";
|
|
12
10
|
import {
|
|
13
11
|
getParentFunctionOrProgram,
|
|
14
12
|
isDefiningIdentifier,
|
|
@@ -215,19 +213,25 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
215
213
|
// Placeholder variables should always be renamed
|
|
216
214
|
if (name.startsWith(placeholderVariablePrefix)) return true;
|
|
217
215
|
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
const binding = bindings?.get(name);
|
|
217
|
+
|
|
218
|
+
if (binding) {
|
|
219
|
+
// Do not rename exports
|
|
220
|
+
if (isExportedIdentifier(binding)) return false;
|
|
221
|
+
}
|
|
220
222
|
|
|
221
223
|
if (name === me.obfuscator.getStringCompressionLibraryName())
|
|
222
224
|
return false;
|
|
223
225
|
|
|
224
226
|
// Global variables are additionally checked against user option
|
|
225
227
|
if (isGlobal) {
|
|
226
|
-
if (!computeProbabilityMap(me.options.renameGlobals, name))
|
|
228
|
+
if (!me.computeProbabilityMap(me.options.renameGlobals, name))
|
|
227
229
|
return false;
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
if (
|
|
232
|
+
if (
|
|
233
|
+
!me.computeProbabilityMap(me.options.renameVariables, name, isGlobal)
|
|
234
|
+
)
|
|
231
235
|
return false;
|
|
232
236
|
|
|
233
237
|
return true;
|
|
@@ -26,7 +26,6 @@ import {
|
|
|
26
26
|
NativeFunctionTemplate,
|
|
27
27
|
StrictModeTemplate,
|
|
28
28
|
} from "../../templates/tamperProtectionTemplates";
|
|
29
|
-
import { computeProbabilityMap } from "../../probability";
|
|
30
29
|
|
|
31
30
|
export default ({ Plugin }: PluginArg): PluginObject => {
|
|
32
31
|
const me = Plugin(Order.Lock, {
|
|
@@ -36,6 +35,11 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
36
35
|
});
|
|
37
36
|
|
|
38
37
|
if (me.options.lock.startDate instanceof Date) {
|
|
38
|
+
// Ensure date is in the past
|
|
39
|
+
if (me.options.lock.startDate.getTime() > Date.now()) {
|
|
40
|
+
me.warn("lock.startDate is detected to be in the future");
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
me.options.lock.customLocks.push({
|
|
40
44
|
code: [
|
|
41
45
|
`
|
|
@@ -54,6 +58,11 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
if (me.options.lock.endDate instanceof Date) {
|
|
61
|
+
// Ensure date is in the future
|
|
62
|
+
if (me.options.lock.endDate.getTime() < Date.now()) {
|
|
63
|
+
me.warn("lock.endDate is detected to be in the past");
|
|
64
|
+
}
|
|
65
|
+
|
|
57
66
|
me.options.lock.customLocks.push({
|
|
58
67
|
code: [
|
|
59
68
|
`
|
|
@@ -127,7 +136,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
127
136
|
const timesMap = new WeakMap<CustomLock, number>();
|
|
128
137
|
|
|
129
138
|
let countermeasuresNode: NodePath<t.Identifier>;
|
|
130
|
-
let invokeCountermeasuresFnName;
|
|
139
|
+
let invokeCountermeasuresFnName: string;
|
|
131
140
|
|
|
132
141
|
if (me.options.lock.countermeasures) {
|
|
133
142
|
invokeCountermeasuresFnName = me.getPlaceholder("invokeCountermeasures");
|
|
@@ -356,7 +365,9 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
356
365
|
// Don't apply to invokeCountermeasures function (Intended)
|
|
357
366
|
if (me.obfuscator.isInternalVariable(functionName)) return;
|
|
358
367
|
|
|
359
|
-
if (
|
|
368
|
+
if (
|
|
369
|
+
!me.computeProbabilityMap(me.options.lock.integrity, functionName)
|
|
370
|
+
)
|
|
360
371
|
return;
|
|
361
372
|
|
|
362
373
|
var newFnName = me.getPlaceholder();
|
package/src/transforms/minify.ts
CHANGED
|
@@ -8,7 +8,12 @@ import {
|
|
|
8
8
|
isUndefined,
|
|
9
9
|
} from "../utils/ast-utils";
|
|
10
10
|
import { Binding, Scope } from "@babel/traverse";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
NO_REMOVE,
|
|
13
|
+
NodeSymbol,
|
|
14
|
+
placeholderVariablePrefix,
|
|
15
|
+
UNSAFE,
|
|
16
|
+
} from "../constants";
|
|
12
17
|
|
|
13
18
|
const identifierMap = new Map<string, () => t.Expression>();
|
|
14
19
|
identifierMap.set("undefined", () =>
|
|
@@ -120,6 +125,19 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
120
125
|
}
|
|
121
126
|
},
|
|
122
127
|
},
|
|
128
|
+
// "a" + "b" -> "ab"
|
|
129
|
+
BinaryExpression: {
|
|
130
|
+
exit(path) {
|
|
131
|
+
if (path.node.operator !== "+") return;
|
|
132
|
+
|
|
133
|
+
const left = path.get("left");
|
|
134
|
+
const right = path.get("right");
|
|
135
|
+
|
|
136
|
+
if (!left.isStringLiteral() || !right.isStringLiteral()) return;
|
|
137
|
+
|
|
138
|
+
path.replaceWith(t.stringLiteral(left.node.value + right.node.value));
|
|
139
|
+
},
|
|
140
|
+
},
|
|
123
141
|
// a["key"] -> a.key
|
|
124
142
|
MemberExpression: {
|
|
125
143
|
exit(path) {
|
|
@@ -215,7 +233,8 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
215
233
|
const id = path.get("id");
|
|
216
234
|
if (
|
|
217
235
|
id.isIdentifier() &&
|
|
218
|
-
!id.node.name.startsWith(placeholderVariablePrefix)
|
|
236
|
+
!id.node.name.startsWith(placeholderVariablePrefix) &&
|
|
237
|
+
!(path.node as NodeSymbol)[NO_REMOVE]
|
|
219
238
|
) {
|
|
220
239
|
const binding = path.scope.getBinding(id.node.name);
|
|
221
240
|
if (
|
|
@@ -285,6 +304,9 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
285
304
|
const fn = getParentFunctionOrProgram(path);
|
|
286
305
|
if ((fn.node as NodeSymbol)[UNSAFE]) return;
|
|
287
306
|
|
|
307
|
+
// Node explicitly marked as not to be removed
|
|
308
|
+
if ((id as NodeSymbol)[NO_REMOVE]) return;
|
|
309
|
+
|
|
288
310
|
const binding = path.scope.getBinding(id.node.name);
|
|
289
311
|
|
|
290
312
|
if (
|
|
@@ -2,9 +2,8 @@ import { PluginArg, PluginObject } from "./plugin";
|
|
|
2
2
|
import { Order } from "../order";
|
|
3
3
|
import { NodePath } from "@babel/traverse";
|
|
4
4
|
import * as t from "@babel/types";
|
|
5
|
-
import { getBlock } from "../utils/ast-utils";
|
|
6
5
|
import { chance, getRandomString } from "../utils/random-utils";
|
|
7
|
-
import
|
|
6
|
+
import PredicateGen from "../utils/PredicateGen";
|
|
8
7
|
|
|
9
8
|
export default ({ Plugin }: PluginArg): PluginObject => {
|
|
10
9
|
const me = Plugin(Order.OpaquePredicates, {
|
|
@@ -13,12 +12,10 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
13
12
|
},
|
|
14
13
|
});
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
const controlObject = me.getControlObject(getBlock(path));
|
|
18
|
-
|
|
19
|
-
var trueValue = controlObject.createTruePredicate();
|
|
15
|
+
const predicateGen = new PredicateGen(me);
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
function createTruePredicate(path: NodePath) {
|
|
18
|
+
return predicateGen.generateTrueExpression(path);
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
let active = true;
|
|
@@ -27,7 +24,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
27
24
|
if (!active) return false;
|
|
28
25
|
if (path.find((p) => me.isSkipped(p))) return false;
|
|
29
26
|
|
|
30
|
-
if (!computeProbabilityMap(me.options.opaquePredicates)) return false;
|
|
27
|
+
if (!me.computeProbabilityMap(me.options.opaquePredicates)) return false;
|
|
31
28
|
|
|
32
29
|
transformCount++;
|
|
33
30
|
|
package/src/transforms/pack.ts
CHANGED
|
@@ -55,8 +55,14 @@ export default function pack({ Plugin }: PluginArg): PluginObject {
|
|
|
55
55
|
if (reservedIdentifiers.has(identifierName)) return;
|
|
56
56
|
if (me.obfuscator.options.globalVariables.has(identifierName)) return;
|
|
57
57
|
if (identifierName === variableFunctionName) return;
|
|
58
|
+
if (identifierName === objectName) return;
|
|
58
59
|
|
|
59
60
|
if (!path.scope.hasGlobal(identifierName)) return;
|
|
61
|
+
if (path.scope.hasBinding(identifierName)) return;
|
|
62
|
+
|
|
63
|
+
// Check user's custom implementation
|
|
64
|
+
if (!me.computeProbabilityMap(me.options.pack, identifierName))
|
|
65
|
+
return;
|
|
60
66
|
|
|
61
67
|
if (
|
|
62
68
|
path.key === "argument" &&
|
package/src/transforms/plugin.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { NodePath, Visitor } from "@babel/traverse";
|
|
2
2
|
import Obfuscator from "../obfuscator";
|
|
3
|
-
import {
|
|
3
|
+
import { getRandomString } from "../utils/random-utils";
|
|
4
4
|
import { Order } from "../order";
|
|
5
5
|
import * as t from "@babel/types";
|
|
6
|
-
import { FN_LENGTH, NodeSymbol, SKIP
|
|
6
|
+
import { FN_LENGTH, NodeSymbol, SKIP } from "../constants";
|
|
7
7
|
import { SetFunctionLengthTemplate } from "../templates/setFunctionLengthTemplate";
|
|
8
8
|
import { prepend, prependProgram } from "../utils/ast-utils";
|
|
9
|
-
import ControlObject from "../utils/ControlObject";
|
|
10
|
-
import { ok } from "assert";
|
|
11
9
|
import { numericLiteral } from "../utils/node";
|
|
12
10
|
|
|
13
11
|
export interface PluginObject {
|
|
@@ -30,9 +28,14 @@ export class PluginInstance {
|
|
|
30
28
|
constructor(
|
|
31
29
|
public pluginOptions: { name?: string; order?: number },
|
|
32
30
|
public obfuscator: Obfuscator
|
|
33
|
-
) {
|
|
31
|
+
) {
|
|
32
|
+
this.computeProbabilityMap = obfuscator.computeProbabilityMap.bind(
|
|
33
|
+
this.obfuscator
|
|
34
|
+
);
|
|
35
|
+
}
|
|
34
36
|
|
|
35
37
|
public changeData: { [key: string]: number } = {};
|
|
38
|
+
public computeProbabilityMap: Obfuscator["computeProbabilityMap"];
|
|
36
39
|
|
|
37
40
|
get name() {
|
|
38
41
|
return this.pluginOptions.name || "unnamed";
|
|
@@ -74,43 +77,48 @@ export class PluginInstance {
|
|
|
74
77
|
setFunctionLength(path: NodePath<t.Function>, originalLength: number) {
|
|
75
78
|
(path.node as NodeSymbol)[FN_LENGTH] = originalLength;
|
|
76
79
|
|
|
77
|
-
//
|
|
78
|
-
if (this.options.preserveFunctionLength
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
} else if (
|
|
102
|
-
t.isFunctionExpression(path.node) ||
|
|
103
|
-
t.isArrowFunctionExpression(path.node)
|
|
104
|
-
) {
|
|
105
|
-
path.replaceWith(
|
|
80
|
+
// Skip if user disabled this feature
|
|
81
|
+
if (!this.options.preserveFunctionLength) return;
|
|
82
|
+
|
|
83
|
+
// Skip if function has no parameters
|
|
84
|
+
if (originalLength === 0) return;
|
|
85
|
+
|
|
86
|
+
// Create the function length setter if it doesn't exist
|
|
87
|
+
if (!this.setFunctionLengthName) {
|
|
88
|
+
this.setFunctionLengthName = this.getPlaceholder("fnLength");
|
|
89
|
+
|
|
90
|
+
this.skip(
|
|
91
|
+
prependProgram(
|
|
92
|
+
path,
|
|
93
|
+
SetFunctionLengthTemplate.compile({
|
|
94
|
+
fnName: this.setFunctionLengthName,
|
|
95
|
+
})
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (t.isFunctionDeclaration(path.node)) {
|
|
101
|
+
prepend(
|
|
102
|
+
path.parentPath,
|
|
103
|
+
t.expressionStatement(
|
|
106
104
|
t.callExpression(t.identifier(this.setFunctionLengthName), [
|
|
107
|
-
path.node,
|
|
105
|
+
t.identifier(path.node.id.name),
|
|
108
106
|
numericLiteral(originalLength),
|
|
109
107
|
])
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
108
|
+
)
|
|
109
|
+
);
|
|
110
|
+
} else if (
|
|
111
|
+
t.isFunctionExpression(path.node) ||
|
|
112
|
+
t.isArrowFunctionExpression(path.node)
|
|
113
|
+
) {
|
|
114
|
+
path.replaceWith(
|
|
115
|
+
t.callExpression(t.identifier(this.setFunctionLengthName), [
|
|
116
|
+
path.node,
|
|
117
|
+
numericLiteral(originalLength),
|
|
118
|
+
])
|
|
119
|
+
);
|
|
120
|
+
} else {
|
|
121
|
+
// TODO
|
|
114
122
|
}
|
|
115
123
|
}
|
|
116
124
|
|
|
@@ -125,36 +133,6 @@ export class PluginInstance {
|
|
|
125
133
|
return "__p_" + getRandomString(4) + (suffix ? "_" + suffix : "");
|
|
126
134
|
}
|
|
127
135
|
|
|
128
|
-
/**
|
|
129
|
-
* Retrieves (or creates) a `ControlObject` for the given `blockPath`.
|
|
130
|
-
*/
|
|
131
|
-
getControlObject(blockPath: NodePath<t.Block>, createMultiple = true) {
|
|
132
|
-
ok(blockPath.isBlock());
|
|
133
|
-
|
|
134
|
-
var controlObjects = (blockPath.node as NodeSymbol)[CONTROL_OBJECTS];
|
|
135
|
-
if (!controlObjects) {
|
|
136
|
-
controlObjects = [];
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
controlObjects.length === 0 ||
|
|
141
|
-
(createMultiple &&
|
|
142
|
-
chance(
|
|
143
|
-
controlObjects[0].propertyNames.size - 15 * controlObjects.length
|
|
144
|
-
))
|
|
145
|
-
) {
|
|
146
|
-
var newControlObject = new ControlObject(this, blockPath);
|
|
147
|
-
|
|
148
|
-
controlObjects.push(newControlObject);
|
|
149
|
-
|
|
150
|
-
(blockPath.node as NodeSymbol)[CONTROL_OBJECTS] = controlObjects;
|
|
151
|
-
|
|
152
|
-
return newControlObject;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return choice(controlObjects);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
136
|
/**
|
|
159
137
|
* Logs a message to the console, only if `verbose` is enabled.
|
|
160
138
|
* @param messages
|
|
@@ -4,7 +4,6 @@ import { PluginArg, PluginObject } from "./plugin";
|
|
|
4
4
|
import { Order } from "../order";
|
|
5
5
|
import { NameGen } from "../utils/NameGen";
|
|
6
6
|
import { ok } from "assert";
|
|
7
|
-
import { computeProbabilityMap } from "../probability";
|
|
8
7
|
|
|
9
8
|
const LABEL = Symbol("label");
|
|
10
9
|
|
|
@@ -127,7 +126,7 @@ export default function ({ Plugin }: PluginArg): PluginObject {
|
|
|
127
126
|
if (isRequired) {
|
|
128
127
|
var newName = labelInterface.label;
|
|
129
128
|
if (
|
|
130
|
-
computeProbabilityMap(
|
|
129
|
+
me.computeProbabilityMap(
|
|
131
130
|
me.options.renameLabels,
|
|
132
131
|
labelInterface.label
|
|
133
132
|
)
|