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,186 +1,186 @@
1
- import { NodePath } from "@babel/traverse";
2
- import { PluginArg, PluginObject } from "../plugin";
3
- import { Order } from "../../order";
4
- import * as t from "@babel/types";
5
- import {
6
- getMemberExpressionPropertyAsString,
7
- getObjectPropertyAsString,
8
- getParentFunctionOrProgram,
9
- } from "../../utils/ast-utils";
10
-
11
- export default ({ Plugin }: PluginArg): PluginObject => {
12
- const me = Plugin(Order.ObjectExtraction, {
13
- changeData: {
14
- objects: 0,
15
- },
16
- });
17
-
18
- return {
19
- visitor: {
20
- Program: {
21
- enter(path) {
22
- path.scope.crawl();
23
- },
24
- },
25
- VariableDeclaration(varDecPath) {
26
- if (varDecPath.node.declarations.length !== 1) return;
27
- const declaration = varDecPath.get(
28
- "declarations.0"
29
- ) as NodePath<t.VariableDeclarator>;
30
-
31
- // Must be simple variable declaration (No destructuring)
32
- const identifier = declaration.get("id");
33
- if (!identifier.isIdentifier()) return;
34
-
35
- // Must be an object expression
36
- const objectExpression = declaration.get("init");
37
- if (!objectExpression.isObjectExpression()) return;
38
-
39
- // Not allowed to reassign the object
40
- const binding = varDecPath.scope.getBinding(identifier.node.name);
41
- if (!binding || binding.constantViolations.length > 0) return;
42
-
43
- var pendingReplacements: {
44
- path: NodePath<t.MemberExpression>;
45
- replaceWith: t.Expression;
46
- }[] = [];
47
-
48
- const newObjectName = me.getPlaceholder() + "_" + identifier.node.name;
49
- const newPropertyMappings = new Map<string, string>();
50
-
51
- // Create new property names from the original object properties
52
- var newDeclarations: t.VariableDeclarator[] = [];
53
- for (var property of objectExpression.get("properties")) {
54
- if (!property.isObjectProperty()) return;
55
- const propertyKey = getObjectPropertyAsString(property.node);
56
- if (!propertyKey) {
57
- // Property key is not a static string, not allowed
58
- return;
59
- }
60
-
61
- let newPropertyName = newPropertyMappings.get(propertyKey);
62
- if (newPropertyName) {
63
- // Duplicate property, not allowed
64
- return;
65
- } else {
66
- newPropertyName =
67
- newObjectName +
68
- "_" +
69
- (t.isValidIdentifier(propertyKey)
70
- ? propertyKey
71
- : me.getPlaceholder());
72
- newPropertyMappings.set(propertyKey, newPropertyName);
73
- }
74
-
75
- // Check function for referencing 'this'
76
- const value = property.get("value");
77
- if (value.isFunction()) {
78
- var referencesThis = false;
79
-
80
- value.traverse({
81
- ThisExpression(thisPath) {
82
- referencesThis = true;
83
- },
84
- });
85
-
86
- if (referencesThis) {
87
- // Function references 'this', not allowed
88
- // When extracted, this will not refer to the original object
89
- return;
90
- }
91
- }
92
-
93
- newDeclarations.push(
94
- t.variableDeclarator(
95
- t.identifier(newPropertyName),
96
- value.node as t.Expression
97
- )
98
- );
99
- }
100
-
101
- var isObjectSafe = true;
102
-
103
- getParentFunctionOrProgram(varDecPath).traverse({
104
- Identifier: {
105
- exit(idPath) {
106
- if (idPath.node.name !== identifier.node.name) return;
107
- if (idPath === identifier) return; // Skip the original declaration
108
-
109
- const memberExpression = idPath.parentPath;
110
- if (!memberExpression || !memberExpression.isMemberExpression()) {
111
- isObjectSafe = false;
112
- return;
113
- }
114
- const property = getMemberExpressionPropertyAsString(
115
- memberExpression.node
116
- );
117
- if (!property) {
118
- isObjectSafe = false;
119
- return;
120
- }
121
-
122
- // Delete expression check
123
- if (
124
- memberExpression.parentPath.isUnaryExpression({
125
- operator: "delete",
126
- })
127
- ) {
128
- // Deleting object properties is not allowed
129
- isObjectSafe = false;
130
- return;
131
- }
132
-
133
- let newPropertyName = newPropertyMappings.get(property);
134
- if (!newPropertyName) {
135
- // Property added later on, not allowed
136
- isObjectSafe = false;
137
- return;
138
- }
139
-
140
- const extractedIdentifier = t.identifier(newPropertyName);
141
-
142
- pendingReplacements.push({
143
- path: memberExpression,
144
- replaceWith: extractedIdentifier,
145
- });
146
- },
147
- },
148
- });
149
-
150
- // Object references are too complex to safely extract
151
- if (!isObjectSafe) return;
152
-
153
- if (
154
- !me.computeProbabilityMap(
155
- me.options.objectExtraction,
156
- identifier.node.name
157
- )
158
- )
159
- return;
160
-
161
- const newDeclarationKind =
162
- varDecPath.node.kind === "const" ? "let" : varDecPath.node.kind;
163
-
164
- varDecPath
165
- .replaceWithMultiple(
166
- newDeclarations.map((declaration) =>
167
- t.variableDeclaration(newDeclarationKind, [declaration])
168
- )
169
- )
170
- .forEach((path) => {
171
- // Make sure to register the new declarations
172
- path.scope.registerDeclaration(path);
173
- });
174
-
175
- // Replace all references to new singular identifiers
176
- for (const { path, replaceWith } of pendingReplacements) {
177
- path.replaceWith(replaceWith);
178
- }
179
-
180
- me.log("Extracted object", identifier.node.name);
181
-
182
- me.changeData.objects++;
183
- },
184
- },
185
- };
186
- };
1
+ import { NodePath } from "@babel/traverse";
2
+ import { PluginArg, PluginObject } from "../plugin";
3
+ import { Order } from "../../order";
4
+ import * as t from "@babel/types";
5
+ import {
6
+ getMemberExpressionPropertyAsString,
7
+ getObjectPropertyAsString,
8
+ getParentFunctionOrProgram,
9
+ } from "../../utils/ast-utils";
10
+
11
+ export default ({ Plugin }: PluginArg): PluginObject => {
12
+ const me = Plugin(Order.ObjectExtraction, {
13
+ changeData: {
14
+ objects: 0,
15
+ },
16
+ });
17
+
18
+ return {
19
+ visitor: {
20
+ Program: {
21
+ enter(path) {
22
+ path.scope.crawl();
23
+ },
24
+ },
25
+ VariableDeclaration(varDecPath) {
26
+ if (varDecPath.node.declarations.length !== 1) return;
27
+ const declaration = varDecPath.get(
28
+ "declarations.0"
29
+ ) as NodePath<t.VariableDeclarator>;
30
+
31
+ // Must be simple variable declaration (No destructuring)
32
+ const identifier = declaration.get("id");
33
+ if (!identifier.isIdentifier()) return;
34
+
35
+ // Must be an object expression
36
+ const objectExpression = declaration.get("init");
37
+ if (!objectExpression.isObjectExpression()) return;
38
+
39
+ // Not allowed to reassign the object
40
+ const binding = varDecPath.scope.getBinding(identifier.node.name);
41
+ if (!binding || binding.constantViolations.length > 0) return;
42
+
43
+ var pendingReplacements: {
44
+ path: NodePath<t.MemberExpression>;
45
+ replaceWith: t.Expression;
46
+ }[] = [];
47
+
48
+ const newObjectName = me.getPlaceholder() + "_" + identifier.node.name;
49
+ const newPropertyMappings = new Map<string, string>();
50
+
51
+ // Create new property names from the original object properties
52
+ var newDeclarations: t.VariableDeclarator[] = [];
53
+ for (var property of objectExpression.get("properties")) {
54
+ if (!property.isObjectProperty()) return;
55
+ const propertyKey = getObjectPropertyAsString(property.node);
56
+ if (!propertyKey) {
57
+ // Property key is not a static string, not allowed
58
+ return;
59
+ }
60
+
61
+ let newPropertyName = newPropertyMappings.get(propertyKey);
62
+ if (newPropertyName) {
63
+ // Duplicate property, not allowed
64
+ return;
65
+ } else {
66
+ newPropertyName =
67
+ newObjectName +
68
+ "_" +
69
+ (t.isValidIdentifier(propertyKey)
70
+ ? propertyKey
71
+ : me.getPlaceholder());
72
+ newPropertyMappings.set(propertyKey, newPropertyName);
73
+ }
74
+
75
+ // Check function for referencing 'this'
76
+ const value = property.get("value");
77
+ if (value.isFunction()) {
78
+ var referencesThis = false;
79
+
80
+ value.traverse({
81
+ ThisExpression(thisPath) {
82
+ referencesThis = true;
83
+ },
84
+ });
85
+
86
+ if (referencesThis) {
87
+ // Function references 'this', not allowed
88
+ // When extracted, this will not refer to the original object
89
+ return;
90
+ }
91
+ }
92
+
93
+ newDeclarations.push(
94
+ t.variableDeclarator(
95
+ t.identifier(newPropertyName),
96
+ value.node as t.Expression
97
+ )
98
+ );
99
+ }
100
+
101
+ var isObjectSafe = true;
102
+
103
+ getParentFunctionOrProgram(varDecPath).traverse({
104
+ Identifier: {
105
+ exit(idPath) {
106
+ if (idPath.node.name !== identifier.node.name) return;
107
+ if (idPath === identifier) return; // Skip the original declaration
108
+
109
+ const memberExpression = idPath.parentPath;
110
+ if (!memberExpression || !memberExpression.isMemberExpression()) {
111
+ isObjectSafe = false;
112
+ return;
113
+ }
114
+ const property = getMemberExpressionPropertyAsString(
115
+ memberExpression.node
116
+ );
117
+ if (!property) {
118
+ isObjectSafe = false;
119
+ return;
120
+ }
121
+
122
+ // Delete expression check
123
+ if (
124
+ memberExpression.parentPath.isUnaryExpression({
125
+ operator: "delete",
126
+ })
127
+ ) {
128
+ // Deleting object properties is not allowed
129
+ isObjectSafe = false;
130
+ return;
131
+ }
132
+
133
+ let newPropertyName = newPropertyMappings.get(property);
134
+ if (!newPropertyName) {
135
+ // Property added later on, not allowed
136
+ isObjectSafe = false;
137
+ return;
138
+ }
139
+
140
+ const extractedIdentifier = t.identifier(newPropertyName);
141
+
142
+ pendingReplacements.push({
143
+ path: memberExpression,
144
+ replaceWith: extractedIdentifier,
145
+ });
146
+ },
147
+ },
148
+ });
149
+
150
+ // Object references are too complex to safely extract
151
+ if (!isObjectSafe) return;
152
+
153
+ if (
154
+ !me.computeProbabilityMap(
155
+ me.options.objectExtraction,
156
+ identifier.node.name
157
+ )
158
+ )
159
+ return;
160
+
161
+ const newDeclarationKind =
162
+ varDecPath.node.kind === "const" ? "let" : varDecPath.node.kind;
163
+
164
+ varDecPath
165
+ .replaceWithMultiple(
166
+ newDeclarations.map((declaration) =>
167
+ t.variableDeclaration(newDeclarationKind, [declaration])
168
+ )
169
+ )
170
+ .forEach((path) => {
171
+ // Make sure to register the new declarations
172
+ path.scope.registerDeclaration(path);
173
+ });
174
+
175
+ // Replace all references to new singular identifiers
176
+ for (const { path, replaceWith } of pendingReplacements) {
177
+ path.replaceWith(replaceWith);
178
+ }
179
+
180
+ me.log("Extracted object", identifier.node.name);
181
+
182
+ me.changeData.objects++;
183
+ },
184
+ },
185
+ };
186
+ };
@@ -1,74 +1,74 @@
1
- import { PluginArg, PluginObject } from "./plugin";
2
- import * as t from "@babel/types";
3
- import { Order } from "../order";
4
- import stringEncoding from "./string/stringEncoding";
5
- import { GEN_NODE, NodeSymbol, variableFunctionName } from "../constants";
6
- import { ok } from "assert";
7
-
8
- export default ({ Plugin }: PluginArg): PluginObject => {
9
- const me = Plugin(Order.Finalizer);
10
- const stringEncodingPlugin = stringEncoding(me);
11
-
12
- return {
13
- visitor: {
14
- // String encoding
15
- ...stringEncodingPlugin.visitor,
16
-
17
- // Backup __JS_CONFUSER_VAR__ replacement
18
- // While done in Preparation, Rename Variables
19
- // This accounts for when Rename Variables is disabled and an inserted Template adds __JS_CONFUSER_VAR__ calls
20
- ...(me.obfuscator.hasPlugin(Order.RenameVariables)
21
- ? {}
22
- : {
23
- CallExpression: {
24
- exit(path) {
25
- if (
26
- path.get("callee").isIdentifier({
27
- name: variableFunctionName,
28
- })
29
- ) {
30
- var args = path.get("arguments");
31
- ok(args.length === 1);
32
-
33
- var arg = args[0];
34
- ok(arg.isIdentifier());
35
-
36
- var name = arg.node.name;
37
- path.replaceWith(t.stringLiteral(name));
38
- }
39
- },
40
- },
41
- }),
42
-
43
- // Hexadecimal numbers
44
- NumericLiteral: {
45
- exit(path) {
46
- if (me.options.hexadecimalNumbers) {
47
- const { value } = path.node;
48
-
49
- if (
50
- Number.isNaN(value) ||
51
- !Number.isFinite(value) ||
52
- Math.floor(value) !== value
53
- ) {
54
- return;
55
- }
56
-
57
- // Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
58
- // This code handles it regardless
59
- var isNegative = value < 0;
60
- var hex = Math.abs(value).toString(16);
61
-
62
- var newStr = (isNegative ? "-" : "") + "0x" + hex;
63
-
64
- var id = t.identifier(newStr);
65
- (id as NodeSymbol)[GEN_NODE] = true;
66
-
67
- path.replaceWith(id);
68
- path.skip();
69
- }
70
- },
71
- },
72
- },
73
- };
74
- };
1
+ import { PluginArg, PluginObject } from "./plugin";
2
+ import * as t from "@babel/types";
3
+ import { Order } from "../order";
4
+ import stringEncoding from "./string/stringEncoding";
5
+ import { GEN_NODE, NodeSymbol, variableFunctionName } from "../constants";
6
+ import { ok } from "assert";
7
+
8
+ export default ({ Plugin }: PluginArg): PluginObject => {
9
+ const me = Plugin(Order.Finalizer);
10
+ const stringEncodingPlugin = stringEncoding(me);
11
+
12
+ return {
13
+ visitor: {
14
+ // String encoding
15
+ ...stringEncodingPlugin.visitor,
16
+
17
+ // Backup __JS_CONFUSER_VAR__ replacement
18
+ // While done in Preparation, Rename Variables
19
+ // This accounts for when Rename Variables is disabled and an inserted Template adds __JS_CONFUSER_VAR__ calls
20
+ ...(me.obfuscator.hasPlugin(Order.RenameVariables)
21
+ ? {}
22
+ : {
23
+ CallExpression: {
24
+ exit(path) {
25
+ if (
26
+ path.get("callee").isIdentifier({
27
+ name: variableFunctionName,
28
+ })
29
+ ) {
30
+ var args = path.get("arguments");
31
+ ok(args.length === 1);
32
+
33
+ var arg = args[0];
34
+ ok(arg.isIdentifier());
35
+
36
+ var name = arg.node.name;
37
+ path.replaceWith(t.stringLiteral(name));
38
+ }
39
+ },
40
+ },
41
+ }),
42
+
43
+ // Hexadecimal numbers
44
+ NumericLiteral: {
45
+ exit(path) {
46
+ if (me.options.hexadecimalNumbers) {
47
+ const { value } = path.node;
48
+
49
+ if (
50
+ Number.isNaN(value) ||
51
+ !Number.isFinite(value) ||
52
+ Math.floor(value) !== value
53
+ ) {
54
+ return;
55
+ }
56
+
57
+ // Technically, a Literal will never be negative because it's supposed to be inside a UnaryExpression with a "-" operator.
58
+ // This code handles it regardless
59
+ var isNegative = value < 0;
60
+ var hex = Math.abs(value).toString(16);
61
+
62
+ var newStr = (isNegative ? "-" : "") + "0x" + hex;
63
+
64
+ var id = t.identifier(newStr);
65
+ (id as NodeSymbol)[GEN_NODE] = true;
66
+
67
+ path.replaceWith(id);
68
+ path.skip();
69
+ }
70
+ },
71
+ },
72
+ },
73
+ };
74
+ };