Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

restringer

Package Overview
Dependencies
Maintainers
2
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

restringer - npm Package Compare versions

Comparing version 1.10.3 to 1.10.4

4

package.json
{
"name": "restringer",
"version": "1.10.3",
"version": "1.10.4",
"description": "Deobfuscate Javascript with emphasis on reconstructing strings",

@@ -14,3 +14,3 @@ "main": "index.js",

"dependencies": {
"flast": "^1.6.0",
"flast": "^1.7.1",
"isolated-vm": "^5.0.1",

@@ -17,0 +17,0 @@ "jsdom": "^24.1.0",

@@ -20,2 +20,3 @@ # Restringer

* [Create Custom Deobfuscators](#create-custom-deobfuscators)
* [Boilerplate Code for Starting from Scratch](#boilerplate-code-for-starting-from-scratch)
* [Read More](#read-more)

@@ -84,3 +85,3 @@ ***

The basic structure of such a deobfuscator would be an array of deobfuscation modules
(either [safe](src/modules/safe) or [unsafe](src/modules/unsafe)), run via the [runLoop](src/modules/utils/runLoop.js) util function.
(either [safe](src/modules/safe) or [unsafe](src/modules/unsafe)), run via flAST's applyIteratively utility function.

@@ -93,4 +94,4 @@ Unsafe modules run code through `eval` (using [isolated-vm](https://www.npmjs.com/package/isolated-vm) to be on the safe side) while safe modules do not.

unsafe: {resolveDefiniteBinaryExpressions, resolveLocalCalls},
utils: {runLoop}
} = require('restringer').deobModules;
const {applyIteratively} = require('flast').utils;
let script = 'obfuscated JS here';

@@ -102,3 +103,3 @@ const deobModules = [

];
script = runLoop(script, deobModules);
script = applyIteratively(script, deobModules);
console.log(script); // Deobfuscated script

@@ -111,11 +112,11 @@ ```

unsafe: {resolveLocalCalls},
utils: {runLoop}
} = require('restringer').deobModules;
const {applyIteratively} = require('flast').utils;
let script = 'obfuscated JS here';
// It's better to define a function with a name that can show up in the log (otherwise you'll get 'undefined')
// It's better to define a function with a meaningful name that can show up in the log
function resolveLocalCallsInGlobalScope(arb) {
return resolveLocalCalls(arb, n => n.parentNode?.type === 'Program');
}
script = runLoop(script, [resolveLocalCallsInGlobalScope]);
script = applyIteratively(script, [resolveLocalCallsInGlobalScope]);
console.log(script); // Deobfuscated script

@@ -133,3 +134,3 @@ ```

// res.logger.setLogLevel(res.logger.logLevels.DEBUG);
// res.logger.setLogLevelDebug();
res.detectObfuscationType = false; // Skip obfuscation type detection, including any pre and post processors

@@ -148,2 +149,36 @@

```
***
### Boilerplate code for starting from scratch
```javascript
const {logger, applyIteratively, treeModifier} = require('flast').utils;
// Optional loading from file
// const fs = require('node:fs');
// const inputFilename = process.argv[2] || 'target.js';
// const code = fs.readFileSync(inputFilename, 'utf-8');
const code = `(function() {
function createMessage() {return 'Hello' + ' ' + 'there!';}
function print(msg) {console.log(msg);}
print(createMessage());
})();`;
logger.setLogLevelDebug();
let script = code;
// Use this function to target the relevant nodes
const f = n => n.type === 'Literal' && replacements[n.value];
// Use this function to modify the nodes according to your needs.
// markNode(n) would delete the node, while markNode(n, {...}) would replace the node with the supplied node.
const m = (n, arb) => arb.markNode(n, {
type: 'Literal',
value: replacements[n.value],
});
const swc = treeModifier(f, m, 'StarWarsChanger');
script = applyIteratively(script, [swc]);
if (code !== script) {
console.log(script);
// fs.writeFileSync(inputFilename + '-deob.js', script, 'utf-8');
} else console.log(`No changes`);
```
***

@@ -150,0 +185,0 @@

@@ -1,5 +0,4 @@

const {generateFlatAST} = require('flast');
const logger = require(__dirname + '/../utils/logger');
const getCache = require(__dirname + '/../utils/getCache');
const generateHash = require(__dirname + '/../utils/generateHash');
const {generateFlatAST, utils: {logger}} = require('flast');

@@ -6,0 +5,0 @@ /**

@@ -1,5 +0,4 @@

const {generateFlatAST} = require('flast');
const logger = require(__dirname + '/../utils/logger');
const getCache = require(__dirname + '/../utils/getCache');
const generateHash = require(__dirname + '/../utils/generateHash');
const {generateFlatAST, utils: {logger}} = require('flast');

@@ -6,0 +5,0 @@ /**

@@ -1,2 +0,2 @@

const logger = require(__dirname + '/../utils/logger');
const {logger} = require('flast').utils;

@@ -3,0 +3,0 @@ const minArrayLength = 20;

@@ -0,3 +1,3 @@

const {logger} = require('flast').utils;
const {badValue} = require(__dirname + '/../config');
const logger = require(__dirname + '/../utils/logger');
const Sandbox = require(__dirname + '/../utils/sandbox');

@@ -4,0 +4,0 @@ const evalInVm = require(__dirname + '/../utils/evalInVm');

@@ -0,3 +1,3 @@

const {logger} = require('flast').utils;
const {badValue} = require(__dirname + '/../config');
const logger = require(__dirname + '/../utils/logger');
const Sandbox = require(__dirname + '/../utils/sandbox');

@@ -4,0 +4,0 @@ const evalInVm = require(__dirname + '/../utils/evalInVm');

@@ -1,5 +0,4 @@

const logger = require(__dirname + '/logger');
const {generateCode, parseCode} = require('flast');
const {badValue} = require(__dirname + '/../config');
const getObjType = require(__dirname + '/getObjType');
const {generateCode, parseCode, utils: {logger}} = require('flast');

@@ -6,0 +5,0 @@ /**

@@ -0,5 +1,5 @@

const {logger} = require('flast').utils;
const Sandbox = require(__dirname + '/sandbox');
const assert = require('node:assert');
const {badValue} = require(__dirname + '/../config');
const logger = require(__dirname + '/../utils/logger');
const getObjType = require(__dirname + '/../utils/getObjType');

@@ -6,0 +6,0 @@ const generateHash = require(__dirname + '/../utils/generateHash');

@@ -5,4 +5,5 @@ // noinspection HtmlRequiredLangAttribute,HtmlRequiredTitleElement

const Sandbox = require(__dirname + '/sandbox');
// eslint-disable-next-line no-unused-vars
const {JSDOM} = require('jsdom');
const logger = require(__dirname + '/../utils/logger');
const {logger} = require('flast').utils;
const generateHash = require(__dirname + '/../utils/generateHash');

@@ -9,0 +10,0 @@

@@ -18,7 +18,5 @@ module.exports = {

isNodeMarked: require(__dirname + '/isNodeMarked'),
logger: require(__dirname + '/logger'),
normalizeScript: require(__dirname + '/normalizeScript'),
runLoop: require(__dirname + '/runLoop'),
safeImplementations: require(__dirname + '/safeImplementations'),
sandbox: require(__dirname + '/sandbox'),
};

@@ -1,2 +0,2 @@

const runLoop = require(__dirname + '/runLoop');
const {applyIteratively} = require('flast').utils;
const normalizeComputed = require(__dirname + '/../safe/normalizeComputed');

@@ -12,3 +12,3 @@ const normalizeEmptyStatements = require(__dirname + '/../safe/normalizeEmptyStatements');

function normalizeScript(script) {
return runLoop(script, [
return applyIteratively(script, [
normalizeComputed,

@@ -15,0 +15,0 @@ normalizeRedundantNotOperator,

@@ -1,4 +0,3 @@

const {Arborist} = require('flast');
const {Arborist, utils: {logger}} = require('flast');
const generateHash = require(__dirname + '/generateHash');
const logger = require(__dirname + '/../utils/logger');
const {defaultMaxIterations, getGlobalMaxIterations} = require(__dirname + '/../config');

@@ -5,0 +4,0 @@

#!/usr/bin/env node
const {logger, applyIteratively} = require('flast').utils;
const processors = require(__dirname + '/processors');

@@ -7,5 +8,3 @@ const detectObfuscation = require('obfuscation-detector');

utils: {
runLoop,
normalizeScript,
logger,
},

@@ -37,3 +36,3 @@ safe,

this.logger = logger;
this.logger.setLogLevel(logger.logLevels.LOG); // Default log level
this.logger.setLogLevelLog();
this.detectObfuscationType = true;

@@ -111,3 +110,3 @@ // Deobfuscation methods that don't use eval

this.modified = false;
script = runLoop(this.script, this.safeMethods.concat(this.unsafeMethods));
script = applyIteratively(this.script, this.safeMethods.concat(this.unsafeMethods));
if (this.script !== script) {

@@ -136,3 +135,3 @@ this.modified = true;

if (this.modified && this.normalize) this.script = normalizeScript(this.script);
if (clean) this.script = runLoop(this.script, [unsafe.removeDeadNodes]);
if (clean) this.script = applyIteratively(this.script, [unsafe.removeDeadNodes]);
return this.modified;

@@ -149,3 +148,3 @@ }

const processor = processors[i];
this.script = runLoop(this.script, [processor], 1);
this.script = applyIteratively(this.script, [processor], 1);
}

@@ -166,4 +165,4 @@ }

const restringer = new REstringer(content);
if (args.quiet) restringer.logger.setLogLevel(logger.logLevels.NONE);
else if (args.verbose) restringer.logger.setLogLevel(logger.logLevels.DEBUG);
if (args.quiet) restringer.logger.setLogLevelNone();
else if (args.verbose) restringer.logger.setLogLevelDebug();
logger.log(`[!] REstringer v${REstringer.__version__}`);

@@ -170,0 +169,0 @@ logger.log(`[!] Deobfuscating ${args.inputFilename}...`);

@@ -15,3 +15,3 @@ const assert = require('node:assert');

function testCodeSample(testName, source, expected) {
process.stdout.write(`Testing ${testName}... `);
process.stdout.write(`${testName}... `);
console.time('PASS');

@@ -36,3 +36,3 @@ const restringer = new REstringer(source);

skippedTests++;
console.log(`Testing [${moduleName}] ${test.name}...`.padEnd(101, '.') + ` SKIPPED: ${test.reason}`);
console.log(`[${moduleName}] ${test.name}...`.padEnd(101, '.') + ` SKIPPED: ${test.reason}`);
}

@@ -39,0 +39,0 @@ }

const assert = require('node:assert');
const {Arborist} = require('flast');
const {runLoop, logger} = require(__dirname + '/../src/modules').utils;
const {logger, applyIteratively} = require('flast').utils;

@@ -22,3 +22,3 @@ const tests = {

function testModuleOnce(testName, testFunc, source, expected, prepTest = defaultPrepTest, prepRes = defaultPrepRes) {
process.stdout.write(`Testing ${testName}... `);
process.stdout.write(`${testName}... `);
console.time('PASS');

@@ -42,6 +42,6 @@ const testInput = prepTest(source);

function testModuleInLoop(testName, testFunc, source, expected, prepTest = null, prepRes = null) {
process.stdout.write(`Testing ${testName}... `);
process.stdout.write(`${testName}... `);
console.time('PASS');
const testInput = prepTest ? prepTest(source) : source;
const rawResult = runLoop(testInput, [testFunc]);
const rawResult = applyIteratively(testInput, [testFunc]);
const result = prepRes ? prepRes(rawResult) : rawResult;

@@ -63,7 +63,7 @@ assert.deepEqual(result, expected);

if (!test.looped) testModuleOnce(`[${moduleName}] ${test.name}`.padEnd(90, '.'), require(test.func), test.source, test.expected, test.prepareTest, test.prepareResult);
// Tests will have the `isUtil` flag if they do not return an Arborist instance (i.e. can't use runLoop)
// Tests will have the `isUtil` flag if they do not return an Arborist instance (i.e. can't use applyIteratively)
if (!test.isUtil) testModuleInLoop(`[${moduleName}] ${test.name} (looped)`.padEnd(90, '.'), require(test.func), test.source, test.expected, test.prepareTest, test.prepareResult);
} else {
skippedTests++;
console.log(`Testing [${moduleName}] ${test.name}...`.padEnd(101, '.') + ` SKIPPED: ${test.reason}`);
console.log(`[${moduleName}] ${test.name}...`.padEnd(101, '.') + ` SKIPPED: ${test.reason}`);
}

@@ -70,0 +70,0 @@ }

@@ -20,3 +20,3 @@ const fs = require('node:fs');

function testSampleDeobfuscation(testSampleName, testSampleFilename) {
process.stdout.write(`Testing '${testSampleName}' obfuscated sample...`.padEnd(60, '.'));
process.stdout.write(`'${testSampleName}' obfuscated sample...`.padEnd(60, '.'));
console.time(' PASS');

@@ -23,0 +23,0 @@ const obfuscatedSource = fs.readFileSync(testSampleFilename, 'utf-8');

@@ -21,3 +21,3 @@ const {Arborist} = require('flast');

function testProcessor(testName, testProcs, source, expected, prepTest = defaultPrepTest, prepRes = defaultPrepRes) {
process.stdout.write(`Testing ${testName}... `);
process.stdout.write(`${testName}... `);
console.time('PASS');

@@ -43,3 +43,3 @@ let rawRes = prepTest(source);

skippedTests++;
console.log(`Testing [${processorName}] ${test.name}...`.padEnd(101, '.') + ` SKIPPED: ${test.reason}`);
console.log(`[${processorName}] ${test.name}...`.padEnd(101, '.') + ` SKIPPED: ${test.reason}`);
}

@@ -46,0 +46,0 @@ }

@@ -14,3 +14,3 @@ const assert = require('node:assert');

function testCodeSample(testName, testFunc, verifyFunc) {
process.stdout.write(`Testing ${testName}... `);
process.stdout.write(`${testName}... `);
console.time('PASS');

@@ -34,3 +34,3 @@ const results = testFunc();

skippedTests++;
console.log(`Testing [${moduleName}] ${test.name}...`.padEnd(101, '.') + ` SKIPPED: ${test.reason}`);
console.log(`[${moduleName}] ${test.name}...`.padEnd(101, '.') + ` SKIPPED: ${test.reason}`);
}

@@ -37,0 +37,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc