Module refinery.units.scripting.js

Expand source code Browse git
from __future__ import annotations

from refinery.lib.scripts.js.deobfuscation import deobfuscate
from refinery.lib.scripts.js.model import JsScript
from refinery.lib.scripts.js.parser import JsParser
from refinery.lib.scripts.js.synth import JsSynthesizer
from refinery.units.scripting import IterativeDeobfuscator


class js(IterativeDeobfuscator):
    """
    AST-based JavaScript deobfuscator and pretty-printer.

    Parses the script into an abstract syntax tree, applies simplifying transformations, and
    synthesizes clean output. This deobfuscator iterates until stable; running it twice does
    not change the output.
    """

    def parse(self, data: str) -> JsScript:
        return JsParser(data).parse()

    transform = staticmethod(deobfuscate)

    def synthesize(self, ast: JsScript) -> str:
        return JsSynthesizer().convert(ast)

Classes

class js (timeout=500)

AST-based JavaScript deobfuscator and pretty-printer.

Parses the script into an abstract syntax tree, applies simplifying transformations, and synthesizes clean output. This deobfuscator iterates until stable; running it twice does not change the output.

Expand source code Browse git
class js(IterativeDeobfuscator):
    """
    AST-based JavaScript deobfuscator and pretty-printer.

    Parses the script into an abstract syntax tree, applies simplifying transformations, and
    synthesizes clean output. This deobfuscator iterates until stable; running it twice does
    not change the output.
    """

    def parse(self, data: str) -> JsScript:
        return JsParser(data).parse()

    transform = staticmethod(deobfuscate)

    def synthesize(self, ast: JsScript) -> str:
        return JsSynthesizer().convert(ast)

Ancestors

Subclasses

Class variables

var reverse

The type of the None singleton.

Static methods

def transform(ast, max_steps=5000)

Apply all available deobfuscators to the input. A non-zero max_steps bounds the total number of change-producing transformer passes and raises DeobfuscationTimeout once it is exceeded, so a transform that fails to converge fails loudly instead of hanging. The default is generous — real inputs settle in a few to a few dozen passes (the differential corpus peaks in the low tens) — so it never bounds a legitimate deobfuscation, only a runaway loop. Pass 0 to disable the bound entirely.

Expand source code Browse git
def deobfuscate(ast: JsScript, max_steps: int = 5000) -> int:
    """
    Apply all available deobfuscators to the input. A non-zero *max_steps* bounds the total number of
    change-producing transformer passes and raises
    `refinery.lib.scripts.pipeline.DeobfuscationTimeout` once it is exceeded, so a transform that fails
    to converge fails loudly instead of hanging. The default is generous — real inputs settle in a few
    to a few dozen passes (the differential corpus peaks in the low tens) — so it never bounds a
    legitimate deobfuscation, only a runaway loop. Pass `0` to disable the bound entirely.
    """
    return _pipeline.run(ast, max_steps=max_steps, models=ModelCache(ast))

Methods

def parse(self, data)
Expand source code Browse git
def parse(self, data: str) -> JsScript:
    return JsParser(data).parse()
def synthesize(self, ast)
Expand source code Browse git
def synthesize(self, ast: JsScript) -> str:
    return JsSynthesizer().convert(ast)

Inherited members