Skip to content

Repository files navigation

REstringer

Node.js CIDownloadsnpm version

A JavaScript deobfuscation tool that reconstructs strings and simplifies complex logic.

REstringer automatically detects obfuscation patterns and applies targeted deobfuscation techniques to restore readable JavaScript code. It handles various obfuscation methods while respecting scope limitations and maintaining code functionality.

📧 Contact: For questions and suggestions, open an issue or find me on Twitter / X - Ben Baryo - @ctrl__esc


Table of Contents


Features

Automatic Obfuscation Detection: Uses Obfuscation Detector to identify specific obfuscation types

🔧 Modular Architecture: 40+ deobfuscation modules organized into safe and unsafe categories

🛡️ Safe Execution: Unsafe modules use a sandbox isolated-vm for secure code evaluation

🎯 Targeted Processing: Specialized processors for common obfuscators (obfuscator.io, Caesar Plus, etc.)

Performance Optimized: Match/transform patterns and performance improvements throughout

🔍 Comprehensive Coverage: Handles string reconstruction, dead code removal, control flow simplification, and more


Installation

Requirements

  • Node.js v20+ (v22+ recommended)

Global Installation (CLI)

npm install -g restringer

Local Installation (Module)

npm install restringer

Development Installation

git clone https://github.com/HumanSecurity/restringer.git
cd restringer
npm install

Usage

Command-Line Usage

Usage: restringer input_filename [-h] [-c] [-q | -v] [-m M] [-o [output_filename]]
positional arguments:
input_filename The obfuscated JavaScript file
optional arguments:
-h, --help Show this help message and exit
-c, --clean Remove dead nodes after deobfuscation (unsafe)
-q, --quiet Suppress output to stdout
-v, --verbose Show debug messages during deobfuscation
-m, --max-iterations M Maximum deobfuscation iterations (must be > 0)
-o, --output [filename] Write output to file (default: <input>-deob.js)

Examples

Basic deobfuscation (print to stdout):

restringer obfuscated.js

Save to specific file:

restringer obfuscated.js -o clean-code.js

Verbose output with iteration limit:

restringer obfuscated.js -v -m 10 -o output.js

Quiet mode (no console output):

restringer obfuscated.js -q -o output.js

Remove dead code (potentially unsafe):

restringer obfuscated.js -c -o output.js

Module Usage

Basic Example

import{REstringer}from'restringer';constobfuscatedCode=`const _0x4c2a = ['hello', 'world'];const _0x3f1b = _0x4c2a[0] + ' ' + _0x4c2a[1];console.log(_0x3f1b);`;constrestringer=newREstringer(obfuscatedCode);if(restringer.deobfuscate()){console.log('✅ Deobfuscation successful!');console.log(restringer.script);// Output: console.log('hello world');}else{console.log('❌ No changes made');}

Advanced Usage

Custom Deobfuscators

Create targeted deobfuscators using REstringer's modular system:

import{applyIteratively}from'flast';import{safe,unsafe}from'restringer';// Import specific modulesconstnormalizeComputed=safe.normalizeComputed.default;constremoveRedundantBlockStatements=safe.removeRedundantBlockStatements.default;constresolveDefiniteBinaryExpressions=unsafe.resolveDefiniteBinaryExpressions.default;constresolveLocalCalls=unsafe.resolveLocalCalls.default;letscript='your obfuscated code here';// Define custom deobfuscation pipelineconstcustomModules=[resolveDefiniteBinaryExpressions,// Resolve literal math operationsresolveLocalCalls,// Inline function callsnormalizeComputed,// Convert obj['prop'] to obj.propremoveRedundantBlockStatements,// Clean up unnecessary blocks];// Apply modules iterativelyscript=applyIteratively(script,customModules);console.log(script);

Targeted Processing

Use candidate filters to target specific nodes:

import{unsafe}from'restringer';import{applyIteratively}from'flast';const{resolveLocalCalls}=unsafe;functionresolveGlobalScopeCalls(arb){// Only process calls in global scopereturnresolveLocalCalls(arb,n=>n.parentNode?.type==='Program');}functionresolveSpecificFunctions(arb){// Only process calls to functions with specific namesreturnresolveLocalCalls(arb,n=>{constcallee=n.callee;returncallee.type==='Identifier'&&['decode','decrypt','transform'].includes(callee.name);});}constscript=applyIteratively(code,[resolveGlobalScopeCalls,resolveSpecificFunctions]);

Custom Method Integration

Replace or customize built-in methods:

importfsfrom'node:fs';import{REstringer}from'restringer';constcode=fs.readFileSync('obfuscated.js','utf-8');constrestringer=newREstringer(code);// Find and replace a specific methodconsttargetMethod=restringer.unsafeMethods.find(m=>m.name==='resolveLocalCalls');if(targetMethod){letprocessedCount=0;constmaxProcessing=5;// Custom implementation with limitsconstcustomMethod=functionlimitedResolveLocalCalls(arb){returntargetMethod(arb,()=>processedCount++<maxProcessing);};// Replace the methodconstindex=restringer.unsafeMethods.indexOf(targetMethod);restringer.unsafeMethods[index]=customMethod;}restringer.deobfuscate();

Architecture

Module Categories

Safe Modules (src/modules/safe/):

  • Perform transformations without code evaluation
  • No risk of executing malicious code
  • Examples: String normalization, syntax simplification, dead code removal

Unsafe Modules (src/modules/unsafe/):

  • Use eval() in an isolated sandbox for dynamic analysis
  • Can resolve complex expressions and function calls
  • Secured using isolated-vm

Processing Pipeline

  1. Detection: Identify obfuscation type using pattern recognition
  2. Preprocessing: Apply obfuscation-specific preparations
  3. Core Deobfuscation: Run safe and unsafe modules iteratively
  4. Postprocessing: Clean up and optimize the result
  5. Validation: Ensure output correctness

Processor Architecture

Specialized processors handle specific obfuscation patterns:

  • Match/Transform Pattern: Separate identification and modification logic
  • Performance Optimized: Pre-compiled patterns and efficient algorithms
  • Configurable: Support for custom filtering and targeting

Development

Project Structure

restringer/
├── src/
│ ├── modules/
│ │ ├── safe/ # Safe deobfuscation modules
│ │ ├── unsafe/ # Unsafe deobfuscation modules
│ │ └── utils/ # Utility functions
│ ├── processors/ # Obfuscation-specific processors
│ └── restringer.js # Main REstringer class
├── tests/ # Comprehensive test suites
└── docs/ # Documentation

Running Tests

# Quick test suite (without testing against samples)
npm run test:quick
# Watch mode for development (quick tests)
npm run test:quick:watch
# Full test suite with samples
npm test

Contributing

We welcome contributions! Please see our Contributing Guide for detailed guidelines on:

  • Setting up the development environment
  • Code standards and best practices
  • Module and processor development
  • Testing requirements
  • Pull request process

Resources

Documentation

Related Projects

Research & Blog Posts

The REstringer Tri(b)logy:

Additional Resources:

Community


License

This project is licensed under the MIT License.


Made with ❤️ by HUMAN Security

About

A Javascript Deobfuscator

Resources

Contributing

Stars

603 stars

Watchers

12 watching

Forks

Releases

Used by

Contributors

Languages