@dacely/toildefender 0.1.6 → 0.1.7
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/README.md +1 -1
- package/esutils.js +12 -8
- package/obfuscator.js +101 -12
- package/package.json +1 -1
- package/processors/deadCode.js +32 -0
- package/processors/flattener.js +73 -8
- package/processors/identifiers.js +26 -6
- package/processors/literals.js +82 -2
- package/processors/methods.js +47 -34
- package/processors/modules.js +2 -2
- package/processors/normalizer.js +435 -69
- package/processors/numericVm.js +270 -83
- package/processors/postprocessing.js +4 -4
- package/processors/scopes.js +366 -50
- package/processors/uglifier.js +22 -2
- package/processors/variables.js +51 -8
package/processors/methods.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const METHODS_INJECT = `
|
|
4
|
-
function
|
|
4
|
+
function toildefender$mergeArguments(a, b) {
|
|
5
5
|
return Array.prototype.slice.call(a).concat(Array.prototype.slice.call(b));
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
function
|
|
8
|
+
function toildefender$bind() {
|
|
9
9
|
var fn = arguments[0], prepend = Array.prototype.slice.call(arguments, 1);
|
|
10
10
|
var wrapper = function() {
|
|
11
11
|
return fn.apply(this, prepend.concat(Array.prototype.slice.call(arguments)));
|
|
@@ -14,13 +14,13 @@ function veilmark$bind() {
|
|
|
14
14
|
return wrapper;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
function
|
|
17
|
+
function toildefender$sliceArguments(args, num) {
|
|
18
18
|
return Array.prototype.slice.call(args, num);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var toildefender$objectKeys = {};
|
|
22
22
|
|
|
23
|
-
function
|
|
23
|
+
function toildefender$toObject(cacheKey, schema, values) {
|
|
24
24
|
if (values === undefined && Array.isArray(cacheKey)) {
|
|
25
25
|
values = schema;
|
|
26
26
|
schema = cacheKey;
|
|
@@ -33,7 +33,7 @@ function veilmark$toObject(cacheKey, schema, values) {
|
|
|
33
33
|
}
|
|
34
34
|
return obj;
|
|
35
35
|
}
|
|
36
|
-
var decoded = cacheKey ?
|
|
36
|
+
var decoded = cacheKey ? toildefender$objectKeys[cacheKey] : null;
|
|
37
37
|
if (decoded) {
|
|
38
38
|
for (var cached = 0; cached < decoded.length; cached += 1) {
|
|
39
39
|
obj[decoded[cached]] = values[cached];
|
|
@@ -54,12 +54,12 @@ function veilmark$toObject(cacheKey, schema, values) {
|
|
|
54
54
|
obj[key] = values[i];
|
|
55
55
|
}
|
|
56
56
|
if (cacheKey) {
|
|
57
|
-
|
|
57
|
+
toildefender$objectKeys[cacheKey] = keys;
|
|
58
58
|
}
|
|
59
59
|
return obj;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function
|
|
62
|
+
function toildefender$objectWithoutKeys(source, excluded) {
|
|
63
63
|
var target = {};
|
|
64
64
|
if (source == null) {
|
|
65
65
|
return target;
|
|
@@ -72,11 +72,11 @@ function veilmark$objectWithoutKeys(source, excluded) {
|
|
|
72
72
|
return target;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
function
|
|
75
|
+
function toildefender$decodeString(arr) {
|
|
76
76
|
return arr.map(function(x) { return String.fromCharCode(x & ~0 >>> 16) + String.fromCharCode(x >> 16); }).join("");
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function
|
|
79
|
+
function toildefender$fromCharCodes() {
|
|
80
80
|
return String.fromCharCode.apply(null, arguments);
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -93,10 +93,10 @@ var estest = require("../estest");
|
|
|
93
93
|
var traverser = require("../traverser");
|
|
94
94
|
var utils = require("../utils");
|
|
95
95
|
|
|
96
|
-
const ANON_METHOD_ID = "
|
|
96
|
+
const ANON_METHOD_ID = "toildefender$anonymousMethodId";
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
* Wrap function with
|
|
99
|
+
* Wrap function with toildefender$bind.
|
|
100
100
|
* @param {Identifier} Function identifier
|
|
101
101
|
* @returns {Node} Wrapped function
|
|
102
102
|
*/
|
|
@@ -105,7 +105,7 @@ function createMethodStub(id) {
|
|
|
105
105
|
|
|
106
106
|
return {
|
|
107
107
|
type: "CallExpression",
|
|
108
|
-
callee: { type: "Identifier", name: "
|
|
108
|
+
callee: { type: "Identifier", name: "toildefender$bind" },
|
|
109
109
|
arguments: [
|
|
110
110
|
id
|
|
111
111
|
]
|
|
@@ -119,7 +119,7 @@ function anonymousMethodName(node) {
|
|
|
119
119
|
Object.defineProperty(node, ANON_METHOD_ID, {
|
|
120
120
|
configurable: false,
|
|
121
121
|
enumerable: false,
|
|
122
|
-
value: `
|
|
122
|
+
value: `toildefender$anon$${utils.hash(node)}`
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -134,7 +134,7 @@ function functionDeclarationName(node) {
|
|
|
134
134
|
Object.defineProperty(node, ANON_METHOD_ID, {
|
|
135
135
|
configurable: false,
|
|
136
136
|
enumerable: false,
|
|
137
|
-
value: `
|
|
137
|
+
value: `toildefender$anon$${utils.hash(node)}`
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
140
|
node.id = { type: "Identifier", name: node[ANON_METHOD_ID] };
|
|
@@ -194,6 +194,10 @@ function isClassMethodFunction(stack) {
|
|
|
194
194
|
return stack.some(frame => frame.node.type == "MethodDefinition" || frame.node.type == "ClassBody");
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
function isNumericVmInternalFunction(node, stack) {
|
|
198
|
+
return node.toildefender$numericVmInternal === true || stack.some(frame => frame.node && frame.node.toildefender$numericVmInternal === true);
|
|
199
|
+
}
|
|
200
|
+
|
|
197
201
|
/**
|
|
198
202
|
* Get index of argument in function.
|
|
199
203
|
* @param {Function} method Function
|
|
@@ -211,7 +215,7 @@ function rawArgumentsIdentifier() {
|
|
|
211
215
|
return {
|
|
212
216
|
type: "Identifier",
|
|
213
217
|
name: "arguments",
|
|
214
|
-
|
|
218
|
+
toildefender$rawArguments: true
|
|
215
219
|
};
|
|
216
220
|
}
|
|
217
221
|
|
|
@@ -252,7 +256,7 @@ module.exports = class Methods {
|
|
|
252
256
|
* Inserts code to copy/slice arguments from the arguments array like
|
|
253
257
|
* function () { ... }
|
|
254
258
|
* to
|
|
255
|
-
* function () { var
|
|
259
|
+
* function () { var toildefender$arguments = toildefender$sliceArguments(arguments, 1); ... }
|
|
256
260
|
* @param {Function} method
|
|
257
261
|
* @param {number} num Number of arguments to be sliced off. 0 if none.
|
|
258
262
|
*/
|
|
@@ -266,24 +270,24 @@ module.exports = class Methods {
|
|
|
266
270
|
declarations: [
|
|
267
271
|
{
|
|
268
272
|
type: "VariableDeclarator",
|
|
269
|
-
id: { type: "Identifier", name: "
|
|
273
|
+
id: { type: "Identifier", name: "toildefender$arguments" },
|
|
270
274
|
init: rawArgumentsIdentifier()
|
|
271
275
|
},
|
|
272
276
|
{
|
|
273
277
|
type: "VariableDeclarator",
|
|
274
|
-
id: { type: "Identifier", name: "
|
|
278
|
+
id: { type: "Identifier", name: "toildefender$bareArguments" },
|
|
275
279
|
init: num > 0 ? {
|
|
276
280
|
type: "CallExpression",
|
|
277
|
-
callee: { type: "Identifier", name: "
|
|
281
|
+
callee: { type: "Identifier", name: "toildefender$sliceArguments" },
|
|
278
282
|
arguments: [
|
|
279
283
|
rawArgumentsIdentifier(),
|
|
280
|
-
{ type: "Literal", value: num,
|
|
284
|
+
{ type: "Literal", value: num, toildefender$removeFirstArguments: true }
|
|
281
285
|
]
|
|
282
286
|
} : rawArgumentsIdentifier()
|
|
283
287
|
}
|
|
284
288
|
],
|
|
285
|
-
|
|
286
|
-
|
|
289
|
+
toildefender$reassigningArguments: true,
|
|
290
|
+
toildefender$followsSlicingArguments: num > 0
|
|
287
291
|
});
|
|
288
292
|
}
|
|
289
293
|
|
|
@@ -298,6 +302,9 @@ module.exports = class Methods {
|
|
|
298
302
|
var methods = [];
|
|
299
303
|
|
|
300
304
|
traverser.traverse(ast, [], (node, stack) => {
|
|
305
|
+
if (isNumericVmInternalFunction(node, stack)) {
|
|
306
|
+
return node;
|
|
307
|
+
}
|
|
301
308
|
if (node.type == "FunctionDeclaration") { // Statement
|
|
302
309
|
methods.push(functionDeclarationName(node));
|
|
303
310
|
} else if (node.type == "FunctionExpression" && !isClassMethodFunction(stack)) { // Expression
|
|
@@ -321,6 +328,9 @@ module.exports = class Methods {
|
|
|
321
328
|
var methods = [];
|
|
322
329
|
|
|
323
330
|
traverser.traverse(ast, [], (node, stack) => {
|
|
331
|
+
if (isNumericVmInternalFunction(node, stack)) {
|
|
332
|
+
return node;
|
|
333
|
+
}
|
|
324
334
|
if (node.type == "FunctionDeclaration") { // Statement
|
|
325
335
|
functionDeclarationName(node);
|
|
326
336
|
methods.push(node);
|
|
@@ -346,9 +356,9 @@ module.exports = class Methods {
|
|
|
346
356
|
* Replaces direct argument references with arguments references like
|
|
347
357
|
* function (a) { return a; }
|
|
348
358
|
* to
|
|
349
|
-
* function (a) { return
|
|
359
|
+
* function (a) { return toildefender$arguments[0]; }
|
|
350
360
|
* @param {Function} method Function whose body will be transformed
|
|
351
|
-
* @param {boolean} useReassignedVariable Use
|
|
361
|
+
* @param {boolean} useReassignedVariable Use toildefender$arguments instead of arguments
|
|
352
362
|
* @returns {Function} Function from method parameter
|
|
353
363
|
*/
|
|
354
364
|
replaceArgumentReferences (method, useReassignedVariable) {
|
|
@@ -357,14 +367,14 @@ module.exports = class Methods {
|
|
|
357
367
|
traverser.traverse(method.body, [], (node, stack) => {
|
|
358
368
|
if (node.type == "Identifier") {
|
|
359
369
|
var nestedFunction = stack.some(frame => estest.isFunction(frame.node));
|
|
360
|
-
if (useReassignedVariable && node.name == "arguments" && !node.
|
|
361
|
-
return { type: "Identifier", name: "
|
|
370
|
+
if (useReassignedVariable && node.name == "arguments" && !node.toildefender$rawArguments && !nestedFunction) {
|
|
371
|
+
return { type: "Identifier", name: "toildefender$bareArguments" };
|
|
362
372
|
}
|
|
363
373
|
var index = getArgumentIndex(method, node);
|
|
364
374
|
if (index != -1) {
|
|
365
375
|
return {
|
|
366
376
|
type: "MemberExpression",
|
|
367
|
-
object: { type: "Identifier", name: useReassignedVariable ? "
|
|
377
|
+
object: { type: "Identifier", name: useReassignedVariable ? "toildefender$arguments" : "arguments" },
|
|
368
378
|
property: { type: "Literal", value: index },
|
|
369
379
|
computed: true
|
|
370
380
|
};
|
|
@@ -383,7 +393,7 @@ module.exports = class Methods {
|
|
|
383
393
|
* Replaces function calls with main calls like
|
|
384
394
|
* test()
|
|
385
395
|
* to
|
|
386
|
-
*
|
|
396
|
+
* toildefender$bind(main, 1234)()
|
|
387
397
|
* @param {Node} ast Root node
|
|
388
398
|
* @param {Object[]} methodEntryExitPoints Method entry point table
|
|
389
399
|
* @param {number} methodEntryExitPoints[].entry Entry point
|
|
@@ -393,11 +403,14 @@ module.exports = class Methods {
|
|
|
393
403
|
assert.equal(typeof methodEntryExitPoints, "object");
|
|
394
404
|
|
|
395
405
|
traverser.traverse(ast, [], (node, stack) => {
|
|
406
|
+
if (isNumericVmInternalFunction(node, stack)) {
|
|
407
|
+
return node;
|
|
408
|
+
}
|
|
396
409
|
if (node.type == "Identifier" && methodEntryExitPoints[node.name] && methodEntryExitPoints[node.name].entry) {
|
|
397
410
|
var dispatcher = methodEntryExitPoints[node.name].dispatcher || "main";
|
|
398
411
|
return {
|
|
399
412
|
type: "CallExpression",
|
|
400
|
-
callee: { type: "Identifier", name: "
|
|
413
|
+
callee: { type: "Identifier", name: "toildefender$bind" },
|
|
401
414
|
arguments: [
|
|
402
415
|
{ type: "Identifier", name: dispatcher },
|
|
403
416
|
{ type: "Identifier", name: methodEntryExitPoints[node.name].entry }
|
|
@@ -410,9 +423,9 @@ module.exports = class Methods {
|
|
|
410
423
|
|
|
411
424
|
/**
|
|
412
425
|
* Bumps all arguments indices like
|
|
413
|
-
*
|
|
426
|
+
* toildefender$arguments[0]
|
|
414
427
|
* to
|
|
415
|
-
*
|
|
428
|
+
* toildefender$arguments[1]
|
|
416
429
|
* @param {Function} method Function whose body will be transformed
|
|
417
430
|
* @param {number} inc Number to be added to all argument indices
|
|
418
431
|
*/
|
|
@@ -421,10 +434,10 @@ module.exports = class Methods {
|
|
|
421
434
|
assert.equal(typeof inc, "number");
|
|
422
435
|
|
|
423
436
|
traverser.traverse(method.body, [], (node, stack) => {
|
|
424
|
-
if (node.type == "MemberExpression" && node.object.type == "Identifier" && node.object.name == "
|
|
437
|
+
if (node.type == "MemberExpression" && node.object.type == "Identifier" && node.object.name == "toildefender$arguments") {
|
|
425
438
|
node.property.value += inc;
|
|
426
439
|
}
|
|
427
|
-
if (node.
|
|
440
|
+
if (node.toildefender$removeFirstArguments) {
|
|
428
441
|
node.value += inc;
|
|
429
442
|
}
|
|
430
443
|
return node;
|
package/processors/modules.js
CHANGED
|
@@ -100,7 +100,7 @@ module.exports = class Modules {
|
|
|
100
100
|
scope.references
|
|
101
101
|
.filter(reference => !utils.isResolvedReference(reference))
|
|
102
102
|
.forEach(reference => {
|
|
103
|
-
var parent = reference.identifier.
|
|
103
|
+
var parent = reference.identifier.toildefender$parent;
|
|
104
104
|
|
|
105
105
|
if (reference.identifier.name == "exports") {
|
|
106
106
|
this.esutils.replaceNode(ast, reference.identifier, utils.cloneISwearIKnowWhatImDoing(replacement));
|
|
@@ -210,7 +210,7 @@ module.exports = class Modules {
|
|
|
210
210
|
|
|
211
211
|
]
|
|
212
212
|
},
|
|
213
|
-
|
|
213
|
+
toildefender$module: path
|
|
214
214
|
});
|
|
215
215
|
}
|
|
216
216
|
|