How to Perform Local Node.js Environment Reconstruction for JS Algorithms
The zhaoxuya520/reverse-skill repository provides a five-phase pipeline that uses a minimal shim and Node.js VM isolation to execute obfuscated JavaScript algorithms locally, capturing the first divergence point for forensic analysis.
Local Node.js environment reconstruction for JS algorithms enables security researchers to execute and analyze obfuscated browser scripts in a controlled, reproducible runtime. The zhaoxuya520/reverse-skill repository implements this workflow through a lightweight shim approach documented in skills/js-reverse/references/node-env-rebuild.md. By isolating the target algorithm in a minimal Node.js context, you can capture execution traces without browser overhead or external dependencies.
Prerequisites: Installing Node.js
The reconstruction pipeline requires Node.js version 22.x or higher to support modern JavaScript features used by target algorithms and the MCP bridge tooling.
Linux Installation
For Linux hosts, install Node.js via the NodeSource repository or using nvm. Detailed instructions are available in docs/platforms/linux.md.
macOS Installation
On macOS, use Homebrew (brew install node) or nvm to install the runtime. Refer to docs/platforms/macos.md for platform-specific guidance.
Verify Your Installation
Confirm the version meets the minimum requirement specified in README_AI.md:
node -v
The 5-Phase Reconstruction Pipeline
According to skills/js-reverse/references/node-env-rebuild.md, the reconstruction process follows a strict execution flow designed to minimize environmental noise while maximizing forensic evidence.
Phase 1: Import the Target Script
Load the algorithm file into the Node.js process using the fs module. This decouples the script from its original web context.
const fs = require('fs');
const script = fs.readFileSync('./samples/target.js', 'utf8');
Phase 2: Construct the Minimal Shim
Create a minimal host object supplying only the globals the script expects, such as window, document, or custom APIs. This "最小 shim 宿主对象" (minimal shim host object) keeps the attack surface small and analysis focused.
global.window = {};
global.document = {
createElement: () => ({}),
getElementById: () => ({}),
};
global.customApi = {
fetchData: () => ({ /* mock response */ })
};
Phase 3: Execute in Isolated Context
Use Node.js's built-in vm module to create a sandboxed context. This prevents the target script from accessing the host file system or environment variables.
const vm = require('vm');
const context = vm.createContext(global);
vm.runInContext(script, context, { filename: 'target.js' });
Phase 4: Capture First Divergence
Wrap execution in a try-catch block to record the first exception or logical branch. This "first divergence" provides the most informative evidence for reverse-engineering the algorithm's internal logic or anti-tampering checks.
try {
vm.runInContext(script, context, { filename: 'target.js' });
} catch (e) {
console.error('First divergence captured:', e);
// Log stack to ./evidence/first-divergence.txt
}
Phase 5: Back-fill Missing Evidence
If the error indicates missing data (e.g., network responses), manually inject the required mocks into the global object and re-run. This "页面证据补齐缺口" (page evidence gap filling) closes analytical holes iteratively without polluting the initial environment.
// Augment the shim with missing network payload
global.customApi.fetchData = () => ({ mock: 'network payload' });
Complete Implementation Example
The following implementation from the reverse-skill repository demonstrates the full pipeline in a single script, from loading the algorithm to capturing the initial crash:
// ==== 1️⃣ Load the target algorithm ====
const fs = require('fs');
const script = fs.readFileSync('./samples/alg.js', 'utf8');
// ==== 2️⃣ Minimal shim (global object) ====
global.window = {};
global.document = {
createElement: () => ({}),
getElementById: () => ({}),
};
global.myApi = {
fetchData: () => ({ /* mock data */ })
};
// ==== 3️⃣ Execute the script inside a sandboxed VM ====
const vm = require('vm');
const context = vm.createContext(global);
try {
vm.runInContext(script, context, { filename: 'alg.js' });
} catch (e) {
// ==== 4️⃣ Capture first exception/divergence ====
console.error('First divergence captured:', e);
// Store stack trace for later analysis
}
// ==== 5️⃣ Optional: augment evidence ====
// If the error indicates a missing network response, inject it:
global.myApi.fetchData = () => ({ mock: 'network payload' });
// Re-run the script or continue analysis as needed.
Key Source Files
| File | Purpose |
|---|---|
skills/js-reverse/references/node-env-rebuild.md |
Core reconstruction guide documenting the five-phase pipeline and shim construction |
skills/js-reverse/SKILL.md |
High-level JavaScript reverse-engineering skill documentation |
docs/platforms/linux.md |
Node.js installation instructions for Linux (NodeSource, nvm) |
docs/platforms/macos.md |
Node.js installation instructions for macOS (Homebrew, nvm) |
README_AI.md |
Repository overview and required tool versions (Node ≥ 22.x) |
Summary
- Local Node.js environment reconstruction requires Node.js ≥ 22.x and the
vmmodule for sandboxed execution. - The minimal shim approach restricts global objects to only what the target algorithm expects, reducing environmental noise.
- Capture the first divergence (exception or branch) to identify the algorithm's protective logic or decryption routines.
- Iteratively back-fill missing evidence by mocking APIs and network responses until execution paths are fully understood.
- All documentation and examples are maintained in the
zhaoxuya520/reverse-skillrepository.
Frequently Asked Questions
What is the minimum Node.js version required for JS algorithm reconstruction?
The reverse-skill repository requires Node.js version 22.x or higher, as documented in README_AI.md. This ensures compatibility with modern JavaScript syntax used by obfuscated algorithms and the MCP bridge tooling.
Why use the vm module instead of running the script directly?
The vm module creates an isolated context that prevents the target script from accessing the host file system, environment variables, or other Node.js internals. This containment is essential for safely analyzing potentially malicious or unknown algorithms without risking the host system.
How do I know what global objects to include in the shim?
Start with an empty shim and execute the script. The first divergence (caught exception) will typically indicate a missing global (e.g., window is not defined). Add only the specific properties the error demands, following the "最小 shim 宿主对象" principle from node-env-rebuild.md to avoid introducing unnecessary complexity.
Can this method handle algorithms that require browser-specific APIs like Canvas or WebGL?
Yes, but you must manually mock those APIs. The reconstruction process supports iterative evidence back-filling: when the script fails due to a missing Canvas context, add a mock implementation to the shim and re-run until the algorithm proceeds to the next divergence point, gradually mapping the entire execution graph.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →