← Back
caomod2077

caomod2077/Deobfuscator-Luraph-V15

A standalone, high-performance deobfuscator and devirtualizer for Roblox Luau scripts protected by Luraph v15.

View on GitHub ↗
deobfuscatordevirtualizerluauluraphluraph-v15reverse-engineeringroblox
Stars
118
Forks
70
Watchers
118
Open issues
5
Contributors
1
Language
JavaScript
License
MIT License
Default branch
master
Created Sep 26, 2026Updated Sep 29, 2026

Star growth

Today—
This week—
This month—

Star history will appear here once this repo has been tracked for a couple of days.

README

Luraph v15 Deobfuscator

License: MIT Platform Target

A standalone, high-performance deobfuscator for Roblox Luau scripts protected by Luraph v15.


Overview

Luraph v15 compiles Luau scripts into an interpreted virtual machine (VM) with flattened dispatch loops, encrypted memory buffers (LPH_ENCSTR, LPH_ENCFUNC), and anti-tamper crash traps (LPH_CRASH()).

This tool acts as a reverse compiler:

  • Recovers original control flow structures (if/else, while, for, repeat/until) from low-level VM dispatchers.
  • Decrypts lazy in-memory constants using a live sandboxed Luau runtime.
  • Isolates and bypasses anti-tamper traps to discover hidden code paths.

How It Works

The deobfuscator operates across 5 stages:

┌────────────────────────┐
│ Protected Luraph Script│
└───────────┬────────────┘
            │
            ▼
┌────────────────────────┐
│ 1. AST Hooking         │ ➔ Discovers VM dispatchers & hooks closure makers
└───────────┬────────────┘
            │
            ▼
┌────────────────────────┐
│ 2. Sandboxed Simulation│ ➔ Runs in offline Roblox VM; isolates anti-tamper traps
└───────────┬────────────┘
            │
            ▼
┌────────────────────────┐
│ 3. Live REPL Decryption│ ➔ Queries in-memory Luau VM to decrypt lazy constants
└───────────┬────────────┘
            │
            ▼
┌────────────────────────┐
│ 4. CFG & SSA Lifting   │ ➔ Reconstructs control flow graph & loop structures
└───────────┬────────────┘
            │
            ▼
┌────────────────────────┐
│ 5. Polish & Naming     │ ➔ Infers local variable names from Roblox API usage
└───────────┬────────────┘
            │
            ▼
┌────────────────────────┐
│ Clean Luau Source Code │
└────────────────────────┘
  1. AST Analysis & Hooking (vmmap): Parses the input script with luau-ast to map out the VM interpreter loop and closure constructors. Injects non-destructive telemetry hooks to track proto execution and register states.

  2. Sandboxed Simulation (harness): Executes the script inside an isolated, offline Roblox engine emulator (envlog.luau). If execution encounters an anti-tamper trap (LPH_CRASH()), the engine identifies the responsible function, disables the trap path, and reruns along stable branches.

  3. Live REPL Memory Decryption (devirt): Luraph's lazy encryption requires dynamic decryption keys. The engine communicates directly with an active Luau REPL process via IPC to decrypt string and numerical constants live in memory.

  4. Control Flow Graph (CFG) Reconstruction (structure, loops): Uses Sparse Conditional Constant Propagation (SCCP) to trace virtual register values. Basic blocks are assembled into a control flow graph, restoring nested loops (while, for, for-in) and branching logic (if/elseif/else).

  5. Polish & Variable Naming (backend, names): Virtual registers are analyzed across basic blocks using Static Single Assignment (SSA) web analysis. Variables are assigned context-aware names based on Roblox API usage (e.g. Players, TweenService, ReplicatedStorage), and the output is verified through syntax compilation.

For compiler theory, opcode mechanics, and detailed analysis passes, see TECHNICAL.md.


Features

  • Full Devirtualization: Recovers high-level control flow, closures, and scoping instead of simple trace logging.
  • Optimized Symbolic Engine: Shared mode-dispatch cache, iterative AST traversal, and declaration memoization deliver up to 2.1x faster devirtualization.
  • Robust Table Lifting: Handles table.pack-style packed lists ({n = count}) in VM registers, plus symbolic indexing, comparison, and boolean coercion on packed values.
  • Fast-Path Engine: Skips redundant verification passes once all constants are decoded live.
  • Offline Roblox Sandbox: Includes offline models for Roblox services, Path2D, UDim2, Vector3, CFrame, and executor globals. No Roblox client needed.
  • Self-Contained: Luau binaries, runtime emulators, and analysis modules are bundled directly inside this repository.

