Docs  /  Reference

Using Rerius in a Backend Project

This guide explains how to add Rerius as an npm dependency in any Node.js backend project - no manual compilation needed.

Repository: https://github.com/ECLS-Studio/rerius


How It Works#

Rerius is a native Node.js addon (.node file). The npm install process automatically compiles the C source into a platform-specific binary. No separate build step required on the consumer side.

npm install rerius
        ↓
  postinstall script runs
        ↓
  checks for prebuilt binary (prebuilds/<platform>-<arch>.node)
        ↓  if not found:
  compiles from source using clang/gcc + Node headers
        ↓
  rerius.node ready

Installation#

npm install rerius
# or
yarn add rerius
# or
pnpm add rerius

Requirements for compilation (if no prebuild): - C compiler: clang or gcc - Node.js dev headers (usually bundled with Node) - make (optional - installer falls back to direct compile)

Termux/Android:

pkg install nodejs clang
npm install rerius

Basic Usage#

const rerius = require('rerius');

// One-liner with auto-close
rerius.withBinary('/path/to/binary', bin => {
    console.log(bin.arch);          // 'AArch64 (ARM64)'
    console.log(bin.sha256);        // 'a3f8bc...'
    console.log(bin.isPie);         // true

    const fns  = bin.functions();   // detected functions
    const syms = bin.symbols();     // symbol table
    const xr   = bin.xrefs();       // cross-references

    console.log(fns.length, 'functions,', syms.length, 'symbols');
});

Express.js Backend Example#

mkdir my-re-backend && cd my-re-backend
npm init -y
npm install express rerius
// app.js
const express = require('express');
const rerius  = require('rerius');
const path    = require('path');

const app = express();
app.use(express.json());

// POST /analyze - analyze an uploaded binary path
app.post('/analyze', async (req, res) => {
    const { file } = req.body;
    if (!file) return res.status(400).json({ error: 'body.file required' });

    try {
        const result = rerius.withBinary(file, bin => ({
            arch:       bin.arch,
            format:     bin.format,
            sha256:     bin.sha256,
            isPie:      bin.isPie,
            isStripped: bin.isStripped,
            entry:      String(bin.entry),
            functions:  bin.functions().length,
            symbols:    bin.symbols().length,
            xrefs:      bin.xrefs().length,
            sections:   bin.sections().map(s => ({
                name: s.name,
                type: s.type,
                size: String(s.size),
            })),
        }));
        res.json(result);
    } catch (e) {
        res.status(500).json({ error: e.message });
    }
});

// POST /disasm - disassemble a section
app.post('/disasm', (req, res) => {
    const { file, section = '.text', limit = 200 } = req.body;
    if (!file) return res.status(400).json({ error: 'body.file required' });

    try {
        const insns = rerius.withBinary(file, bin =>
            bin.disasmJson(section, { limit: parseInt(limit, 10) })
               .map(i => ({
                   address:  String(i.address),
                   mnemonic: i.mnemonic,
                   operands: i.operands,
                   group:    i.group,
                   symbol:   i.symbol,
               }))
        );
        res.json({ section, count: insns.length, instructions: insns });
    } catch (e) {
        res.status(500).json({ error: e.message });
    }
});

// POST /entropy - entropy scan
app.post('/entropy', (req, res) => {
    const { file } = req.body;
    if (!file) return res.status(400).json({ error: 'body.file required' });
    try {
        const output = rerius.withBinary(file, bin => bin.entropy());
        res.json({ output });
    } catch (e) {
        res.status(500).json({ error: e.message });
    }
});

// POST /decompile - decompile a function by index
app.post('/decompile', (req, res) => {
    const { file, funcIdx = 0 } = req.body;
    if (!file) return res.status(400).json({ error: 'body.file required' });
    try {
        const output = rerius.withBinary(file, bin =>
            bin.decompile(parseInt(funcIdx, 10))
        );
        res.json({ output });
    } catch (e) {
        res.status(500).json({ error: e.message });
    }
});

app.listen(3000, () => console.log('RE backend running on :3000'));
node app.js

# Test
curl -s -X POST http://localhost:3000/analyze \
  -H 'Content-Type: application/json' \
  -d '{"file":"/bin/ls"}' | jq .

Fastify Backend Example#

npm install fastify rerius
// server.js
const Fastify = require('fastify');
const rerius  = require('rerius');

const app = Fastify({ logger: true });

app.post('/api/info', async (req) => {
    const { file } = req.body;
    return rerius.withBinary(file, bin => bin.info);
});

app.post('/api/functions', async (req) => {
    const { file } = req.body;
    return rerius.withBinary(file, bin => ({
        functions: bin.functions().map(f => ({
            name:       f.name,
            start:      String(f.start),
            size:       String(f.size),
            insnCount:  f.insnCount,
            hasCalls:   f.hasCalls,
            hasLoops:   f.hasLoops,
        }))
    }));
});

app.post('/api/full', async (req) => {
    const { file } = req.body;
    // Full analysis pipeline - symbols, funcs, xrefs, CFG, unicode
    return rerius.withBinary(file, bin => {
        const r = bin.analyze();
        return {
            info:      r.info,
            functions: r.functions.length,
            xrefs:     r.xrefs.length,
            blocks:    r.blocks.length,
            timing:    r.analysisTimeMs,
        };
    });
});

