js-confuser 2.0.0-alpha.5 → 2.0.1

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.
Files changed (113) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +43 -43
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  3. package/.github/workflows/node.js.yml +28 -28
  4. package/.prettierrc +4 -4
  5. package/CHANGELOG.md +1015 -989
  6. package/CODE_OF_CONDUCT.md +131 -131
  7. package/CONTRIBUTING.md +52 -52
  8. package/LICENSE +21 -21
  9. package/Migration.md +72 -71
  10. package/README.md +86 -78
  11. package/dist/constants.js +43 -43
  12. package/dist/index.js +14 -23
  13. package/dist/obfuscator.js +31 -25
  14. package/dist/order.js +4 -4
  15. package/dist/presets.js +31 -31
  16. package/dist/templates/integrityTemplate.js +4 -4
  17. package/dist/templates/template.js +1 -2
  18. package/dist/transforms/astScrambler.js +1 -2
  19. package/dist/transforms/calculator.js +1 -2
  20. package/dist/transforms/controlFlowFlattening.js +93 -63
  21. package/dist/transforms/deadCode.js +1 -2
  22. package/dist/transforms/dispatcher.js +4 -5
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +1 -2
  24. package/dist/transforms/extraction/objectExtraction.js +1 -2
  25. package/dist/transforms/finalizer.js +1 -2
  26. package/dist/transforms/flatten.js +1 -2
  27. package/dist/transforms/identifier/globalConcealing.js +15 -2
  28. package/dist/transforms/identifier/movedDeclarations.js +8 -7
  29. package/dist/transforms/identifier/renameVariables.js +7 -7
  30. package/dist/transforms/lock/integrity.js +11 -10
  31. package/dist/transforms/lock/lock.js +2 -3
  32. package/dist/transforms/minify.js +11 -29
  33. package/dist/transforms/opaquePredicates.js +1 -2
  34. package/dist/transforms/pack.js +5 -2
  35. package/dist/transforms/plugin.js +18 -19
  36. package/dist/transforms/preparation.js +16 -16
  37. package/dist/transforms/renameLabels.js +1 -2
  38. package/dist/transforms/rgf.js +8 -9
  39. package/dist/transforms/shuffle.js +1 -2
  40. package/dist/transforms/string/encoding.js +1 -2
  41. package/dist/transforms/string/stringCompression.js +3 -4
  42. package/dist/transforms/string/stringConcealing.js +8 -3
  43. package/dist/transforms/string/stringEncoding.js +1 -2
  44. package/dist/transforms/variableMasking.js +1 -2
  45. package/dist/utils/NameGen.js +2 -2
  46. package/dist/utils/PredicateGen.js +1 -2
  47. package/dist/utils/ast-utils.js +87 -88
  48. package/dist/utils/function-utils.js +8 -8
  49. package/dist/utils/node.js +5 -6
  50. package/dist/utils/object-utils.js +4 -4
  51. package/dist/utils/random-utils.js +20 -20
  52. package/dist/utils/static-utils.js +1 -2
  53. package/dist/validateOptions.js +4 -7
  54. package/index.d.ts +17 -17
  55. package/package.json +61 -59
  56. package/src/constants.ts +168 -168
  57. package/src/index.ts +118 -118
  58. package/src/obfuscationResult.ts +49 -49
  59. package/src/obfuscator.ts +501 -497
  60. package/src/options.ts +407 -407
  61. package/src/order.ts +54 -54
  62. package/src/presets.ts +125 -125
  63. package/src/templates/bufferToStringTemplate.ts +57 -57
  64. package/src/templates/deadCodeTemplates.ts +1185 -1185
  65. package/src/templates/getGlobalTemplate.ts +76 -76
  66. package/src/templates/integrityTemplate.ts +64 -64
  67. package/src/templates/setFunctionLengthTemplate.ts +11 -11
  68. package/src/templates/stringCompressionTemplate.ts +20 -20
  69. package/src/templates/tamperProtectionTemplates.ts +120 -120
  70. package/src/templates/template.ts +224 -224
  71. package/src/transforms/astScrambler.ts +99 -99
  72. package/src/transforms/calculator.ts +99 -99
  73. package/src/transforms/controlFlowFlattening.ts +1716 -1664
  74. package/src/transforms/deadCode.ts +82 -82
  75. package/src/transforms/dispatcher.ts +450 -450
  76. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +156 -158
  77. package/src/transforms/extraction/objectExtraction.ts +186 -186
  78. package/src/transforms/finalizer.ts +74 -74
  79. package/src/transforms/flatten.ts +421 -420
  80. package/src/transforms/identifier/globalConcealing.ts +315 -295
  81. package/src/transforms/identifier/movedDeclarations.ts +252 -251
  82. package/src/transforms/identifier/renameVariables.ts +328 -321
  83. package/src/transforms/lock/integrity.ts +117 -114
  84. package/src/transforms/lock/lock.ts +418 -425
  85. package/src/transforms/minify.ts +615 -629
  86. package/src/transforms/opaquePredicates.ts +100 -100
  87. package/src/transforms/pack.ts +239 -231
  88. package/src/transforms/plugin.ts +173 -173
  89. package/src/transforms/preparation.ts +349 -347
  90. package/src/transforms/renameLabels.ts +175 -175
  91. package/src/transforms/rgf.ts +322 -322
  92. package/src/transforms/shuffle.ts +82 -82
  93. package/src/transforms/string/encoding.ts +144 -144
  94. package/src/transforms/string/stringCompression.ts +128 -128
  95. package/src/transforms/string/stringConcealing.ts +312 -298
  96. package/src/transforms/string/stringEncoding.ts +80 -80
  97. package/src/transforms/string/stringSplitting.ts +77 -77
  98. package/src/transforms/variableMasking.ts +257 -257
  99. package/src/utils/IntGen.ts +33 -33
  100. package/src/utils/NameGen.ts +116 -116
  101. package/src/utils/PredicateGen.ts +61 -61
  102. package/src/utils/ast-utils.ts +663 -663
  103. package/src/utils/function-utils.ts +50 -50
  104. package/src/utils/gen-utils.ts +48 -48
  105. package/src/utils/node.ts +78 -78
  106. package/src/utils/object-utils.ts +21 -21
  107. package/src/utils/random-utils.ts +93 -93
  108. package/src/utils/static-utils.ts +66 -66
  109. package/src/validateOptions.ts +256 -259
  110. package/tsconfig.json +13 -14
  111. package/dist/probability.js +0 -1
  112. package/dist/transforms/functionOutlining.js +0 -230
  113. package/dist/utils/ControlObject.js +0 -125
