Deobfuscate Javascript with emphasis on reconstructing strings
npm install restringer


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.
š Try it online: restringer.tech
š§ Contact: For questions and suggestions, open an issue or find me on Twitter / X - Ben Baryo - @ctrl__esc
---
- Features
- Installation
- Usage
- Command-Line Usage
- Module Usage
- Advanced Usage
- Custom Deobfuscators
- Targeted Processing
- Custom Method Integration
- Architecture
- Development
- Contributing
- Resources
---
⨠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
---
bash
npm install -g restringer
`$3
`bash
npm install restringer
`$3
`bash
git clone https://github.com/HumanSecurity/restringer.git
cd restringer
npm install
`---
Usage
$3
`
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: -deob.js)
`#### Examples
Basic deobfuscation (print to stdout):
`bash
restringer obfuscated.js
`Save to specific file:
`bash
restringer obfuscated.js -o clean-code.js
`Verbose output with iteration limit:
`bash
restringer obfuscated.js -v -m 10 -o output.js
`Quiet mode (no console output):
`bash
restringer obfuscated.js -q -o output.js
`Remove dead code (potentially unsafe):
`bash
restringer obfuscated.js -c -o output.js
`$3
#### Basic Example
`javascript
import {REstringer} from 'restringer';const obfuscatedCode =
;const restringer = new REstringer(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
$3
Create targeted deobfuscators using REstringer's modular system:
`javascript
import {applyIteratively} from 'flast';
import {safe, unsafe} from 'restringer';// Import specific modules
const normalizeComputed = safe.normalizeComputed.default;
const removeRedundantBlockStatements = safe.removeRedundantBlockStatements.default;
const resolveDefiniteBinaryExpressions = unsafe.resolveDefiniteBinaryExpressions.default;
const resolveLocalCalls = unsafe.resolveLocalCalls.default;
let script = 'your obfuscated code here';
// Define custom deobfuscation pipeline
const customModules = [
resolveDefiniteBinaryExpressions, // Resolve literal math operations
resolveLocalCalls, // Inline function calls
normalizeComputed, // Convert obj['prop'] to obj.prop
removeRedundantBlockStatements, // Clean up unnecessary blocks
];
// Apply modules iteratively
script = applyIteratively(script, customModules);
console.log(script);
`$3
Use candidate filters to target specific nodes:
`javascript
import {unsafe} from 'restringer';
import {applyIteratively} from 'flast';const {resolveLocalCalls} = unsafe;
function resolveGlobalScopeCalls(arb) {
// Only process calls in global scope
return resolveLocalCalls(arb, n => n.parentNode?.type === 'Program');
}
function resolveSpecificFunctions(arb) {
// Only process calls to functions with specific names
return resolveLocalCalls(arb, n => {
const callee = n.callee;
return callee.type === 'Identifier' &&
['decode', 'decrypt', 'transform'].includes(callee.name);
});
}
const script = applyIteratively(code, [
resolveGlobalScopeCalls,
resolveSpecificFunctions
]);
`$3
Replace or customize built-in methods:
`javascript
import fs from 'node:fs';
import {REstringer} from 'restringer';const code = fs.readFileSync('obfuscated.js', 'utf-8');
const restringer = new REstringer(code);
// Find and replace a specific method
const targetMethod = restringer.unsafeMethods.find(m =>
m.name === 'resolveLocalCalls'
);
if (targetMethod) {
let processedCount = 0;
const maxProcessing = 5;
// Custom implementation with limits
const customMethod = function limitedResolveLocalCalls(arb) {
return targetMethod(arb, () => processedCount++ < maxProcessing);
};
// Replace the method
const index = restringer.unsafeMethods.indexOf(targetMethod);
restringer.unsafeMethods[index] = customMethod;
}
restringer.deobfuscate();
`---
Architecture
$3
Safe Modules (
src/modules/safe/):
- Perform transformations without code evaluation
- No risk of executing malicious code
- Examples: String normalization, syntax simplification, dead code removalUnsafe Modules (
src/modules/unsafe/):
- Use eval() in an isolated sandbox for dynamic analysis
- Can resolve complex expressions and function calls
- Secured using isolated-vm$3
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
$3
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
$3
`
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
`$3
`bash
Quick test suite (without testing against samples)
npm run test:quickWatch mode for development (quick tests)
npm run test:quick:watchFull test suite with samples
npm test
``---
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
---
The REstringer Tri(b)logy:
- š The Far Point of a Static Encounter - Part 1: Understanding static analysis challenges
- š§ Automating Skimmer Deobfuscation - Part 2: Automated deobfuscation techniques
- š”ļø Defeating JavaScript Obfuscation - Part 3: The story of REstringer
Additional Resources:
- š Caesar Plus Deobfuscation - Deep dive into Caesar cipher obfuscation
---
This project is licensed under the MIT License.
---
Made with ā¤ļø by HUMAN Security