js-confuser 2.0.0-alpha.4 → 2.0.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/workflows/node.js.yml +1 -1
- package/CHANGELOG.md +10 -12
- package/Migration.md +2 -1
- package/README.md +20 -12
- package/dist/constants.js +2 -4
- package/dist/index.js +6 -1
- package/dist/transforms/controlFlowFlattening.js +92 -64
- package/dist/transforms/lock/integrity.js +3 -1
- package/dist/transforms/lock/lock.js +1 -1
- package/dist/transforms/pack.js +4 -0
- package/dist/transforms/plugin.js +12 -3
- package/dist/transforms/string/stringConcealing.js +7 -1
- package/dist/utils/ast-utils.js +15 -33
- package/package.json +2 -2
- package/src/constants.ts +2 -2
- package/src/index.ts +6 -1
- package/src/templates/integrityTemplate.ts +1 -1
- package/src/transforms/controlFlowFlattening.ts +116 -86
- package/src/transforms/flatten.ts +0 -2
- package/src/transforms/lock/integrity.ts +5 -2
- package/src/transforms/lock/lock.ts +1 -8
- package/src/transforms/pack.ts +8 -0
- package/src/transforms/plugin.ts +19 -9
- package/src/transforms/string/stringConcealing.ts +15 -1
- package/src/utils/ast-utils.ts +10 -21
|
@@ -107,7 +107,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
107
107
|
// Breaks any code formatter
|
|
108
108
|
var namedFunction = function(){
|
|
109
109
|
const test = function(){
|
|
110
|
-
const regExp=new RegExp('\\n');
|
|
110
|
+
const regExp= new RegExp('\\n');
|
|
111
111
|
return regExp['test'](namedFunction)
|
|
112
112
|
};
|
|
113
113
|
|
|
@@ -116,13 +116,6 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
// Prepack Breaker
|
|
120
|
-
if(Math.random() > 1) {
|
|
121
|
-
while(true) {
|
|
122
|
-
console.log("Prepack Breaker");
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
119
|
return namedFunction();
|
|
127
120
|
}
|
|
128
121
|
)();
|
package/src/transforms/pack.ts
CHANGED
|
@@ -60,6 +60,14 @@ export default function pack({ Plugin }: PluginArg): PluginObject {
|
|
|
60
60
|
// Ensure bindings are removed -> variable becomes a global -> added to mappings object
|
|
61
61
|
path.scope.crawl();
|
|
62
62
|
},
|
|
63
|
+
|
|
64
|
+
// TODO: Add support for export statements
|
|
65
|
+
"ExportNamedDeclaration|ExportDefaultDeclaration|ExportAllDeclaration"(
|
|
66
|
+
path
|
|
67
|
+
) {
|
|
68
|
+
me.error("Export statements are not supported in packed code.");
|
|
69
|
+
},
|
|
70
|
+
|
|
63
71
|
Program(path) {
|
|
64
72
|
path.scope.crawl();
|
|
65
73
|
},
|
package/src/transforms/plugin.ts
CHANGED
|
@@ -97,14 +97,24 @@ export class PluginInstance {
|
|
|
97
97
|
);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
const createCallArguments = (node: t.Expression): t.Expression[] => {
|
|
101
|
+
var args = [node];
|
|
102
|
+
|
|
103
|
+
// 1 is the default value in the setFunction template, can exclude it
|
|
104
|
+
if (originalLength !== 1) {
|
|
105
|
+
args.push(numericLiteral(originalLength));
|
|
106
|
+
}
|
|
107
|
+
return args;
|
|
108
|
+
};
|
|
109
|
+
|
|
100
110
|
if (t.isFunctionDeclaration(path.node)) {
|
|
101
111
|
prepend(
|
|
102
112
|
path.parentPath,
|
|
103
113
|
t.expressionStatement(
|
|
104
|
-
t.callExpression(
|
|
105
|
-
t.identifier(
|
|
106
|
-
|
|
107
|
-
|
|
114
|
+
t.callExpression(
|
|
115
|
+
t.identifier(this.setFunctionLengthName),
|
|
116
|
+
createCallArguments(t.identifier(path.node.id.name))
|
|
117
|
+
)
|
|
108
118
|
)
|
|
109
119
|
);
|
|
110
120
|
} else if (
|
|
@@ -112,10 +122,10 @@ export class PluginInstance {
|
|
|
112
122
|
t.isArrowFunctionExpression(path.node)
|
|
113
123
|
) {
|
|
114
124
|
path.replaceWith(
|
|
115
|
-
t.callExpression(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
t.callExpression(
|
|
126
|
+
t.identifier(this.setFunctionLengthName),
|
|
127
|
+
createCallArguments(path.node)
|
|
128
|
+
)
|
|
119
129
|
);
|
|
120
130
|
} else {
|
|
121
131
|
// TODO
|
|
@@ -158,6 +168,6 @@ export class PluginInstance {
|
|
|
158
168
|
* @param messages
|
|
159
169
|
*/
|
|
160
170
|
error(...messages: any[]): never {
|
|
161
|
-
throw new Error(`[${this.name}] ${messages.join("
|
|
171
|
+
throw new Error(`[${this.name}] ${messages.join(" ")}`);
|
|
162
172
|
}
|
|
163
173
|
}
|
|
@@ -45,6 +45,7 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
45
45
|
const blocks: NodePath<t.Block>[] = [];
|
|
46
46
|
const stringMap = new Map<string, number>();
|
|
47
47
|
const stringArrayName = me.getPlaceholder() + "_array";
|
|
48
|
+
const stringArrayCacheName = me.getPlaceholder() + "_cache";
|
|
48
49
|
|
|
49
50
|
let encodingImplementations: { [identity: string]: CustomStringEncoding } =
|
|
50
51
|
Object.create(null);
|
|
@@ -263,6 +264,16 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
263
264
|
])
|
|
264
265
|
);
|
|
265
266
|
|
|
267
|
+
// Create the string cache
|
|
268
|
+
prependProgram(
|
|
269
|
+
programPath,
|
|
270
|
+
new Template(`
|
|
271
|
+
var {stringArrayCacheName} = {};
|
|
272
|
+
`).single({
|
|
273
|
+
stringArrayCacheName,
|
|
274
|
+
})
|
|
275
|
+
);
|
|
276
|
+
|
|
266
277
|
for (var block of blocks) {
|
|
267
278
|
const { encodingImplementation, fnName } = (
|
|
268
279
|
block.node as NodeStringConcealing
|
|
@@ -283,7 +294,10 @@ export default ({ Plugin }: PluginArg): PluginObject => {
|
|
|
283
294
|
// The main function to get the string value
|
|
284
295
|
const retrieveFunctionDeclaration = new Template(`
|
|
285
296
|
function ${fnName}(index) {
|
|
286
|
-
|
|
297
|
+
if (typeof ${stringArrayCacheName}[index] === 'undefined') {
|
|
298
|
+
return ${stringArrayCacheName}[index] = ${decodeFnName}(${stringArrayName}[index]);
|
|
299
|
+
}
|
|
300
|
+
return ${stringArrayCacheName}[index];
|
|
287
301
|
}
|
|
288
302
|
`)
|
|
289
303
|
.addSymbols(NO_REMOVE)
|
package/src/utils/ast-utils.ts
CHANGED
|
@@ -215,17 +215,6 @@ export function getMemberExpressionPropertyAsString(
|
|
|
215
215
|
return null; // If the property cannot be determined
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
function registerPaths(paths: NodePath[]) {
|
|
219
|
-
for (var path of paths) {
|
|
220
|
-
if (path.isVariableDeclaration() && path.node.kind === "var") {
|
|
221
|
-
getParentFunctionOrProgram(path).scope.registerDeclaration(path);
|
|
222
|
-
}
|
|
223
|
-
path.scope.registerDeclaration(path);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return paths;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
218
|
function nodeListToNodes(nodesIn: (t.Statement | t.Statement[])[]) {
|
|
230
219
|
var nodes: t.Statement[] = [];
|
|
231
220
|
if (Array.isArray(nodesIn[0])) {
|
|
@@ -257,12 +246,12 @@ export function append(
|
|
|
257
246
|
if (listParent.isProgram()) {
|
|
258
247
|
var lastExpression = listParent.get("body").at(-1);
|
|
259
248
|
if (lastExpression.isExpressionStatement()) {
|
|
260
|
-
return
|
|
249
|
+
return lastExpression.insertBefore(nodes);
|
|
261
250
|
}
|
|
262
251
|
}
|
|
263
252
|
|
|
264
253
|
if (listParent.isSwitchCase()) {
|
|
265
|
-
return
|
|
254
|
+
return listParent.pushContainer("consequent", nodes);
|
|
266
255
|
}
|
|
267
256
|
|
|
268
257
|
if (listParent.isFunction()) {
|
|
@@ -278,11 +267,11 @@ export function append(
|
|
|
278
267
|
|
|
279
268
|
ok(body.isBlockStatement());
|
|
280
269
|
|
|
281
|
-
return
|
|
270
|
+
return body.pushContainer("body", nodes);
|
|
282
271
|
}
|
|
283
272
|
|
|
284
273
|
ok(listParent.isBlock());
|
|
285
|
-
return
|
|
274
|
+
return listParent.pushContainer("body", nodes);
|
|
286
275
|
}
|
|
287
276
|
|
|
288
277
|
/**
|
|
@@ -322,11 +311,11 @@ export function prepend(
|
|
|
322
311
|
|
|
323
312
|
if (afterImport === 0) {
|
|
324
313
|
// No import declarations, so we can safely unshift everything
|
|
325
|
-
return
|
|
314
|
+
return listParent.unshiftContainer("body", nodes);
|
|
326
315
|
}
|
|
327
316
|
|
|
328
317
|
// Insert the nodes after the last import declaration
|
|
329
|
-
return
|
|
318
|
+
return body[afterImport - 1].insertAfter(nodes);
|
|
330
319
|
}
|
|
331
320
|
|
|
332
321
|
if (listParent.isFunction()) {
|
|
@@ -342,15 +331,15 @@ export function prepend(
|
|
|
342
331
|
|
|
343
332
|
ok(body.isBlockStatement());
|
|
344
333
|
|
|
345
|
-
return
|
|
334
|
+
return body.unshiftContainer("body", nodes);
|
|
346
335
|
}
|
|
347
336
|
|
|
348
337
|
if (listParent.isBlock()) {
|
|
349
|
-
return
|
|
338
|
+
return listParent.unshiftContainer("body", nodes);
|
|
350
339
|
}
|
|
351
340
|
|
|
352
341
|
if (listParent.isSwitchCase()) {
|
|
353
|
-
return
|
|
342
|
+
return listParent.unshiftContainer("consequent", nodes);
|
|
354
343
|
}
|
|
355
344
|
|
|
356
345
|
ok(false);
|
|
@@ -564,7 +553,7 @@ export function isModifiedIdentifier(identifierPath: NodePath<t.Identifier>) {
|
|
|
564
553
|
|
|
565
554
|
export function replaceDefiningIdentifierToMemberExpression(
|
|
566
555
|
path: NodePath<t.Identifier>,
|
|
567
|
-
memberExpression: t.MemberExpression
|
|
556
|
+
memberExpression: t.MemberExpression | t.Identifier
|
|
568
557
|
) {
|
|
569
558
|
// function id(){} -> var id = function() {}
|
|
570
559
|
if (path.key === "id" && path.parentPath.isFunctionDeclaration()) {
|