app.listen({ port: 3000 }, err => {
    if (err) { app.log.error(err); process.exit(1); }
});

TypeScript Example#

npm install rerius
# TypeScript declarations are bundled - no @types/rerius needed
// analyze.ts
import { withBinary, BinaryInfo, Function, Section } from 'rerius';

interface AnalysisReport {
    info:      BinaryInfo;
    topFuncs:  Function[];
    sections:  Section[];
}

export function analyzeFile(filePath: string): AnalysisReport {
    return withBinary(filePath, bin => ({
        info:     bin.info,
        topFuncs: bin.hottestFunctions(10).map(h => h.function),
        sections: bin.sections(),
    }));
}

// Async version
export async function analyzeAsync(filePath: string) {
    const { withBinaryAsync } = await import('rerius');
    return withBinaryAsync(filePath, async bin => {
        const r = bin.analyze();
        return {
            sha256:    r.info.sha256,
            functions: r.functions.length,
            isPacked:  bin.entropy().includes('PACKED'),
        };
    });
}

Advanced: Long-running Analysis Service#

For a server that analyzes many binaries, reuse binary handles to avoid repeated parsing:

const rerius = require('rerius');

// Cache parsed binaries keyed by SHA-256
const cache = new Map();

function getOrLoad(filePath) {
    const bin = rerius.load(filePath);
    const key = bin.sha256;
    if (cache.has(key)) {
        bin.close(); // close the duplicate
        return cache.get(key);
    }
    cache.set(key, bin);
    return bin;
}

// Clean up on process exit
process.on('exit',    () => cache.forEach(b => b.close()));
process.on('SIGINT',  () => { cache.forEach(b => b.close()); process.exit(0); });
process.on('SIGTERM', () => { cache.forEach(b => b.close()); process.exit(0); });

Handling BigInt in JSON Responses#

Rerius uses bigint for all addresses. JSON.stringify doesn't handle bigint natively. Two options:

// Option 1: Convert to hex strings before sending
const insns = bin.disasmJson('.text', { limit: 100 }).map(i => ({
    ...i,
    address: `0x${i.address.toString(16)}`,
}));

// Option 2: Custom JSON replacer
const replacer = (_, v) => typeof v === 'bigint' ? `0x${v.toString(16)}` : v;
res.json(JSON.parse(JSON.stringify(data, replacer)));

// Option 3: Use the built-in REST server (handles bigint automatically)
// node node_modules/rerius/server/server.js
// → http://localhost:7070

Built-in REST Server (zero extra code)#

Rerius ships its own REST server with 42 endpoints and a web UI:

# Start from node_modules
node node_modules/rerius/server/server.js

# Custom port
PORT=8080 node node_modules/rerius/server/server.js

# Programmatic start
const { createServer } = require('rerius/server/server');
createServer({ port: 8080 });

All endpoints: POST /api/<name> with { "file": "/absolute/path" } - see js/README.md for the full list.

Web UI: https://rerius.sbs


API Surface (quick reference)#

const rerius = require('rerius');

// Module-level
rerius.load(path)                    // → ReriusBinary
rerius.version()                     // → '1.0.0'
rerius.withBinary(path, cb)         // → T  (auto-close)
rerius.withBinaryAsync(path, cb)    // → Promise<T>

// ReriusBinary properties
bin.arch / .format / .os / .entry / .sha256 / .isPie / .isStripped / .hasDebug

// Analysis
bin.sections()           bin.symbols()           bin.functions()
bin.xrefs()              bin.xrefsTo(addr)       bin.xrefsFrom(addr)
bin.blocks()             bin.unicodeStrings()    bin.strings()
bin.hottestFunctions(n)  bin.analyze()

// Lookup
bin.symAt(addr)          bin.funcAt(addr)
bin.sectionByName(name)  bin.sectionAt(addr)
bin.readBytes(addr, len)

// Disassembly
bin.disasm(section?)
bin.disasmJson(section?, { limit, offset })

// Advanced (ARM64, RISC-V; symexec also x86-64 -- see docs/API.md for exact coverage)
bin.symexec(funcIdx?)    bin.ssa(funcIdx?)
bin.decompile(funcIdx?)  bin.emulate(funcIdx?, initRegs?)

// Detection
bin.entropy()            bin.rda(section?)       bin.ivf()

// Formats: ELF64 (all 3 archs) · ELF32 (RV32 only) · PE64+ · Mach-O 64/FAT · Raw
// (PE32 and ELF32 x86/ARM are not currently supported -- see docs/BINARY_FORMATS.md)

// Lifecycle
bin.close()
Edit this page on GitHub Source: docs/NPM_USAGE.md · Rerius v1.0.0
On this page
Using Rerius in a Backend Project How It Works Installation Basic Usage Express.js Backend Example Fastify Backend Example TypeScript Example Advanced: Long-running Analysis Service Handling BigInt in JSON Responses Built-in REST Server (zero extra code) API Surface (quick reference)
ESC
↑↓ navigate openesc close