@@ -1,251 +1,252 @@
1
- import { NodePath } from "@babel/traverse";
2
- import { Order } from "../../order";
3
- import { PluginArg, PluginObject } from "../plugin";
4
- import { NodeSymbol, PREDICTABLE } from "../../constants";
5
- import * as t from "@babel/types";
6
- import { isStaticValue } from "../../utils/static-utils";
7
- import {
8
- getPatternIdentifierNames,
9
- isStrictMode,
10
- prepend,
11
- } from "../../utils/ast-utils";
12
- import Template from "../../templates/template";
13
-
14
- /**
15
- * Moved Declarations moves variables in two ways:
16
- *
17
- * 1) Move variables to top of the current block
18
- * 2) Move variables as unused function parameters
19
- */
20
- export default ({ Plugin }: PluginArg): PluginObject => {
21
- const me = Plugin(Order.MovedDeclarations, {
22
- changeData: {
23
- variableDeclarations: 0,
24
- functionParameters: 0,
25
- },
26
- });
27
-
28
- function isFunctionEligibleForParameterPacking(
29
- functionPath: NodePath<t.Function>,
30
- proposedParameterName: string
31
- ) {
32
- // Getter/setter functions must have zero or one formal parameter
33
- // We cannot add extra parameters to them
34
- if (functionPath.isObjectMethod() || functionPath.isClassMethod()) {
35
- if (functionPath.node.kind !== "method") {
36
- return false;
37
- }
38
- }
39
-
40
- // Rest params check
41
- if (functionPath.get("params").find((p) => p.isRestElement())) return false;
42
-
43
- // Max 1,000 parameters
44
- if (functionPath.get("params").length > 1_000) return false;
45
-
46
- // Check for duplicate parameter names
47
- var bindingIdentifiers = getPatternIdentifierNames(
48
- functionPath.get("params")
49
- );
50
-
51
- // Duplicate parameter name not allowed
52
- if (bindingIdentifiers.has(proposedParameterName)) return false;
53
-
54
- return true;
55
- }
56
-
57
- return {
58
- visitor: {
59
- FunctionDeclaration: {
60
- exit(path) {
61
- var functionPath = path.findParent((path) =>
62
- path.isFunction()
63
- ) as NodePath<t.Function>;
64
-
65
- if (!functionPath || !(functionPath.node as NodeSymbol)[PREDICTABLE])
66
- return;
67
-
68
- var fnBody = functionPath.get("body");
69
-
70
- if (!fnBody.isBlockStatement()) return;
71
-
72
- // Must be direct child of the function
73
- if (path.parentPath !== fnBody) return;
74
-
75
- const functionName = path.node.id.name;
76
-
77
- // Must be eligible for parameter packing
78
- if (
79
- !isFunctionEligibleForParameterPacking(functionPath, functionName)
80
- )
81
- return;
82
-
83
- var strictMode = isStrictMode(functionPath);
84
-
85
- // Default parameters are not allowed when 'use strict' is declared
86
- if (strictMode) return;
87
-
88
- var functionExpression = path.node as t.Node as t.FunctionExpression;
89
- functionExpression.type = "FunctionExpression";
90
- functionExpression.id = null;
91
-
92
- var identifier = t.identifier(functionName);
93
- functionPath.node.params.push(identifier);
94
-
95
- var paramPath = functionPath.get("params").at(-1);
96
-
97
- // Update binding to point to new path
98
- const binding = functionPath.scope.getBinding(functionName);
99
- if (binding) {
100
- binding.kind = "param";
101
- binding.path = paramPath;
102
- binding.identifier = identifier;
103
- }
104
-
105
- prepend(
106
- fnBody,
107
- new Template(`
108
- if(!${functionName}) {
109
- ${functionName} = {functionExpression};
110
- }
111
- `).single({ functionExpression: functionExpression })
112
- );
113
-
114
- path.remove();
115
- me.changeData.functionParameters++;
116
- },
117
- },
118
- VariableDeclaration: {
119
- exit(path) {
120
- if (me.isSkipped(path)) return;
121
- if (path.node.kind !== "var") return;
122
- if (path.node.declarations.length !== 1) return;
123
-
124
- var insertionMethod = "variableDeclaration";
125
- var functionPath = path.findParent((path) =>
126
- path.isFunction()
127
- ) as NodePath<t.Function>;
128
-
129
- const declaration = path.node.declarations[0];
130
- if (!t.isIdentifier(declaration.id)) return;
131
- const varName = declaration.id.name;
132
-
133
- var allowDefaultParamValue = true;
134
-
135
- if (functionPath && (functionPath.node as NodeSymbol)[PREDICTABLE]) {
136
- // Check for "use strict" directive
137
- // Strict mode disallows non-simple parameters
138
- // So we can't move the declaration to the function parameters
139
- var strictMode = isStrictMode(functionPath);
140
- if (strictMode) {
141
- allowDefaultParamValue = false;
142
- }
143
-
144
- // Cannot add variables after rest element
145
- // Cannot add over 1,000 parameters
146
- if (isFunctionEligibleForParameterPacking(functionPath, varName)) {
147
- insertionMethod = "functionParameter";
148
- }
149
- }
150
-
151
- const { name } = declaration.id;
152
- const value = declaration.init || t.identifier("undefined");
153
-
154
- const isStatic = isStaticValue(value);
155
- let isDefinedAtTop = false;
156
- const parentPath = path.parentPath;
157
- if (parentPath.isBlock()) {
158
- isDefinedAtTop =
159
- parentPath
160
- .get("body")
161
- .filter((x) => x.type !== "ImportDeclaration")
162
- .indexOf(path) === 0;
163
- }
164
-
165
- // Already at the top - nothing will change
166
- if (insertionMethod === "variableDeclaration" && isDefinedAtTop) {
167
- return;
168
- }
169
-
170
- let defaultParamValue: t.Expression;
171
-
172
- if (
173
- insertionMethod === "functionParameter" &&
174
- isStatic &&
175
- isDefinedAtTop &&
176
- allowDefaultParamValue
177
- ) {
178
- defaultParamValue = value;
179
- path.remove();
180
- } else {
181
- // For-in / For-of can only reference the variable name
182
- if (
183
- parentPath.isForInStatement() ||
184
- parentPath.isForOfStatement()
185
- ) {
186
- path.replaceWith(t.identifier(name));
187
- } else {
188
- path.replaceWith(
189
- t.assignmentExpression(
190
- "=",
191
- t.identifier(name),
192
- declaration.init || t.identifier("undefined")
193
- )
194
- );
195
- }
196
- }
197
-
198
- switch (insertionMethod) {
199
- case "functionParameter":
200
- var identifier = t.identifier(name);
201
-
202
- var param: t.Pattern | t.Identifier = identifier;
203
- if (allowDefaultParamValue && defaultParamValue) {
204
- param = t.assignmentPattern(param, defaultParamValue);
205
- }
206
-
207
- functionPath.node.params.push(param);
208
-
209
- var paramPath = functionPath.get("params").at(-1);
210
-
211
- // Update binding to point to new path
212
- const binding = functionPath.scope.getBinding(name);
213
- if (binding) {
214
- binding.kind = "param";
215
- binding.path = paramPath;
216
- binding.identifier = identifier;
217
- }
218
-
219
- me.changeData.functionParameters++;
220
- break;
221
- case "variableDeclaration":
222
- var block = path.findParent((path) =>
223
- path.isBlock()
224
- ) as NodePath<t.Block>;
225
-
226
- var topNode = block.node.body.filter(
227
- (x) => x.type !== "ImportDeclaration"
228
- )[0];
229
- const variableDeclarator = t.variableDeclarator(
230
- t.identifier(name)
231
- );
232
-
233
- if (t.isVariableDeclaration(topNode) && topNode.kind === "var") {
234
- topNode.declarations.push(variableDeclarator);
235
- break;
236
- } else {
237
- prepend(
238
- block,
239
- me.skip(t.variableDeclaration("var", [variableDeclarator]))
240
- );
241
- }
242
-
243
- me.changeData.variableDeclarations++;
244
-
245
- break;
246
- }
247
- },
248
- },
249
- },
250
- };
251
- };
1
+ import { NodePath } from "@babel/traverse";
2
+ import { Order } from "../../order";
3
+ import { PluginArg, PluginObject } from "../plugin";
4
+ import { NodeSymbol, PREDICTABLE } from "../../constants";
5
+ import * as t from "@babel/types";
6
+ import { isStaticValue } from "../../utils/static-utils";
7
+ import {
8
+ getPatternIdentifierNames,
9
+ isStrictMode,
10
+ prepend,
11
+ } from "../../utils/ast-utils";
12
+ import Template from "../../templates/template";
13
+
14
+ /**
15
+ * Moved Declarations moves variables in two ways:
16
+ *
17
+ * 1) Move variables to top of the current block
18
+ * 2) Move variables as unused function parameters
19
+ */
20
+ export default ({ Plugin }: PluginArg): PluginObject => {
21
+ const me = Plugin(Order.MovedDeclarations, {
22
+ changeData: {
23
+ variableDeclarations: 0,
24
+ functionParameters: 0,
25
+ },
26
+ });
27
+
28
+ function isFunctionEligibleForParameterPacking(
29
+ functionPath: NodePath<t.Function>,
30
+ proposedParameterName: string,
31
+ ) {
32
+ // Getter/setter functions must have zero or one formal parameter
33
+ // We cannot add extra parameters to them
34
+ if (functionPath.isObjectMethod() || functionPath.isClassMethod()) {
35
+ if (functionPath.node.kind !== "method") {
36
+ return false;
37
+ }
38
+ }
39
+
40
+ // Rest params check
41
+ if (functionPath.get("params").find((p) => p.isRestElement())) return false;
42
+
43
+ // Max 1,000 parameters
44
+ if (functionPath.get("params").length > 1_000) return false;
45
+
46
+ // Check for duplicate parameter names
47
+ var bindingIdentifiers = getPatternIdentifierNames(
48
+ functionPath.get("params"),
49
+ );
50
+
51
+ // Duplicate parameter name not allowed
52
+ if (bindingIdentifiers.has(proposedParameterName)) return false;
53
+
54
+ return true;
55
+ }
56
+
57
+ return {
58
+ visitor: {
59
+ FunctionDeclaration: {
60
+ exit(path) {
61
+ var functionPath = path.findParent((path) =>
62
+ path.isFunction(),
63
+ ) as NodePath<t.Function>;
64
+
65
+ if (!functionPath || !(functionPath.node as NodeSymbol)[PREDICTABLE])
66
+ return;
67
+
68
+ var fnBody = functionPath.get("body");
69
+
70
+ if (!fnBody.isBlockStatement()) return;
71
+
72
+ // Must be direct child of the function
73
+ if (path.parentPath !== fnBody) return;
74
+
75
+ const functionName = path.node.id.name;
76
+
77
+ // Must be eligible for parameter packing
78
+ if (
79
+ !isFunctionEligibleForParameterPacking(functionPath, functionName)
80
+ )
81
+ return;
82
+
83
+ var strictMode = isStrictMode(functionPath);
84
+
85
+ // Default parameters are not allowed when 'use strict' is declared
86
+ if (strictMode) return;
87
+
88
+ var functionExpression = path.node as t.Node as t.FunctionExpression;
89
+ functionExpression.type = "FunctionExpression";
90
+ functionExpression.id = null;
91
+
92
+ var identifier = t.identifier(functionName);
93
+ functionPath.node.params.push(identifier);
94
+
95
+ var paramPath = functionPath.get("params").at(-1);
96
+
97
+ // Update binding to point to new path
98
+ const binding = functionPath.scope.getBinding(functionName);
99
+ if (binding) {
100
+ binding.kind = "param";
101
+ binding.path = paramPath;
102
+ binding.identifier = identifier;
103
+ }
104
+
105
+ prepend(
106
+ fnBody,
107
+ new Template(`
108
+ if(!${functionName}) {
109
+ ${functionName} = {functionExpression};
110
+ }
111
+ `).single({ functionExpression: functionExpression }),
112
+ );
113
+
114
+ path.remove();
115
+ me.changeData.functionParameters++;
116
+ },
117
+ },
118
+ VariableDeclaration: {
119
+ exit(path) {
120
+ if (me.isSkipped(path)) return;
121
+ if (path.node.kind !== "var") return;
122
+ if (path.node.declarations.length !== 1) return;
123
+ if (path.parentPath?.isExportDeclaration()) return;
124
+
125
+ var insertionMethod = "variableDeclaration";
126
+ var functionPath = path.findParent((path) =>
127
+ path.isFunction(),
128
+ ) as NodePath<t.Function>;
129
+
130
+ const declaration = path.node.declarations[0];
131
+ if (!t.isIdentifier(declaration.id)) return;
132
+ const varName = declaration.id.name;
133
+
134
+ var allowDefaultParamValue = true;
135
+
136
+ if (functionPath && (functionPath.node as NodeSymbol)[PREDICTABLE]) {
137
+ // Check for "use strict" directive
138
+ // Strict mode disallows non-simple parameters
139
+ // So we can't move the declaration to the function parameters
140
+ var strictMode = isStrictMode(functionPath);
141
+ if (strictMode) {
142
+ allowDefaultParamValue = false;
143
+ }
144
+
145
+ // Cannot add variables after rest element
146
+ // Cannot add over 1,000 parameters
147
+ if (isFunctionEligibleForParameterPacking(functionPath, varName)) {
148
+ insertionMethod = "functionParameter";
149
+ }
150
+ }
151
+
152
+ const { name } = declaration.id;
153
+ const value = declaration.init || t.identifier("undefined");
154
+
155
+ const isStatic = isStaticValue(value);
156
+ let isDefinedAtTop = false;
157
+ const parentPath = path.parentPath;
158
+ if (parentPath.isBlock()) {
159
+ isDefinedAtTop =
160
+ parentPath
161
+ .get("body")
162
+ .filter((x) => x.type !== "ImportDeclaration")
163
+ .indexOf(path) === 0;
164
+ }
165
+
166
+ // Already at the top - nothing will change
167
+ if (insertionMethod === "variableDeclaration" && isDefinedAtTop) {
168
+ return;
169
+ }
170
+
171
+ let defaultParamValue: t.Expression;
172
+
173
+ if (
174
+ insertionMethod === "functionParameter" &&
175
+ isStatic &&
176
+ isDefinedAtTop &&
177
+ allowDefaultParamValue
178
+ ) {
179
+ defaultParamValue = value;
180
+ path.remove();
181
+ } else {
182
+ // For-in / For-of can only reference the variable name
183
+ if (
184
+ parentPath.isForInStatement() ||
185
+ parentPath.isForOfStatement()
186
+ ) {
187
+ path.replaceWith(t.identifier(name));
188
+ } else {
189
+ path.replaceWith(
190
+ t.assignmentExpression(
191
+ "=",
192
+ t.identifier(name),
193
+ declaration.init || t.identifier("undefined"),
194
+ ),
195
+ );
196
+ }
197
+ }
198
+
199
+ switch (insertionMethod) {
200
+ case "functionParameter":
201
+ var identifier = t.identifier(name);
202
+
203
+ var param: t.Pattern | t.Identifier = identifier;
204
+ if (allowDefaultParamValue && defaultParamValue) {
205
+ param = t.assignmentPattern(param, defaultParamValue);
206
+ }
207
+
208
+ functionPath.node.params.push(param);
209
+
210
+ var paramPath = functionPath.get("params").at(-1);
211
+
212
+ // Update binding to point to new path
213
+ const binding = functionPath.scope.getBinding(name);
214
+ if (binding) {
215
+ binding.kind = "param";
216
+ binding.path = paramPath;
217
+ binding.identifier = identifier;
218
+ }
219
+
220
+ me.changeData.functionParameters++;
221
+ break;
222
+ case "variableDeclaration":
223
+ var block = path.findParent((path) =>
224
+ path.isBlock(),
225
+ ) as NodePath<t.Block>;
226
+
227
+ var topNode = block.node.body.filter(
228
+ (x) => x.type !== "ImportDeclaration",
229
+ )[0];
230
+ const variableDeclarator = t.variableDeclarator(
231
+ t.identifier(name),
232
+ );
233
+
234
+ if (t.isVariableDeclaration(topNode) && topNode.kind === "var") {
235
+ topNode.declarations.push(variableDeclarator);
236
+ break;
237
+ } else {
238
+ prepend(
239
+ block,
240
+ me.skip(t.variableDeclaration("var", [variableDeclarator])),
241
+ );
242
+ }
243
+
244
+ me.changeData.variableDeclarations++;
245
+
246
+ break;
247
+ }
248
+ },
249
+ },
250
+ },
251
+ };
252
+ };