@dacely/toildefender 0.1.0 → 0.1.2

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.
@@ -1,185 +1,185 @@
1
- "use strict";
2
-
3
- var assert = require("assert");
4
-
5
- var _ = require("lodash");
6
-
7
- var estest = require("../estest");
8
- var ESUtils = require("../esutils");
9
- var traverser = require("../traverser");
10
- var utils = require("../utils");
11
-
12
- module.exports = class Variables {
13
-
14
- constructor (logger) {
15
- this.logger = logger;
16
- this.esutils = new ESUtils(logger);
17
- }
18
-
19
- /**
20
- * Removes the id property from FunctionExpressions.
21
- * They trip up functionDeclarationToExpression and escope (?),
22
- * causing scopes.js to incorrectly rename some references.
23
- * @param {Node} ast Root node
24
- * @returns {Node} Root node
25
- */
26
- removeFunctionExpressionIds (ast) {
27
- return traverser.traverse(ast, [], (node, stack) => {
28
- if (node.type == "FunctionExpression" && node.id) {
29
- node.id = null;
30
- }
31
- return node;
32
- });
33
- }
34
-
35
- /**
36
- * Converts function declarations like
37
- * function test() { ... }
38
- * to function expression variables like
39
- * var test = function() { ... };
40
- * @param {Node} ast Root node
41
- * @param {ScopeManager} scopeManager Scope manager
42
- */
43
- functionDeclarationToExpression (ast, scopeManager) {
44
- assert.ok(estest.isNode(ast));
45
-
46
- this.esutils.setParentsRecursive(ast);
47
-
48
- scopeManager.scopes.forEach(scope => {
49
- scope.variables.forEach(variable => {
50
- variable.defs.forEach(def => {
51
- if (def.type == "FunctionName") {
52
- assert(estest.isFunction(def.node));
53
- /**
54
- * Here you have to ensure that def.node is statement.
55
- * Expressions like { foo: function() { ... }} are parsed
56
- * as a FunctionExpression with an id, which are then
57
- * mistakingly replaced with EmptyStatements.
58
- */
59
- if (estest.isStatement(def.node)) {
60
- this.esutils.replaceNode(ast, def.node, { type: "EmptyStatement" });
61
- this.esutils.insertIntoScope(scope, {
62
- type: "VariableDeclaration",
63
- kind: "var",
64
- declarations: [
65
- {
66
- type: "VariableDeclarator",
67
- id: def.node.id,
68
- init: {
69
- type: "FunctionExpression",
70
- params: def.node.params,
71
- body: def.node.body
72
- }
73
- }
74
- ]
75
- });
76
- }
77
- }
78
- });
79
- });
80
- });
81
- }
82
-
83
- /**
84
- * Renames identifiers with unique names, e.g.
85
- * var a, b = 5;
86
- * to
87
- * var $$var$123$a, $$var$123$b = 5;
88
- * @param {Node} ast Root node
89
- * @param {ScopeManager} scopeManager Scope manager
90
- */
91
- obfuscateIdentifiers (ast, scopeManager) {
92
- scopeManager.scopes.forEach(scope => {
93
- if (scope.isStatic()) {
94
- scope.variables.sort((a, b) => {
95
- if (a.tainted) {
96
- return 1;
97
- }
98
- if (b.tainted) {
99
- return -1;
100
- }
101
- return (b.identifiers.length + b.references.length) - (a.identifiers.length + a.references.length);
102
- });
103
-
104
- for (let variable of scope.variables) {
105
- var name = "$$var$" + utils.hash(variable) + "$" + variable.name;
106
-
107
- if (variable.tainted) {
108
- continue;
109
- }
110
-
111
- if (variable.identifiers.length === 0) {
112
- // do not change names since this is a special name
113
- continue;
114
- }
115
-
116
- for (let def of variable.identifiers) {
117
- // change definition's name
118
- def.name = name;
119
- }
120
-
121
- for (let ref of variable.references) {
122
- // change reference's name
123
- ref.identifier.name = name;
124
- }
125
- }
126
- }
127
- });
128
- }
129
-
130
- /**
131
- * Replaces direct parameter references like
132
- * function (a) {
133
- * return a;
134
- * }
135
- * to copys like
136
- * function (a) {
137
- * var $$arg$abc = a;
138
- * return $$arg$abc;
139
- * }
140
- * @param {Node} ast Root node
141
- * @param {ScopeManager} scopeManager Scope manager
142
- */
143
- redefineParameters (ast, scopeManager) {
144
- function getArgumentIndex(method, identifier) {
145
- assert(method.type == "FunctionDeclaration" || method.type == "FunctionExpression");
146
- assert(identifier.type == "Identifier");
147
- for (var i = 0; i < method.params.length; ++i) {
148
- if (method.params[i].name == identifier.name) {
149
- return i;
150
- }
151
- }
152
- return -1;
153
- }
154
-
155
- var rng = new utils.UniqueRandomAlpha(3);
156
-
157
- scopeManager.scopes.forEach(scope => {
158
- scope.variables.forEach(variable => {
159
- variable.defs.forEach(def => {
160
- if (def.type == "Parameter") {
161
- assert(def.name.type == "Identifier");
162
- var name = "$$arg$" + rng.get();
163
-
164
- this.esutils.insertIntoScope(scope, {
165
- type: "VariableDeclaration",
166
- kind: "var",
167
- declarations: [
168
- {
169
- type: "VariableDeclarator",
170
- id: { type: "Identifier", name: name },
171
- init: def.name
172
- }
173
- ]
174
- });
175
-
176
- variable.references.forEach(reference => {
177
- reference.identifier.name = name;
178
- });
179
- }
180
- });
181
- });
182
- });
183
- }
184
-
185
- };
1
+ "use strict";
2
+
3
+ var assert = require("assert");
4
+
5
+ var _ = require("lodash");
6
+
7
+ var estest = require("../estest");
8
+ var ESUtils = require("../esutils");
9
+ var traverser = require("../traverser");
10
+ var utils = require("../utils");
11
+
12
+ module.exports = class Variables {
13
+
14
+ constructor (logger) {
15
+ this.logger = logger;
16
+ this.esutils = new ESUtils(logger);
17
+ }
18
+
19
+ /**
20
+ * Removes the id property from FunctionExpressions.
21
+ * They trip up functionDeclarationToExpression and escope (?),
22
+ * causing scopes.js to incorrectly rename some references.
23
+ * @param {Node} ast Root node
24
+ * @returns {Node} Root node
25
+ */
26
+ removeFunctionExpressionIds (ast) {
27
+ return traverser.traverse(ast, [], (node, stack) => {
28
+ if (node.type == "FunctionExpression" && node.id) {
29
+ node.id = null;
30
+ }
31
+ return node;
32
+ });
33
+ }
34
+
35
+ /**
36
+ * Converts function declarations like
37
+ * function test() { ... }
38
+ * to function expression variables like
39
+ * var test = function() { ... };
40
+ * @param {Node} ast Root node
41
+ * @param {ScopeManager} scopeManager Scope manager
42
+ */
43
+ functionDeclarationToExpression (ast, scopeManager) {
44
+ assert.ok(estest.isNode(ast));
45
+
46
+ this.esutils.setParentsRecursive(ast);
47
+
48
+ scopeManager.scopes.forEach(scope => {
49
+ scope.variables.forEach(variable => {
50
+ variable.defs.forEach(def => {
51
+ if (def.type == "FunctionName") {
52
+ assert(estest.isFunction(def.node));
53
+ /**
54
+ * Here you have to ensure that def.node is statement.
55
+ * Expressions like { foo: function() { ... }} are parsed
56
+ * as a FunctionExpression with an id, which are then
57
+ * mistakingly replaced with EmptyStatements.
58
+ */
59
+ if (estest.isStatement(def.node)) {
60
+ this.esutils.replaceNode(ast, def.node, { type: "EmptyStatement" });
61
+ this.esutils.insertIntoScope(scope, {
62
+ type: "VariableDeclaration",
63
+ kind: "var",
64
+ declarations: [
65
+ {
66
+ type: "VariableDeclarator",
67
+ id: def.node.id,
68
+ init: {
69
+ type: "FunctionExpression",
70
+ params: def.node.params,
71
+ body: def.node.body
72
+ }
73
+ }
74
+ ]
75
+ });
76
+ }
77
+ }
78
+ });
79
+ });
80
+ });
81
+ }
82
+
83
+ /**
84
+ * Renames identifiers with unique names, e.g.
85
+ * var a, b = 5;
86
+ * to
87
+ * var $$var$123$a, $$var$123$b = 5;
88
+ * @param {Node} ast Root node
89
+ * @param {ScopeManager} scopeManager Scope manager
90
+ */
91
+ obfuscateIdentifiers (ast, scopeManager) {
92
+ scopeManager.scopes.forEach(scope => {
93
+ if (scope.isStatic()) {
94
+ scope.variables.sort((a, b) => {
95
+ if (a.tainted) {
96
+ return 1;
97
+ }
98
+ if (b.tainted) {
99
+ return -1;
100
+ }
101
+ return (b.identifiers.length + b.references.length) - (a.identifiers.length + a.references.length);
102
+ });
103
+
104
+ for (let variable of scope.variables) {
105
+ var name = "$$var$" + utils.hash(variable) + "$" + variable.name;
106
+
107
+ if (variable.tainted) {
108
+ continue;
109
+ }
110
+
111
+ if (variable.identifiers.length === 0) {
112
+ // do not change names since this is a special name
113
+ continue;
114
+ }
115
+
116
+ for (let def of variable.identifiers) {
117
+ // change definition's name
118
+ def.name = name;
119
+ }
120
+
121
+ for (let ref of variable.references) {
122
+ // change reference's name
123
+ ref.identifier.name = name;
124
+ }
125
+ }
126
+ }
127
+ });
128
+ }
129
+
130
+ /**
131
+ * Replaces direct parameter references like
132
+ * function (a) {
133
+ * return a;
134
+ * }
135
+ * to copys like
136
+ * function (a) {
137
+ * var $$arg$abc = a;
138
+ * return $$arg$abc;
139
+ * }
140
+ * @param {Node} ast Root node
141
+ * @param {ScopeManager} scopeManager Scope manager
142
+ */
143
+ redefineParameters (ast, scopeManager) {
144
+ function getArgumentIndex(method, identifier) {
145
+ assert(method.type == "FunctionDeclaration" || method.type == "FunctionExpression");
146
+ assert(identifier.type == "Identifier");
147
+ for (var i = 0; i < method.params.length; ++i) {
148
+ if (method.params[i].name == identifier.name) {
149
+ return i;
150
+ }
151
+ }
152
+ return -1;
153
+ }
154
+
155
+ var rng = new utils.UniqueRandomAlpha(3);
156
+
157
+ scopeManager.scopes.forEach(scope => {
158
+ scope.variables.forEach(variable => {
159
+ variable.defs.forEach(def => {
160
+ if (def.type == "Parameter") {
161
+ assert(def.name.type == "Identifier");
162
+ var name = "$$arg$" + rng.get();
163
+
164
+ this.esutils.insertIntoScope(scope, {
165
+ type: "VariableDeclaration",
166
+ kind: "var",
167
+ declarations: [
168
+ {
169
+ type: "VariableDeclarator",
170
+ id: { type: "Identifier", name: name },
171
+ init: def.name
172
+ }
173
+ ]
174
+ });
175
+
176
+ variable.references.forEach(reference => {
177
+ reference.identifier.name = name;
178
+ });
179
+ }
180
+ });
181
+ });
182
+ });
183
+ }
184
+
185
+ };
package/toildefender.js CHANGED
@@ -1,7 +1,7 @@
1
- #!/usr/bin/env node
2
-
3
- if (require.main === module) {
4
- require("./cli").run();
5
- } else {
6
- module.exports = require("./obfuscator");
7
- }
1
+ #!/usr/bin/env node
2
+
3
+ if (require.main === module) {
4
+ require("./cli").run();
5
+ } else {
6
+ module.exports = require("./obfuscator");
7
+ }
package/traverser.js CHANGED
@@ -1,115 +1,115 @@
1
- "use strict";
2
-
3
- var assert = require("assert");
4
-
5
- var estraverse = require("estraverse");
6
-
7
- var estest = require("./estest");
8
- var utils = require("./utils");
9
-
10
- // Depth-first
11
- exports.traverse = function (node, stack, processor) {
12
- assert.ok(estest.isNode(node));
13
- assert.ok(Array.isArray(stack));
14
- assert.equal(typeof processor, "function");
15
-
16
- exports.visitChildren(node, (child, key) => {
17
- return exports.traverse(child, [ { node: node, key: key } ].concat(stack), processor);
18
- });
19
-
20
- return processor(node, [ { node: node } ].concat(stack));
21
- };
22
-
23
- // Breadth-first
24
- exports.traverseEx = function (node, stack, processor) {
25
- assert.ok(estest.isNode(node));
26
- assert.ok(Array.isArray(stack));
27
- assert.equal(typeof processor, "function");
28
-
29
- var abort = false;
30
- var controller = {
31
- abort: function() {
32
- abort = true;
33
- }
34
- };
35
-
36
- var queue = [];
37
- exports.visitChildrenEx(node, (child, key) => {
38
- var repl = processor.call(controller, child, [ { node: node } ].concat(stack));
39
- if (repl == child) {
40
- queue.push({
41
- child: child,
42
- key: key
43
- });
44
- }
45
- return repl;
46
- });
47
- if (!abort) {
48
- queue.every(elem => {
49
- exports.traverseEx.call(controller, elem.child, [ { node: node, key: elem.key } ].concat(stack), processor);
50
- return !abort;
51
- });
52
- }
53
- return node;
54
- };
55
-
56
- exports.visitChildren = function (node, processor) {
57
- assert.ok(estest.isNode(node));
58
- assert.equal(typeof processor, "function");
59
-
60
- var keys = estraverse.VisitorKeys[node.type] || [];
61
- keys.forEach(key => {
62
- if (Array.isArray(node[key])) {
63
- node[key] = node[key].map(x => {
64
- if (x == null) {
65
- return x;
66
- }
67
- var repl = processor(x, key);
68
- assert(repl);
69
- return repl;
70
- });
71
- } else if (node[key]) {
72
- var repl = processor(node[key], key);
73
- assert(repl);
74
- node[key] = repl;
75
- }
76
- });
77
- };
78
-
79
- exports.visitChildrenEx = function (node, processor) {
80
- assert.ok(estest.isNode(node));
81
- assert.equal(typeof processor, "function");
82
-
83
- var keys = estraverse.VisitorKeys[node.type] || [];
84
- keys.forEach(key => {
85
- if (Array.isArray(node[key])) {
86
- let i = node[key].length;
87
- while (i--) {
88
- if (node[key][i] == null) {
89
- continue;
90
- }
91
- let replacement = processor(node[key][i], key);
92
- assert(replacement);
93
- if (replacement.length == 1) {
94
- replacement = replacement[0];
95
- }
96
- if (Array.isArray(replacement)) {
97
- utils.splice(node[key], i, 1, replacement);
98
- } else {
99
- node[key][i] = replacement;
100
- }
101
- }
102
- } else if (node[key]) {
103
- let replacement = processor(node[key], key);
104
- assert(replacement);
105
- if (replacement.length == 1) {
106
- replacement = replacement[0];
107
- }
108
- if (Array.isArray(replacement)) {
109
- throw new Error("Cannot use array here: " + node.type + "." + key + "\n" + JSON.stringify(node) + "\n" + JSON.stringify(replacement));
110
- } else {
111
- node[key] = replacement;
112
- }
113
- }
114
- });
115
- };
1
+ "use strict";
2
+
3
+ var assert = require("assert");
4
+
5
+ var estraverse = require("estraverse");
6
+
7
+ var estest = require("./estest");
8
+ var utils = require("./utils");
9
+
10
+ // Depth-first
11
+ exports.traverse = function (node, stack, processor) {
12
+ assert.ok(estest.isNode(node));
13
+ assert.ok(Array.isArray(stack));
14
+ assert.equal(typeof processor, "function");
15
+
16
+ exports.visitChildren(node, (child, key) => {
17
+ return exports.traverse(child, [ { node: node, key: key } ].concat(stack), processor);
18
+ });
19
+
20
+ return processor(node, [ { node: node } ].concat(stack));
21
+ };
22
+
23
+ // Breadth-first
24
+ exports.traverseEx = function (node, stack, processor) {
25
+ assert.ok(estest.isNode(node));
26
+ assert.ok(Array.isArray(stack));
27
+ assert.equal(typeof processor, "function");
28
+
29
+ var abort = false;
30
+ var controller = {
31
+ abort: function() {
32
+ abort = true;
33
+ }
34
+ };
35
+
36
+ var queue = [];
37
+ exports.visitChildrenEx(node, (child, key) => {
38
+ var repl = processor.call(controller, child, [ { node: node } ].concat(stack));
39
+ if (repl == child) {
40
+ queue.push({
41
+ child: child,
42
+ key: key
43
+ });
44
+ }
45
+ return repl;
46
+ });
47
+ if (!abort) {
48
+ queue.every(elem => {
49
+ exports.traverseEx.call(controller, elem.child, [ { node: node, key: elem.key } ].concat(stack), processor);
50
+ return !abort;
51
+ });
52
+ }
53
+ return node;
54
+ };
55
+
56
+ exports.visitChildren = function (node, processor) {
57
+ assert.ok(estest.isNode(node));
58
+ assert.equal(typeof processor, "function");
59
+
60
+ var keys = estraverse.VisitorKeys[node.type] || [];
61
+ keys.forEach(key => {
62
+ if (Array.isArray(node[key])) {
63
+ node[key] = node[key].map(x => {
64
+ if (x == null) {
65
+ return x;
66
+ }
67
+ var repl = processor(x, key);
68
+ assert(repl);
69
+ return repl;
70
+ });
71
+ } else if (node[key]) {
72
+ var repl = processor(node[key], key);
73
+ assert(repl);
74
+ node[key] = repl;
75
+ }
76
+ });
77
+ };
78
+
79
+ exports.visitChildrenEx = function (node, processor) {
80
+ assert.ok(estest.isNode(node));
81
+ assert.equal(typeof processor, "function");
82
+
83
+ var keys = estraverse.VisitorKeys[node.type] || [];
84
+ keys.forEach(key => {
85
+ if (Array.isArray(node[key])) {
86
+ let i = node[key].length;
87
+ while (i--) {
88
+ if (node[key][i] == null) {
89
+ continue;
90
+ }
91
+ let replacement = processor(node[key][i], key);
92
+ assert(replacement);
93
+ if (replacement.length == 1) {
94
+ replacement = replacement[0];
95
+ }
96
+ if (Array.isArray(replacement)) {
97
+ utils.splice(node[key], i, 1, replacement);
98
+ } else {
99
+ node[key][i] = replacement;
100
+ }
101
+ }
102
+ } else if (node[key]) {
103
+ let replacement = processor(node[key], key);
104
+ assert(replacement);
105
+ if (replacement.length == 1) {
106
+ replacement = replacement[0];
107
+ }
108
+ if (Array.isArray(replacement)) {
109
+ throw new Error("Cannot use array here: " + node.type + "." + key + "\n" + JSON.stringify(node) + "\n" + JSON.stringify(replacement));
110
+ } else {
111
+ node[key] = replacement;
112
+ }
113
+ }
114
+ });
115
+ };