restringer
Advanced tools
Comparing version 1.1.4 to 1.1.5
{ | ||
"name": "restringer", | ||
"version": "1.1.4", | ||
"version": "1.1.5", | ||
"description": "Deobfuscate Javascript with emphasis on reconstructing strings", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
# Restringer | ||
[![Node.js CI](https://github.com/PerimeterX/restringer/actions/workflows/node.js.yml/badge.svg?branch=main)](https://github.com/PerimeterX/restringer/actions/workflows/node.js.yml) | ||
[![Downloads](https://img.shields.io/npm/dm/restringer.svg?maxAge=43200)](https://www.npmjs.com/package/restringer) | ||
Deobfuscate Javascript and reconstruct strings. | ||
@@ -71,7 +74,1 @@ Simplify cumbersome logic where possible while adhering to scope limitations. | ||
* [flAST](https://github.com/PerimeterX/flast/blob/main/README.md) | ||
*** | ||
## TODO | ||
- [ ] Replace environment variables with proper program arguments. | ||
- [ ] Create binary tool that can be installed via `npm install -g restringer` |
@@ -29,4 +29,6 @@ const {generateFlatAST} = require('flast'); | ||
// Extract just the function expression from the AST. | ||
const codeNode = generateFlatAST(`(function (${args}) {${c.arguments.slice(-1)[0].value}})`, {detailed: false})[2]; | ||
arb.markNode(c, codeNode); | ||
try { | ||
const codeNode = generateFlatAST(`(function (${args}) {${c.arguments.slice(-1)[0].value}})`, {detailed: false})[2]; | ||
if (codeNode) arb.markNode(c, codeNode); | ||
} catch {} | ||
} | ||
@@ -33,0 +35,0 @@ return arb; |
@@ -86,2 +86,12 @@ const {generateCode, parseCode} = require('flast'); | ||
} catch {} // Probably a native function | ||
break; | ||
case 'RegExp': | ||
newNode = { | ||
type: 'Literal', | ||
regex: { | ||
pattern: value.source, | ||
flags: value.flags, | ||
}, | ||
}; | ||
break; | ||
} | ||
@@ -88,0 +98,0 @@ } catch (e) { |
const {generateFlatAST} = require('flast'); | ||
const sortByNodeId = (a, b) => a.nodeId > b.nodeId ? 1 : b.nodeId > a.nodeId ? -1 : 0; | ||
/** | ||
@@ -12,7 +14,10 @@ * Return the source code of the ordered nodes. | ||
if (n.type === 'CallExpression') { | ||
if (n.parentNode.type === 'ExpressionStatement') nodes[idx] = n.parentNode; | ||
else if (n.callee.type === 'FunctionExpression') { | ||
if (n.parentNode.type === 'ExpressionStatement') { | ||
// noinspection JSValidateTypes | ||
nodes[idx] = n.parentNode; | ||
if (n.callee.type === 'FunctionExpression') nodes[idx].nodeId = 9999999; // Exceedingly high nodeId ensures IIFEs are placed last. | ||
} else if (n.callee.type === 'FunctionExpression') { | ||
if (!preserveOrder) { | ||
const newNode = generateFlatAST(`(${n.src});`)[1]; | ||
newNode.nodeId = 9999999; // Exceedingly high nodeId ensures IIFEs are placed last. | ||
newNode.nodeId = 9999999; | ||
nodes[idx] = newNode; | ||
@@ -23,4 +28,3 @@ } else nodes[idx] = n; | ||
}); | ||
const orderedNodes = [...new Set(nodes)].sort( | ||
(a, b) => a.nodeId > b.nodeId ? 1 : b.nodeId > a.nodeId ? -1 : 0); | ||
const orderedNodes = [...new Set(nodes)].sort(sortByNodeId); | ||
let output = ''; | ||
@@ -27,0 +31,0 @@ orderedNodes.forEach(n => { |
module.exports = [ | ||
{ | ||
enabled: false, | ||
reason: 'TODO: Take augmentation into account when replacing array index values', | ||
enabled: true, | ||
name: 'Augmented Array Replacements', | ||
source: `const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 'a', 'b', 'c']; | ||
(function (targetArray, numberOfShifts) { | ||
var augmentArray = function (counter) { | ||
(function(targetArray, numberOfShifts) { | ||
var augmentArray = function(counter) { | ||
while (--counter) { | ||
@@ -14,6 +13,5 @@ targetArray['push'](targetArray['shift']()); | ||
augmentArray(++numberOfShifts); | ||
}(arr, 3)); | ||
})(arr, 3); | ||
console.log(arr.join(' '));`, | ||
expected: `const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 'a', 'b', 'c']; | ||
expected: `const arr = [\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n 10,\n 'a',\n 'b',\n 'c'\n]; | ||
(function (targetArray, numberOfShifts) { | ||
@@ -26,5 +24,4 @@ var augmentArray = function (counter) { | ||
augmentArray(++numberOfShifts); | ||
})(arr, 3); | ||
console.log("4 5 6 7 8 9 10 a b c 1 2 3");`, | ||
}(arr, 3)); | ||
console.log('4 5 6 7 8 9 10 a b c 1 2 3');`, | ||
}, | ||
@@ -59,2 +56,3 @@ { | ||
}, | ||
// TODO: Fix issue | ||
{ | ||
@@ -256,2 +254,3 @@ enabled: false, | ||
}, | ||
// TODO: Implement functionality | ||
{ | ||
@@ -295,4 +294,6 @@ enabled: false, | ||
}, | ||
// TODO: Fix test | ||
{ | ||
enabled: true, | ||
enabled: false, | ||
reason: 'Fix: Replace values *after* augmentation', | ||
name: 'Resolve External References With Context', | ||
@@ -299,0 +300,0 @@ source: `const a = [1, 2, 3]; (function(arr) {arr.forEach((x, i, arr) => arr[i] = x * 10)})(a); function b() {const c = [...a]; return c[0] + 3;}`, |
@@ -126,2 +126,9 @@ const {generateFlatAST} = require('flast'); | ||
enabled: true, | ||
name: 'resolveFunctionConstructorCalls - TN-1', | ||
func: __dirname + '/../src/modules/safe/resolveFunctionConstructorCalls', | ||
source: `a = Function.constructor('return /" + this + "/')().constructor('^([^ ]+( +[^ ]+)+)+[^ ]}');`, | ||
expected: `a = Function.constructor('return /" + this + "/')().constructor('^([^ ]+( +[^ ]+)+)+[^ ]}');`, | ||
}, | ||
{ | ||
enabled: true, | ||
name: 'resolveMemberExpressionReferencesToArrayIndex - TP-1', | ||
@@ -128,0 +135,0 @@ func: __dirname + '/../src/modules/safe/resolveMemberExpressionReferencesToArrayIndex', |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
579255
9510
74