Luraph v14.x Support (EXPERIMENTAL)

Support for older Luraph builds is experimental and does not yet recover full source for every script. Honest status per version:

Version Status
v14.7 Lifts real source for many scripts (verified on multiple samples, e.g. a full hub script recovered statement-for-statement). Some samples still fall back to the behaviour trace or hit parser limits.
v14.8 Experimental. Detection and bytecode walking work; the lift often stops at runtime-built helper closures and falls back to the behaviour trace.
v14.9 Experimental. Same as v14.8, plus 1-2 MB blob decodes that are slow in the emulator. Full source recovery is not guaranteed.

The v14 engine shares the v15 core (trace harness, SCCP walk, structuring, codegen) and layers the v14 quirks on top:

  • version detection from the header or the return({...}) / local init = (function(... shapes;
  • VM chunk extraction: for bytecode-wrapper samples the VM lives inside a loadstring'd chunk, which is captured and instrumented automatically (the first pass aborts right after the chunk dump instead of executing the raw VM);
  • dispatch loops of both shapes (while true do local op=(ARR[pc]); ... and v14.8/v14.9's repeat ... until false), with parenthesised and type-asserted opcode fetches;
  • closure factories whose prototype is maker argument 0, often installed inside an initializer whose locals the VM closes over (recovered from the __venv runtime captures where the initializer builds them statically);
  • flattened handler state that reads an unresolved table or does arithmetic on a missing value stays symbolic instead of aborting the walk;
  • native LPH_NO_VIRTUALIZE closures are preserved as Luau source with their upvalue bindings rebuilt.

What is still missing for full v14.8/v14.9 source recovery: the runtime-built VM-object tables whose methods are re-indexed numerically at run time (e.g. obj[54]) are not yet bound back to their AST definitions, so those lifts abort and the behaviour trace is written instead.

node deob.js sample/v14/v14.7/<sample>.lua -o out.lua

Large v14.8/v14.9 samples (1-2 MB) need longer budgets because the bytecode blob decode is slow in the emulator:

node deob.js sample.lua --timeout 1200 --budget 1200 -o out.lua

Batch mode can process a folder with parallel jobs:

node deob.js sample/v14/v14.7 --jobs 4

Quick Start

Prerequisites

  • Node.js: v18.0.0 or higher
  • Python: 3.10 or higher (powers the backend symbolic execution engine)

Installation

Clone the repository and install dependencies:

git clone https://github.com/caomod2077/Deobfuscator-Luraph-V15.git
cd Deobfuscator-Luraph-V15
npm install

Basic Commands

# Deobfuscate a single script (saves to ./output/<filename>)
node deob.js input.lua

# Save to a specific output path
node deob.js input.lua -o output.lua

# Batch mode: process a whole folder of scripts
node deob.js ./my_scripts_folder/

# Batch mode: process multiple files at once
node deob.js file1.lua file2.lua file3.lua

# Fast trace-only mode (~2 seconds, skips bytecode lifting)
node deob.js input.lua --no-devirt

# Detect if a script is protected by Luraph without running it
node deob.js input.lua --detect

Note: If your system uses a different Python command (py, python3, or a virtual environment binary), set the PYTHON_BIN environment variable:

set PYTHON_BIN=py        # Windows
export PYTHON_BIN=python3   # Linux / macOS

Performance

The engine has been heavily optimized (symbolic AST caching, iterative tree walks, single-pass state analysis, shared dispatch-loop cache, and a bounded SCCP walk). Measured on the bundled sample/ scripts, the current build is 1.6x to 1.8x faster than the previous release, and scripts that previously crashed now lift completely:

Benchmark Size Functions Before After Speedup
Blox Fruit.lua 646 KB 520 2m 04s 1m 02s 2.0x
+1 Speed Keyboard Escape.lua 543 KB 316 1m 17s 37s 2.1x
Grow A Garden 2 (1).lua 645 KB 545 3m 51s 2m 25s 1.6x
Grow a Garden.lua 804 KB 767 1m 54s 1m 51s 1.0x
9eccab05cff67267.lua 222 KB 36 crashed 4m 02s fixed
5ae248d6527b5c01.lua 170 KB 1 3.7s 3.7s —

Additional stress tests on fresh scripts (run once with the current build, no baseline):

Stress Test Size Functions Time Result
StealAnEgg.lua 1.62 MB 1,723 12m 21s 32,435 lines (1.8 MB)
Steal-a-Brainrot.lua 1.07 MB 1,138 6m 59s 19,407 lines (463 KB)
JumpForAnimals.lua 503 KB 457 1m 38s 7,217 lines (160 KB)
RideAPet.lua 397 KB 328 55s 5,170 lines (113 KB)

Every input and its reference deobfuscated output is committed in sample/ and sample/output/. All outputs pass luau-ast syntax validation (COMPILE OK). StealAnEgg.lua lifts 99.97% of its 1,723 functions; the remaining 46 blocks (0.03%) are guarded with an explicit error("devirt: unexplored successor ...") marker instead of silently emitting wrong code.

Reproduce it yourself — every input in the table above ships in sample/ and the expected deobfuscated result for each one is committed in sample/output/, so you can verify both the timings and the output quality on your own machine:

node deob.js "sample/Blox Fruit.lua" -o "output/Blox Fruit.lua"
node deob.js "sample/9eccab05cff67267.lua" -o "output/9eccab05cff67267.lua"

Hardware used for the table: consumer Windows machine, Node.js 24, Python 3.12. Exact times vary with CPU and background load; the relative speedup holds.


Frequently Asked Questions (FAQ)

Q: How long does deobfuscation take?

Script Size Function Count Average Time Mode
Small / Micro Script 1 – 20 functions 1 – 5 seconds Full Devirtualize
Medium Script (Hubs) 50 – 200 functions 15 – 35 seconds Full Devirtualize
Large Script (Full Games / Complex) 500 – 750+ functions 1 – 2 minutes Full Devirtualize
Any Script (Trace Mode) Any size 1 – 3 seconds --no-devirt

Q: Why do large scripts take 1 to 2 minutes?

Luraph v15 is a virtual machine obfuscator, not simple encryption. The deobfuscator performs full compiler-grade reverse compilation:

  1. It symbolically simulates virtual registers across thousands of instruction paths.
  2. It sends requests to an in-memory Luau VM to decrypt 2,000–2,600 constants on-the-fly.
  3. It performs dominator tree analysis to reconstruct nested control flow loops.
  4. It analyzes register lifetimes to assign clean local variables across 10,000+ lines of code.

The current build cuts this cost with a shared dispatch-loop cache (mode resolution is computed once per VM instead of once per function), iterative AST walkers with declaration caching, a single-pass state-variable analysis, and a converged SCCP walk limit that keeps CFG minimization proportional to real code size.

Q: How can I deobfuscate in just a couple of seconds?

If you only need to see what a script does (URLs fetched, remotes fired, UI setup, webhooks) without needing the full lifted source code, use the --no-devirt flag:

node deob.js input.lua --no-devirt

This runs the script in the sandboxed Luau runtime and extracts the complete execution trace in ~2 seconds.


Command Line Options

Option Short Default Description
--output <file> -o ./output/<name> Custom destination path for the deobfuscated file
--no-devirt false Fast execution trace only (skips VM bytecode lifting)
--no-hooks false Disable VM closure entry instrumentation
--no-fold false Disable loop and helper folding in trace mode
--timeout <sec> 90 Hard timeout per Luau execution pass
--budget <sec> 30 Soft execution budget for script runtime
--max-runs <n> 12 Maximum reruns allowed for anti-tamper traps
--devirt-rounds 200 Maximum constant decryption rounds
--detect false Detect and print obfuscator type, then exit
--debug false Keep intermediate disassembly files in output folder

Technical Details

For in-depth explanations of the reverse-engineering methodology, SCCP symbolic evaluation, opcode dispatcher mapping, and SSA register renaming, see TECHNICAL.md.


License

This project is open-source under the MIT License.

Credits

Thanks source to ccjvwsod on Discord This version was rebuilt by me using Node so that multiple Deobf instances can run simultaneously


Support The Project

If this tool saved you time, consider buying me a coffee. Every donation keeps the updates coming (new obfuscator versions, faster lifts, better structuring).

Bitcoin (BTC)

Bitcoin

Ethereum (ETH)

Ethereum

Litecoin (LTC) Litecoin

Tron (TRX) Tron

Mb bank (cho ai ng việt muốn donate) Mb bank