Giter Club home page Giter Club logo

restringer's Introduction

Restringer

Node.js CI Downloads

Deobfuscate Javascript and reconstruct strings. Simplify cumbersome logic where possible while adhering to scope limitations.

Try it online @ restringer.tech.

For comments and suggestions feel free to open an issue or find me on Twitter - @ctrl__esc

Table of Contents


Installation

npm

npm install restringer

Clone The Repo

Requires Node 16 or newer.

git clone [email protected]:PerimeterX/restringer.git
cd restringer
npm install

Usage

The restringer.js uses generic deobfuscation methods that reconstruct and restore obfuscated strings and simplifies redundant logic meant only to encumber. REstringer employs the Obfuscation Detector to identify specific types of obfuscation for which there's a need to apply specific deobfuscation methods in order to circumvent anti-debugging mechanisms or other code traps preventing the script from being deobfuscated.

Command-Line Usage

Usage: restringer input_filename [-h] [-c] [-q | -v] [-m M] [-o [output_filename]]

positional arguments:
	input_filename                  The obfuscated JS file

optional arguments:
	-h, --help                      Show this help message and exit.
	-c, --clean                     Remove dead nodes from script after deobfuscation is complete (unsafe).
	-q, --quiet                     Suppress output to stdout. Output result only to stdout if the -o option is not set.
																	Does not go with the -v option.
	-m, --max-iterations M          Run at most M iterations
	-v, --verbose                   Show more debug messages while deobfuscating. Does not go with the -q option.
	-o, --output [output_filename]  Write deobfuscated script to output_filename. 
																	Use <input_filename>-deob.js if no filename is provided.

Use as a Module

const {REstringer} = require('restringer');

const restringer = new REstringer('"RE" + "stringer"');
if (restringer.deobfuscate()) {
  console.log(restringer.script);
} else {
  console.log('Nothing was deobfuscated :/');
}
// Output: 'REstringer';

Create Custom Deobfuscators

REstringer is highly modularized. It exposes modules that allow creating custom deobfuscators that can solve specific problems.

The basic structure of such a deobfuscator would be an array of deobfuscation modules (either safe or unsafe), run via the runLoop util function.

Unsafe modules run code through eval (using isolated-vm to be on the safe side) while safe modules do not.

const {
  safe: {normalizeComputed},
  unsafe: {resolveDefiniteBinaryExpressions, resolveLocalCalls},
  utils: {runLoop}
} = require('restringer').deobModules;
let script = 'obfuscated JS here';
const deobModules = [
  resolveDefiniteBinaryExpressions,
  resolveLocalCalls,
  normalizeComputed,
];
script = runLoop(script, deobModules);
console.log(script); // Deobfuscated script

With the additional candidateFilter function argument, it's possible to narrow down the targeted nodes:

const {
  unsafe: {resolveLocalCalls},
  utils: {runLoop}
} = require('restringer').deobModules;
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')
function resolveLocalCallsInGlobalScope(arb) {
  return resolveLocalCalls(arb, n => n.parentNode?.type === 'Program');
}
script = runLoop(script, [resolveLocalCallsInGlobalScope]);
console.log(script); // Deobfuscated script

You can also customize any deobfuscation method while still using REstringer without running the loop yourself:

const fs = require('node:fs');
const {REstringer} = require('restringer');

const inputFilename = process.argv[2];
const code = fs.readFileSync(inputFilename, 'utf-8');
const res = new REstringer(code);

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

const targetFunc = res.unsafeMethods.find(m => m.name === 'resolveLocalCalls');
let changes = 0;		// Resolve only the first 5 calls
res.safeMethods[res.unsafeMethods.indexOf(targetFunc)] = function customResolveLocalCalls(n) {return targetFunc(n, () => changes++ < 5)}

res.deobfuscate();

if (res.script !== code) {
  console.log('[+] Deob successful');
  fs.writeFileSync(`${inputFilename}-deob.js`, res.script, 'utf-8');
} else console.log('[-] Nothing deobfuscated :/');

Read More

restringer's People

Contributors

benbaryopx avatar ctrl-escp avatar j4k0xb avatar faeyumbrea avatar lanvent avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.