disrobe: static software recovery

Recover source, unpack payloads, and trace the evidence back to the input.
disrobe is a Rust command-line suite for examining compiled and obfuscated software. It decompiles supported bytecode and native code, reverses source obfuscation, extracts frozen applications and embedded frontends, and unpacks supported packers, archives, and firmware containers. Recovery reports identify the input, the stages that ran, the artifacts they produced, and the conditions that prevented further recovery.
The default path never executes the sample. One opt-in PyArmor v6/v7 fallback does execute it and requires --allow-dynamic; use that path only inside an isolated sandbox. Start with the forensics and malware-safety posture when handling untrusted material.
Watch or download the full video · Read the transcript. Twenty CLI commands cover unpacking, source recovery, Android resources, indicators, reports, artifact verification, and project setup in 2 minutes 12 seconds. The transcript includes the recorded build's complete command inventory.
Try it in your browser: the
disrobeplayground. Decompile a.pyc, scan a pickle for malicious reduce callables, and summarize a.wasmmodule, all client-side, with the core passes compiled to WebAssembly. Nothing is uploaded.
The live catalog spans 15 ecosystems: Python, JavaScript and TypeScript, WebAssembly, JVM and Android, .NET, native PE/ELF/Mach-O/NE, Go, Lua, PHP, Ruby, Erlang and Elixir on BEAM, Swift and Objective-C, ActionScript 3, mobile runtimes, and shell languages. The implemented native-packer tier currently lists Donut, sRDI, UPX, ASPack, Petite, MPRESS, FSG, PECompact, Yoda's Crypter, NSPack, MEW, kkrunchy. Run disrobe catalog [ecosystem] for the per-family recovery tier compiled into your binary.
Guarantees and boundaries
- No model runs in the recovery path. Metadata bundles are deterministic structured data for downstream tools.
- Output ordering and serialization are checked by hashing three fixture recoveries across Linux, macOS, Windows, and batch runs with one and four workers.
- The main CLI ships as one Rust binary. In-house paths launch no external program. Commands with optional backends invoke an installed tool only when you name it with
--backend. - The shared artifact layer can store recovered state in a content-addressed
.drenvelope with an rkyv payload, postcard sidecar, and BLAKE3 root. Chain runs record topology and per-stage provenance separately. - Python's normalized opcode-structure agreement is 95.18% on a fixed 574-module CPython 3.14 core population (17396 of 18276 code objects), excluding
idlelibandturtledemo. Its pinned 200-module subset reaches 97.66% (6139 of 6286). See the comparison rules.
Start with an artifact
After installation, replace sample.bin with the file you want to examine:
disrobe auto sample.bin --out recovered/ --capture-stages
disrobe context --out recovered/
disrobe report recovered/ --format html > recovery.html
auto selects recovery passes from the file's bytes. context summarizes their outcomes; the HTML report brings the artifact inventory, evidence, and recovery limits into one document. --capture-stages retains intermediate bytes so you can inspect a layer or pass it to another tool. The quickstart explains the output and direct commands.
| Your task | Useful starting point |
|---|---|
| Triage a packed or obfuscated sample | Automatic recovery, followed by recon and indicator extraction over the recovered files |
| Document a forensic examination | Run reports with input digests, artifact locations, stage outcomes, and provenance |
| Audit a closed binary or investigate a vulnerability | Native recovery, queryable IR and capabilities, and the relevant language guide |
| Recover your own lost source | Direct decompilation of a supported .pyc, .jar, .dll, or JavaScript bundle; start with the quickstart examples |
| Build recovery into another tool | Rust library APIs, typed Python bindings, daemon protocols, metadata bundles, or the browser playground |
Choose a recovery path
disrobe passes lists direct command families and the automatic recovery routes included in the current build, with their ecosystems and support tiers. Direct commands also provide recon, taint analysis, and optional external decompilers. Electron and Tauri frontends use webview.carve; Wails can use Go's embedded-filesystem route. Use disrobe --help for commands and disrobe catalog [ecosystem] for recognized families.
In-house recovery remains available without optional toolchains. JVM, Android, .NET, and native commands can also use installed tools such as CFR, Vineflower, jadx, ILSpy, de4dot, or Ghidra where their command-specific backend policy allows it. disrobe doctor reports what is installed; it does not make an unavailable backend part of an in-house result.
Measured recovery
Every figure below comes from a committed test gate or a local measurement harness. strong figures are graded against an independent oracle; coverage-self-reported figures state the inspected population and count disrobe's own output. The full per-value sourcing lives in xtask/data/recovery.json.
Open the full-size recovery chart.
Colour identifies the comparison method. A filled mark denotes a CI gate on its documented triggers; a hollow mark denotes a local measurement. Each descriptor lists its inputs and prerequisites.
| Ecosystem | Measured | Oracle |
|---|---|---|
| Python bytecode | Normalized opcode-structure agreement: 95.18% across the fixed 574-module core population (17396 of 18276); 97.66% on the pinned corpus (6139 of 6286). Whole-module agreement, where every compared code object matches: 130 of 200 modules | CPython 3.14.5 compilation and normalized opcode comparison; jump targets and most operands are excluded |
| WebAssembly | 1034 of 1034 opcodes lowered across the 38 parseable modules (133 of 133 functions), counted against an inventory wasm-tools produced rather than one disrobe produced; 57 of 57 execution-eligible functions equivalent | external opcode inventory for coverage, wasmtime differential for execution |
| JVM classfile | 131 of 131 methods recompile error-free | real javac |
| Android (Dalvik) | 100% of the verifier-presented classes in the committed dex corpus pass the JVM verifier (118 of 118). A further 37 of 155 classes are link-skipped and never reach the verifier, because they reference supertypes the harness does not bundle, so those are ungraded rather than passing | -Xverify:all over assembled jar |
| Ruby YARV | greeter 100%, megafile 100% original opcode-name multiset recall | recompile on MRI; ordering, operands and additional opcodes are excluded from this score |
| PyArmor | 72 / 72 manifest-named v8/v9 default-trial wrappers decrypt and decode one complete header-anchored root CodeObject | self-reported structural check; no source, emitted .pyc, semantic, execution, or external comparison |
| Containers | 103 formats detected, including a bounded raw-volume-key LUKS1 route; 30 generic routes write member bytes from a committed input that match an independent extractor | extraction over the committed corpus, pinned per format; tracked LUKS1 plaintext comparison |
Recovery reports include support tiers and per-stage outcomes. Native-virtualized code, runtime-only keys, and RSA-wrapped capsule keys remain detect-only when the required information is absent from the input.
Recovery limits
An unsupported instruction, ambiguous signature, or unavailable runtime key can stop a recovery stage. Its report names the reason and retains the recovered structure available up to that point. Supplying additional artifacts, such as a matching runtime or name map, can make another recovery path available. See reading a result for outcomes and error codes.
Where to start
- First run: Installation, then Quickstart.
- The design: Architecture overview, then the five-rung IR ladder.
- One language: its language guide.
- The full family list: the supported families catalog, or
disrobe catalog [ecosystem]. - Triage of stripped code or recovered source: queryable IR and capabilities and recon, prowl, and indicators.
- Embedding: Use it as a library, or the browser playground first.
- An exact command or flag: the CLI command reference.
- Untrusted samples: Forensics and malware-safety posture, before anything else.
Installation
Install disrobe from GitHub Releases or build the CLI from source. GitHub Releases is the canonical distribution point for the standalone binary; the Python bindings are a separate integration.
Prebuilt binaries (recommended)
Each tagged release includes prebuilt binaries for the common targets, alongside SHA256SUMS, a cosign keyless signature bundle per archive, a GitHub build-provenance attestation, and a CycloneDX SBOM. See SECURITY.md for artifact verification.
| OS | Architectures |
|---|---|
| Windows 10/11 | x86-64, ARM64 |
| Linux (glibc) | x86-64, ARM64 |
| Linux (musl) | x86-64 |
| macOS 13+ | x86-64, ARM64 (Apple Silicon) |
-
Download the archive for your platform from the Releases page.
-
Verify the checksum:
sha256sum -c SHA256SUMS # Linux / macOS -
(Optional) verify the cosign signature against the Sigstore transparency log:
cosign verify-blob \ --certificate-identity-regexp '^https://github.com/1-3-7/disrobe/' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ --bundle disrobe-<version>-<target>.tar.zst.cosign.bundle \ disrobe-<version>-<target>.tar.zst -
Extract and place
disrobe(disrobe.exeon Windows) anywhere on yourPATH.
Build from source
The workspace declares Rust 1.95 as its minimum supported version. Use the repository's selected Rust toolchain and a linker/C toolchain for your target; native dependencies also compile during the build. On Windows with the MSVC target, install the Visual C++ build tools and Windows SDK. Optional analysis backends and the language runtimes used by grading tests are separate prerequisites.
git clone https://github.com/1-3-7/disrobe
cd disrobe
cargo build --locked --release -p disrobe-cli --bin disrobe
./target/release/disrobe --version
The binary lands at target/release/disrobe; copy it onto your PATH.
Per-OS notes
- Windows: the binary is
disrobe.exe. - Linux: the musl build is fully static; the glibc build needs a matching glibc.
- macOS: x86-64 and ARM64 (Apple silicon) archives are published separately. Gatekeeper may quarantine an unsigned download; clear it with
xattr -d com.apple.quarantine disrobe.
The dependency boundary
The required tools depend on whether you are building the CLI, selecting an external backend, or reproducing a measurement.
| Category | What is in it | What breaks without it |
|---|---|---|
| CLI build | Supported Rust toolchain and target linker/C toolchain | The CLI cannot be built until its compiler and native dependency prerequisites are present |
| Optional backend | Ghidra, CFR, jadx, ILSpy, de4dot, and others, selected by the command's backend option | Behavior depends on the command's selection and fallback contract; inspect the reported backend, especially when the requested tool is unavailable |
| Grading only | CPython, javac, the real JVM verifier, wasmtime, lua/luac, MRI, the .NET SDK, and the Go toolchain | One grade: the recovery is unaffected, but that ecosystem's number cannot be regraded locally |
| Benchmark repro only | The pinned competing tools in evidence/competitors/ | One number: the head-to-head row cannot be reproduced; disrobe's own recovery is unaffected |
The per-ecosystem list for the last two rows is in evidence/README.md.
Slim build
The CLI's default features select the full build. For a smaller artifact, the slim build keeps the always-on core and drops optional passes. A command can remain visible in help while its implementation reports that the corresponding feature was not compiled in:
cargo build -p disrobe-cli --release --no-default-features
# same build, shorter
cargo build-slim
Slim excludes optional language passes and their dependencies, including native, Python, WebView, and the embedded JavaScript and WebAssembly toolchains. Core byte inspection and static string extraction remain available. It also excludes optional service and collection surfaces. The dependency-tree gate enforces the expected crate graph for the selected features.
Binary size and command availability depend on the target, source revision and selected features.
Compare builds of the same revision with the same compiler and profile before claiming a size
reduction. Some commands are omitted from help; others, including wasm, remain declared and
report the missing feature when invoked:
$ disrobe wasm decompile app.wasm
Error: the `wasm` pass is not compiled into this binary (slim build); rebuild with default features (feature `wasm`)
Layer specific passes back onto a slim base with --features, for example
--no-default-features --features native,py,webview or --no-default-features --features wasm,jvm.
Git history scanning uses the git-history feature, which the full build includes. In a slim
build, frisk --git reports that this feature is required; use --features git-history to enable it.
Verifying the install
disrobe --version # print the version
disrobe passes # direct families plus auto-chain pass IDs
disrobe --help # full subcommand surface
disrobe <pass> --help # drill into any pass, e.g. `disrobe py --help`
Optional external backends
Disrobe includes its own recovery engines for native code and the supported bytecode languages. External backends add rendering and analysis paths: Ghidra for native decompilation; CFR, Vineflower, Procyon, and JADX for JVM and Android inputs; ILSpy, dnSpy, dnSpyEx, and de4dot for .NET. Backend selection is command-specific. JVM and .NET decompilation invoke an installed tool only when --backend names it; the JVM and .NET disrobe auto passes use their in-process engines. Recompilation checks have separate compiler/interpreter prerequisites, as listed above.
Probe what is installed and what is missing:
disrobe doctor # probe 46 to 51 external tools depending on the platform
disrobe doctor --auto-install # install every missing tool that has a known install action
A missing tool with no install action (a commercial tool, a tool that ships bundled with another
tool, a platform-exclusive tool, or a tool preinstalled by the operating system) is not silently
dropped. --auto-install records it as a skip with a typed reason, in both text and --json
output.
Install a single tool through your platform's native package manager (winget / brew / apt / dnf / pacman / apk). disrobe never installs itself this way; it only fetches the optional backends:
disrobe install --list # list every known tool + per-platform package name
disrobe install ghidra
disrobe install upx
Heavyweight dependencies that ship as upstream release archives rather than OS packages (Ghidra, for instance) have a dedicated installer:
disrobe install-deps ghidra
disrobe install-deps --all
Shell completions and man pages
disrobe completions bash --install # also: zsh, fish, powershell, elvish
disrobe man --out ./man # one .1 page per subcommand
Quickstart
This walkthrough takes a local file through automatic recovery, inspects the result, and shows how to select a direct command when you know the format. Replace the example filenames with your own inputs.
Check the installation
Follow installation, then confirm which binary and optional tools are available:
disrobe --version
disrobe doctor
doctor reports installed, missing, and stale external tools. The in-house recovery paths do not require all of them. Install a tool when the command or verification step you need requires it; see optional backends.
For a first run, use a file you own or a trusted compiled fixture. For an untrusted sample, read the handling guidance first. The default recovery path does not execute the input.
Auto-detect and chain
disrobe auto suspect.exe --out recovered/ --capture-stages
disrobe context --out recovered/
disrobe report recovered/ --format html > recovery.html
auto identifies the input and selects a recovery chain from the available passes. Open recovery.html for the artifact inventory, evidence, and stage outcomes. context gives a shorter terminal view of the passes that ran, their confidence tiers, the final verdict, and provenance.
The output directory contains chain.json, recovery.json, anti-analysis.json, and report.json. Use these structured reports when another tool needs the topology, recovery status, or forensic summary. Check the input identity and any incomplete or failed stages before treating the recovered files as a complete account of the input. See reading a result for the status vocabulary and next steps.
The selected passes depend on the bytes recovered at each stage:
| Input | Automatic route and output |
|---|---|
| UPX-packed Go executable | native.packer-unpack recovers the executable; go.classify recovers Go runtime metadata and symbols |
| PyInstaller containing a supported PyArmor wrapper | pyinstaller.extract extracts members; pyarmor.unpack uses available runtime/key material; py.decompile handles recovered bytecode |
| Android APK | jvm.classify recovers DEX source, manifest information, and supported child artifacts |
| Electron ASAR | webview.carve extracts the frontend tree; recognized JavaScript children can continue through js.deob |
Read the pass list and the recovery report for the route and support tier actually selected. A missing key or unsupported variant can end a branch before source recovery.
Use --capture-stages to mirror the exact bytes written by each executed pass under <out>/NN-<pass>/ and link the terminal stage or stages under <out>/final/. These are exact stage records; a decompiler's source output is not a byte-identical copy of the compiled input. Cap the chain depth with --max-depth (default 8).
Per-language one-liners
Choose a direct command when you know the format or want to inspect one layer of a chain. The output path in each example identifies the source file, extracted tree, or report to inspect next. Run disrobe <command> --help before relying on a backend or emit that is not shown here.
Python bytecode and frozen applications
Decompile a .pyc, inspect its instructions, clean obfuscated source, or extract an application bundle:
disrobe py decompile module.pyc --out recovered/
disrobe py disasm module.pyc --out trace.txt
disrobe py deob obfuscated.py --out clean.py --cleanup
disrobe pyinstaller extract onefile.exe --out out/
disrobe pyarmor unpack protected.py --out out/
disrobe nuitka extract app.exe --out out/
Python's default round-trip check needs a matching interpreter. Read its result before relying on the emitted source; a missing interpreter leaves the comparison unperformed. Python recovery describes the comparison and version limits.
PyArmor v6/v7 may require the dynamic-hook fallback. That path executes the sample and is disabled unless you add --allow-dynamic. Use it only inside an isolated sandbox with no network or sensitive mounts. PyArmor v8/v9 and --allow-bcc remain static.
JavaScript, WebAssembly, and embedded frontends
Clean a bundle, split its modules, lift WebAssembly, or extract a desktop application's frontend:
disrobe js deob bundle.min.js --out clean.js
disrobe js unbundle app.bundle.js --out src/
disrobe wasm decompile module.wasm --target rust --out lifted.rs
disrobe webview desktop.exe --out frontend/
JVM, Android, and .NET
These examples request installed external backends. Check doctor and the command's reported backend: availability and fallback behavior are command-specific. The corresponding auto passes use in-house recovery.
disrobe jvm decompile app.apk --backend jadx --out src/
disrobe dotnet decompile App.dll --backend ilspy --out src/
Native executables and Go
Unpack an executable or recover symbols and Go runtime metadata:
disrobe native unpack packed.exe --out unpacked.bin
disrobe native symbols app.exe --out symbols.json
disrobe go recover app --out symbols.json
disrobe catalog native
For source recovery and architecture limits, see the native decompiler. A symbol report and recovered function bodies answer different questions; inspect the artifact the selected command actually emits.
Mobile runtimes and other bytecode
Recover the supported source or structural view for the input:
disrobe hermes decompile index.android.bundle --out surface/
disrobe flutter dump libapp.so --out layout.json
disrobe lua decompile script.luac --out script.lua
disrobe ruby decompile app.rb
disrobe php decode payload.php --out out/payload-php/
disrobe beam parse module.beam
Use the catalog to inspect each family's Recover, Partial, or Detect-only support tier:
disrobe catalog python
Extract indicators from recovered files
frisk scans local files offline for secrets, endpoints, and indicators, with source locations:
disrobe frisk recovered/ --format json > frisk.json
Network enrichment is a separate step. prowl queries the selected public archives and feeds for a domain or URL; use a target you intend to disclose to those providers. indicators merges the local and network reports and can print a deduplicated target list:
disrobe prowl example.com --subs --sources wayback,urlscan,crtsh --format json > prowl.json
disrobe indicators frisk.json prowl.json --targets-only > targets.txt
Secret values remain visible by default in recon reports. See recon, redaction, and indicators before sharing them.
Structured output
The global --json, --ndjson, and --sarif flags select machine-readable output where a command supports those formats. For example, scan can emit SARIF 2.1.0 for GitHub code scanning:
disrobe scan firmware.bin --sarif > findings.sarif
Inspecting a run
To revisit a chain run without rerunning recovery:
disrobe context --out recovered/
If a stage failed, use its reported DR- error code with disrobe explain. A registered entry describes the cause and the input or prerequisite that may resolve it. Reading a result also covers stalls, caps, cycles, and verification failures.
If you created or received a .dr envelope, inspect its metadata and verify its integrity separately:
disrobe envelope inspect module.dr
disrobe verify module.dr
Generating a metadata sidecar
Commands that implement metadata bundles accept --metadata-pack-1 through --metadata-pack-4. --llm is a compatibility alias for pack 4; it does not run a model.
disrobe py decompile module.pyc --out recovered/ --metadata-pack-4 --llm-briefs
See metadata sidecar and provenance for the full category and pack model.
Reading a result
Start by confirming the input identity, then inspect the recovered artifacts and the stages that stopped. The reports let you connect a result to the bytes supplied and decide whether another pass, tool, or input can help. A source file, a symbol list, and a detection report provide different evidence; the output's presence alone does not establish complete recovery.
What a run leaves behind
disrobe auto and disrobe chain write four documents into the output directory, and a fifth, run.json, when --timings is given.
| File | Contents |
|---|---|
chain.json | The executed topology, schema disrobe.chain/v2. One node per stage with its pass id, input and output BLAKE3, sizes, the detector pick that selected it, a per-stage verdict, optional registered string metadata, and an error string when a stage failed. |
recovery.json | The per-run report, schema disrobe.recovery/v2. Each stage's status and confidence tier, and a tier histogram. |
anti-analysis.json | Anti-analysis techniques observed across the run. See anti-analysis defeat. |
report.json | The forensic summary rendered by disrobe report, including findings and their evidence. |
run.json | Written only with --timings, schema disrobe.run/v1: the start and end clocks, the worker count, the tool version, the run's duration, and each node's duration keyed by node id. No other document records a duration, the worker count, or a clock, so two runs over one input write identical documents. |
Use disrobe context for a terminal summary of recovery.json:
disrobe auto sample.bin --out ./out/sample --capture-stages
disrobe context --out ./out/sample
The summary prints the input identity, overall verdict, tier histogram, and stage rows. This recorded run on the repository's corpus/webview/tauri/wvfix.exe fixture used version 0.10.5; its timings describe that run:
schema: disrobe.recovery/v1
tool: 0.10.5
verdict: FanOutPartial
total_ms: 468
tiers: exact=0 semantic=1 partial=0 skeleton=11 (total 12)
passes:
webview.carve advanced skeleton 53ms
terminal incomplete skeleton -
disrobe report ./out/sample renders the same run as text, markdown, JSON, or a self-contained HTML page, and adds a recovery score, the artifact inventory, and the detect-only and skeleton caveats. See run reports.
Pass --capture-stages on any run you expect to debug. It mirrors the exact bytes written by each stage to ./out/sample/NN-<pass>/output.bin and links the terminal stages under ./out/sample/final/, which lets you re-enter the pipeline at the stage that stopped. Exact capture does not mean a decompiler's source output is byte-identical to the compiled input. Without capture you have the verdicts but not the stage bytes.
Support, confidence, and status
Read these labels together: the family's supported recovery, the confidence assigned to this stage, and the stage's execution status.
A support tier describes a family, not a run. It is the standing claim about how far recovery goes for that packer or obfuscator, and it comes from the catalog or disrobe catalog <ecosystem>: Recover, Partial, or Detect-only.
A confidence tier describes one stage of one run. It comes from recovery.json, and the four values, ranked, are exact, semantic, partial, skeleton. A family at support tier Recover can still produce a skeleton stage on your sample. Check the pass's output and verification result to determine which bodies or structures were recovered.
Stage status is a third axis, with five values:
| Status | Set when |
|---|---|
recovered | The stage completed with output, or extracted children. |
advanced | The stage produced output the chain then fed onward. |
incomplete | The branch ended at a stall, a cycle, or a cap. |
failed | The pass returned an error, which includes a stated refusal. |
skipped | A plan-only run (disrobe auto --dry-run), where nothing executed. |
The chain stopped early
Symptom. Chain verdict Stalled in the text view, "stalled" in JSON. The last disrobe context row is named terminal, with status incomplete and confidence skeleton:
verdict: Stalled
tiers: exact=0 semantic=0 partial=0 skeleton=1 (total 1)
passes:
terminal incomplete skeleton -
Meaning. No detector result for that stage's bytes met the selection floor of 0.5. The runner stopped because it could not select a pass with sufficient confidence. No pass executed at that node, so the terminal row has no pass name to attribute a recovery to. A stall does not establish that the input is unrecoverable.
chain.json's stats.rejected_passes counts candidates dropped below the floor across the run. A nonzero count records low-confidence detections somewhere in the run; it does not identify the stalled artifact by itself.
Next. Identify the stalled bytes, then select a supported pass explicitly if its input requirements match. The stage path below is an example; use the path from your capture.
disrobe detect ./out/sample/final/02-pyinstaller-extract/output.bin
disrobe identify ./out/sample/final/02-pyinstaller-extract/output.bin
disrobe chain sample.bin --chain 'pyinstaller.extract,pyarmor.unpack,py.decompile' --out ./out/sample-explicit
An explicit --chain bypasses detector selection for the passes you name, so a family that scored 0.4 still gets its pass run. It does not supply missing keys or make an unsupported input valid. Chain pass IDs are dotted and comma-separated (pyinstaller.extract, pyarmor.unpack, py.decompile, native.packer-unpack, binfmt.container, and the rest), and a trailing ,* hands the remaining depth back to auto-detection. disrobe passes lists the chain IDs available in your binary after its direct-command summary. An unknown ID fails with DR-CLI-0298 and lists the registered IDs.
When auto recovers nothing it already prints a note on stderr naming the format it thinks it saw and the command group to try:
note: auto recovered no files and could not identify the format. Run `disrobe detect <file>` to identify it, then the matching subcommand.
The chain hit a cap
Symptom. Verdict CapReached, or "cap-reached" in JSON, on a branch that still had unprocessed output.
Meaning. One of two bounds stopped the branch: the depth cap, eight passes by default, or the cumulative-output budget of 512 MiB across the whole run. Both bound work on nested archives and repeatedly emitted output; see depth and cycle safety. A cap records unfinished processing. Inspect the completed stages and their captured output before deciding how to continue.
Next. If the report identifies the depth cap, increase it within the supported limit. Otherwise, split the work and re-enter on the captured child you need to examine. Substitute its actual capture path in the second command:
disrobe auto sample.bin --max-depth 16 --out ./out/sample --capture-stages
disrobe auto ./out/sample/final/03-binfmt-container/output.bin --out ./out/sample-inner
Sixteen is the ceiling for --max-depth; above it the spec is rejected. The cap is also settable per project as max_depth under [execution] in .disrobe.toml. The byte budget is fixed and not exposed as a flag, so a run that exhausts it has to be split.
The chain saw the same bytes twice
Symptom. Verdict Cycle.
Meaning. A stage produced bytes already seen earlier in the chain. Each stage output is content-hashed with BLAKE3, and a repeat stops the branch instead of looping. Usually this is a pass that did not change its input, or an archive that contains itself.
Next. Compare input_blake3 and output_blake3 across the nodes in chain.json to find the stage that repeated, then run that stage's pass directly on the captured bytes to see what it did and did not change.
A body came back as a skeleton
Symptom. Confidence skeleton on a stage that did execute, or a nonzero skeleton count in the histogram.
Meaning. The chain assigns semantic to a stage that completed with source output and partial to one that completed with a byte payload. Everything else is skeleton, so at chain level the tier tells you the stage did not produce a recognized recovery, not how much of each body survived. For that, read the pass's own output. Passes that recover bodies separate the levels explicitly rather than mixing them: disrobe nuitka decompile writes real source lifted from frozen bytecode into frozen/ and typed signatures of native-compiled modules into skeleton/, and labels each in its disrobe.nuitka.recovery-manifest/v1 sidecar (decompiled-from-bytecode against signatures-only-native-compiled), so no signature is ever presented as a recovered body.
Check whether the report identifies a missing lifter operation or data absent from the artifact, such as a runtime-only decryption key. A different recovery engine may handle the former. The latter requires additional material; retrying the same bytes cannot supply it.
Next. Check the family's standing support tier, then read the code the pass emitted.
disrobe catalog python
disrobe explain DR-PYARM-0013
Names and signatures can still locate modules or functions for further analysis. Keep their signatures-only status with the result so a consumer does not treat them as recovered implementations.
A pass reported a refusal
Symptom. Status failed on a stage, with a DR- code in the message. In chain.json that node's verdict is "error" and the message is in its error field.
Meaning. A pass can return an error for a processing failure or a deliberate refusal, so failed alone does not distinguish them. Read the code and full message. A refusal should identify the unsupported condition or missing evidence; retain that limitation with any recovered artifacts.
Next. Look up the DR-<DOMAIN>-<NNNN> code. For registered entries, explain prints the description, causes, and fixes:
disrobe explain DR-PYARM-0013
disrobe explain pyarm-13 # short form, zero-padded for you
disrobe explain pyarmor-13 --json # long domain aliases also resolve
DR-PYARM-0013
title: PyArmor v3/v4/v5 capsule walled on the RSA-wrapped key
description: v3-v5 capsule structure and metadata parse, but the bytecode AES key is
RSA-wrapped with a private key the author never ships, so the plaintext is
not in the artifact and cannot be recovered statically.
common fixes:
- supply the cleartext capsule key if you hold it; structure, version, and metadata
still parse without it
This entry separates what parsed from what is absent and names the additional input recovery requires. Not every code in the binary has a registered entry; the domains that carry entries are CLI, PYARM, PYINST, PYFRZ, NUITKA, SDEF, PYDEOB, JSDEOB, WASMDEOB, MARSHAL, and BINFMT. An unregistered code returns DR-CLI-0102 and asks you to file an issue with the full message you saw.
The absent-data case
Some failures identify a prerequisite you can supply: a missing PyArmor runtime extension, a wrapper altered by another obfuscator, or a .pyc without the interpreter needed for verification. Supplying that prerequisite allows the affected step to run; its result still needs inspection.
Other cases require data outside the supplied artifact: a key that exists only at run time, state held in a live process, or a payload fetched from the network on execution. Static recovery of the supplied bytes cannot reconstruct that missing material. The catalog marks these detect-only cases per family and identifies the missing input.
Record the missing input when handing the result to another analyst. A detect-only result with an absent-data reason calls for additional evidence; a stall, cap, or lifter gap calls for a different recovery step.
The recovery did not verify
Symptom. disrobe py decompile prints a roundtrip: line that is not perfect.
Meaning. By default, Python decompilation attempts to recompile the emitted source on a matching interpreter and compare the code objects. The label reports the comparison or why it did not run:
| Label | Meaning |
|---|---|
perfect | The recompiled code object is byte-identical in code, consts, names, and varnames, nested objects included. |
semantic | Not byte-identical, but the normalized opcode sequences match op for op. |
code-diff | The normalized sequences differ. The detail names the qualified name and the first differing index. |
no-interpreter | No matching interpreter was found, so the check did not run. |
recompile-failed | The emitted source did not compile. The captured stderr says why. |
skipped | The check was disabled with --no-roundtrip. |
For no-interpreter, install the matching interpreter and rerun the command. For skipped, remove --no-roundtrip to enable the comparison. Neither status reports a comparison result.
The semantic label refers to the documented opcode normalization, not an execution comparison. Read the Python comparison rules before using it as evidence about behavior.
The emit you asked for is not there
Symptom. An --emit kind wrote a small JSON document instead of an artifact.
Meaning. Commands that implement the standardized emit contract return either the requested artifact or a stub with "applicable": false, "schema": "disrobe.emit.stub/v0", and a reason. The shared parser recognizes fifteen emit labels, but support is command-specific and auto accepts only recovery. See standardized emits.
Next. Run the pass the reason names. disrobe auto --emit accepts only recovery, which echoes recovery.json to stdout under --json; for structured emits, drive the per-language subcommand directly.
disrobe auto sample.bin --emit recovery --json --out ./out/sample
disrobe py decompile ./out/sample/final/02-pyarmor-unpack/output.bin --emit source,disasm,report
Before you conclude anything
Anything you read out of a run is a claim about the bytes you supplied. Confirm the input identity in recovery.json matches the sample you meant to analyze: the blake3 and size fields are there so a report can be tied back to an artifact, and so two runs can be compared. disrobe diff and disrobe guard verify compare chain.json documents stage by stage when you need to prove two runs agree. For handling of the sample itself, read forensics and malware-safety posture.
Architecture overview
disrobe is a workspace of focused Rust crates exposed through one CLI. Direct commands run a selected operation; auto composes registered passes by detecting each stage's output. The IR ladder describes available representations, and the optional .dr envelope stores an artifact with its integrity hash.
Crate map
The workspace splits into shared cores and dedicated ecosystem or recovery-surface crates:
| Crate | Role |
|---|---|
disrobe-core | Shared artifacts, error codes (DR-<DOMAIN>-<NNNN>), confidence tiers, the Pass and Detector traits, pass selection, and the chain state machine. |
disrobe-prowl | Async URL and IOC harvester over public archives and threat-intel feeds, with bounded paging, per-host rate limits, key resolution, and typed reports. |
disrobe-ir | The five-rung IR ladder, the .dr envelope (rkyv hot + postcard cold + BLAKE3 root), transcoders, capability descriptors. |
disrobe-nir, disrobe-nir-lift | Normalized MIR plus bytecode front ends for AVM2, BEAM, CIL, Dalvik, JVM, Lua, Python, WebAssembly, and YARV. |
disrobe-binfmt | Container, archive, filesystem, firmware, and encrypted-volume layer (103 formats detected; 102 generic extraction routes plus bounded raw-volume-key LUKS1, with 30 generic routes whose members from a committed input match an independent extractor, plus recursive carving) with shared path-safety and decompression-quota machinery. |
disrobe-passes | Single assembly point for the feature-selected auto-chain registry. The standard CLI enables a specific subset; disrobe passes prints the resulting IDs. |
disrobe-llm-metadata | The --llm sidecar: 18 categories, 4 packs, AGENTS.md / SKILL.md brief generation. |
disrobe-mcp | The rmcp Model Context Protocol companion wired to disrobe serve --mcp. |
disrobe-py-marshal | CPython marshal reader: code objects across 3.8-3.15. |
disrobe-pass-* | One crate per ecosystem or recovery surface, including Python, JavaScript, WebAssembly, JVM, .NET, native, Go, Lua, PHP, Ruby, BEAM, Swift/Objective-C, AS3, mobile, shell, and webview desktop assets. The native pass adds the iced-backed disassembler, symbol-independent function discovery, call graph and basic-block CFG, instruction re-encode/relocate, C++ RTTI/vtable recovery, and emulation-driven string recovery. |
disrobe-query | Queryable-IR layer over the disassembled native code: functions, calls-to, xrefs, string-decoders, complexity, capability sites, behind disrobe query. |
disrobe-capabilities | Capability rule engine over the queryable IR, mapping matched behaviors to MITRE ATT&CK and MBC, behind disrobe capabilities. |
disrobe-taint | Source-to-sink data-flow analysis over normalized native, WebAssembly, JVM, Dalvik, and .dr inputs, behind disrobe taint. |
disrobe-cli | The disrobe binary: argument parsing, direct command handlers, output formats, chain integration, and daemon protocols. |
disrobe-validator | Walks a corpus and validates every fixture round-trips, used in CI. |
The Pass trait
Every chain pass implements one trait (Pass in disrobe-core, re-exported as chain::detector::Pass): it exposes an ID, a Detector, an output kind, and a run method that transforms an Artifact. The trait does not require adjacent rung transitions; unpackers can return another raw artifact. The chain runner re-detects the current bytes after each stage and selects a registered pass using detector confidence and precedence. This lets a supported PyInstaller -> PyArmor -> .pyc decompile input run through one disrobe auto invocation.
The CLI also has a standardized emit vocabulary, but it is not part of the Pass trait and support varies by command. A command wired to the emit helper writes an applicable: false stub when a requested kind does not apply. auto accepts only the recovery emit. See Standardized emits.
The four pillars
- The five-rung IR ladder: the representations available to recovery and analysis passes.
- Passes and pass selection: what each pass registers and how the chain runner picks between them.
- The chain runner: auto-detection, stage mirrors, depth and cycle caps.
- The
.drenvelope: the content-addressed wire format that makes caching deterministic.
Determinism is a design constraint, not a feature
The recovery architecture is designed for reproducible output. No model runs in the decompile path, and recovery output does not depend on randomness. Opt-in redaction uses the first 96 bits of the value's unsalted SHA-256 digest, so the same value receives the same sentinel across runs. Values shorter than 16 characters reveal no source characters. Longer values reveal only the first two and last two characters. Run documents record no duration, worker count, or clock, so two runs over one input write identical bytes; --timings records durations and clocks separately in run.json. The .dr envelope is content-addressed with BLAKE3 rather than timestamp-addressed, so a cache hit identifies the same bytes. This makes disrobe output usable as a forensic baseline and as a disrobe diff input across versions.
The committed cross-platform gate exercises three real fixtures. Each of the test job's Linux, macOS, and Windows legs runs the CLI against those fixtures, and the downstream determinism-cross-platform job hashes the recovered output with BLAKE3 and fails if the operating systems disagree. A companion check runs the same fixtures through the batch path at --jobs 1 and --jobs 4 and compares the two output directories byte for byte. These checks establish determinism for that population; they do not turn three fixtures into a claim about every input. See crates/disrobe-cli/tests/determinism_cross_platform.rs and the determinism-cross-platform job in .github/workflows/ci.yml.
The five-rung IR ladder
Disrobe uses five intermediate representations, from original bytes to rendered source. A recovery can use several rungs or stop at one. Unpackers commonly transform raw bytes into another raw artifact; passes do not have to visit each rung in order.
Open the full-size IR diagram.
The shared disrobe-ir enum defines Rung::{Raw, Disasm, Mir, Hir, Surface}. Individual backends choose the representations needed for their supported inputs.
Raw: file bytes
The input bytes and recovered container members. Format detection, extraction, unpacking, and decryption operate here. A byte comparison can grade a recovered member when its original is available; a successful extraction alone does not establish byte identity.
Disasm: instructions
Decoded operations with their offsets, operands, and labels. Commands such as disrobe py disasm, disrobe beam disasm, and disrobe as3 disasm expose instruction listings directly. The supported decoder and input format determine which bytes can be represented.
MIR: basic blocks
Normalized operations and control flow: blocks, branches, stack effects, and values. This representation gives structural recovery a common vocabulary without requiring the original source syntax.
HIR: program structure
Recovered loops, conditions, expressions, and other source constructs. Available names and types come from the input's metadata and the backend's analysis. Missing information can limit the structure a pass recovers.
Surface: readable source
Rendered text in the selected output language, such as Python, Java, C#, Lua, Erlang, WAT, C, Rust, or TypeScript. Some backends produce pseudo-source. Consult the language guide and recovery report before treating an output as compilable or behaviorally equivalent to its input.
Python's published comparison recompiles output and compares normalized opcode structure. It excludes jump targets and most operands, so agreement measures that structure rather than program equivalence. See the comparison rules and measured population.
Composition and storage
The chain runner uses detectors to select passes and re-inspects each stage's output. The shared artifact envelope carries the representation and integrity metadata. Rung names describe what an artifact contains; they do not determine the next pass by themselves.
The transcode registry is keyed by (from_version, from_rung, to_version, to_rung). disrobe envelope migrate-check <from.dr> <to.dr> checks whether a registered migration path satisfies the required capabilities.
Confidence tiers
Recovery producers map their evidence to four tiers in disrobe-core:
| Tier | Assigned for |
|---|---|
exact | A byte-roundtrip-verified signal. |
semantic | A recompilation-equivalence or full-body-lift signal. |
partial | Some recovered bodies or structured output without verification. |
skeleton | Signatures only or no recovered body. |
These are producer-reported classifications. In particular, semantic can mean that a full body was lifted without an independent execution comparison. Read the accompanying evidence and result documents for the limits of a recovery.
Passes and pass selection
A pass is the unit of work in disrobe. Chain passes implement a shared trait and register a detector that scores how confidently each one recognizes a given input. Ecosystem crates may expose one or more passes plus direct APIs. disrobe auto picks the next pass by comparing detector verdicts, not by matching capability descriptors between passes; see Pass selection below.
Commands and auto-chain passes
The CLI has two related surfaces:
- Direct commands are the operations shown by
disrobe --help. They include ecosystem command families such aspy,native, andjvm, plus analysis commands such asscan,frisk,query,taint, andwebview. - Chain passes implement the shared
Passtrait and can be selected bydisrobe auto. Their IDs are not necessarily CLI subcommand names.
disrobe passes prints both layers. Its first block summarizes direct recovery families. Its second block is the authoritative list of chain pass IDs reachable from disrobe auto in that binary, with an ecosystem and full, partial, or detect-only tier. The standard CLI build at this revision reports:
| Group | Auto-chain pass IDs |
|---|---|
| Python | nuitka.extract, pickle.classify, py.decompile, py.deob, py.disasm, pyarmor.unpack, pyfreeze.extract, pyinstaller.extract, sourcedefender.decrypt |
| Managed and mobile | dotnet.classify, jvm.classify, mobile.classify, swift-objc.classify |
| Source and bytecode | as3.classify, beam.classify, js.deob, lua.deob, php.peel, ruby.classify, scriptlang.classify, shell.deob, wasm.deob |
| Native and containers | binfmt.container, go.classify, native.image-classify, native.ne-structure, native.packer-unpack, nativelang.classify, webview.carve |
The standard CLI enables automatic webview recovery: Electron and Tauri use webview.carve, while Wails uses go.classify with Go support enabled. disrobe webview also provides direct frontend extraction. Build features can change the chain registry; disrobe passes lists the routes in the binary you are running.
native.image-classify handles structurally valid PE, ELF, and Mach-O images when no more specific ecosystem detector wins. Its partial tier includes identity, signatures, recovered symbols, and bounded pseudo-source reports on supported architectures. The native decompiler provides the direct source-recovery options and architecture limits.
The direct JavaScript catalog currently carries 11 bundler families. The WebAssembly catalog carries 3 families whose transformation runs through wasm deob (Jscrambler-WASM, Wobfuscator and Wasmixer); Tigress-via-Emscripten and wasm-name-obfuscator are classification-only there, and the Tigress unflattener is a library helper no recovery path calls. These catalog counts describe direct command capability and do not add chain pass IDs.
Pass selection
Rather than hard-coding which pass follows which, every pass registers a Detector (chain::detector::Detector in disrobe-core) that inspects the current bytes and, if it recognizes them, returns a DetectVerdict: a pass ID, a format tag, a family (obfuscator-wrapper, packer-archive, interpreter-bytecode, source, container, native-format, or unknown), a confidence score, and a specificity rank.
PassRegistry::run_all (chain/registry.rs) runs every registered detector against the bytes. Six extraction-first passes (nuitka.extract, pyinstaller.extract, pyfreeze.extract, pyarmor.unpack, binfmt.container, sourcedefender.decrypt) are tried before the rest, and the sweep stops early the moment one of them returns a High-band verdict (confidence >= 0.90) with specificity <= 30. A raw confidence buckets into ConfidenceBand::Low (< 0.70), Medium (0.70-0.89), or High (>= 0.90).
A SelectionPolicy then picks the winner among whatever verdicts came back: candidates below its minimum confidence (0.5 by default) are dropped, and the survivors are ranked by precedence::compare (chain/precedence.rs), which breaks ties in order: confidence band, then raw confidence, then the lower specificity value, then a fixed family-precedence table (obfuscator-wrapper beats packer-archive beats interpreter-bytecode beats source beats container beats native-format beats unknown), then the lexically smaller pass ID.
The chain driver (chain/state_machine.rs) runs this selection once per queued artifact, executes the winning pass, and re-runs detection on its output to decide what happens next. A branch ends when no verdict clears the minimum confidence (Stalled), when the same output bytes reappear (Cycle), or when the depth cap or cumulative-output budget is exceeded (CapReached). This is why disrobe auto can detect that a PyInstaller archive contains a PyArmor-protected module and route it through the unpack-then-decompile chain without any per-combination glue code.
Standardized emits
The CLI's shared emit parser recognizes these fifteen labels:
source disasm ast cfg ir manifest sourcemap symbols strings
imports signatures fingerprints report recovery provenancemap
Commands opt into this contract individually. Where a command accepts --emit, pass a comma-separated subset such as --emit source,disasm,report. A supporting command writes an explicit stub when the requested kind does not apply:
{
"schema": "disrobe.emit.stub/v0",
"pass": "beam-lift",
"emit_kind": "fingerprints",
"applicable": false,
"reason": "not implemented for the beam pass in this build"
}
Support is not universal. auto accepts only --emit recovery, and commands that do not expose --emit use their own output contract. --all-emits is also command-specific. Check disrobe <command> --help before building a consumer around an emit.
Error codes
Many diagnostics carry a DR-<DOMAIN>-<NNNN> code. The curated error registry provides explanations for registered codes:
disrobe explain DR-PYARM-0007
disrobe explain CLI-1 # short form also works
The chain runner
The chain runner detects each artifact, runs a matching recovery pass, and routes its output to the next pass. It backs both disrobe auto (automatic selection) and disrobe chain (an explicit pipeline).
Auto-detection
disrobe auto suspect.exe --out recovered/
disrobe auto suspect.exe --out shareable/ --redact
disrobe auto fingerprints the input, picks the highest-confidence pass, runs it, then re-fingerprints the output and repeats until no further pass clears the confidence threshold or the depth cap is hit. disrobe passes prints the auto-chain pass IDs compiled into the current binary, with each pass ecosystem and support tier. Use that output instead of a copied count. Direct commands such as scan, frisk, taint, and webview are separate surfaces and do not become auto-chain passes merely because the CLI can run them. See Pass selection for exactly how the next pass is chosen.
--redact replaces secret values in machine output, printed paths and messages, the generated reports (chain.json, recovery.json, anti-analysis.json, report.json, report.sarif, and run.json), and every extracted file that looks like JSON: a .json name, or content that starts with { or [ after an optional byte-order mark and whitespace. The values come from a recon scan of the input and of every extracted file, from the secret values listed in extracted recon.json, secret-scan, and mobile reports, and from a rescan of each document. An extracted JSON file that contains a secret is rewritten as indented JSON; one that does not parse, or exceeds the redactor's depth, node, or string limits, has its text scrubbed instead; one larger than 64 MiB is not written, and a DR-CLI-0366 line on stderr names it. Other recovered source, extracted binaries, and the raw stage copies that --capture-stages writes are not altered. disrobe chain applies the same redaction when .disrobe.toml sets output.redact = true. Raw report values remain the default.
Representative routes include native.packer-unpack -> go.classify for a UPX-packed Go executable and pyinstaller.extract -> pyarmor.unpack -> py.decompile when the extracted Python wrapper and available runtime/key material support those stages. APKs reach jvm.classify; Electron ASAR archives reach webview.carve, whose recognized JavaScript children can continue through js.deob. See the quickstart route table for their outputs and registered passes for the complete list.
Explicit chains
When you want to pin the pipeline rather than auto-detect:
disrobe chain input.bin --chain 'pyarmor.unpack,py.decompile' --out recovered/
disrobe chain input.bin --chain 'auto:8' --out recovered/ # auto-detect, depth 8
disrobe chain input.bin --chain 'auto:8' --chain-pin pyarmor.unpack --out recovered/
Explicit chains use comma-separated pass IDs from disrobe passes. With --chain auto[:N], --chain-pin fixes a pass prefix before automatic selection continues; it does not select package versions.
Layered payload recovery
disrobe unwraps obfuscated and packed payloads recursively. A structural check gates every step (compression magic, a loadable marshal object, a valid parse, a validated crib), so a decode never advances on garbage, and every decompression is bomb-bounded.
| Layer | What it reverses |
|---|---|
| Recursive peel | Stacked encoding and compression down to the real payload. The Python engine unwinds base64/85/32/16, zlib/gzip/bz2/xz/lzma, pyc-strip, marshal, and cipher layers (depth-capped, bomb-bounded); PHP, JavaScript (atob chains), and shell have their own recursive peelers; and the chain driver re-detects and re-routes every carved child, so stacked containers across any ecosystem peel end-to-end |
| Marshaled Python code objects | A raw CPython marshal blob (3.8 through 3.15) is loaded, its nested code objects (up to 64 deep) recovered, and each layer decompiled to source |
| Encoding and cipher reversal | base64/85/32/16, base58/62/45/91/92/122, ascii85/Z85, uuencode/xxencode/yEnc, percent-URL, HTML entity, and Punycode, plus gzip/zlib/xz/lzma/bz2 and rot-N. Keyed layers (XOR single and repeating-key, RC4, TEA/XTEA/XXTEA, ChaCha20, Salsa20) are recovered when the key is a literal, a crib, or brute-forceable; custom and shuffled base64 alphabets are sniffed from cribs. A blind cascade keeps only decodes a structural validator accepts; runtime-only-key crypto is stated as a wall, not guessed |
| Per-language loader unwrap | Python exec/eval/compile, PHP eval/assert/preg_replace-e/create_function, JavaScript eval/Function indirection plus esoteric encoders (JSFuck, the Dean Edwards packer, JJEncode, AAEncode) and V8 bytenode/SEA/asar carving, Lua per-obfuscator string and VM recovery, and PowerShell and bash Invoke-Obfuscation families |
Depth and cycle safety
Adversarial input can try to make a chain recurse forever (an archive nested inside itself, a packer that re-emits its own signature). The chain runner defends against this:
- Depth cap.
--max-depth(default 8) bounds how many passes can run in one chain. - Cycle detection. Each stage's output is content-hashed (BLAKE3); if a stage produces bytes already seen earlier in the chain, the runner stops rather than looping.
Output layout
auto and chain write into the --out directory:
out/
├── extracted/
│ ├── lib/app.dll # a fan-out member, at its path inside the container
│ └── recovered/
│ ├── app.py # recovered source, named after its input with the language's extension
│ └── chain-node-4.cs # a source whose input had no name
├── chain.json
└── recovery.json
- Recovered source. Every stage that ends a branch with recovered source writes it under
extracted/recovered/. The file keeps the directory and stem of the member it came from, and takes the extension of its language:.pyfor Python,.csfor C#,.javafor Java,.mfor Objective-C and MATLAB. A source whose input had no name is written aschain-node-<id>. - Existing output.
--outmust be empty or absent. A directory that already holds files is refused withDR-CLI-0913, because the new run's reports would cite files the run did not write.--forceaccepts such a directory and first deletes the earlier run'sextracted/.DR-CLI-0912reports a directory that cannot be read or cleared. - Batch runs. A directory run gives each input its own output directory, named after the input's relative path. Inputs whose names would give the same directory get numbered suffixes (
app-1,app-2), so no two inputs share one.
Verdicts
Every node in chain.json carries a verdict, and the run carries one overall verdict computed from the branches that end in a leaf.
| Verdict | Meaning | Grade |
|---|---|---|
complete | every counted branch ends in recovered source; the formats are listed | ok |
extracted | a container was opened and its members written, and no pass claims any member | ok |
not-applicable | no pass claims the input, or the only claiming pass found nothing to reverse and returned the input unchanged; nothing is written as recovered | ok |
fan-out-partial | some branches ended in recovered source and others did not | incomplete |
stalled | a pass produced bytes that no further pass claims, or produced nothing | incomplete |
cycle, cap-reached | the branch repeated an artifact or hit the depth or output cap | incomplete |
error | every counted branch failed; a container that opens with no members is an error, not an empty success | failed |
A member of a container that no pass claims is not-applicable on its own node and does not count against the run: a ZIP holding one .pyc and a README is complete once the .pyc decompiles. A directory run classifies each file from its verdict as recovered (grade ok), incomplete, not applicable or failed, and manifest.json counts each class.
Stage mirrors
Pass --capture-stages to materialize the exact bytes written by every executed pass. This records each stage faithfully; it does not mean decompiled source is byte-identical to the compiled input.
recovered/
├── 01-pyinstaller/ # exact recorded output of pass 1
├── 02-pyarmor/ # exact recorded output of pass 2
├── 03-py-decompile/ # exact recorded output of pass 3
├── final/ # terminal stage(s), linked
│ └── 03-py-decompile/ # symlink, or a recursive copy when symlinks are unavailable
├── chain.json # the chain topology descriptor
└── recovery.json # per-pass status and confidence histogram
The final/ link prefers a symlink and falls back to a recursive copy, so final/ always resolves to the terminal artifact regardless of platform and privilege. On Windows without the symlink privilege or Developer Mode, final/ is a copy.
chain.json: the topology descriptor
chain.json records the executed pipeline: each pass, its version, the input and output BLAKE3 hashes, the rung transition, byte sizes, and the per-stage verdict. It is the document disrobe diff and disrobe guard verify operate on (see Diff and guard tooling).
Each node includes a metadata object whose keys and values are strings. The object is empty when the stage has no metadata. Registered keys use lowercase dotted namespaces. Serialized keys remain in deterministic lexical order.
anti.recovered_techniques is a published metadata key. Its value is a nonempty comma-separated list of technique labels with no empty elements, embedded commas, or whitespace around delimiters. The encoded value is limited to 4,096 UTF-8 bytes. An absent key means that the stage reported no recovered technique metadata. An empty or malformed value is an error, not an absent value. The CLI reports malformed metadata as DR-CLI-0299 before it derives anti-analysis evidence or writes the final chain output.
recovery.json: the provenance sidecar
recovery.json is the per-run report: each pass's status and a confidence-tier histogram. Summarize it without reading raw JSON:
disrobe context --out recovered/
run.json: timings on request
chain.json, recovery.json, report.json, and report.sarif record no duration, no worker count, and no clock, so two runs over one input write identical bytes. Pass --timings to auto or chain to also write run.json (schema disrobe.run/v1): the start and end clocks, the worker count, the tool version, the run's duration, and each node's duration in milliseconds keyed by node id. Node 0, the input, covers the whole run; a node that ran a pass holds that pass's run time; any other node holds the time spent on it. disrobe context prints run.json when the directory holds one.
This prints per-pass status, confidence tiers, the overall verdict, and provenance, which is the human-facing view of what the chain actually managed to recover and how much to trust it.
The .dr envelope
The .dr envelope is disrobe's content-addressed IR wire format. A caller can persist a supported artifact as one, inspect or verify it without running a recovery pass, and pass it to consumers that accept its rung. The chain runner uses disrobe-core::Artifact between stages and writes separate chain.json and recovery.json records; it does not require every stage to become a .dr file.
Anatomy
A .dr envelope has three parts:
- Hot payload (rkyv). The primary typed IR data, serialized with rkyv 0.8. The mmap reader validates the header, declared lengths, and root hash before exposing the archived payload for zero-copy access.
- Cold sidecar (postcard). Secondary metadata serialized with postcard, kept out of the hot path so the common case stays fast.
- BLAKE3 root hash. A content hash over both the hot and cold bytes. Equal roots identify equal payload and sidecar bytes. The root does not include the header fields, so it is not by itself a claim that two complete envelope files are byte-identical.
The fixed header also carries the schema version, IR rung (see the ladder), flags, hot and cold lengths, and root hash. The postcard sidecar stores the producer, producer version, capability set, and string provenance map. MBA outputs that use the peephole table record its deterministic rule-pack content ID in provenance and in the corresponding chain artifact record; this identifies the exact table and audit data used for that result.
Why content-addressed, not timestamp-addressed
The root binds the typed payload and sidecar to their bytes rather than to a path or timestamp. disrobe envelope verify recomputes that root and rejects a mismatch. Cache entries use a separate key derived from the operation, input bytes, and effective configuration, and the cache reader validates its own stored checksum before returning a hit.
Working with envelopes
# Create an envelope from a source file
disrobe envelope create source.bin --out source.dr
# Inspect: version, rung, capabilities, provenance, root hash
disrobe envelope inspect source.dr
# Verify the BLAKE3 root against the payload
disrobe envelope verify source.dr
disrobe verify source.dr # convenience alias
# Structurally diff two envelopes
disrobe envelope diff a.dr b.dr # version, rung, flags, root hash, producer, capabilities, provenance
# Validate one envelope against another envelope's version and rung
disrobe envelope migrate-check source.dr target.dr
migrate-check answers a precise question: can the source envelope be transcoded to the target envelope's (version, rung) through a registered path while every Requires capability remains satisfiable? It validates the proposed transition; it does not rewrite either input.
Transcoding across schema versions
disrobe-ir carries a transcode registry keyed on (from_version, from_rung, to_version, to_rung). Identity transcodes are registered for every current rung. A non-identity transition succeeds only when the caller requests a registered path and its capability requirements remain satisfiable; no implicit rung change occurs.
Hardening
The envelope decoder parses a content-addressed binary format and is treated as a security-sensitive surface. Adversarial envelopes that attempt read-past-end, integer overflow, or BLAKE3-mismatch acceptance are in scope for the security policy. The decoder lives in crates/disrobe-ir/src/envelope.rs and is fuzzed.
Metadata sidecar and provenance
disrobe can emit a structured metadata bundle beside recovered output. The bundle carries call graph, types, control flow, capability surface, decompile provenance, and round-trip verdicts in one schema-conforming sidecar. It is deterministic data derived from the same pass results as the human output; no model runs in the recovery path.
Turning it on
disrobe py decompile module.pyc --out recovered/ --metadata-pack-4
disrobe py decompile module.pyc --out recovered/ --metadata-pack-4 --llm-briefs
--llm remains as a compatibility alias for the full Pack-4 selection. Prefer --metadata-pack-4 in new scripts. --llm-briefs additionally renders AGENTS.md and SKILL.md reconstruction briefs next to the bundle.
By default the bundle is written next to the primary output as <stem>.disrobe.llm.json. Override with --metadata-out <path> and choose the format with --metadata-format json|jsonl|cbor|msgpack.
The sidecar example
shows workspace initialization, recovery and recompilation of add.py, and the resulting
Pack-4 bundle. It includes the commands, generated-file hashes, and reconstruction briefs.
The four packs
Packs are cumulative presets over the 18 categories:
| Pack | Flag | Adds |
|---|---|---|
| Pack-1 | --metadata-pack-1 | ast + disasm + symbols + strings |
| Pack-2 | --metadata-pack-2 | Pack-1 + cfg + types + imports + provenance |
| Pack-3 | --metadata-pack-3 | Pack-2 + dfg + signatures + constants + roundtrip + sourcemap + manifest |
| Pack-4 | --metadata-pack-4 / --llm | Pack-3 + confidence + opcode-coverage + pii-map + decryption-keys. Only decryption-keys is auth-gated. |
The 18 categories
Each category can also be toggled individually:
ast disasm cfg dfg symbols strings types imports constants signatures
provenance roundtrip-verdict source-map manifest-cat decryption-keys
confidence opcode-coverage pii-map
Fine-tune any pack:
disrobe py decompile m.pyc --metadata-pack-3 --metadata-exclude ast,symbols
disrobe py decompile m.pyc --metadata-include cfg,types,provenance
Which commands write a bundle
The metadata flags are declared on the root parser, so every subcommand accepts them, but only these commands act on them. Every other subcommand ignores the flags and writes no bundle, and disrobe auto rejects them with DR-CLI-0843 because the chain engine writes a single chain.json instead.
| Command | Contributes |
|---|---|
disrobe py decompile | ast, disasm, symbols, strings, imports, constants, signatures, provenance, roundtrip-verdict, source-map, manifest, and cfg + dfg when the input reaches Mir |
disrobe py deob | symbols, strings, provenance, confidence, source-map, and cfg + dfg when the input reaches Mir |
disrobe py disasm | disasm, symbols, strings, constants, opcode-coverage, provenance, and cfg + dfg when the input reaches Mir |
disrobe taint | cfg + dfg |
Every command in this table also contributes pii-map when requested. A dedicated pass (disrobe-llm-metadata-pii) scans the raw input bytes for PII-bearing indicators and secret findings, independent of which language command ran, so pii-map behaves like cfg/dfg rather than like the per-language categories above: one shared scan wired into the bundle writer, not a per-command implementation. It reports applicable: false with a reason when it finds nothing, distinct from an unimplemented category.
Control flow and data flow
The cfg and dfg categories are summaries of the normalized IR, so a command produces them only for an input that reaches the Mir rung. These input families reach it:
- Native PE, ELF and Mach-O binaries, through the disassembler.
- WebAssembly modules, JVM class files, Dalvik
.dex, managed .NET PE, SWF and raw ABC, RubyYARBbytecode, Lua chunks, BEAM modules, and CPython.pyc, each through its own lifter. - Any Disasm-rung or Mir-rung
.drenvelope.
Both categories are emitted as one entry describing the whole module. function names the unit, blocks carries every basic block with the label of the function it belongs to, and edges carries from and to block indices with a kind of fallthrough, branch_true, branch_false or jump. A functions array carries the per-function address, export flag, cyclomatic complexity and block count. The dfg value reports memory defs, the uses each def reaches, and unreached_reads for reads no write reaches.
An input that never reaches Mir gets applicable: false and a reason naming the missing rung. A module that reaches Mir but produces no findings gets applicable: true with an empty array. Consumers can distinguish an unavailable analysis from a completed analysis with no findings.
Auth-gated categories
The decryption-keys category exposes recovered keys and IVs and is gated: passing --decryption-keys without --i-have-authorization fails with DR-CLI-0420. Other legally sensitive recovery paths document their own authorization gate where the CLI exposes one. The pii-map category itself carries no such gate: it emits only a placeholder and a location for each finding, never the matched value, so it adds no secret material of its own. Other categories such as strings and ast still report full recovered text by design, so a pack-4 bundle as a whole is not a scrubbed artifact.
Schema and reproducible output
Every bundle names its shape in schema (disrobe.metadata.llm.v2) and schema_version (2.0.0) and validates against schemas/disrobe-metadata-llm-v2.json. Each pipeline step and each provenance chain entry names a pass, its version, and the rungs it read and wrote. They record no durations.
The only timestamp is the top-level generated_at, and it appears only when SOURCE_DATE_EPOCH is set. It holds that Unix time as an RFC 3339 UTC timestamp with millisecond precision: SOURCE_DATE_EPOCH=1700000000 gives 2023-11-14T22:13:20.000Z. Without the variable the bundle carries no clock, so repeating a command on the same host with the same input and flags writes byte-identical bundles. A value that is not a whole number of seconds, or that falls after 9999-12-31T23:59:59Z, fails the command with DR-CLI-0318 and no bundle is written. The AGENTS.md brief lists a generated row only when the bundle carries generated_at.
Version 2 removed the per-step duration_ms and made generated_at optional, so a consumer written for disrobe.metadata.llm.v1 must stop requiring either field.
Provenance sidecars
Independently of the metadata bundle, a chain run records its stages and recovery results:
recovery.json: per-pass status and the confidence-tier histogram. Summarize withdisrobe context --out <dir>.chain.json: stage identities, input and output hashes, detector choices, and verdicts.
Neither file carries a clock or a duration. With --timings, the run also writes run.json, which holds the start and end clocks, the job count, the tool version, and each node's duration; disrobe context prints it.
See Reading a result for the full output contract. A line-level provenance map is not a guaranteed output of every chain run.
The .disrobe/ workspace
Scaffold a full agent workspace in the current directory:
disrobe init # scaffold .disrobe/
disrobe init --ide claude # also generate IDE-specific settings (claude, cursor, windsurf, aider)
This lays down an AGENTS.md forensic-framing template, per-symbol annotation schemas under .disrobe/annotations/, skill packs under .disrobe/skills/, slash commands, and a settings file (see Diff and guard tooling for what its hook does and does not do). Maintain it with:
disrobe annot refresh # rebuild .disrobe/annotations/<stem>.annot.json
disrobe rename oldName newName --note "why" # append-only rename record
disrobe context --out recovered/ # summarize the recovery report
Supported families catalog
This is the authoritative per-ecosystem list of every packer, obfuscator, protector, freezer, and bundler disrobe recognizes, with the support tier for each. The live CLI view is disrobe catalog [ecosystem]; a default build, which turns the full feature on, reports 169 families across 15 ecosystems, and the totals on this page are the full ones. Most catalogs sit behind a cargo feature, so a build with features trimmed registers fewer catalogs and reports a smaller total.
cargo run -p xtask -- regen --check re-derives the headline total, the native tier split, and the per-pass counts in the tables below from the tables the binary itself carries (Packer in crates/disrobe-pass-native/src/packers/mod.rs, CATALOG_COUNT in each pass chain_detector.rs, Protector::ALL in crates/disrobe-pass-dotnet/src/protectors.rs, and RaspVendor in crates/disrobe-pass-jvm/src/rasp.rs), so a family added to the binary without this page moving with it fails that check. Three rows count something no catalog table holds, Freezers / packagers, Freezers / packagers (experimental, unvalidated), and JS bundlers (unbundler); for those the check compares the published count against the family list beside it, which keeps the two halves of a row consistent but proves neither against the binary.
disrobe catalog
disrobe catalog native
disrobe catalog python --json
Three words describe how far recovery goes for a family, the same three the README uses:
- Recover: real recovered output (source, bytes, or structure), measured against an independent oracle where one exists.
- Partial: the layer is identified and what is intact is extracted or peeled, with the residual stated.
- Detect-only: identification plus a stated reason the rest cannot be recovered statically.
A wall identifies a required input that is absent, such as a runtime key or network-fetched payload. Every wall is detect-only, and detect-only also covers families identified without static recovery. See recovery limits and reading a result for how to interpret these reports.
disrobe catalog prints the same three tiers with the SupportQuality labels the binary carries (crates/disrobe-core/src/chain/obfuscator_catalog.rs), where full is the Recover tier: [full], [partial], [detect-only].
The disrobe auto chain at the bottom is what stitches these together: it fingerprints the input, runs the matching pass, re-fingerprints the output, and repeats until nothing else applies.
Native packers and protectors (29)
The Packer enum carries 29 variants across five UnpackerStatus tiers (12 + 6 + 3 + 6 + 2 = 29). The native chain detector catalog advertises 27 of them; the two CLR-layer crypters route to the .NET pass, so disrobe catalog native lists 27.
The tier names below are the in-tree UnpackerStatus values, so the split is exactly what the binary advertises. crates/disrobe-pass-native/src/packers/mod.rs test published_tier_counts_match_this_enum asserts every count in the table below against unpacker_status, so a variant cannot be added or moved between tiers without this page failing. The family names in each row are written by cargo run -p xtask -- regen from the same enum, and regen --check fails when a row names a family the binary does not carry, omits one it does, or files one under the wrong tier. Only the Implemented tier reaches an unpack routine, and the same check fails when a family in that row has no dispatch arm in crates/disrobe-pass-native/src/chain_detector.rs or when a family outside it has one.
Tier (UnpackerStatus) | Count | Families |
|---|---|---|
| Implemented: byte-exact decoders plus an in-house x86 stub emulator | 12 | Donut, sRDI, UPX, ASPack, Petite, MPRESS, FSG, PECompact, Yoda's Crypter, NSPack, MEW, kkrunchy |
| StubEvalPending: stub emulator validated against a spec-built stub, real-sample recovery tracked | 6 | ASProtect, Morphine, nPack, NeoLite, PolyCryptor, Warzone Crypter |
| GreyZoneDetectAndCarve: virtualizing tier, runtime-keyed handler stream | 3 | Yoda's Protector, VMProtect, Themida / WinLicense |
| GreyZoneDetectOnly: commercial protector tier, reported without static recovery | 6 | PE-Protector, PELock, Enigma Protector, Armadillo, Obsidium, WinLicense |
| DelegatedToDotnet: managed CLR crypter, recovery delegated to the .NET pass | 2 | DotNetPatcher, NetCryptor |
Donut and sRDI are shellcode loaders, so what the Implemented tier recovers for them is the embedded payload rather than a decompressed image. Donut recovery is graded on one Binject/go-donut instance (Chaskey-encrypted, LZNT1 and uncompressed modules); XPRESS and XPRESS-Huffman modules are reported as undecoded, and no instance built by the original C generator is in the corpus.
The recover tier is scored byte-for-byte against real committed originals: UPX .text and .pdata are bit-identical (the whole loaded image about 96%, the residual being loader-rebuilt relocations and IAT the OS resolves at run time), ASPack and PECompact rebuild the decompressed image with the reconstructed IAT at least 98% byte-identical, and Yoda's Crypter .rsrc is byte-identical with its .text decrypted to full plaintext. NSPack, FSG and Petite each reproduce from a clean checkout with one committed packed-and-original pair apiece. For the NSPack pair the gate holds the whole loaded image at or above 94.1% and the .text, .rdata and .data span at or above 99.3%. A per-section gate scores those three decoders over a wider span that also counts .rsrc: NSPack 57721 of 60060 bytes, FSG 55263 of 60060, and Petite 86986 of 89648. .text and .data are byte-identical for all three, and NSPack's .rdata is byte-identical as well, because its import lookup and address tables are rebuilt from the module record the stub carries rather than left for the loader. Their shared residual is the resource directory, now recovering 2333 of 4672 bytes for NSPack and 1552 of 4672 for FSG once the original tree is placed at its own RVA, and relocations are scored separately as loader-rebuilt. Larger local-only samples score lower on the whole-image measure, and no figure is published for them because those samples are not committed and nothing pins them, so the numbers above describe the committed pairs rather than the families. kkrunchy is byte-exact against committed fixtures and does reproduce. The full breakdown is in the native guide.
Python
| Surface | Count | Families |
|---|---|---|
| Freezers / packagers | 8 | PyInstaller 2.x-6.20+, Nuitka (onefile / standalone / module / wheel), cx_Freeze, py2exe, shiv, pex, Briefcase, SourceDefender .pye |
| Freezers / packagers (experimental, unvalidated) | 1 | PyOxidizer (experimental, unvalidated) |
| Protector (PyArmor) | 7 versions | PyArmor v6-v9-pro modes are cataloged and routed. Separately, the 72 / 72 manifest-named v8/v9 default-trial wrappers decrypt and decode one complete header-anchored root CodeObject. This self-reported structural result does not cover v6/v7, other v8/v9 wrapper populations, registered-license/pro, BCC, or super mode. The v3-v5 RSA-wrapped-key tier is a runtime-key wall. |
| Source obfuscators (AST-evaluator) | 19 | Kramer/Specter, Berserker, Jawbreaker, BlankOBF, PlusOBF, pyobfuscate.com, pyobfuscate.com (2026 XOR/lambda), PyObfuscator (mauricelambert), python-obfuscator (PyPI), ObfuXtreme, Manglify, Oxyry, pyminifier, online-obfuscator family, Xindex, pyobfus, Pypacker, Patchwork, pyc-zipper |
Jawbreaker's b16/b32/b64 loader shell is decoded statically, but a payload it fetches from a remote paste at run time is absent from the file. ObfuXtreme's AES-CBC/b85/xor static body is recovered; its runtime-payload segment is not in the artifact. python-obfuscator (PyPI), pyobfus, and Pypacker are detect plus partial-peel. Compiled Cython extensions (.pyd / .so) have their Python-visible surface (function and class names, docstrings, signatures) recovered from the module's symbol tables, with a structural fallback when the binary is stripped. See the Python guide.
JavaScript / TypeScript / WebAssembly
| Surface | Count | Families |
|---|---|---|
| JS chain catalog | 10 | 4 obfuscators (obfuscator.io full pipeline, JS-Confuser, Jscrambler, js-obfuscator (jsobfu)) plus 6 bundler markers (webpack, Vite, Rollup, esbuild, Turbopack, Bun) |
| JS esoteric encoders + protectors | separate detectors | JSFuck, aaencode, jjencode, JSFiretruck, Dean Edwards Packer (decoded); JSDefender and Arxan / Digital.ai (detect + static-transform peel); PACE (detect-only) |
| JS bundlers (unbundler) | 11 | webpack 4, webpack 5, Vite, Rollup, Rolldown, esbuild, Turbopack, Bun, Parcel, Browserify, SystemJS |
| WASM obfuscators | 5 (catalog) | Jscrambler-WASM, Wobfuscator, Tigress-via-Emscripten, Wasmixer (3 with transforms undone on modelled output, no artifact from the tools themselves is committed); Tigress-via-Emscripten and wasm-name-obfuscator are detect + classify only because the Tigress dispatcher and name helpers are not on the wasm deob run path, and wasm-name-obfuscator's hex renames destroy the original names |
The JS and WebAssembly guides cover each pipeline.
JVM / Android / .NET
| Surface | Count | Families |
|---|---|---|
| JVM / Android protectors | 10 | ProGuard/R8 (mapping replay to a name-restoration sidecar), Zelix KlassMaster, Allatori, Stringer, DashO, DexGuard (detect + structural peel, with in-class string-decrypt emulation for the keyed-constant variants), BlackObfuscator (DEX dispatcher recognition and block-order annotation); yGuard, SkidSuite2, JBCO (detect-only) |
| Android RASP vendors | 8 | Promon SHIELD, Guardsquare DexGuard RASP, Guardsquare ThreatCast, Appdome, OneSpan, Arxan / Digital.ai, Zimperium zShield, Licel DexProtector. No command runs this detector yet; behavior and auto report the runtime markers of five of them |
| .NET protectors | 23 | ConfuserEx, ConfuserEx2, Dotfuscator, Dotfuscator CE, SmartAssembly, Babel, DeepSea, Spices.Net, Goliath, Skater, .NET Reactor, Eazfuscator.NET, CryptoObfuscator, ArmDot, Agile.NET, Obfuscar, Themida (.NET wrapper), ILProtector, MaxToCode, KoiVM, DotNetPatcher, NetCryptor, BitMono |
On .NET, ConfuserEx2 constant decryption is reversed on a real committed sample, the Eazfuscator VM tier is devirtualized at 67 of 67 instructions across six bodies against an in-repo EazVM virtualizer of our own, and the KoiVM VM tier is devirtualized on a sample produced by the real KoiVM tool (6 of 6 bodies lifted to CIL). ILProtector, MaxToCode, and the Themida/.NET wrapper derive their per-method key in a native loader absent from the artifact, so those bodies are runtime-key walled. See the JVM and Android and .NET guides.
Detection covers every family in that row. String decryption is a narrower claim and it rests on different evidence per family. It is graded against a committed assembly the protector's own tool produced for ConfuserEx2, Obfuscar, BitMono. For SmartAssembly, Spices.Net, Skater, .NET Reactor, Eazfuscator.NET, CryptoObfuscator the decoder implements the published algorithm and is graded against a fixture built to that algorithm; no assembly produced by those products is committed, so each of those families is detected and its decryption modelled, not confirmed against a real protected assembly. String recovery stops at detection for Themida (.NET wrapper), ILProtector, MaxToCode, whose keys live in a native loader the artifact does not carry.
Lua
The Lua chain catalog is 16 entries: 14 obfuscator families plus the Luau and GLua dialect detectors.
| Surface | Count | Families |
|---|---|---|
| Obfuscators | 14 | IronBrew2 (full VM devirtualization), Prometheus, MoonSec V1, MoonSec V2, MoonSec V3, AztupBrew, DarkSec, Boronide, PSU, WeAreDevs, luaobfuscator.com, SLua, Hercules, Luraph |
| Dialect detectors | 2 | Luau bytecode, Garry's Mod Lua (GLua) |
IronBrew2 2.7.0 is reversed on real committed output in standard and MAX mode, validated by a real-lua execution differential. MoonSec-shape recovery runs against a synthetic bootstrap of our own design pending a real sample. The Lua guide walks the devirtualizer.
Shell
| Surface | Count | Families |
|---|---|---|
| Shell obfuscators | 19 | Graded on the tool's own output: Invoke-Stealth, Chameleon, psobf (Invoke-PSObfuscation), Bashfuscator (Token, String, Obfuscate, Compress) and node-bash-obfuscate. Graded on output of a from-spec generator because the upstream tool cannot run here: PowerShell Invoke-Obfuscation (Token, AST, String, Encoding, Compress, Launcher; Defender blocks the module) and Batch %random% and set-indirection. Graded on hand-written snippets: bash IFS/eval indirection. Detected by signature with no committed sample: PowerHell (upstream removed) and ISESteroids (commercial) |
Full VBA p-code decompile (264-opcode table, VBA5/6/7) with VBA-stomping detection rounds out the shell pass, alongside Excel 4.0 (XLM) macro-formula recovery (BIFF8 and BIFF12 Ptg decode, shared-formula resolution, and Auto_Open resolution in BIFF8 workbooks) and PDF maldoc analysis (embedded JavaScript, launch and embedded-file actions, both xref forms, RC4/AESV2 empty-password decrypt). See the shell guide.
PHP
| Surface | Count | Families |
|---|---|---|
| Commercial encoders | 3 (catalog) | ionCube, SourceGuardian, Zend Guard: envelope detect and wall (the decrypt key is native-loader-resident), with a partial op_array skeleton for the legacy statically-keyed cases |
Stacked eval-chain obfuscation (FOPO and the base64/gzinflate/rot13/XOR layer set) and Phar archives are peeled and walked in the same pass. See the PHP guide.
Other runtimes
| Ecosystem | Coverage |
|---|---|
| Go | garble report graded None / Detected / Partial / Full; garble -literals simple and full-key literals recovered through static blob pairing plus bounded x86-64 thunk/inline emulation. Type names resolved above an 85% floor on the committed go1.26.3 fixture. |
| Ruby | MRI/YARV 2.6-3.4 and mruby source recovery; the published MRI measure compares opcode-name multiset recall after recompilation. Ruby2Exe and Ocra freezers detected; JRuby and TruffleRuby AOT classified. |
| BEAM | .beam and .ez chunk parse, Core Erlang lift, Elixir Dbgi quoted-AST recovery. |
| Swift / Obj-C | Mach-O class-dump plus SwiftShield mapping parser and explicit-key single-byte XOR blob decoding; objc_msgSend call sites in recovered native bodies resolved to selector and receiver class. |
| ActionScript 3 | SWF parse and AVM2 disasm; commercial obfuscators (secureSWF, DoSWF, Kindi, Irrfuscator, swfLock) detect-only. |
| Hermes / Flutter | Hermes bytecode v60-v96 header parse, v62/v71/v74/v76/v83/v84/v89/v96 lift against builds of one sample by the real Hermes compiler; Flutter Dart kernel byte-exact body recovery and ARM64 AOT disasm, graded against a self-authored Dart 3.12.2 android-arm64 product-mode corpus and, measured locally, a real RustDesk 1.4.9 libapp.so fetched by pinned hash. |
| Containers / archives / filesystems / firmware / encrypted volumes | 103 formats detected. 102 carry a generic in-tree extractor; LUKS1 carries a bounded raw-volume-key route and a typed keyless wall. 30 generic routes write member bytes from a committed input that match an independent extractor (bsdtar, 7-Zip or the format's own decompressor); LUKS1 is graded separately against tracked plaintext. |
The disrobe auto chain
disrobe auto is the front door to the pass registry compiled into the current binary. It fingerprints the input, picks the highest-confidence pass, runs it, re-fingerprints the output, and repeats until no further pass clears the confidence threshold or the depth cap is hit. disrobe passes prints that registry. Some cataloged operations are reachable only through direct commands; disrobe --help is the authority for those surfaces.
disrobe auto suspect.exe --out recovered/ # detect + chain the whole pipeline
disrobe auto suspect.exe --out recovered/ --capture-stages # keep the exact output written by each stage
disrobe auto firmware-dir/ --out out/ --batch-max-depth 6
Representative chains:
PE -> UPX -> rust-demanglePyInstaller -> PyArmor -> .pyc decompileAPK -> dex -> Java + manifestElectron .asar -> unbundle -> source.NET PE -> in-house CIL decompile -> C#
Compiled webview frontends also have a direct static recovery path:
disrobe webview desktop.exe --out frontend/
The standard CLI also recovers supported Electron and Tauri layouts through webview.carve in auto; Wails uses go.classify. See Webview desktop frontends for the output paths and package extraction workflow.
With --capture-stages, stage outputs land in out/01-*/, out/02-*/, ..., out/final/. The full mechanism, including the depth cap, cycle detection, and the chain.json topology descriptor, is in The chain runner.
Anti-analysis defeat
disrobe analyzes samples statically by default. It recognizes obfuscation and anti-analysis patterns, recovers the available code and data, and reports missing runtime keys or unsupported transformations.
Signature defeat
Identification never trusts a single magic byte. A zeroed or flipped magic, renamed UPX0/UPX1 sections, or a corrupt UPX! marker is re-identified from internal self-consistency:
- PE through
e_lfanewto the COFF and optional headers. - ELF / Mach-O by header offsets that close against the file length.
- ZIP by its end-of-central-directory anchor.
- DEX by section-offset consistency.
- Classfile by a constant-pool walk.
- wasm by the LEB section stream.
A real UPX executable with a flipped MZ and renamed sections still unpacks byte-identically, because the structural PackHeader (method id, self-consistent compressed and uncompressed lengths, plausible version) is the signal a scrambler cannot remove without breaking the stub's own ability to self-extract.
Code-signing verification
Malware often ships with a broken, expired, self-signed, or mismatched Authenticode signature to look trustworthy at a glance. For a signed PE, disrobe native identify verifies the signature end to end rather than trusting its presence: it recomputes the Authenticode hash and compares it to the claimed digest, walks the PKCS#7/CMS certificate chain to an embedded bundle of trusted code-signing roots, requires the code-signing extended key usage on the leaf, and cryptographically verifies any RFC 3161 timestamp before letting it extend validity. The result is a single verdict (Valid, HashMismatch, Expired, SelfSigned, UntrustedChain, WrongKeyUsage, and the rest), so a tampered .text, a forged timestamp, or a chain that does not reach a trusted root is surfaced instead of silently accepted. The native guide lists the signed-fixture and osslsigncode cross-checks behind it.
String and data encryption
| Scheme | What disrobe does |
|---|---|
| Single-byte XOR stack strings | Recovers them with English-likeness key detection, on native via the in-house x86 emulator driving each decoder-shaped function. |
| Per-family keyed strings | Mirai, Dridex, and Trickbot keyed-string schemes decoded from their known transforms. |
| JVM string encryption | Emulates the in-class decrypt(String) / decrypt(int, String) method over the encrypted constants, running <clinit> for a static key or constructing the receiver for an instance key. |
| .NET constant decryption | ConfuserEx2 constants reversed on a real committed sample by emulating the in-assembly decryptor. |
| JS string-array rotation | The rotated string array is rebuilt and call sites inlined. |
Python exec/eval/compile payloads | Unwrapped through base64/85/16/32 and zlib/lzma decode chains. |
Recovery stops when a required key exists only in a system property, environment variable, clock value, random source, or runtime table.
Control-flow obfuscation
- BlackObfuscator DEX flattening is recognized: the
String.hashCode()-keyed dispatcher and itsconst-stringblock names are used to annotate the recovered block order. The flattened method body remains in the emitted source. - OLLVM-style control-flow flattening is deflattened on native, and the result is reported as a cover rather than as an equivalence.
disrobeenumerates every state the dispatcher can select out of the sample's own compare tree or jump table, resolves the state transition out of each case region by value-set analysis over the state variable, and reports which states the recovered program reaches. A state it cannot reach stays in the denominator and carries a named reason. Thedeobf.jsonsidecar publishes the whole cover: the state list, the recovered state-to-state edge set, the case regions with their block spans, and one reason per uncovered state. Itsfully_recoveredflag is true only when all three of these hold: every dispatcher state is reached, no reached state has an unresolved transition, and the recovered edge set passes its consistency check. It is not a claim that the recovered program and the flattened one agree on every input. Bogus control flow and instruction substitution are reversed on the same path. - Proven-dead conditional arms are folded on the AArch64
native decompilepath by a symbolic devirtualizer that runs before structuring (on by default, disabled with--no-devirt). The fold is transactional: on any proof miss or budget exhaustion it reverts to the original function, so it replaces a construct only with a proven-equivalent one and adds no edges. - Obfuscator-planted out-of-range exception entries that poison the JVM control-flow graph are dropped before structuring.
- Flattened JS dispatchers are collapsed back to structured control flow.
Anti-disassembly and MBA
The JVM, Dalvik, and CIL decoders tolerate broken StackMapTable, fake exception ranges, and illegal-but-verifiable bytecode. On native, jump-into-the-middle desync, overlapping instructions, and opaque predicates are resolved in-tree. A mixed-boolean-arithmetic simplifier, wired through the JS and WebAssembly decoders as well, collapses MBA expressions back to their algebraic form through a layered stack: linear signature solving, nonlinear reduction modulo the null-polynomial ideal, e-graph equality saturation over proven ring identities, bounded enumerative synthesis for opaque leaves, and permutation-polynomial inversion. Each layer is sound or abstains, and a rewrite is emitted only after equivalence is proven over the full bitvector domain, so an expression the stack cannot prove is left untouched rather than approximated.
Indirect dispatch is resolved before the SMT tier is ever consulted. A strided-interval value-set analysis reads the masked, compare-guarded, or position-independent index bound off the path constraints and enumerates the jump table to a concrete target set that over-approximates, and usually equals, the reachable targets. It abstains when the table is writable or the index is unbounded, and defers to the solver only for a disequality residual, rather than narrowing past what it can justify. The over-approximation property is unit-tested and graded against a real gcc-compiled switch; it is not proved for every input. The value-set tier carries no solver dependency and compiles without one.
Every SMT verdict the simplifier and the devirtualizer depend on is independently checked before it is trusted. A SAT verdict is re-evaluated against the model the solver returned; an UNSAT verdict is reconfirmed by BDD bit-blasting, or, for the multiply-heavy opaque predicates the bit-blaster cannot settle, by a finite-difference polynomial certificate. A verdict that fails its own check, or a solver that panics or exhausts its budget, degrades to abstain, so a solver bug the independent check catches costs a recovery rather than producing a wrong answer. The external differential runs against pinned Z3 4.16.0 in CI and includes a seeded wrong rewrite as its control. The same harness supports Bitwuzla for local runs, but CI does not provision it. A defect shared by both the solver and its checker is outside what the differential can rule out.
Bytecode virtualization
| Target | Status |
|---|---|
| Lua (IronBrew2 2.7.0) | Devirtualized in standard and MAX mode, graded by a real-lua execution differential. |
| Native generic VM | disrobe native devirt locates the interpreter, fingerprints each handler's micro-op behaviorally through the in-tree x86 emulator, and lifts to a re-executable IR plus pseudo-code, validated end-to-end on a self-authored Tigress-shape VM (the recovered IR re-executes byte-identically from machine code alone). |
| VMProtect / Themida / Enigma front-ends | Detection and structural analysis based on published format research. Recovery of a machine-keyed handler stream requires its key. |
Overlay inflation
The PE overlay carve computes the true end of the executable image and isolates any trailing archive (gzip, xz, zstd, bzip2, tar, 7z, cab, rar) into its own segment, so padding cannot mask an appended payload.
Symbol stripping
ProGuard/R8 mappings are replayed into name-restoration.json with overload matching; the emitted Java names are unchanged. Go type and stdlib names are recovered from surviving pclntab/moduledata on stripped binaries, Rust/C++/Swift/Itanium symbols are demangled, and structure is recovered from DWARF. garble's hashed user names remain unresolved without the required naming information; the report retains the structure and metadata that can be recovered.
What grades each capability
The table links each capability to its compiler, runtime, verifier, or repository test. Partial and Detect-only rows identify the remaining recovery limits.
| Capability | What it does | Grading oracle |
|---|---|---|
| Opaque-predicate fold | Folds OLLVM bogus-control-flow always-taken / always-dead branches to their constant outcome | crates/disrobe-pass-native/tests/lifting/ollvm_passes.rs (OpaqueResult::AlwaysTaken, real classify_fla.bin and self-authored predicate) |
| Control-flow-flattening deflatten | Enumerates every state an OLLVM-flattened dispatcher can select, resolves the transition out of each case region, and places the reachable ones as a direct-edge program. Each state it does not reach is reported with a named reason instead of being dropped | crates/disrobe-pass-native/tests/lifting/cff_dispatcher_cover.rs. Cover is 9 of the 9 dispatcher states across the two committed OLLVM *_fla.bin functions, with each denominator read back out of that sample's own compare tree rather than typed into the test. Separately a bounded stub_emu differential runs the flattened bytes and the re-emitted recovered bytes on 15 arguments per function and compares the return value against corpus/native/ollvm/probe_src.c, which is 60 executions under a 200000-step and 16 KiB-stack budget. A seeded missing state and a seeded wrong edge each turn one of those gates red |
| Verified MBA simplify | Collapses mixed-boolean-arithmetic back to algebraic form through the layered simplifier described above, then proves equivalence over the full bitvector domain before emitting | The acceptance gate records a proof at the expression's actual width through exhaustive enumeration where the domain is runnable, exact linear-column identity, BDD bit-blasting, or a finite-difference polynomial identity. A candidate is emitted only with one of those proven verdicts; otherwise the input is left untouched |
| OLLVM substitution undo | Lifts substituted arithmetic sequences (including shift-encoded carries and movzx/xchg-loaded narrow operands) back to the original operation, proven minimal | ollvm_passes.rs (undo_ollvm_substitution, asserts changed && proven, simplified_nodes < original_nodes) |
| Jump-table + PIC switch recovery | Resolves register-indirect dispatch and position-independent switch tables to concrete case-to-target lists | disrobe-pass-native deobf, graded by stub-emulator dispatch equivalence with clobbered-base and out-of-image counter-tests |
| Stack-string reconstruction | Drives each decoder-shaped function through the in-house x86 emulator to recover plaintext that only exists after the decoder runs | crates/disrobe-pass-native/tests/oracles/stack_string_oracle.rs (gcc-compiled object, stub_emu CPU memory state) |
| ABI / calling-convention inference | Infers calling convention, argument count, and return value from liveness on stripped code | crates/disrobe-pass-native/tests/oracles/abi_inference_oracle.rs (real clang-compiled prototypes, graded vs the source prototype) |
| Static type recovery | Recovers per-slot integer width and signedness from instruction semantics, splits a reused stack slot into distinct objects through region-typed memory-SSA and live-range analysis, and reconstructs struct, array, and union shape from access paths. Types resolved from a known library or OS prototype propagate backward into the caller's locals with library!function provenance; a slot with no sign signal, or an unresolved or conflicting call target, is reported unknown rather than guessed. native decompile emits the result as a types.json sidecar | crates/disrobe-typerec graded against an unstripped sibling's DWARF on an O0 corpus: width and struct field offset/width recall 1.0, live-range splitting lifts signedness recall from 0.25 to 1.0 on slot-reuse cases, with mutation checks that reject seeded-wrong widths, signs, offsets, and merged or invented fields |
| Solver-free indirect-dispatch resolution | A strided-interval value-set analysis resolves masked, compare-guarded, and position-independent indirect jumps to a concrete target set that over-approximates the reachable targets, usually exactly. It abstains, or defers to the SMT tier on a disequality residual, rather than narrowing past what it can justify | disrobe-mba jump-table VSA, unit-tested for the over-approximation property and graded against a real gcc-compiled switch (crates/disrobe-mba/tests/jumptable_compiler_oracle.rs, crates/disrobe-mba/src/jumptable/vsa.rs) |
| Copy-prop + branch-fold cleanup | Register copy-propagation and dead-store elimination over junk-shuffle blocks | crates/disrobe-pass-native/tests/oracles/copyprop_oracle.rs (concrete re-execution, live register equal before and after across seeds) |
| Path-sensitive dead-code removal | Drops blocks unreachable under the resolved predicate constraints | disrobe-pass-native deobf/pathsense.rs, applied only on a proven path constraint |
| Anti-disasm tolerance | Resolves jump-into-the-middle desync, overlapping instructions, and junk bytes; the JVM/Dalvik/CIL decoders tolerate broken StackMapTable and fake exception ranges | in-tree, exercised on real obfuscator output and malformed-bytecode fixtures |
| noreturn propagation | Propagates non-returning calls so the disassembler stops decoding junk past a terminal call | disrobe-pass-native flow analysis on the disassembled call graph |
| Generic VM devirt | Locates the interpreter, behaviorally fingerprints each handler through the x86 emulator, and lifts to re-executable IR plus pseudo-code | crates/disrobe-pass-native/tests/oracles/vm_devirt_oracle.rs (clang-compiled synthetic VM, recovered IR re-executes byte-identically from machine code alone); Lua IronBrew2 2.7.0 graded by a real-lua execution differential |
| Source-to-sink taint tracking | Tracks values from configured source calls to sink calls through register, stack, and inter-procedural propagation over the normalized IR | On NIST SARD Juliet v1.3, the native path detects 93 of 190 labeled CWE-78 flows (48.9%) with gcc 16.2.0 -O2, and 12 of 190 (6.3%) with -O0. Both runs produce zero false positives. Detection across more than one call remains 0 of 15 at either optimization level. The grader uses Juliet's manifest.xml and Flow Variant headers. Wasm, JVM, Dalvik and CIL inputs reach the same engine; these figures cover native input only |
Warning the analyst before anything runs
disrobe also flags the evasion a sample attempts. disrobe behavior and disrobe capabilities surface al-khaser / Pafish-class anti-debug, anti-VM, anti-sandbox, and timing checks, mapped to MITRE ATT&CK and MBC, with a confidence grade per technique. This is detection only: disrobe never executes the sample on its default path and never implements any of these techniques itself.
Runtime-keyed protection
With a matching pyarmor_runtime, the static path supports the variants listed in the Python guide. The 72-of-72 structural result covers the manifest's v8/v9 default-trial wrappers: each decodes to a complete header-anchored root CodeObject. That measurement does not grade source recovery, original .pyc identity, or semantic equivalence. Some v6/v7 variants require the opt-in, sandboxed dynamic-capture path. For ionCube, SourceGuardian, Zend Guard, ILProtector, and MaxToCode, a required key may reside in a native loader or live process outside the artifact. Disrobe reports the missing key and leaves that content unrecovered.
See the forensics and malware-safety posture for how the default static path stays safe on untrusted input.
Queryable IR and capabilities
disrobe query and disrobe capabilities turn a stripped binary into something you can interrogate. Both run over the same symbol-independent IR the native disassembler builds (disrobe-query and disrobe-capabilities), and both accept a raw binary or a .dr envelope.
disrobe query: ask the IR a question
disrobe query app.exe functions # discovered functions, complexity, exports
disrobe query app.exe calls-to malloc # call sites to a target
disrobe query app.exe xrefs-to sekret # references to a symbol or address
disrobe query app.exe string-decoders # decoder-shaped functions (loops + byte arith)
disrobe query app.exe complexity-over 20 # functions over a cyclomatic threshold
disrobe query app.exe capability network # instructions tied to a capability
disrobe query classes implementors 'Lpkg/Root;' # concrete JVM/DEX implementors
The query layer is built on the same function discovery the disassembler uses (call-target and prologue scanning), so it works without a symbol table. It accepts a .dr envelope at the Disasm or Mir rung; an envelope at any other rung is rejected with an explicit unsupported-rung error rather than silently returning empty or wrong results. The seven verbs are:
| Verb | Returns |
|---|---|
functions | Every discovered function with its address, size, cyclomatic complexity, and any export name. |
calls-to <target> | Call sites that reach a named import or address. |
xrefs-to <symbol> | All references to a symbol or address, code and data. |
string-decoders | Functions shaped like a string decoder: a loop plus byte arithmetic over a buffer. |
complexity-over <n> | Functions whose cyclomatic complexity exceeds a threshold, to triage the dense routines first. |
capability <name> | Instructions tied to a capability category (network, filesystem, process, crypto, and so on). |
implementors <descriptor> | Concrete JVM or DEX classes reachable from an interface or abstract-class descriptor, with a child-to-target inheritance proof. |
Every query honors the global --json flag, so the output drops straight into a script.
implementors accepts a single .class or .dex file, or a directory containing .class and .dex files. JVM descriptors such as Lpkg/Type; use nonempty components and allow Unicode, hyphens, and control characters except ., ;, [, and /. DEX descriptors follow the file version's SimpleName grammar: ASCII letters and digits, $, -, _, and the format's declared Unicode ranges are valid in every position; DEX 040 additionally admits its declared space characters. Controls, parentheses, and code points outside those ranges are rejected. Target descriptors are limited to 1,048,576 UTF-8 bytes. Quote descriptors at a shell prompt because the terminator is a semicolon. Text output escapes control characters; JSON preserves accepted descriptors. Results and proof paths are sorted by descriptor. The result records missing targets, duplicate definitions, malformed edges, cycles, rejected directory artifacts, and every traversal budget that produced a partial result. A rejected .class or .dex in a directory does not discard valid siblings. Malformed, missing-definition, and rejected-artifact identities are capped independently by count and byte length, with typed truncation diagnostics. APK and JAR containers are not query inputs, and DEX 041 container-relative layouts are rejected explicitly.
Navigation through MCP
The MCP companion exposes the same module model through call_graph, xrefs, function_summary, and neighborhood. These tools use ids derived from the module source hash and function address rather than function names, so duplicate names remain addressable. Direct-call outcomes distinguish an exact function start, an address inside one function, an ambiguous overlap, a non-function symbol, and an unresolved address. Calls without a direct target remain explicit indirect-call records.
call_graph, xrefs, and neighborhood paginate deterministically. Each cursor binds the source hash and request parameters, and a cursor from another module or neighborhood is rejected. A content-derived discriminator keeps distinct same-address function records addressable without depending on their position in the module. Graph construction has fixed function, instruction, call, cross-reference, candidate-work, and retained-memory ceilings before response pagination. Neighborhood traversal records visited ids and bounds both depth and retained records, so recursion and mutual recursion terminate without dropping their cycle edges.
disrobe capabilities: behavior to ATT&CK
disrobe capabilities app.exe
disrobe capabilities app.exe --json
disrobe capabilities runs a rule engine over the same IR and reports the behaviors it matched, each mapped to MITRE ATT&CK techniques and Malware Behavior Catalog (MBC) IDs. Every match carries the instruction offsets that triggered it as per-rule evidence, so a finding can be traced to the exact bytes rather than taken on faith.
The report names the detected format, the match count, and the per-rule evidence. The MCP server also offers a behavior summary, which uses a separate byte-analysis API; its results are not interchangeable with this IR rule report.
Where the IR comes from
The native disassembler (an in-tree iced-x86 decoder, detailed in the native guide) discovers functions, partitions them into basic blocks, and records each instruction's register, memory, and rflags effects. The query and capability layers read that structure rather than the original symbols, which is why a stripped binary answers the same questions a symbol-rich one does. Pointing either tool at a .dr envelope reuses a cached disassembly instead of re-decoding the bytes.
Recon, prowl, and indicators
disrobe frisk scans files, directories, APKs, and recovered source trees for secrets and indicators.
Findings include cloud keys, service tokens, private keys, API routes, storage buckets, URLs,
domains, IP addresses, emails, .onion addresses, and webhooks. Android manifest analysis reports
deep links, exported components, content-provider authorities, and dangerous permissions.
Findings carry source locations so you can inspect the surrounding content.
Usage
disrobe frisk app/ # walk a directory or recovered source tree
disrobe frisk app.apk # APK manifest exposure + secrets + IOCs
disrobe frisk recovered/ --format json # text, json, or sarif
disrobe frisk recovered/ --format sarif > frisk.sarif
disrobe frisk app/ --pattern rules.txt # custom rule pack: name=regex per line
disrobe frisk app/ --suppress example.com # drop findings whose value contains a substring
disrobe frisk app/ --emit-baseline > baseline.json # snapshot current findings
disrobe frisk app/ --baseline baseline.json # report only new findings
disrobe frisk app/ --entropy # include high-entropy generic-secret findings
disrobe frisk app/ --redact --format sarif # replace secret values in shareable output
frisk is offline. Network enrichment is explicit through prowl, and schema merging is explicit through indicators.
Secret values remain visible by default. Pass --redact, or set output.redact = true, to replace detected secret values throughout text, JSON, SARIF, and HTML reports. Redaction runs after suppression and baseline filtering. It preserves finding counts, locations, and offsets.
Each token contains the first 96 bits of the unsalted SHA-256 digest. The same secret therefore receives the same token across runs. A 96-bit identifier makes an accidental collision improbable. Redaction returns an error when renamed JSON object keys would collide. Values shorter than 16 characters reveal no source characters. Longer values include only the first two and last two characters. Because the digest is unsalted, anyone who holds or can guess a candidate value can compute its token and confirm whether that value appears in a report, so a token hides a secret only from readers who cannot enumerate it. Literal replacement processes longer matches first so an overlapping shorter value cannot expose part of a longer value.
Redaction scrubs finding values, previews, messages, paths, URI user information, and nested serialized fields. Nested JSON traversal stops at 64 levels, 1,048,576 values, or 64 MiB of string data. The command returns an error instead of emitting a partially redacted document when a limit is exceeded or redacted object keys would collide.
Decoded string layers
A secret hidden behind an encoding is still a secret, so frisk does not scan only the literal bytes. It peels base58, base62, base45, base91, base92, base122, Ascii85, Z85, uuencode, xxencode, yEnc, percent-encoding, HTML entities, and Punycode recursively, with decompression-bomb caps at every level, and rescans each recovered layer for the same secrets and IOCs. A finding inside a decoded layer reports the position in the file that carried it.
Wide strings
frisk and ioc read UTF-16 text in both byte orders on every input. No flag turns wide scanning on or off, and no flag selects a byte order.
A wide run is four or more ASCII characters, each held in a two-byte code unit whose other byte is zero. Eight bytes is therefore the shortest run that can be reported. A run may start at any byte offset, odd or even. The indicator scan accepts printable ASCII, tab, line feed, and carriage return inside a run. The endpoint and .onion pass accepts printable ASCII only. A code unit outside the accepted set ends the run, and the scan resumes at the next position rather than stopping.
The endpoint and .onion pass in disrobe frisk reads at most 65536 wide runs per file for each byte order, and stops a single run at 65536 bytes. The indicator scan stops after 100000 indicators for one input, wide and plain findings together.
What a wide scan reports
The indicator layer reads wide runs in both byte orders. URLs, domains, IPv4 and IPv6 addresses, emails, and wallet addresses surface from wide text in both commands. disrobe ioc also reports Windows paths, registry keys, and Unix paths found in wide text. disrobe frisk keeps those three only when the value matches a persistence indicator. The endpoint rules and the .onion rule run over each wide run as well.
Secret rules and --pattern rule packs do not read wide runs. They match the file's own bytes and its lossy UTF-8 text. A credential stored only as UTF-16 is reported only when the secret rule matches the raw bytes. frisk and ioc read UTF-16 only, and neither reads UTF-32.
disrobe frisk anchors every finding taken from a wide run to the file offset, line, and column where the run starts, not to a position inside the decoded text. disrobe ioc reports the run's file offset plus the index of the match inside the decoded run, so the offset is exact for a match at the start of a run and approximate for a match further in.
The opposite reading of the same bytes starts one byte later and produces a different value. Both readings can therefore report a finding over one run. Read the rule id suffix, or the encoding value, to see which reading produced a given finding.
Byte order in the output
| Surface | Where the byte order appears |
|---|---|
disrobe frisk, every format | The rule id gains -UTF16LE or -UTF16BE, for example DR-RECON-ONION-UTF16BE. |
disrobe ioc, text output | The encoding column reads utf16le or utf16be. |
disrobe ioc --format json | The encoding field reads utf16_le or utf16_be. |
disrobe ioc --format sarif | The rule id comes from the indicator kind and carries no suffix. The encoding appears in the result message. |
disrobe ioc sample.bin --format json | jq '.indicators[] | select(.encoding == "utf16_be")'
disrobe frisk recovered/ --format json | jq '.findings[] | select(.rule_id | endswith("-UTF16BE"))'
In disrobe frisk, the suffix is part of the fingerprint that --emit-baseline and --baseline compare. A wide finding and its plain-text twin are two separate entries in a baseline.
Finding categories
Every finding carries a category, a rule id, the matched value, a severity, and a file:line:column (or byte offset for non-text input).
| Category | What it surfaces |
|---|---|
secret | Cloud keys, SaaS and AI provider tokens, private keys, webhook URLs. High-entropy generic secrets are gated behind --entropy. |
endpoint | API endpoints, routes, and request targets recovered from source. |
manifest | Android manifest exposure: deep-link schemes and hosts, exported activities/services/receivers/providers, content-provider authorities, dangerous permissions. |
url | HTTP and HTTPS URLs. |
domain | Bare domains. |
ipv4, ipv6 | IP-address IOCs. |
email | Email addresses. |
onion | Tor v2 and v3 .onion hidden-service addresses. |
custom | Matches from a --pattern rule pack. |
Flags
| Flag | Effect |
|---|---|
--format <text|json|sarif> | Output format. SARIF 2.1.0 drops into GitHub code scanning. |
--pattern <FILE> | Custom rule pack, one name=regex per line; # comments allowed. |
--suppress <SUBSTR> | Drop findings whose value contains the substring. Repeatable. |
--emit-baseline | Print the current findings as a baseline JSON array to snapshot. |
--baseline <FILE> | Report only findings absent from the baseline array. |
--entropy | Include high-entropy generic-secret findings. |
Custom rule packs
A rule pack is one name=regex per line:
# rules.txt
internal-host=https://[a-z0-9.-]+\.corp\.example\.com
deploy-token=DEPLOY_[A-Z0-9]{32}
disrobe frisk recovered/ --pattern rules.txt --format json
Baselines
Snapshot the current findings, then report only new ones on later runs, so a CI gate fires only when a fresh secret or endpoint appears:
disrobe frisk app/ --emit-baseline > frisk-baseline.json
disrobe frisk app/ --baseline frisk-baseline.json --format sarif > new-findings.sarif
Network harvest with prowl
disrobe prowl example.com --subs --sources wayback,commoncrawl,urlscan --format json > prowl.json
disrobe prowl --targets-file targets.txt --proxy http://127.0.0.1:8080 --timeout 20
disrobe prowl --recon-input frisk.json --ioc domain,ipv4,email
disrobe prowl keyring set virustotal
disrobe prowl queries public archives and threat-intel feeds and writes disrobe.prowl/v0. The source labels are:
| Source | Notes |
|---|---|
wayback | Wayback capture URLs, date-filtered by --from and --to. |
commoncrawl | Common Crawl index URLs. |
otx | AlienVault OTX URLs and pulses; optional key. |
urlscan | urlscan submissions; optional key. |
crtsh | Certificate transparency names from crt.sh. |
urlhaus | URLhaus URLs and payload IOCs; key-supported. |
threatfox | ThreatFox IOCs; key-supported. |
virustotal | VirusTotal URL/domain data; vt is accepted as an alias and a key is required. |
Important flags:
| Flag | Effect |
|---|---|
--targets-file <FILE> | Read one domain or URL per line. |
--stdin | Read targets or a prior recon/IOC JSON report from stdin. |
--recon-input <FILE> | Seed targets from frisk, ioc, or prowl JSON. |
--sources <LIST> | Comma-separated source labels; empty means every source. |
--subs | Include subdomains for the target. |
--blacklist <EXT> | Drop URLs with matching extensions. |
--mc <CODE> / --fc <CODE> | Keep or drop HTTP status codes. |
--mt <MIME> / --ft <MIME> | Keep or drop MIME substrings. |
--ioc <KIND> | Keep selected IOC kinds: subdomain, domain, ipv4, ipv6, email, md5, sha1, sha256, asn. |
--fp | Collapse URLs that differ only in query-parameter values. |
--no-iocs | Keep URL records without deriving structured IOCs. |
--proxy <URL> | Route requests through an HTTP(S) or SOCKS proxy. |
--timeout <SECS> | Per-request timeout, default 45. |
--concurrency <N> | In-flight source/target requests, default 12. |
--per-host-rps <RPS> | Per-host request rate, default 4; 0 disables. |
--max-pages <N> | Max paginated requests per source, default 50. |
--max-urls <N> | Max retained URLs, default 1000000. |
--max-iocs <N> | Max retained IOCs, default 1000000. |
--retries <N> | Retries on 429/5xx, default 3. |
--api-key <PROVIDER=KEY> | Provide a key for one run. Prefer env vars or keyring for normal use. |
Key resolution order is flags, provider environment variables, OS keyring, then the permissions-checked TOML config. Use disrobe prowl keyring set|get|rm|list <provider> to manage stored keys.
Indicator bundles
disrobe frisk recovered/ --format json > frisk.json
disrobe ioc sample.bin --format json > ioc.json
disrobe prowl --recon-input frisk.json --format json > prowl.json
disrobe indicators frisk.json ioc.json prowl.json --format json > indicators.json
disrobe indicators frisk.json prowl.json --targets-only > targets.txt
disrobe indicators ingests disrobe.recon/v0, disrobe.ioc/v0, and disrobe.prowl/v0, deduplicates indicators by class and value, preserves each value's source provenance, and emits disrobe.indicators/v0. --targets-only prints network indicators ready for prowl --targets-file.
String reader
disrobe_core::recon::string_emu holds the wide-run reader behind the endpoint and .onion pass in disrobe frisk. It reads UTF-16LE and UTF-16BE runs from the input bytes and reports each run's encoding and offset.
Python
disrobe disassembles and decompiles Python bytecode across CPython 3.8-3.15 and the alternative runtimes, peels source-level obfuscators, and unwraps freezers and protectors back to .pyc.
The Python decompiler is implemented in Rust. The command uses this engine; pycdc, PyLingual, decompyle3, and uncompyle6 appear in comparison benchmarks.
At a glance
| Layer | Coverage |
|---|---|
| Bytecode disassembly | CPython 3.8-3.15, PyPy, MicroPython .mpy v0-v6, Jython, IronPython, Brython |
| Decompilation | CPython 3.8-3.15 with per-version opcode dispatch. Normalized opcode-structure agreement on CPython 3.14.5: 17396 of 18276 code objects in a fixed core population; 6139 of 6286 in its pinned 200-module subset. See the measurement definition below. |
| Modern constructs | match, walrus, f-strings and PEP 750 t-strings, exception groups, PEP 695/696/709 |
| Control flow | try/except/else and try/finally structured from the exception-table forest, with-statement folding, multi-exit while True and while COND loops, conditional (ternary) expressions, and chained comparisons in conditions, each recompile-checked |
| Freezers | PyInstaller 2.x-6.20+, Nuitka, cx_Freeze, py2exe, shiv, pex, PyOxidizer (experimental, unvalidated), Briefcase, SourceDefender |
| Protectors | PyArmor v6-v9-pro, and 19 catalogued source obfuscators routed to an AST-evaluator backend; per-family depth is in the catalog |
Commands
disrobe py decompile module.pyc --out recovered/
disrobe py decompile module.pyc --out recovered/ --backend native # accepted for explicitness; native is the only backend
disrobe py decompile module.pyc --out recovered/ --emit source,disasm,ast
disrobe py disasm module.pyc --out trace.txt
disrobe py deob obfuscated.py --out clean.py
disrobe py deob obfuscated.py --out clean.py --cleanup
decompile runs the in-tree engine: a frame-tree pre-pass, per-version opcode dispatch, then round-trip verification. --backend native is accepted for explicitness; no external Python decompiler backend is exposed by this command.
disasm writes a faithful per-instruction trace across every supported interpreter dialect. This is the Disasm rung: lossless, offset-preserving, no structural reconstruction.
deob peels source-level obfuscator wrappers (Kramer/Specter, Berserker, Jawbreaker, BlankOBF, PlusOBF, pyobfuscate.com, PyObfuscator (mauricelambert), python-obfuscator (PyPI), ObfuXtreme, Manglify, Oxyry, pyminifier, online obfuscator family, Xindex, pyobfus, Pypacker, Patchwork) with an AST-evaluator backend. --cleanup runs a ruff-AST constant-fold and dead-branch-elimination pass afterward.
Freezers and packagers
disrobe pyinstaller extract onefile.exe --out out/ # PyInstaller 2.x .. 6.20+, AES-CTR/CFB decrypt
disrobe pyinstaller detect onefile.exe # cookie, Python version, TOC offsets, no extract
disrobe pyfreeze extract app.exe --out out/ # cx_Freeze / py2exe / shiv / pex / PyOxidizer (experimental, unvalidated) / Briefcase
disrobe nuitka detect app.exe # flavor + Python version
disrobe nuitka extract app.exe --out out/ # --onefile payload (zstd)
disrobe nuitka symbols app.exe # impl_* + module-init scan on --standalone builds
disrobe py sourcedefender app.pye --out app.msgpack # SourceDefender .pye decrypt
PyArmor
disrobe pyarmor unpack protected.py --out out/
disrobe pyarmor unpack protected.py --out out/ --allow-bcc
disrobe pyarmor unpack protected.py --out out/ --allow-dynamic --dynamic-timeout 60
unpack extracts a decrypted payload and can reconstruct a .pyc; reconstructed output is not claimed byte-identical to an original .pyc. The published 72/72 result is narrower: it covers manifest-named v8/v9 default-trial wrappers and requires one complete header-anchored root CodeObject, not source recovery, emitted .pyc identity, semantic or execution equivalence, or external agreement. v6/v7 can optionally use a dynamic-hook fallback that runs the obfuscated wrapper in a watched subprocess to capture marshal streams; this is opt-in and unsafe on untrusted input.
The
--allow-dynamicpath executes the sample. Only enable it on trusted samples or inside an isolated sandbox. See Forensics and malware-safety posture.
Other useful flags: --mode auto|standard|super, --target 3.11 (rewrite emitted .pyc magic), --allow-bcc, --strict, and --all-emits.
BCC input is refused with DR-PYARM-0050 unless --allow-bcc is set. With that opt-in, the pass lifts extracted native blobs statically in tree; it does not execute them or invoke Ghidra. Windows x86-64 uses the Microsoft x64 ABI, Linux x86-64 uses the System V ABI, and Darwin ARM64 uses AAPCS64. A function that depends on the PyArmor or CPython runtime dispatch remains an unmodeled record with native disassembly and a typed reason.
The dedicated command writes bcc/bcc-recovery.json, bcc/bcc-pseudo-c.c, and bcc/bcc-recovered.py beneath --out. Path-aware PyArmor extraction through disrobe auto writes the same three byte-identical artifacts. The canonical JSON schema is disrobe.pyarmor.bcc.recovery/v1; it embeds disrobe.pyarmor.bcc.function_map/1 and represents modeled, unmodeled, and refused blob outcomes. The recovered Python file is a deterministic source skeleton derived from the same publication, not a claim of source identity or execution equivalence.
--strict returns DR-PYARM-0052 when unpacking produces no .pyc, records a fallback reason, or records a marshal decode error. It does not add a separate failure condition for incomplete BCC lifting.
End to end
A real-world Python sample is often frozen, then protected, then compiled. disrobe auto chains the whole stack:
disrobe auto suspect.exe --out recovered/ # PyInstaller -> PyArmor -> .pyc decompile
Coverage and fidelity
How the in-house engine works
The engine reconstructs nested source constructs from the CPython 3.11+ exception table before walking instructions. Its round-trip checker recompiles recovered source when a matching interpreter is available, then compares the resulting code objects. Reports distinguish exact matches, normalized matches, code differences, compilation failures, and an unavailable interpreter. A normalized match is evidence about the compared representation, not a proof of identical behavior.
Measured opcode structure
The benchmark compiles each original module and its recovered source with CPython 3.14.5 at optimization level zero. It compares normalized opcode streams and three argument-count fields for each original code object. Normalization removes or merges selected instructions and omits jump targets and most operands. The comparison excludes __annotate__ code objects and does not penalize additional recovered code objects. These results measure opcode structure, not bytecode identity or program equivalence.
The fixed core population contains 574 modules and excludes idlelib and turtledemo: 17396 of 18276 code objects agree, or 95.18%. Its pinned 200-module subset yields 6139 of 6286 (97.66%). The committed module lists define both populations.
full_stdlib_recompile_gate.rs measures the 574-module population on explicit invocation. CI runs a 115-module subset and runs the 200-module gate on tags and scheduled builds, with a 97.66% regression threshold for the latter.
The recorded run includes the executable and interpreter hashes, comparison rules, exact counts, and reproduction command. Its unmatched objects identify all 880 code differences, missing objects, and collisions by module, qualified name, and occurrence.
Per-interpreter bands
Each band uses the same normalized opcode-structure comparison and pinned module list, compiling both sources on the listed interpreter. Modules absent from that interpreter are excluded. The different denominators prevent a direct ranking between bands.
| Band | Interpreter | Recovered | Rate | Modules | Enforced on |
|---|---|---|---|---|---|
| 3.8 | CPython 3.8.20 | 4599 / 5088 code objects | 90.38% | 154 | tag, schedule |
| 3.9 | CPython 3.9.25 | 5032 / 5233 code objects | 96.15% | 157 | tag, schedule |
| 3.10 | CPython 3.10.20 | 5279 / 5458 code objects | 96.72% | 161 | push, tag, schedule |
| 3.11 | CPython 3.11.15 | 5504 / 5638 code objects | 97.62% | 172 | tag, schedule |
| 3.12 | CPython 3.12.13 | 5484 / 5659 code objects | 96.90% | 177 | push, tag, schedule |
| 3.13 | CPython 3.13.14 | 5793 / 5966 code objects | 97.10% | 190 | push, tag, schedule |
| 3.14 | CPython 3.14.5 | 6139 / 6286 code objects | 97.66% | 200 | no band gate, mirrored |
| 3.15 | CPython 3.15.0b4 | 6296 / 6480 code objects | 97.16% | 199 | tag, schedule |
The recorded results and interpreter versions are in xtask/data/recovery.json.
The 3.10, 3.12, and 3.13 bands run on each push to main. Tag builds and weekly scheduled builds also run the remaining band gates. The dedicated 3.10, 3.12, 3.13, 3.14, and 3.15 checks require their pinned interpreters. The 3.8 and 3.9 counts were measured on Windows x86-64; their gates run in the weekly test job, which installs both interpreters, and skip when the interpreter is absent.
The 3.14 row reads differently from the rest: it reports the pinned 200-module subset of the accepted 574-module measurement; both use the same source hashes and comparison rules.
Cython compiled extensions
A Cython module compiles to a native .pyd / .so, but the module still exposes the surface CPython needs to import it. The disrobe-binfmt Cython reader (disrobe_binfmt::containers::cython) recovers that surface from the compiled ELF, PE, or Mach-O: function names, qualified names, docstrings, calling-convention flags, per-class method groupings, and the original .pyx / .pxd source filenames. It walks the PyMethodDef and PyTypeObject tables through the module's symbols when they survive, and falls back to a bounded structural scan of the readable data sections for PyMethodDef-shaped records when the binary is stripped, resolving data pointers through both static section relocations and ELF dynamic relocations.
Recovery is graded against real compiled Cython fixtures (unstripped, stripped, and separately linked) with a known ground-truth .pyx: the expected functions recover with their exact docstrings and signatures, and the report records whether each name came from a symbol or from the structural fallback (real_cython.rs).
disrobe auto claims a Cython extension through the python.cython-surface pass and writes two files: <module>.pyi, a stub that declares every recovered function, class and method with its parameters, defaults, Python-typed annotations and docstring, and cython-surface.json, the full recovered record. The stub of the committed fixture is parsed by CPython's ast and compared with the authored .pyx (cython_stub_reference.rs): every function and method is declared with the authored parameter names and defaults, and a dropped default turns the comparison red. A stripped module keeps every function and method name, grouped under its class by the qualified signature Cython embeds; parameters come only from those embedded signatures, and a class whose type table did not survive stripping has no __init__ declaration.
Limits
- The pyc-zipper real-output grader covers 30 pinned outputs against CPython 3.12. Compressed payloads recover their opcode structure; obfuscation can permanently delete variable names and line information. Twenty-five source recoveries print the same bytes as the authored programs; the five generator cases retain named partial status. Eighteen outputs also have broken loaders in the tool itself, recorded separately from static recovery.
- The pyobfus real-output grader covers 15 generated sources. Recovery removes the generator header and preserves the body exactly, including generated names, literals and reflection lookups. All 15 re-execute like the authored inputs. Original identifier names are unavailable, so recovery remains partial; three other requested cases failed in the tool and produced no fixtures.
- A Cython module's Python source is gone once compiled. Only the import surface described above is recoverable, not the
.pyxbodies. - PyArmor v6/v7 may need the opt-in dynamic-hook fallback, which executes the sample. The manifest-named v8/v9 default-trial result is a pure-static structural decoding check only; it does not establish recovery for other variants.
JavaScript / TypeScript
disrobe reverses supported JavaScript and TypeScript obfuscation, extracts modules from recognized bundle layouts, and inspects packaged JavaScript runtimes. Recovery uses static parsers and bounded transformations.
At a glance
| Layer | Coverage |
|---|---|
| Family detector | obfuscator.io, Jscrambler, jsobfu, plus bundler and minified-only classification, each with confidence and markers |
obfuscator.io (--full) | string-array decode, control-flow unflattening, opaque-predicate folding, packing expansion, dead-code and debug-protection strip, iterated to a fixpoint |
| Reverser library | JS-Confuser (string encoding/compression, dispatcher, flatten, opaque predicates, RGF, shuffle, variable masking, locks and integrity) and Jscrambler template reversals; Arxan-JS, JSDefender, and PACE protector detectors |
| Esoteric encoders | jsfuck, JJEncode, AAEncode, JSFiretruck, Dean Edwards Packer, atob/eval indirection |
| Renaming | --rename (hex idents to var_N) and --rename-scope-aware (oxc_semantic, conflict-checked) |
TypeScript helpers (--unminify) | __awaiter with __generator (inline, tslib namespace, or renamed), identified by helper body shape, rewritten to async/await: 41 of 41 async functions across 9 authored programs compiled by tsc 6.0.3 for ES5 and ES2015, and for the ES2015 output after terser 5.51.2 compress and compress-plus-mangle; 3 of 41 for terser-minified ES5 state machines. Node output of every rewritten program matches the compiled original |
| Bundlers | Webpack 4/5, Vite, Rollup, Rolldown, esbuild, Turbopack, Bun, Browserify, Parcel, SystemJS, AMD |
| Packaged runtimes | V8 cached-data .jsc (bytenode), Node SEA blobs, nexe, nw.js zip-suffix, Electron .asar |
| Deno | deno compile executables and bare eszip archives through disrobe auto: every embedded module becomes an output file (see Deno) |
| Compiled webview hosts | Electron ASAR plus embedded Tauri and Wails frontend trees through the direct webview command |
Commands
disrobe js deob bundle.min.js --out clean.js --full --rename-scope-aware
disrobe js deob legacy.js --out clean.js --legacy auto --unminify
disrobe js unbundle app.bundle.js --out src/
disrobe js unbundle app.bundle.js --out src/ --emit sourcemap
disrobe js v8 app.jsc
disrobe js v8 app.asar --json-out report.json
disrobe auto app.asar --out recovered/ # Electron and Node packaging chains run end to end
disrobe auto app.exe --out recovered/ # deno compile executable
disrobe auto modules.eszip --out recovered/ # bare eszip archive
disrobe webview desktop.exe --out frontend/ # Electron, Tauri, or Wails assets
Use js v8 to inspect a packaged JavaScript runtime and webview to recover the shipped frontend tree from a desktop binary. The standard CLI also routes supported desktop layouts through auto. See Webview desktop frontends.
The default deob path runs string-array recovery and writes a detection.json sidecar naming the matched family. --full runs the complete obfuscator.io reversal pipeline and records per-stage statistics in a pipeline.json (string-array call sites inlined, dispatch blocks collapsed, opaque predicates folded, packed blocks expanded). --legacy jsobfu|jscrambler-free|auto targets the older families; --unminify adds constant folding and the AST unminify rules (!0 to true, void 0 to undefined where undefined is not shadowed, bracket to dot access, string concatenation).
For Rust callers, AstRuleId::AsyncRestore is a selector-compatibility no-op: Babel-style async wrappers are preserved. Any call carrying an exact Babel async-helper specifier quarantines the entire AST and preset-env pass, without assuming the callee is CommonJS require. AstRuleId::ArgumentSpread and AstRuleId::TemplateLiteral are disabled-by-default selector-compatibility no-ops, with stable zero-valued report counters. AstRuleId::RegeneratorRestore is a disabled-by-default selector-compatibility no-op with a stable zero-valued report counter; regenerator state machines are preserved. undo_preset_env keeps helpers_removed empty and its spread, class, and async counters at zero; it currently reports only AST-proven optional-chain and nullish-coalescing restoration.
unbundle auto-detects the bundler runtime from its markers (the full table above) or forces one with --target auto|webpack|webpack4|webpack5|vite|rollup|esbuild|turbopack|bun. Modules land as separate files with chunk and module identifiers preserved, plus a manifest.json. --emit sourcemap synthesizes per-chunk v3 source maps and decodes embedded data-url maps.
Coverage and fidelity
js v8 classifies the artifact and prints real detection: bytenode header layout and Node version for .jsc, SEA flags and code length, nexe/nw.js payload geometry, or the .asar entry listing.
For .jsc, Disrobe detects the serializer version across Node 18-24, recovers user strings and every serialized bytecode array, and disrobe auto reports each function's Ignition disassembly with registers named as node --print-bytecode names them, together with a JavaScript lift of it (lifted_js). Each function states lift_complete and its reversible, lossy and runtime-opaque line counts; an instruction without a lift rule is kept as a comment and its accumulator reads as __unlifted_<op>, so an incomplete lift fails when run instead of computing a wrong value. The path runs locally without a patched V8 binary or an external decompiler. Branches and loops lower to a for (;;) switch (__pc) dispatcher over the bytecode offsets, so a lifted function keeps its control flow; functions with jump tables, generators, try/catch, for-in or constant-pool jump offsets keep their jumps as comments and are not complete. It does not rebuild the original source: functions are named function_<index> in serialization order, and loops are not restructured into for or while.
Deno
disrobe auto recognizes the data section deno compile embeds in the executable and extracts each module as its own output file. The section is found by its d3n0l4nd markers and a complete structural parse, not by the host executable format; only Windows x64 executables have been checked. Two section layouts are parsed:
- Deno 2.x module store, checked against Deno 2.9.7 output. Local files come out of the embedded virtual file system at their paths relative to the program root, with the source bytes Deno stored, which for TypeScript is the original TypeScript. Remote modules, such as
https:imports cached at compile time, come out at a path built from the specifier without its scheme; only synthetic payloads cover them. For the checked program the output matches the authored sources byte for byte. - Deno 1.x section, a 40-byte
d3n0l4ndheader followed by an eszip, checked against Deno 1.46.3 output. Modules come out as the eszip stores them: JavaScript and JSON verbatim, TypeScript as Deno's transpiled JavaScript with its source map written beside it as<module>.map. The map'ssourcesContentcarries the original TypeScript.
A bare eszip file (versions ESZIP_V2, ESZIP2.1, ESZIP2.2 and ESZIP2.3) is extracted the same way; a real archive has been checked only for ESZIP2.2 from Deno 1.46.3. SHA-256 checksums are verified when the archive carries them, and a module whose checksum does not match is dropped.
Limits
-
Deno 2.x payloads also hold the transpiled JavaScript and source map of each TypeScript module;
autowrites only the original source. Symlinks in the embedded file system are parsed but not written. -
Deno 1.x executables that bundle npm packages keep those packages in a separate directory after the eszip.
autodoes not extract it and records a refusal saying so. -
Only Deno 1.46.3 and 2.9.7 output has been checked. Other releases, including earlier 1.x releases that wrote a different section layout, are recognized only if their section matches one of the two layouts; a section that differs fails to parse and the input is not reported as a Deno executable.
-
.jscinternalized identifiers (most variable and property names, for exampleconsoleandlog) are serialized as references into V8's read-only snapshot heap, not as inline bytes in the.jsc. Resolving them needs the exact V8 binary's RO heap.disrobereports that as a lossy-internalized-roots boundary and does not decode past it. -
TypeScript
asyncrecovery assumes the globalPromiseis the built-in one when the module runs. A module that visibly rebindsPromiseis left compiled; a replacement installed by another script (for example zone.js) is outside a single-file check. State-machine shapes the rule cannot prove equivalent, such as terser's conditional instruction returns, also stay compiled. -
For V8 snapshots
disrobereports aSnapshotDeserializeWall: the format prevents full bytecode recovery, so it scrapes the string pool (tunable via--scrape-min) and states the boundary; it does not decode past it.
Webview desktop frontends
disrobe webview statically recovers the frontend files embedded in Electron, Tauri, and Wails desktop applications. It writes HTML, JavaScript, CSS, source maps, fonts, images, WebAssembly modules, and other asset bytes under an output directory without starting the application.
disrobe webview desktop.exe --out frontend/
disrobe --json webview desktop.exe --out frontend/ > webview.json
The text result names the detected family and each recovered path, byte size, and compression method. JSON output uses the disrobe.webview.carve/v1 schema and includes the input path, family, output directory, asset count, externally unpacked paths, and per-asset records.
Supported layouts
| Family | Static input | Recovery |
|---|---|---|
| Electron | A standalone ASAR or an ASAR concatenated into a larger executable | Parse the ASAR pickle header and file tree, recover file bytes, verify integrity metadata when present, and preserve safe relative paths. |
| Tauri v1 and v2 | A generated embedded asset map in the native image | Resolve the table through PE, ELF, or Mach-O mappings and relocations, decode each entry, and recover the original asset tree. |
| Wails v2 | A Go embedded filesystem in the native image | Locate the embedded records and recover the original frontend tree. |
The embedded-map decoder handles uncompressed entries plus Brotli, zstd, and gzip. Mixed encodings are decoded per entry. It bounds the number of scan candidates, table probes, paths, recursion depth, output bytes, and compression expansion before allocating or writing output.
Recovered paths pass through the same path sanitizer used by the container layer. A single leading / on a non-empty key is treated as bundle-root-relative. Traversal components, UNC paths, drive prefixes, and other escaping names fail instead of writing outside --out.
Automatic recovery and packages
disrobe auto detects supported webview layouts and writes their frontend assets
under extracted/. Electron and Tauri use webview.carve; JavaScript and
WebAssembly children can continue through their respective analysis passes.
With Go support enabled, Wails uses go.classify, retaining both Go analysis
metadata and the frontend under extracted/embed/frontend/dist/.
disrobe auto desktop.exe --out recovered/
webview accepts one file. If the application image is still inside an archive, installer, disk image, or application bundle, extract that container first and pass the recovered executable to webview:
disrobe extract desktop-package.bin --out package/
disrobe webview package/path/to/application.exe --out frontend/
The standard CLI enables this route through its chain feature. disrobe passes
lists the routes included in a custom build.
Evidence and limits
Committed Tauri v1, Tauri v2, and Wails v2 builds are compared against their complete
source asset trees in crates/disrobe-pass-webview/tests/real_toolchain.rs and
crates/disrobe-cli/tests/cli_webview_carve.rs. These tests compare the full path
set and every file's bytes through the library and automatic CLI routes. Electron
CLI tests cover direct extraction and automatic recovery with one and four workers.
The electron_oracle test also compares extraction with the real @electron/asar
CLI.
The graded host-format matrix covers PE32+, 32-bit and 64-bit ELF in both byte orders, thin Mach-O, and universal Mach-O. PE32 remains declared but unobserved; the shared 32-bit read path is graded on ELF32 in both byte orders. Real committed desktop builds cover the current Tauri and Wails layouts; constructed fixtures exercise the wider host and compression matrix.
Static recovery cannot return assets that a development build reads from disk or a server at run time because those bytes are absent from the executable. Wails v3 remains ungraded while it is prerelease. Tauri resource-section storage is also ungraded because the tested released toolchains emit record arrays instead. These cases are not included in the byte-identity claim.
WebAssembly
disrobe parses WebAssembly modules, lifts them to four target surfaces, reverses Wasm-specific obfuscators, and decodes the Component Model and GC type graphs.
At a glance
| Layer | Coverage |
|---|---|
| Lift targets | Rust, TypeScript, WAT, or C pseudo-source, or a JSON summary |
| Instruction set | MVP plus the SIMD, atomics, bulk-memory, table/element, reference, and tail-call proposals |
| Name recovery | Not applied: DWARF and source-map helpers exist, but no command calls them yet |
| Op-coverage grade | Every operator in the function lowered, and the re-emitted WAT re-parsed by an independent parser |
| Execution grade | Return values, trap parity, and linear memory compared against the original under wasmtime |
| Obfuscators | Jscrambler-WASM integrity imports stripped, Wobfuscator imported operators re-inlined, Wasmixer fragments inlined; Tigress-via-Emscripten and wasm-name-obfuscator detected and classified only |
| Control-flow unflattening | Dispatcher loops whose state lives in a local, a private mutable global, or a non-atomic i32 memory slot are rebuilt as structured control flow; a dispatcher outside that set is left in place |
| Envelopes | Component Model, memory64, and the GC type graph parsed by dedicated scanners; threads instructions also lift to C, Rust, and TypeScript |
Commands
disrobe wasm decompile module.wasm --target rust --out lifted.rs
disrobe wasm decompile module.wasm --target ts --out lifted.ts
disrobe wasm decompile module.wasm --target wat --out lifted.wat
disrobe wasm decompile module.wasm --target c --out lifted.c
disrobe wasm decompile module.wasm --target json --out summary.json
disrobe wasm deob module.wasm --out clean.wat --emit-wasm clean.wasm
disrobe wasm component module.wasm # parse the Component Model envelope -> world / adapter manifest
disrobe wasm types module.wasm # recover the GC type graph (struct / array / ref types)
decompile lifts to Rust, TypeScript, WAT, or C pseudo-source, or a JSON summary.
deob writes the recovered module as WAT to --out. Add --emit-wasm to write the recovered binary as well. Two JSON files land beside the WAT with its extension replaced, so --out clean.wat produces clean.summary.json and clean.recovery.json. The recovery report holds the per-transformation counts, including the unflattening counts described below.
Coverage and fidelity
The committed corpus contains 40 .wat files. wasm-tools 1.250.0 parses 38 of them into 133 functions containing 1034 instructions. Disrobe lowers all 1034 instructions across all 133 functions, with no instruction-inventory disagreements. Coverage includes the MVP instruction set and the SIMD, atomics, bulk-memory, table/element, reference, and tail-call proposals.
The per-function reference inventory is stored in tests/golden/external_wasm_op_inventory.json, keyed by each fixture's BLAKE3. Instructions count as covered only when their function's recovered WAT reassembles; failed output remains in the denominator. Both tools reject the remaining 2 files, whose reference error text is also pinned.
This coverage measure records successful lowering and reassembly, with an external denominator and a self-reported numerator. The execution comparison below grades behavior separately. Regenerate the reference inventory with:
cargo test -p disrobe-pass-wasm-deob --test external_op_denominator -- --ignored regenerate_external_inventory
Regeneration requires wasm-tools 1.250.0. Routine coverage checks use the committed inventory.
All 57 of the 57 execution-eligible functions match the original under Wasmtime over the test's input battery. Eligibility requires a numeric or nullable-reference ABI that can be isolated per function or exercised within a faithful whole module. The semantic_differential test compares return values and trap parity; the first 4096 bytes of linear memory also match in all 6 memory cases.
Both sides run with the same limits: 2 MiB per linear memory or GC heap, at most eight linear memories and eight tables, and 1,024 elements per table. Each call receives two million fuel units; an epoch watchdog bounds the comparison. Imported functions trap instead of calling the host.
wasm deob runs three family passes before the generic folds. It strips Jscrambler-WASM integrity imports, rewrites Wobfuscator's imported arithmetic operators (op_add, op_xor and the like) back into instructions and drops an import only when nothing else references it, and inlines Wasmixer's fragmented functions. It does not recover Wobfuscator's eval op-table and does not unwrap the Wasmixer XOR decrypt stub: rewriting encrypted data would make the stub decrypt it a second time at run time. Tigress-via-Emscripten is detected from its Emscripten-marked exports, but wasm deob does not run its separate dispatcher-unflattening or _Z name helper.
The generic folds keep the module's behaviour. A branch folds only when its condition is a constant expression, or a call into functions that read no mutable global and no memory and do not trap. A call_indirect becomes a direct call only when the table slot is an immediate constant, the table is neither exported, imported nor written at run time, and the target's type matches the call's type. The recovered module is validated before it is written; a module that fails validation is reported as DR-WASMDEOB-0006 instead.
Control-flow unflattening
wasm deob rebuilds control-flow-flattened dispatchers as structured control flow. It recognizes a function that writes a constant start state, enters a loop, selects a case with a br_table on that state, and branches back to the loop head. Each case ends by writing the next state as a constant. The rewriter reads any module, not only one that matches a detected obfuscator family, and it is separate from the Tigress-via-Emscripten helper named above.
The dispatch state can live in three places. A local holds it, read straight into the br_table or copied into a temporary at the loop head. A mutable global holds it, on the condition that the module does not export it and no other function reads or writes it. A linear-memory slot holds it, read at the loop head by a non-atomic i32.load at a fixed offset from a base local and written back by a non-atomic i32.store to the same memory and offset.
Two routes rewrite a recognized dispatcher. The first route applies when the state lives in a local and every case names one successor. It replays the case bodies in execution order, and wraps a repeating tail in a loop. The second route rebuilds the state graph as nested if/else and loop blocks. It takes each case that chooses between two successors, and it takes every dispatcher whose state lives in a global or a memory slot. Both routes remove the br_table from the rewritten function and stop the state cell from carrying dispatch state. flattened_functions_restructured counts a function either route rewrote. flattened_conditional_restructured counts the second route.
The rewrite is graded by execution. For each fixture pair, tests/cff_conditional_reloop.rs first confirms that the flattened module agrees with a separately written module that computes the same function without a dispatcher, over a fixed argument battery under wasmtime. It then requires the rewritten module to agree with that same reference on return value and trap for every argument in the battery. A mutant fixture that swaps the two successors of one conditional transition must disagree with the reference, so a wrong edge cannot pass the battery.
disrobe refuses a dispatcher whose shape it cannot resolve. A refused dispatcher stays as it is, the module still validates and behaves as before, and flattened_dispatchers_walled records it. Set DISROBE_DEBUG=wasm-deob to read the reason on stderr:
state cell is observable outside the dispatcher. The state global is exported or imported, another function reads or writes it, or code after the dispatch loop reads the state cell. A module that carries a function with more nested instruction sequences than the scan bound reports this same reason for every global-state dispatcher in it, because the scan then treats no global as private.state transition is not a resolvable constant edge. A case does not end in a constant state write, hides that write behind a branch, or reads the state cell in its own work or condition.state graph has no sound structured form. The state graph has no equivalent shape built fromif/elseandloop. A cycle entered at two different states or a state the entry cannot reach can land here.
An ordinary compiler can emit a shape outside the supported set. rustc 1.96.1 targeting wasm32-unknown-unknown at -C opt-level=0 lowers a hand-written match over a state variable into a next-state temporary. The rewriter admits the recorded dispatcher when it can resolve that temporary's constant edges; its mutation controls remain walled when those edges change. The committed tests/fixtures/cff_rustc_temp_state.obf.wasm and its Rust source record that case, and the rewritten output validates and behaves the same as the input under wasmtime.
disrobe auto reaches the same rewriter through the wasm chain pass. That pass writes wasm.recovered.wasm and the real counts in wasm.recovery.json when a transformation changed the module. A module whose only finding is a refused dispatcher changes nothing, so its wasm.recovery.json carries zeros. Read a refusal from wasm deob or from DISROBE_DEBUG=wasm-deob, not from the chain sidecar.
Limits
- Two corpus modules are skipped on wat-parse or signature-extraction failure, so the op-coverage figure covers the supported subset, not all of wasm.
- Functions outside the execution-eligible set are op-coverage-only; their behavior is not compared against the original.
- The Component Model envelope, memory64, and the GC type graph are parsed and decoded by dedicated scanners. Their per-instruction semantics are not all lifted to source. Threads are different: all 67 threads-proposal atomic operators lift to C, Rust, and TypeScript, and the runtime tests grade shared-memory contention, wait and notify, fence, and memory growth under a wall-clock deadline.
- Tigress-via-Emscripten is detected and classified only. Its standalone dispatcher-unflattening and name helpers are not on the
wasm deobrun path. - wasm-name-obfuscator destroys the original debug names. The library's
strip_obfuscated_nameshelper removes recognized generated name sections and preserves other custom sections; it cannot restore those names. Its real-output grader compares all 30 pinned outputs with clean wasm-tools references. The helper is separate from thewasm deobpipeline, which detects and classifies this family. - Control-flow unflattening runs only while the module stays under the intra-function folding budget. Above that budget the recovery report sets
intra_function_folding_skippedand no dispatcher is rewritten. - A state cell read with an atomic
i32load is not recognized, sowasm deobleaves that function as it stands. flattened_dispatchers_walledcounts dispatchers the rewriter recognized and then refused. A shape it never recognized is not counted, and only the three reasons above are printed.
JVM and Android
disrobe decompiles JVM classfiles and Android DEX through a unified command, adding protector analysis, ProGuard/R8 mapping reports, and chain auto-detection, with headless wrappers for FOSS decompilers selected by the format's default routing or --backend.
At a glance
| Surface | Support |
|---|---|
| Inputs | .class, .jar, .dex, .apk, .aab; ODEX, single-DEX OAT, JDK .jmod and lib/modules jimage containers; the classfile itself validated in-house (format 1.0.2-25) |
| Decompilers | In-house classfile and Dalvik decompilers, the Dalvik one default on .dex and .apk; CFR, Vineflower, Procyon, JADX, and others via --backend |
| Language surface | Records, sealed types, pattern matching, enum constant bodies, declaration and member annotations, enhanced for, multi-catch, plus Kotlin and Scala idioms |
| Obfuscator handling | String recovery for supported Zelix KlassMaster, Allatori, Stringer, and DashO patterns; DexGuard and BlackObfuscator control-flow analysis; ProGuard/R8 name reports from mapping.txt |
| Detection and routing roster (10) | ProGuard/R8, Zelix KlassMaster, Allatori, Stringer, DashO, DexGuard, BlackObfuscator, yGuard, SkidSuite2, JBCO (the last three detect-only) |
| RASP vendors (8) | Promon SHIELD, Guardsquare DexGuard RASP and ThreatCast, Appdome, OneSpan, Arxan/Digital.ai, Zimperium zShield, Licel DexProtector. No command runs this detector yet; behavior and auto report the runtime markers of Promon, Appdome, Zimperium, Guardsquare, and DexProtector |
| Signatures | v1 signing-material inventory; v2, v3, and v3.1 content-digest verification; v4 .idsig parsing with APK-digest matching to v2 or v3 |
Commands
disrobe jvm decompile App.class --emit source --out src/ # write the in-house Java source
disrobe jvm decompile app.jar --backend vineflower --out src/
disrobe jvm dex2-jar classes.dex --out classes/ # in-house .class tree + classes.jar
disrobe jvm decompile classes.dex --backend dex2-jar --out external/ # installed d2j-dex2jar
disrobe jvm decompile app.apk --backend jadx --out src/
disrobe jvm decompile classes.dex --backend jadx --out src/
disrobe jvm decompile classes.dex --format ghidra --out recovered/
disrobe jvm decompile app.jar --mapping mapping.txt --out src/ # write name-restoration.json
disrobe jvm extract app.apk --out classes/ # extract a .jar / .apk + dump classfile inventory
disrobe jvm backends # report available JVM/Android backends on PATH
disrobe jvm jni app.apk # link native methods against the apk's own .so files
disrobe jvm jni App.class --native libnative.so --json
disrobe jvm jni module.aar # nested classes.jar against jni/<abi>/*.so
disrobe jvm jni base.apk --native split.apk # cross-split link against an APK Set member
disrobe apk app.apk # also prints the JNI link table for the embedded dex/.so pair
disrobe auto app.apk --out recovered/ # recursively process recognized payloads
disrobe auto classes.dex --format json --out recovered/
Every format writes in-house source by default: Dalvik source for .dex and .apk, per-class source for .jar and .class. An external backend runs only when --backend names it: cfr, vineflower, procyon, jd or krakatau for class and jar files, jadx or dex2-jar for DEX and APK input. A named backend that is not installed, or that does not apply to the input format, fails with an error. disrobe validates the classfile itself (format 1.0.2-25) and recovers records, sealed types, and pattern matching where the selected backend supports them, plus Kotlin and Scala idioms.
disrobe jvm dex2-jar is the in-house DEX-to-class translator. It writes a deterministic class tree and classes.jar without an external executable. disrobe jvm decompile <dex> --backend dex2-jar is different: it invokes an installed d2j-dex2jar backend and keeps that backend's contract and output separate from the in-house translator.
The in-house translator carries InnerClasses, EnclosingMethod, and generic Signature attributes from DEX system annotations. The Dalvik renderer uses ownership metadata to group nested classes; a $ in a name alone does not establish nesting. Invalid annotation metadata is reported without rejecting an otherwise parseable DEX.
For a standalone DEX, jvm decompile --format ghidra|ida|json writes descriptor-keyed class, method, and field entries beside the normal output. auto accepts the same formats when the original input itself reaches a successful jvm.classify node and writes the sidecar under exports/dalvik/. It does not reuse a DEX extracted from an APK or another container. Each entry keeps the original owner, original member name, descriptor, and replacement as separate values. When the current recovery path has not changed a name, the original and replacement stay identical. The Ghidra and IDAPython scripts resolve the original logical identity in the loaded DEX database before renaming the database object; they do not assign virtual addresses to Dalvik identifiers. IDAPython class renames require IDA 9.4 or later because that release introduced the loader's persistent DEX type-rename store. Method and field renames use the older DEX record APIs.
Coverage and fidelity
Classfile
The in-house classfile decompiler is gated against real javac: on the EdgeCases corpus, the asserted floor is 131 of 131 decompiled methods (100%) recompiling error-free on JDK 25. Its emitted source carries enum types with their constant bodies, declaration and member annotations, enhanced-for loops over arrays and iterables, and multi-catch clauses, each recompile-checked on the same corpus (foreach_multicatch_recovery.rs). CI provisions a JDK so this gate runs there.
Dalvik
The Dalvik lifter's recovered bodies are graded by the real JVM bytecode verifier rather than by the lifter's own output: a committed gate assembles the recovered classes from the committed dex corpus, loads them under -Xverify:all, and asserts that the recovered classes pass the verifier; 100% of verifier-presented classes pass (118 of 118, 0 lifter verify failures; the other 37 of 155 classes are link-skipped because they reference supertypes the harness does not bundle, Kotlin's Function1 among them, which is a test-harness limit and not a lifter defect). A live-range-splitting pass recovers method bodies whose registers carry conflicting JVM types across control-flow joins; 317 re-hosted bodies verify clean under the same gate. The committed-corpus verifier floor and the EdgeCases recompile floor are asserted by committed test gates.
The in-house Dalvik decompiler, the default for disrobe jvm decompile on .dex and .apk, is graded on the same corpus against the real EdgeCases.java source rather than its own output. A value computed in one basic block and consumed in another (an array length, or a wide argument to a call such as Math.abs or charAt) is materialized into a local at its real use site instead of being dropped across the block boundary, so all eight leaf methods reconstruct their call sites with full fidelity while every method's signature, control flow, and operators recover (dalvik_decompile_oracle.rs).
The same source path reverses core-library desugaring emitted by D8 9.1.31 with desugar_jdk_libs_configuration 2.1.5. It restores marker-confirmed public API types in the j$/time, j$/util, and j$/nio namespaces, receiver-first $-EL calls, $-CC interface static calls, and exact supported Desugar* retarget helpers. The committed minimum-API-21 DEX covers time, streams, functions, Optional, concurrent, and NIO APIs. A minimum-API-34 DEX built from the same Java source provides the original call-shape reference. The test recompiles every recovered compilation unit with Java 11, then executes every recovered API probe method through an independent harness. Unknown configuration identifiers, application-owned j$/ classes, wrapper conversions, API flips, unknown helpers, and malformed receiver shapes remain unreversed instead of being renamed by prefix.
Containers
auto opens four container formats and passes their members to the class and DEX passes. An ODEX yields its embedded classes.dex. An OAT file yields its single DEX, found through the oatdata symbol and the OAT header; when the DEX lives in a separate .vdex, which is the usual layout on current ART, the OAT file yields only its manifest and a refusal, because VDEX is not read. A .jmod yields every entry at its archive path, and a jimage (lib/modules) yields every stored resource as module/parent/name; compressed jimage resources are refused rather than emitted, because no jimage decompressor is implemented. Each container also writes jvm-container.json. The jmod reader shares the zip limits (65,536 entries, 256 MiB per entry, 1 GiB in total) and the jimage reader enforces the same totals. tests/jvm_container_chain.rs grades a committed jmod against jmod extract and the grading JDK's own lib/modules against jimage extract, byte for byte.
Obfuscator analysis and recovery
For JVM classfiles, disrobe peels supported protector string patterns before in-house source emission. On Dalvik, it lifts a DexGuard-style flattened method from the rewired control-flow graph when every dispatcher edge resolves to a constant successor and the state register is read only by its dispatcher; otherwise the method keeps a note naming why it was not rewired. BlackObfuscator dispatchers are analyzed. --mapping parses ProGuard/R8 mappings and writes recovered class and member names to name-restoration.json; it does not rewrite emitted Java source. disrobe registers detection and routing for 10 obfuscator and protector families: ProGuard/R8, Zelix KlassMaster, Allatori, Stringer, DashO, DexGuard, BlackObfuscator, yGuard, SkidSuite2, and JBCO (the last three detect-only, identified by marker strings and, for JBCO, its jsr/ret control flow).
On the Android side it also applies eight runtime application self-protection (RASP) fingerprint rules: Promon SHIELD, Guardsquare DexGuard RASP and ThreatCast, Appdome, OneSpan, Arxan/Digital.ai, Zimperium zShield, and Licel DexProtector. For APK signatures, disrobe inventories v1 signing material, verifies v2, v3, and v3.1 content digests, and parses v4 .idsig files to match their APK digest to a computed v2 or v3 content digest.
String-encryption protectors are decrypted by emulating each class's decrypt method on the encrypted constants rather than by guessing a key, so Allatori and DashO style decrypt(String) and decrypt(int, String) routines are recovered statically. The evaluator runs <clinit> for a per-class static key, constructs the receiver and runs <init> for an instance decrypt keyed on a field, synthesizes the calling frame for a caller/stack-trace-keyed key, and covers the long-accumulator arithmetic, getfield/putfield, and switch-dispatched keystreams these routines emit, all under a hard step cap. With disrobe jvm decompile --mapping mapping.txt, ProGuard and R8 names are written to name-restoration.json, with overloaded methods disambiguated by descriptor argument count; emitted Java identifiers are unchanged.
On the Android side, the BlackObfuscator analyzer recognizes the String.hashCode() keyed dispatcher, matches each block's const-string block-name to its switch case, and reports the recovered linear block order in the decompiled output. The method body remains rendered from the flattened graph; the annotation records the recovered order rather than replacing that body. Separately, obfuscator-planted out-of-range exception-table entries are dropped before classfile structuring so they cannot poison the control-flow graph, and jsr/ret subroutines are inlined into a linear stream.
DexGuard hides string constants in an encrypted static String[] decrypted at run time through java.lang.reflect.Method.invoke rather than a direct call. The key and ciphertext are present in the dex; only the dispatch is reflective. disrobe runs a constrained Dalvik register machine over the dex's own routine: it executes the class <clinit> to rebuild the encrypted table, then runs the decrypt(int) body for each index (read the table element, apply the per-char transform against the embedded key, rebuild the string) and emits the plaintext, with the Class.getDeclaredMethod + Method.invoke call sites resolved to their concrete target. disrobe jvm decompile app.dex surfaces the recovered strings and resolved sites in the manifest.
JNI linking
disrobe jvm jni and disrobe apk link each declared native method to its C implementation across the DEX or classfile to native library boundary. Static binding computes the short and the long JNI symbol from the class name, method name, and descriptor, escaping _, ;, [, $, and non-ASCII characters as the JNI specification requires, and matches both against the library's exported symbols. A JNINativeMethod array that the compiler placed in the library's read-only data is recovered from the file: the tool walks candidate name, signature, and fnPtr triples, applies the ELF dynamic relocations to their pointer fields, and resolves each function address to its symbol. It reads the table, not the RegisterNatives call, so the recovery does not depend on how the call reaches the JNIEnv function table, and it finds no table that the program assembles in memory at run time. The output is the typed link table plus a JNIEXPORT ... JNICALL C prototype per native method.
An APK whose zip carries both the DEX and the native library links them without the caller naming either side; --native supplies the library for a bare .class, .jar, or .dex input. An AAR unzips its nested classes.jar and scans jni/<abi>/*.so, the AAR layout, rather than an APK's lib/<abi>/. An APK Set (.apks), or a base APK plus split APKs passed with --native, merges every split's DEX and native libraries into one input set, so a native method declared in the base DEX can resolve against a symbol that exists only in a config split. A raw .oat file locates its single embedded DEX through the OAT header's oat_dex_files_offset; a multi-dex .oat is refused, because the per-entry record stride changes between ART releases and is not documented. disrobe auto performs the same link and writes jni-link.json when both sides are in one container.
A native method with no matching symbol in any library is reported unresolved rather than dropped, and dynamic_only counts it. A symbol exported by more than one library is reported ambiguous rather than bound to the first. Each resolving library's ABI directory name is carried on its entry, so a multi-ABI APK states which .so a symbol came from.
The tests below run in cargo xtask prepush when disrobe-pass-jvm or disrobe-cli changes, and in the weekly scheduled CI run on Linux, macOS, and Windows; no JNI test runs on every push. "Real" means the input came from a real compiler or tool; "synthetic" means the test built the bytes itself.
| Behaviour | Test | Reference | Input |
|---|---|---|---|
| Short and long symbols, and the C prototypes | jni_prototype_oracle.rs | The header javac -h writes for a class with 28 native methods (overloads, _, $, a non-ASCII name, primitive, array, and reference types); the prototypes must also pass -fsyntax-only against the JDK's own jni.h | real javac output |
[ in a long symbol | unit test in jni.rs | A string written from the JNI specification; the javac -h fixture has no overloaded method with an array parameter | synthetic |
| Symbols for DEX methods | jni_native_surface.rs | Strings written to match javac -h | synthetic DEX and .so |
JNINativeMethod recovery from read-only data | jni_register_natives.rs | readelf symbol values for the four registered functions, one reached through an R_X86_64_RELATIVE relocation | real x86-64 and AArch64 .so compiled from a committed C file that never calls RegisterNatives |
APK linked by disrobe auto, jni-link.json | auto_apk_dex.rs | The four entries of the committed .so | a test-built APK holding the committed Hello.dex and .so |
| AAR | jvm_jni_link.rs | One static and four registered natives, both ABI directories named | a committed AAR: a javac-built classes.jar, one synthetic .so, and the committed x86-64 .so |
JAR with --native | jvm_jni_link.rs | The four registered natives | the committed JAR and .so |
| APK Set, base plus split APK | jvm_jni_link.rs | One native resolved only by the split's symbol | synthetic |
Single-dex .oat | jvm_jni_link.rs; unit tests in oat.rs for the multi-dex refusal | One native resolved | synthetic OAT headers, no dex2oat output |
| Unresolved natives | jvm_jni_link.rs, jni_native_surface.rs | Named in the text and JSON output with a count | synthetic DEX |
A d8-built DEX against a clang-built .so | jvm_jni_link.rs | At least one native resolved | real javac, d8, and host clang output; the test prints UNGRADED and passes when d8 is not on PATH, which is the case in CI |
Not graded by any test: AAB input, a Windows .dll or macOS .dylib passed with --native, the JNI table that disrobe apk prints, ambiguous symbols, a real dex2oat .oat, and an NDK-built library or the NDK's jni.h.
Only two things are absent from the static artifact and therefore unrecoverable: a fnPtr computed at runtime rather than stored as a relocatable pointer, and a FindClass target name built dynamically rather than passed as a string literal. The native function body at a recovered address is not this surface's job; it goes to the native pseudo-C decompiler.
Limits
Disrobe reports lowering 83662 / 83943 methods with code items across three SHA-256-pinned FOSS APKs, or 99.7%. This counts emitted bodies. The APKs contain 89,516 declared methods, including 5,573 abstract, native, and interface-instance declarations without bodies.
The JVM check selects non-stub methods by a deterministic hash of each method name and re-hosts their bodies in isolated carriers. Of the bodies presented, 2988 of 2998 pass -Xverify:all without being invoked. Another 5,421 sampled bodies are ungraded: 1,407 constructors, 1,730 invokespecial receivers, 2,141 unresolved dependencies, and 143 other exclusions. The recovery chart's data records the full candidate and sample populations.
| APK | Emitted bodies / methods with code | JVM accepted / presented |
|---|---|---|
| Transmissionic | 26,360 / 26,416 | 988 / 989 |
| RustDesk | 29,841 / 29,983 | 1,217 / 1,223 |
| EnRecipes | 27,461 / 27,544 | 783 / 786 |
The two measureContentWidth bodies excluded by the sampling rules are ungraded and do not contribute to the accepted count. Verdicts are pinned by method name under crates/disrobe-pass-jvm/tests/golden/dalvik_body_attest/. These measurements use local APKs; CI checks the published counts and the separate committed-DEX corpus.
- Runtime-keyed string schemes (system property, environment, clock, secure random, or a live cross-class table, as Stringer sometimes uses) are flagged as walled instead of faked.
- A DexGuard routine that derives its key from runtime-only state (a system property, the environment, the clock, or a secure random) is reported as runtime-keyed rather than guessed.
- DexGuard-style reflection-string recovery is validated against a benign sample implementing that technique, not output produced by the commercial DexGuard tool. The sample is a hand-written
.javacompiled by realjavacand dexed by reald8; the plaintext reference is the stdout of the same program run under a real JVM. - yGuard, SkidSuite2, and JBCO are detect-only on the protector-specific recovery path. The JBCO real-output grader covers five pinned Soot 4.7.1 outputs: ordinary classfile recovery recompiles
Sample.names.jarto identical behaviour, while four outputs remain named partials. Four other runner invocations failed in the tool and produced no fixtures.
.NET / CIL
disrobe parses .NET PE and CLR metadata, decompiles CIL to C#, F#, and VB pseudo-source, registers detection and routing for 23 protector families, and probes ReadyToRun and Native AOT images.
At a glance
| Surface | Support |
|---|---|
| Decompile | In-house CIL disassembler and CIL-to-C#/F#/VB lowering, so the structural recovery is disrobe's own even when a rendering backend is used |
| Rendering backends | ILSpy, dnSpy, dnSpyEx, de4dot via --backend |
| Images | ReadyToRun (R2R) and Native AOT detection; dotnet native-aot exposes the library's name, type, method-boundary, and managed-signature recovery, graded on real Native AOT builds for PE and on hand-assembled ELF and Mach-O images that carry only a header and two metadata names; single-file bundles extracted member by member |
| ConfuserEx2 | Constant decryption recovered in-house on real ConfuserEx2 1.6.0 output; control-flow deflattening matched to the clean control-flow graph on ConfuserEx 1.x output and checked more narrowly on ConfuserEx2 1.6.0 output; the encrypted-resource layer is carved byte-exact but walled on the runtime key; runtime-string and anti-tamper cleanup delegates to --backend de4dot |
| Eazfuscator.NET | A generic XOR string decryptor emulated over the #US table, graded on a synthetic fixture rather than Eazfuscator.NET output; VM tier devirtualized at all 67 instructions against an in-repo EazVM virtualizer of our own, not the shipping product |
| KoiVM | Devirtualized on a committed sample produced by the real KoiVM tool, all six virtualized bodies lifted back to CIL |
| SmartAssembly, .NET Reactor | Embedded-assembly resource decompressed and encrypted-string table decrypted, graded against Roslyn-built fixtures we build to the published algorithm; no assembly produced by either product is committed |
| Obfuscar | Dedicated in-house peeler: NameMaker odometer classification plus HideStrings recovery |
| ILProtector, MaxToCode | Invoke-stub and zero-RVA structures enumerated on in-repo fixtures; native-keyed configurations remain report-only |
| Themida .NET, ArmDot | Detected; no native-VM devirtualizer ships |
Other registered families produce reports identifying the protector and the static recovery available for that input. Bodies that require an unavailable runtime key remain encrypted.
Commands
disrobe dotnet decompile App.dll --backend ilspy --out src/
disrobe dotnet decompile App.exe --backend dnspy-ex --out src/
disrobe dotnet decompile App.single-file.exe --out recovered/
disrobe dotnet decompile App.dll --backend de4dot --out src/
disrobe dotnet analyze App.dll
disrobe dotnet native-aot App.native.exe --out aot.json
disrobe dotnet backends # report available .NET backends on PATH
disrobe auto App.exe --out recovered/ # static protector peel + in-house CIL-to-C#
decompile always runs the in-house CIL renderer. --backend ilspy|dnspy|dnspy-ex|de4dot also runs that external decompiler; a named backend that is not installed fails with an error. disrobe auto stays on the registered in-house pass and does not launch those backends. analyze reports the PE and CLR summary, protector detection, and whether ReadyToRun (R2R) or Native AOT is detected. Use dotnet native-aot for the detailed AOT report and recovered method bodies.
Coverage and fidelity
Single-file bundles
A .NET single-file deployment packs application files into a host executable. A self-contained
deployment can also carry native runtime components. The bundle reader
(disrobe_binfmt::containers::dotnet_bundle) finds the bundle marker inside a PE, ELF or Mach-O
host, reads the manifest, and returns each embedded member under its sanitized relative path. It
inflates a deflate-compressed member and returns a stored member as it lies. Members are managed
assemblies, native libraries, deps.json, runtimeconfig.json and symbol files. The reader also
parses deps.json into a typed manifest rather than only carving it, so the runtime assembly list
and the library table are readable as data.
disrobe extract writes the members to disk, and disrobe auto routes them onward with no
dedicated flag: an embedded managed assembly reaches the CIL pass on its own. disrobe dotnet decompile accepts the same bundle as a direct input. It stages all recovered output beside the
destination and publishes the directory only after extraction and every managed assembly
decompilation succeed. members/ holds every embedded file. assemblies/<relative-path>/ holds
the normal manifest and pseudo-source for each managed assembly. bundle.manifest.json records the
bundle version, bundle ID, quota accounting, and managed assembly list. The command refuses a
non-empty destination and refuses more than 512 managed assemblies before invoking any rendering
backend.
The format defines exactly three manifest major versions, and the reader accepts those three and
refuses any other by number. Major 1 is what .NET Core 3.x wrote, major 2 is .NET 5, and major 6 is
.NET 6 and later. Major 1 has no deps or runtimeconfig block and records every entry as type
Unknown. Compression exists only from major 6.
Coverage is graded against bundles the real .NET tooling produced, in
corpus/binfmt/dotnet-single-file. Each extracted assembly is compared byte for byte with the
assembly the compiler emitted before bundling. The committed set spans all three major versions,
PE, ELF and Mach-O hosts, every one of the six entry types, and a bundle that mixes compressed and
stored entries. A declared member size that runs past the buffer, a path that escapes the output
directory, a duplicate path and a decompression bomb are each refused.
A universal (fat) Mach-O host is not supported. Its header-offset field is relative to the slice rather than to the file, so the reader sees an implausible version and refuses the file instead of reading the wrong offset.
Native AOT images
The AOT report recovers metadata names, type and method attribution, method boundaries, and
pseudo-C bodies. That coverage is measured on x86_64 PE executables published by the .NET Native
AOT toolchain. The ELF and Mach-O fixtures are hand-assembled: each is a small assembly source
linked by ld.lld or ld64.lld into an image that holds a ReadyToRun header and two metadata
names. On those two formats the tests grade header location, layout-profile selection, and name
recovery only; no ELF or Mach-O image built by the .NET toolchain is committed, and type, method,
and body recovery on them is unmeasured. The parser reads layout metadata from the image; recovery
on aarch64, arm, and x86 remains outside the measured population.
Obfuscator reversal
disrobe registers detection rules for 23 protector families. Recovery depth varies by protector and by what is statically present in the artifact. The per-family evidence below states what artifact is graded, what data is recovered, and where static recovery stops.
Detection and string decryption are separate claims, and the evidence behind the second one differs by family. String decryption evidence below states which families are graded on an assembly the protector itself produced and which are graded on a fixture we build to the published algorithm.
Reversed on a real committed sample (plaintext recovered from the artifact, plaintext-absent oracle):
-
ConfuserEx2: in-house recovery reverses the constants protection (the documented FOSS "Ki.Constants" block-XOR / LZMA-validated algorithm) on a real committed
SampleConstants.confuserex2.dll, with a test whose fixture holds only ciphertext plus the real decryptor and asserts plaintext not present anywhere in it. The encrypted-resource layer is carved byte-exact but walled on the runtime key. Control-flow flattening is deflattened in-house:disroberebuilds the original control-flow graph from thewhile(true)/switchdispatcher and recovers the switch-key encoding. The deflattening evidence comes from two protector lines and differs in strength:- ConfuserEx 1.x (
yck1509/ConfuserEx,ctrl flowprotection): on the NormalPredicate sample all 6 flattened methods recover the clean build's control-flow graph with every opcode and operand in place; on the x86Predicate sample (the native decoder stub emulated through the in-house x86 interpreter) and the ExpressionPredicate sample (the inverse expression folded symbolically) all 8 methods each recover the clean control-flow graph. - ConfuserEx2 1.6.0: in the gauntlet sample the flattened
Processmethod deflattens with no unresolved block, 11 of its 12 block signatures match the clean build, and every call-resultpopsurvives. InHelloAppLegacy.confuserex2.dllevery flattened method (the static constructor and the injected constant decoder) deflattens with no unresolved block and no edge to a missing block; that check has no clean baseline to compare against.
For de4dot's runtime-VM string and anti-tamper handling, confirm de4dot is available with
disrobe dotnet backends, then usedisrobe dotnet decompile App.exe --backend de4dot.disrobe autodoes not invoke that external backend. - ConfuserEx 1.x (
In-assembly-decryptor recovery, graded by round-trip against the pre-encryption original. This list is grouped by how recovery works, not by who produced the sample, so a family in it also appears in String decryption evidence below: the round-trip proves the decoder inverts the encryption, and the table below states whether the encrypted input came from the protector's own tool or from a fixture built to its published algorithm.
- Eazfuscator.NET: locates a static
char[]/byte[]string-decryptor method and emulates its CIL over the encrypted#USliteral table to recover the plaintext strings. The graded decryptor is a generic single-key XOR loop inside a synthetic PE that the test assembles itself; neither Eazfuscator.NET's own string algorithm nor its output is part of that grade, which is why the family also sits in the modelled row below. The VM tier is devirtualized against an in-repo EazVM virtualizer of our own: the committed assembly is encoded by that virtualizer, not the shipping Eazfuscator.NET product.disrobereads the embedded resource, recovers the per-build opcode map from the in-assembly dispatch table by fingerprinting each handler, decrypts the position-keyed instruction stream, and lifts every virtualized method body back to CIL. It then applies width-checked MBA simplification to supported straight-lineint32expressions before grading the result against the clean DLL. The ordered instruction comparison resolves branch targets to instruction indexes, and 67 of 67 instructions match in sequence across six bodies (100%). A second gate evaluates the recovered bodies in the product's bounded CIL emulator with the argumentsMainpasses and requires the six values the clean assembly prints. It also checks both sides of every recovered branch against the C# source, and a mutation of each branch must change a result. No assembly runs. For the committed seeded build, the randomized opcode map is recovered from the assembly rather than read from its sidecar. - KoiVM (ConfuserEx VM): detects the
#Koistream andVMDispatchermarkers, identifies dispatch handlers, decodes each method's instruction stream, and lifts all six virtualized bodies to CIL. The committed fixture was produced by the TheProxyRE KoiVM fork through its public Virtualizer API over a benign test program. Recovery is compared with the separately compiledKoiSample.clean.exeand manually derived operations: Add and Square recover fully, and aggregate structural recovery has a 75% CI floor. The unobfuscated control produces no KoiVM summary. - SmartAssembly (embedded assemblies): the mode-1 chunked raw-DEFLATE resource that carries a merged or embedded dependent assembly is decompressed back to the original assembly bytes, graded byte-for-byte against a committed Roslyn-built fixture. The sample recovers 1 / 1 embedded resource. The payload inside it is a real assembly; the mode-1 framing around it is built to the published algorithm, not taken from a SmartAssembly build. Non-mode-1 carriers are marked Unknown and malformed mode-1 is Rejected; neither produces a decoded value. String encryption is a separate axis (below).
- .NET Reactor (encrypted-resource strings): the AES key and IV are read from the reachable encrypted-string resource and the string table is decrypted back to the original literals, graded against the runtime-validated originals of committed Roslyn-built fixtures carrying the .NET Reactor v4 static-string resource shape (astral-plane, embedded-nul, empty, and CJK strings all round-trip). No assembly produced by .NET Reactor is committed. An ambiguous or disconnected decoy key/IV tuple is Rejected as report-only, never guessed.
- ILProtector / MaxToCode: classified on in-repo structural fixtures by Invoke-stub and zero-RVA method enumeration, runtime-resource and
.mtc/.text1section location, and container-framing parse. For native-keyed configurations, the managed assembly does not carry the per-method key used by the runtime loader, so the encrypted bodies remain report-only. - Obfuscar: dedicated in-house peeler (NameMaker odometer classification plus HideStrings recovery: the hidden
ldstrliterals are read back to their original bytes from the in-assembly FieldRVA carrier through the generated accessor, 15 / 15 on the gauntlet sample).
Babel, Dotfuscator (Pro), Goliath, DeepSea, and Agile.NET have detection and classification support. Babel reports the string-recovery prerequisite: a matching protected/plain sample or a verified decoder chain. The other paths report watermarks, identifier characteristics, and encrypted-resource details. They can also use the generic static decoder for supported pure transforms.
String decryption evidence
Which families disrobe decrypts strings for, and what each claim is graded against:
| Evidence | Families |
|---|---|
| Graded on an assembly the protector's own tool produced | ConfuserEx2, Obfuscar, BitMono |
| Decoder implements the published algorithm, graded against a fixture built to it; no assembly from the product is committed | SmartAssembly, Spices.Net, Skater, .NET Reactor, Eazfuscator.NET, CryptoObfuscator |
| Key is native-loader-resident, so recovery stops at detection | Themida (.NET wrapper), ILProtector, MaxToCode |
The second row tests algorithm implementations against known plaintexts encrypted by repository fixtures. Product versions and per-build variants are outside that comparison; the corpus contains no redistributable product-produced sample for those families. The Eazfuscator.NET entry is weaker than the others in that row: its graded decoder is a generic XOR decryptor on a synthetic fixture, not an implementation of the product's string algorithm.
crates/disrobe-pass-dotnet/src/protectors.rs carries this split as Protector::string_evidence, and the tables above are regenerated from it. cargo run -p xtask -- regen --check fails if a family claims a committed sample the tree does not carry, or claims one whose MANIFEST.toml does not record the tool that produced it, or sits in the modelled row without being published there.
Limits
Recovery stops at these boundaries:
- Themida / .NET wrapper: native VM bodies are outside the current recovery scope;
disrobedoes not ship a native-VM devirtualizer. - ArmDot: detected and reported, but no static devirtualizer ships.
- ILProtector / MaxToCode native-keyed configurations: when the per-method key is computed inside the native stub, the original CIL is not statically present.
- Obfuscar renames: original identifiers require the separate
Mapping.txt; the PE contains no name map.
Protector reports identify the missing key or handler stream when those bytes are unavailable in the artifact.
Native (PE / ELF / Mach-O / NE)
disrobe includes native decompilation for x86-64, AArch64, ARM32, and MIPS32, alongside symbol recovery, disassembly, identification, patching, fingerprinting, and diffing. It can export recovered information to Ghidra and IDA, and drive Ghidra headlessly. Architecture-specific output and limits are described in the decompile guide.
Two adjacent surfaces have their own pages: native decompile for the in-tree decompiler and the Ghidra backend, and native unpacking for packers, protectors, and bytecode-VM devirtualization.
At a glance
| Surface | Support |
|---|---|
| Containers | PE, ELF, Mach-O, Windows 3.x NE, OS/2 1.x NE, plus a flat code blob with --raw |
| Architectures | x86 / ARM / RISC-V / MIPS / PowerPC / SPARC / eBPF / AVR |
| Debug formats | DWARF, PDB, STABS |
| Demangling | Rust and C++ symbols, with the C++ class hierarchy recovered from RTTI and vtable layout |
| Function discovery | Call-target and prologue scanning on stripped input, basic-block partition, whole-program call graph |
| Identification | Compilers, packers, protectors, installers, linkers, and code-signing, each finding routed to the pass that handles it |
| Authenticode | Digest recomputation and PKCS#7 chain walk to a single verdict from nine outcomes |
| Queryable IR | functions, calls-to, xrefs-to, string-decoders, complexity-over, capability |
| Capabilities | MITRE ATT&CK technique and MBC ID mapping, with matching instruction offsets as per-rule evidence |
| String recovery | Static scan plus decoder execution through the in-house x86 emulator |
| Editing | Byte patch and nop-range at a virtual address, wildcarded signature generation, cross-build function diff |
| Object models | Delphi and C++Builder classes with parents, published properties, fields, methods, dynamic method handlers and interfaces, enumeration members, string literals, DFM form resources, and compiler release identification |
| Forensics | Entropy map (text / JSON / SVG), crypto and FLIRT signatures, import/export graph, CycloneDX SBOM |
Commands
disrobe native symbols app.exe --out symbols.json # symbols, sections, imports, debug info, RTTI
disrobe native disasm app.exe --out app.asm # recovered per-function listing
disrobe native disasm app.exe --emit cfg-dot --out cfg.dot # per-function basic-block CFG
disrobe native disasm app.exe --emit json --out disasm.json # structured instruction stream
disrobe native disasm --raw shellcode.bin --base 0x1000 --bits 64 --syntax intel # linear sweep
disrobe native callgraph app.exe --out callgraph.dot # whole-program call graph
disrobe native patch app.exe --at 0x1400 --bytes 0x90,0x90 --out patched.exe # rewrite + revalidate
disrobe native patch app.exe --nop-range 0x1400:0x1410 --out patched.exe # nop a span
disrobe native sigmaker app.exe --at 0x1400 # wildcarded signature
disrobe native diff old.exe new.exe # match functions across builds
disrobe native identify app.exe --out identity.json # compiler, packer, protector, signature verdict
disrobe query app.exe functions # discovered functions, complexity, exports
disrobe query app.exe calls-to malloc # call sites to a target
disrobe query app.exe xrefs-to sekret # references to a symbol
disrobe query app.exe string-decoders # decoder-shaped functions (loops + byte arith)
disrobe query app.exe complexity-over 20 # functions over a cyclomatic threshold
disrobe query app.exe capability network # instructions tied to a capability
disrobe capabilities app.exe # MITRE ATT&CK + MBC behavior report
disrobe strings app.exe # static strings + decoder-execution recovery
disrobe native entropy app.exe # ASCII heat-strip + byte histogram + packed-region runs
disrobe native entropy app.exe --format svg --svg map.svg # dark-theme SVG entropy map with section overlays
disrobe native entropy app.exe --format json --out e.json # the disrobe.native.entropy/v0 document
disrobe native signatures app.exe --out sigs.json # AES T-tables, SHA/MD5 IV+K, ChaCha20 sigma
disrobe native signatures app.exe --flirt db.sig # match against an IDA FLIRT database
disrobe native fingerprint app.exe # crypto + FLIRT + string-xref sidecar
disrobe native graph app.exe --out imports.dot # import/export table as Graphviz DOT
disrobe native sbom app.exe --out app.cyclonedx.json # CycloneDX 1.5 SBOM from cargo-auditable metadata
Coverage and fidelity
Symbol recovery and dumping
native symbols dumps symbols, sections, segments, imports, and debug info from PE, ELF, Mach-O, and 16-bit NE files. It demangles and restores Rust and C++ symbols across x86 / ARM / RISC-V / MIPS / PowerPC / SPARC / eBPF / AVR, reading DWARF, PDB, and STABS debug formats. For C++ binaries it recovers the class hierarchy from the in-memory RTTI and vtable layout: ABI, each class's inheritance kind, direct base classes (virtual flagged), virtual-method slot counts, and detected STL templates.
New Executable structure
The NE parser accepts the little-endian segmented container used by Windows 3.x and OS/2 1.x. It validates the 64-byte header, segment and resource ranges, entry bundles, resident and nonresident names, module references, imported names, relocation records, and non-additive relocation chains. It lowers segment-relative entry addresses, exports, and imported names into the same native model used by behavior, IOC, HTML-report, and native-symbol surfaces. The identify surface classifies both variants. The registered native.ne-structure pass gives detect and auto the validated structure. It does not claim 16-bit disassembly or decompilation.
NE names use an OEM code page rather than UTF-8. Printable ASCII bytes other than backslash render directly. Backslash and every other byte render as \xNN, which keeps the representation unambiguous without guessing a host code page or dropping malformed text.
Disassembly, call graph, and CFG
An in-tree iced-x86 disassembler discovers functions without symbols (call-target and prologue scanning), partitions each into basic blocks, builds the whole-program call graph, and renders the per-function listing or, with --emit cfg-dot, the basic-block CFG. --raw disassembles a flat code blob with no container, and --syntax intel|at&t|nasm|masm selects the dialect for raw output. Each decoded instruction carries its register, memory, and rflags read/write effects, and the native layer can re-encode and relocate instruction blocks (the engine behind native patch).
Patching, signatures, and binary diff
native patch rewrites bytes at a virtual address (or nops a VA span), maps the VA to a file offset, applies the edit, and revalidates the image. native sigmaker generates a wildcarded byte signature from the function at an address (immediates and displacements masked via the instruction decoder), then uniqueness-tests it across the image. native diff matches functions across two binaries by content, relocation-invariant, and control-flow-graph fingerprints and reports the added, removed, and changed functions. All three work on stripped input through the in-tree function discovery.
Queryable IR and capabilities
disrobe query runs a queryable-IR layer over the disassembled code (functions, calls-to, xrefs-to, string-decoders, complexity-over, capability), symbol-independent and driven by the same function discovery. disrobe capabilities runs a rule engine over that IR and reports matched behaviors mapped to MITRE ATT&CK techniques and Malware Behavior Catalog (MBC) IDs, with the matching instruction offsets as per-rule evidence. Both accept a stripped binary directly or a .dr envelope.
Emulation-driven string recovery
Beyond a static scan, disrobe strings locates decoder-shaped functions and drives each through the in-house x86 emulator, recovering the plaintext that only exists after the decoder runs. Emulation-recovered strings are deduplicated against the static set and reported with the decoder and buffer addresses, so a single-byte or multi-byte XOR/sub stack-string scheme yields the decoded text without executing the sample natively.
Identifying the compiler, packer, and protector
An in-house multi-signal signature engine fingerprints what built and protected a binary through self-consistency-based identification, then routes each finding to the disrobe pass that handles it. It detects compilers and toolchains (Go, Rust, MSVC, GCC, Clang, MinGW, Delphi, Nim, Zig, Crystal, Swift, GHC, .NET, Nuitka), packers (UPX, ASPack, PECompact, FSG, MEW, MPRESS, Petite, NSPack, kkrunchy), protectors (Themida, VMProtect, Enigma, Obsidium, Armadillo, ConfuserEx, .NET Reactor, Eazfuscator), installers (NSIS, Inno Setup, InstallShield, AutoIt, PyInstaller, Electron, Bun), linkers (MSVC link via the Rich header, GNU ld, LLD), and code-signing. Every hit carries a support route: a Go binary points at disrobe go recover, a packed PE at disrobe native unpack, a .NET assembly at disrobe dotnet decompile, an installer at disrobe auto.
Unpacking and byte-level recovery
disrobe native unpack is graded per section against a committed original rather than by whether the output merely parses. Three families ship one packed-and-original pair each, so their figures reproduce from a clean checkout:
| Family | .text | .rdata | .data | .rsrc | Content total |
|---|---|---|---|---|---|
FSG (Hash.exe) | 18188 / 18188 | 2311 / 3988 | 33212 / 33212 | 1552 / 4672 | 55263 / 60060 |
NSPack (hash.exe) | 18188 / 18188 | 3988 / 3988 | 33212 / 33212 | 2333 / 4672 | 57721 / 60060 |
Petite (hello.exe) | 70796 / 70796 | 15734 / 18396 | 456 / 456 | none | 86986 / 89648 |
.text and .data are byte-identical for all three, and NSPack's .rdata is byte-identical as well, so the decompressors themselves are exact and the residual is placement and fixups rather than lost payload. The content denominator is the original's own section span and is asserted by equality, so a recovery that emits fewer bytes scores worse instead of shrinking what it is measured against. The byte-identical sections are held as a membership list rather than a count, so a section that stops recovering exactly drops out of the list instead of being masked by another section improving. Two spans are reported and they are not interchangeable: the per-section total above counts .rsrc, while an older whole-image gate measures NSPack over .text, .rdata and .data only and reads 99.36% for the same fixture. Relocations are classified as loader-rebuilt and scored separately, because the OS resolves them at load time.
The residuals have specific causes worth knowing when reading a recovered image. FSG's .rdata gap is the import descriptor region: the stub's block-destination table names one aPLib stream per original section, all four are decoded, and the descriptor block is decoded then deliberately withheld from the recovered image because the stub writes it over original .rdata content at run time. NSPack's .rdata reaches byte identity instead, because its import lookup and address tables are rebuilt from the module record the stub carries rather than left for the loader to resolve. The .rsrc gap is shared across families, at 1552 / 4672 for FSG and 2333 / 4672 for NSPack, and it narrowed once the original resource-directory tree is placed at its own RVA rather than wherever the decompressed image left it; what remains is the part each stub reconstructs at run time. Larger uncommitted vendor samples score lower on the whole-image measure for the same two reasons, and no figure is published for them because those samples are not committed and nothing pins them. kkrunchy and kkrunchy classic recover their payload byte-exactly against committed fixtures.
An absent fixture is never a silent pass. A missing committed fixture always fails the test and names its path. A missing uncommitted vendor sample fails the same way unless tests/optional.toml lists the local packer samples, which it does because CI never has them; the run then writes a not-measured record naming the absent file. A fixture that is present but unreadable is a hard failure in every mode, because that is how a quarantined or truncated sample would otherwise stop grading unnoticed (committed_packer_byte_recovery.rs, fsg_unpack.rs, nspack_byte_recovery.rs, petite_unpack.rs, kkrunchy_unpack.rs).
Authenticode verification
For a signed PE, identify verifies the Authenticode signature rather than only noting its presence. It recomputes the SHA-1/256/384/512 digest over the Authenticode hash range (the file minus the checksum field, the certificate-table directory entry, and the certificate table itself) and compares it to the digest the signature claims. It walks the PKCS#7/CMS signer chain (RSA PKCS#1 v1.5 and ECDSA P-256/P-384) up to an embedded bundle of eight trusted code-signing roots, and requires the code-signing extended key usage on the leaf certificate. It verifies any RFC 3161 timestamp, both its own signer chain and its message imprint, before trusting that timestamp to extend validity. Without a verified timestamp, certificate validity is judged at the time SOURCE_DATE_EPOCH names, or at the current time when the variable is unset; a value that is not a whole number of seconds fails the command with DR-CLI-0318 rather than falling back to the clock. The outcome is a single verdict, one of Valid, NoSignature, HashMismatch, Expired, SelfSigned, UntrustedChain, WrongKeyUsage, UnsupportedAlgorithm, or MalformedSignature, written into identity.json with the computed and claimed hashes, the certificate chain, and the timestamp. The verdicts are graded against real signed PE fixtures carrying injected defects: a flipped .text byte, a forged timestamp, a wrong-EKU leaf, and self-signed and expired chains, each asserted to its expected verdict. The computed digest is cross-checked against osslsigncode where it is installed, and live Microsoft-signed System32 binaries reach Valid against the embedded roots (authenticode_oracle.rs).
Delphi and C++Builder RTTI
For a Delphi or C++Builder binary, the native Delphi analyzer (disrobe_pass_native::delphi::analyze) recovers the published object model from the compiled RTTI. It locates virtual method table anchors across the three ABI eras (pre-2009 32-bit, Delphi 2009+ 32-bit, and 64-bit), accepting a class only when its table is self-consistent, and recovers each class's name, parent, instance size, published properties with the ancestor that introduced each, published methods, published fields with their declared class, dynamic method and message handlers, and implemented interface identifiers. Enumeration member names, ordinal ranges and set element types come from the referenced type records. Compiled-in string literals are recovered from the reference-count header across the pre-2009, code page and 64-bit layouts, accepted only when the declared length lands exactly on the terminator. The unit initialization table is reached by following the entry point stub, giving the unit count and each unit's initialization and finalization address, and is refused unless every address lands in an executable section. Each class is tagged as runtime library or author code from its RTTI unit name, so an analyst can read only the author's classes. The compiler release is named only when independent signals agree: the table layout era, a linked runtime package name, dotted unit scope names, and build toolchain path strings. When they disagree the report says so rather than choosing one. It also decodes the binary DFM form resources (TPF0) back to their textual object ... end representation.
Form decoding is compared byte for byte against form streams and renderings both produced by the Free Pascal RTL converters, over five committed cases covering collections, nested collections, child objects, binary data blocks, value lists, sets, control characters and 64-bit integers; the converter source and a regeneration script ship beside the fixtures. Float rendering is excluded and remains ungraded, because the reference renderer's float format differs from Delphi's. The virtual method table and published table walks are graded against the documented layout rather than against a Delphi-compiled binary, so they catch a regression but not an error shared between the reader and the specification transcription. Each table is rejected whole unless every entry validates, so a wrong layout yields nothing rather than invented names. False-positive controls confirm no class, field, dynamic method, interface, type record or string literal is produced from real kernel32.dll, ntdll.dll, user32.dll or shell32.dll.
Nim, Zig, Crystal, and D binaries
These four compilers erase the source, so recovery works from each binary's own tables rather than from anything resembling the original file. disrobe detects the toolchain, demangles its name scheme, and recovers the symbol and metadata surface the compiler left behind. Where DWARF survives, aggregate members come back with full types, including multi-dimensional array dimensions and const/volatile qualifiers, so a field reads as const u8[4] or u8[2][3] rather than an opaque blob. A stripped D PE, which carries neither DWARF nor a name table, is a wall: the format is identified and nothing further is claimed.
Function bodies are carved and lifted to pseudo-C and pseudo-Rust. The figures below come from committed binaries built by the real compilers, and each count is pinned exactly in body_equivalence.rs, so a change in either direction fails the test.
| Binary | Toolchain | Carved functions | Pseudo-C bodies | Pseudo-Rust bodies |
|---|---|---|---|---|
| Nim, C backend, safety-checked, x86-64 ELF | nim 2.0.8 | 183 | 83 | 83 |
Nim --mm:boehm, x86-64 PE | nim, mingw-w64 gcc 13.2.0 backend | 93 | 12 | 12 |
Nim --mm:arc, orc, refc, markAndSweep, go, none, x86-64 PE | nim, mingw-w64 gcc 13.2.0 backend | 2 each | 1 each | 1 each |
| Zig, safety-checked, x86-64 ELF | zig 0.13.0 | 1356 | 340 | 336 |
| Zig ReleaseFast, x86-64 Linux ELF | zig 0.16.0 | 23 | 9 | 9 |
| Crystal, LLVM backend, stripped x86-64 PE | not recorded in the binary | 314 | 25 | 25 |
These counts measure how many bodies the pass emits, not whether they are correct. Two tests grade the output against independent references. body_recovery_oracle.rs compiles every pseudo-C body recovered from the Nim and Zig ELF files, the Crystal PE, and a D PE with a real C compiler (-fsyntax-only -std=c11), and every pseudo-Rust body with rustc --emit=metadata; it requires at least 492 C and 487 Rust bodies to pass. This grade is compile-only: it shows that each body stands alone as valid source, not that it computes what the original did. body_equivalence.rs compiles 14 recovered pseudo-C bodies from Zig 0.16.0, Nim 2.0.8, and Crystal 1.20.2 builds, runs them on at least 115 input rows, and compares each result with a model of the function transcribed from the original source; each binary must also match its build record (source hash, toolchain, and build command). Both tests run in the weekly scheduled CI run on Linux, macOS, and Windows, not on every push.
Entropy map and byte histogram
disrobe native entropy slides a 4 KB window across the file computing Shannon entropy (bits/byte) to locate packed, compressed, or encrypted regions, and renders the profile three ways via --format text|json|svg:
text(default): a Unicode heat-strip sparkline (one glyph per 4 KB block, taller = higher entropy), a 16-bucket ASCII byte-frequency bar chart, and a list of contiguous high-entropy runs (entropy >= 7.0 bits/byte) with their file offsets, the candidate packed or encrypted regions. Pass--out <path>to also drop the JSON document.svg: a self-contained neutral-gray entropy map with no external dependency. Each block is a column colored on a calm-gray to amber to red ramp, with PE/ELF/Mach-O section boundaries (parsed from the file's own section table) overlaid as labeled dashed markers and a color legend. Written to./out/<stem>.entropy.svgor the explicit--svg <path>(which implies SVG rendering). The SVG is byte-stable for a given input (no clock or RNG) and all section names are XML-escaped.json: the machine-readabledisrobe.native.entropy/v0document: per-block entropy, the sparkline/heat-strip strings, the 16-bucket histogram, the detected high-entropy runs, and the section spans.
The reusable rendering logic lives in disrobe_pass_native::entropy_viz (entropy_sparkline, byte_histogram, histogram_ascii_16, high_entropy_runs, render_entropy_svg) so other tools can embed it.
Limits
- No committed benchmark compares the in-tree decompiler with Ghidra or IDA, so this guide states no ranking against them. What it does state:
disrobehands either one clean, unpacked, symbol-rich input, and can drive Ghidra headlessly. See native decompile for the in-tree decompiler, its two grading levels, and the Ghidra backend. - Themida and VMProtect support covers detection and section carving. See native unpacking for the available outputs and recovery limits.
- Authenticode chain validation walks to an embedded bundle of eight trusted code-signing roots and covers RSA PKCS#1 v1.5 and ECDSA P-256/P-384. Anything outside that lands as
UnsupportedAlgorithmorUntrustedChainrather than a pass. - The Delphi VMT walk accepts a class only when its VMT is self-consistent, so a partially-overwritten or hand-built table yields no class rather than a guessed one.
Native decompile
disrobe's x86-64 decompiler emits C or Rust. Its AArch64, ARM32, and MIPS32 paths emit pseudo-C. These in-tree paths require no external decompiler. Ghidra is available as a separate headless backend.
For symbol recovery, disassembly, and identification see the native guide; for packers and VM protectors see native unpacking.
At a glance
| Surface | Support |
|---|---|
| Architectures | x86-64 uses the shared IR pipeline; AArch64 uses object-context and NIR recovery; ARM32 (A32 and Thumb) and MIPS32 (big- and little-endian) use the p-code/NIR path |
| Output formats | C or Rust for x86-64; pseudo-C for AArch64, ARM32, and MIPS32 |
| Call resolution | Whole-program for validated direct same-image calls in linked AArch64 ELF inputs whose sibling target resolves unambiguously; unresolved, indirect, external, and ambiguous calls abstain. Relocatable AArch64 objects fail before output. |
| Switch dispatch | Dense switch recovered from the binary's own jump table |
| Type recovery | x86-64 structs from fixed-offset access (p->field_8), arrays from scaled indexing (a[i]), unions from conflicting widths, integer width and signedness per frame slot |
| API types | x86-64 resolved imports propagated backward into caller locals from a curated libc, kernel32, and ws2_32 prototype database, each tagged with library!function provenance |
| Calling convention | x86-64 inferred per function, including thiscall and vectorcall |
| AArch64 scalar floating point | h0 to h31, s0 to s31, and d0 to d31; IEEE binary16, binary32, and binary64 arithmetic, conversion, comparison, rounding, and loads or stores |
| Vectorized loops | x86-64 SSE/AVX reduction and pointer-walk map kernels lowered back to the equivalent scalar loop |
| Constant division | x86-64 magic-multiply division and modulo recovered as / and % in C output and as wrapping_div and wrapping_rem in Rust output; a divisor the range check cannot confirm keeps the multiply and shift |
| AArch64 devirtualizer | Symbolic, on by default in a full build, --no-devirt to disable; transactional, reverts on any proof miss |
| Grading | C output is execution-differentially recompiled with real gcc or clang; x86-64 Rust output with rustc |
| Sidecars | manifest.json (schema disrobe.native.decompile/v1) for both architectures; x86-64 also emits types.json (schema disrobe.native.types/v1) |
| Optional backend | Ghidra headless via --backend ghidra |
Commands
disrobe native decompile app.exe --out decompiled/ # x86-64 -> C, default backend
disrobe native decompile app.exe --format rust --out decompiled/ # x86-64 -> idiomatic Rust
disrobe native decompile app_arm64 --out decompiled/ # aarch64 -> pseudo-C, symbolic devirt on by default
disrobe native decompile app_arm64 --no-devirt --out decompiled/ # aarch64 without the symbolic devirtualizer
disrobe native decompile app.exe --backend ghidra --out decompiled/
Output lands at <out>/<stem>.c or <out>/<stem>.rs alongside a manifest.json (schema disrobe.native.decompile/v1) listing which functions recovered, which did not and why, and the emitted symbol name for each. x86-64 output also carries the types.json sidecar.
Coverage and fidelity
Call resolution and structure
--backend native (the default) uses the in-tree decompiler. For linked AArch64 ELF inputs, a validated direct same-image call resolves its callee's real name and integer arity only when the sibling target is unambiguous. Indirect, external, malformed, unsupported, and ambiguous calls abstain. Relocatable AArch64 objects fail before output because section-qualified function identity is not yet carried through the CLI. Dense switch dispatch is recovered from the binary's own jump table. A function with no validated outgoing calls uses per-function recovery. AArch64 uses object-context recovery first, with the NIR lift and image-backed recovery available as narrower fallbacks.
AArch64 scalar floating point
The AArch64 lifter recognizes all 32 scalar floating-point registers through their h, s, and d views. Half-precision values use IEEE binary16 bits in the shared register model. The C emitter uses _Float16; the internal Rust emitter uses u16 at function boundaries because stable Rust does not provide an f16 primitive, then converts those bits through bounded binary16 helpers. Arithmetic, fused multiply-add, minimum and maximum, square root, rounding, integer conversion, precision conversion, comparison, selection, base-register scalar loads, scalar stores, and image-backed s and d literal-pool loads use the declared operand width. Literal-pool recovery reads only the encoded width from a mapped image range and refuses missing or truncated data. The scalar path models the default IEEE floating-point environment. A function that reads or writes FPCR refuses recovery because its rounding, flush-to-zero, default-NaN, or alternative-half controls can change scalar results. Ambient FPCR state established outside the function cannot be inferred, so output that depends on an externally selected nondefault state is not claimed as bit-exact. q and v operands remain vector operations and do not enter the scalar path.
x86-64 type recovery
Types are inferred from the access shape rather than left as raw registers. A pointer walked at several fixed offsets recovers as a struct with named fields (p->field_8), a base indexed by a scaled register recovers as an array (a[i]), and offsets read at conflicting widths recover as a union. The calling convention is inferred per function, including x86 thiscall (implicit this in ecx) and vectorcall (SSE/AVX register arguments), so the recovered signature matches how the function is actually called.
Alongside the source, native decompile writes a types.json sidecar (schema disrobe.native.types/v1) recording the recovered integer width and signedness of each frame slot. The disrobe-typerec crate reads those signals straight from instruction semantics, subregister access, movsx/movzx, div/idiv, sar/shr, and signed against unsigned compares, and resolves them over a lattice with union-find. A frame slot the compiler reused for two variables is split back into distinct objects by a region-typed memory-SSA and live-range pass, so a reused slot recovers as two types instead of one blurred type that loses the signedness of both, and the same crate grades the struct, array, and union shapes the decompiler recovers from those access paths.
When a recovered call reaches a known library or OS function, resolved through the PE import table or ELF relocations to a curated libc, kernel32, and ws2_32 prototype database, that function's parameter and return types are propagated backward into the caller's locals through the same region memory-SSA and written into types.json as api_slots, each carrying its library!function provenance so an API-derived type is distinguishable from an inferred one; an unresolved import, an ordinal-only import, or a call whose backpropagated type conflicts abstains rather than guessing, and those API-derived caller-local types are graded on a stripped-versus-unstripped clang corpus against the unstripped DWARF, recovering pointer, integer-width, and sign with zero wrong types.
Graded against an unstripped sibling's DWARF on an -O0 corpus, integer width and struct field offset and per-field width recover at recall 1.0, live-range splitting lifts signedness recall from 0.25 to 1.0 on the slot-reuse cases, and mutation checks confirm the grader rejects seeded-wrong widths, signs, field offsets, and merged or invented fields instead of passing everything.
AArch64 symbolic devirtualizer
On the AArch64 path a symbolic devirtualizer runs before structuring, on by default in a full build and disabled with --no-devirt. It folds conditional arms it can prove dead against the path constraints, then hands the simplified function to the structurer. The fold is transactional: on any proof miss or budget exhaustion it reverts to the original function, so it replaces a construct only with a proven-equivalent one and adds no edges. Per-function fold counts and status land in the decompile manifest.json under devirt.
Auto-vectorized loops
Auto-vectorized loops are recovered to their scalar meaning: the C backend recognizes SSE/AVX reduction and pointer-walk map kernels that gcc and clang emit at -O2/-O3 and lowers them back to the equivalent scalar loop, tracing each argument to its pristine ABI register so a compiler's entry-sequence register swap does not misattribute the length to the output pointer. Reassociation-unsafe floating-point vector loops are rejected rather than lowered to a wrong scalar form.
x86-64 constant division and modulo
A compiler replaces a division by a constant with a multiply by a magic number, a shift, and a sign correction. The x86-64 path recognizes that sequence and emits the division again. C output uses / and %. Rust output uses wrapping_div and wrapping_rem. The recognized forms are a magic multiply whose product fits a single register, a wide multiply through the one-operand mul or imul, the add-form that carries an implicit high bit, the pre-shift form used for an even divisor, and the signed corrections taken from the sign of the dividend, of the product, or of the quotient. A dividend narrower than 64 bits must be zero-extended into an unsigned form or sign-extended into a signed form. An extension that does not match the form refuses the rewrite.
The divisor is not read out of the magic number. A candidate divisor is accepted only when the multiply and shift reproduce the exact quotient for every dividend in range. A multiply-shift pair that computes a fixed-point scale fails that check and stays a multiply and shift, so a scale is never renamed as a division. A perturbed shift amount, a perturbed multiplier, and a 32-bit magic applied to a 64-bit dividend fail the same range check.
The modulo is recovered from the tail that follows the quotient. Inside a bounded window after the matched sequence, the recovery tracks copies, additions, subtractions, multiplication by a constant, left shifts, and lea with a scale, then emits % for the register that ends up holding dividend - quotient * divisor. When the quotient is still live after that tail, the division and the modulo both emit.
The rewrite replaces straight-line code only. A back edge that targets the first instruction of the matched sequence, or any address before it, refuses the rewrite. A division inside a loop therefore keeps its multiply-and-shift form whenever the loop jumps back to or above the start of the matched sequence. Any other control transfer that lands inside the sequence refuses it as well. A store or a read-modify-write inside the sequence refuses it. Every register the sequence writes, other than the quotient and the copies of the dividend that outlive it, must be dead afterward.
The one-operand imul lifts as a signed wide multiply, so a signed 64-by-64 high-half product emits as __int128 in C and as i128 with wrapping_mul in Rust instead of taking the unsigned form.
Set DISROBE_DEBUG=native to print the address and the recovered divisor of each rewritten sequence.
Grading
C output is graded by execution-differential recompilation against real gcc or clang, and x86-64 Rust output against rustc, never against disrobe's own prior output. The AArch64 pseudo-C lift is held to the C bar against real clang machine code at -O0, -O1, -O2, -O3, and -Os. Its scalar floating-point battery compares raw result bits for register and stack parameters across directed IEEE edge patterns and seeded random inputs. It canonicalizes a comparison only when both results are NaNs, and reports how many comparisons passed on that canonicalization. The struct, array, and union recovery is asserted on recompiled-and-executed fixtures rather than by inspection. The vectorized-loop recovery is held to the same C bar: the recovered scalar loop is recompiled and its output compared bit-for-bit against the original compiled kernel across a spread of input lengths, and on Linux at least one gcc -O3 pointer-walk reduction must recover and execute-prove (simd_devirt_oracle.rs).
Constant-division recovery is held to the same C bar. It is measured over divisors 1 through 1024 plus sampled values up to 4294967295, at -O1, -O2, and -Os, for 32-bit and 64-bit dividends, with whichever of gcc, clang, and cc is on PATH, and a recovered divisor that differs from the one in the source is a failure. Recovered functions are recompiled and executed against the compiled original over a fixed spread of inputs, and that execution grading covers the loop bodies and the signed 128-bit high-half products as well as the plain division and modulo cases. Whole-program recovery is graded on its own, so the rewrite is proven reachable through recover_program and not only through a single leaf function (pseudo_c_const_division_oracle.rs).
Ghidra backend
--backend ghidra runs Ghidra headlessly (install it with disrobe install-deps ghidra) and returns pseudo-C alongside the standardized emits.
Limits
- AArch64 function discovery is symbol-table-based today (the linear-sweep function finder is x86-only), so a stripped AArch64 binary surfaces fewer functions than its unstripped sibling, which enumerates and decompiles in full.
- On the AArch64 path, control-flow-flattening deflatten and jump-table edge rewrite are noted as deferred in the
devirtmanifest section. - AArch64 Rust emission is unsupported.
--format rustfails before native recovery writes output. - On x86-64, where the byte stream carries no sign signal for a frame slot, the
types.jsonsidecar reports it as unknown rather than guessing. - An unresolved import, an ordinal-only import, or a call whose backpropagated type conflicts abstains rather than guessing an API-derived type.
- Reassociation-unsafe floating-point vector loops are rejected rather than lowered to a wrong scalar form.
- Constant-division recovery is x86-64 only. The AArch64 path does not rewrite a magic multiply back into a division.
- Constant-division recovery starts from a magic multiply, so a divisor the compiler lowered to a plain shift stays a shift in the output.
- A magic multiply-shift sequence whose divisor the range check cannot confirm, including a fixed-point scale, is left as a multiply and a shift rather than rewritten.
- A constant division is left alone when a back edge targets the first instruction of the matched sequence or an earlier address, when another control transfer lands inside the sequence, or when the sequence writes to memory.
--backend ghidraruns the optional external decompiler on the input.
Native unpacking and devirtualization
disrobe detects the runtime packer on a PE / ELF / Mach-O and unpacks it, driving stub-based packers through an in-house x86 emulator, and lifts bytecode-VM protected code back to IR and pseudo-code.
For symbol recovery, disassembly, identification, and forensics see the native guide; for the in-tree decompiler see native decompile.
At a glance
| Tier | Support |
|---|---|
| In-house decoders | UPX, MPRESS, Petite, MEW, ASPack, PECompact, FSG, NSPack, kkrunchy and kkrunchy classic |
| Stub emulation | Yoda's Crypter is driven to its original entry point through the in-house x86 stub emulator. The same emulator drives ASProtect, Morphine, nPack, NeoLite, PolyCryptor, Warzone Crypter, whose tier records the emulator as validated against spec-built stubs with real-sample recovery still unproven |
| Detect and carve | Yoda's Protector, VMProtect, Themida / WinLicense. disrobe auto carves the protected sections of a VMProtect or Themida image; the Themida route also accepts .winlice images and labels them WinLicense. native unpack remains detect-only for these families. Yoda's Protector exposes an original-assisted comparison carve and an emulator report, but no single-input recovered-image route |
| Detect only, no static recovery | PE-Protector, PELock, Enigma Protector, Armadillo, Obsidium, WinLicense. These direct packer routes emit no recovered image |
| Bytecode-VM devirtualization | Interpreter located, handler micro-ops fingerprinted behaviorally, opcode table recovered, VM CFG reconstructed, bytecode lifted to re-executable IR plus pseudo-code |
| Devirtualization grade | Recovered IR re-executes to the same outputs as the original across arithmetic, loop, and branch programs, lifted from machine code alone (vm_devirt_oracle.rs) |
| Per-fixture scores | Pinned in corpus/native/packers/MANIFEST.toml |
Commands
disrobe native unpack packed.exe --out unpacked.bin
disrobe native devirt protected.exe --out recovered/
native devirt writes the recovered listing, the pseudo-code, and a devirt.manifest.json (schema disrobe.native.devirt/v1) into the output directory.
Coverage and fidelity
Packers
In-house decoders cover UPX (.text and .pdata byte-identical, ~96% whole loaded image), MPRESS, Petite, MEW, ASPack, and PECompact, plus NSPack, FSG and Petite, each of which ships a committed original and packed pair so its byte-recovery figure re-derives from a clean checkout; kkrunchy and kkrunchy classic ship committed fixtures and recover their payload at a pinned 100.00% floor from a clean checkout.
On committed samples ASPack and PECompact rebuild the decompressed section image at its load RVA: the section report confirms the recovered .text byte-identical and the import table >=98% byte-identical to the original, both gated in CI, while the packed .text of near-random entropy and zero resolvable calls drops to ~6.2-6.5 with hundreds of disassembler-resolvable intra-code calls. Because the whole rebuild is a loaded-memory image rather than a disk-aligned file, the bench marks whole-output byte-identity n/a. MEW rebuilds a flat image of the committed Sysinternals samples, read as the entropy drop to ~4.2-4.9 and tens of thousands of decoded instructions.
Yoda's Crypter is recovered by driving its unpack stub through the in-house x86 stub emulator: the stream decryptor runs to the original entry point inside the emulator, then the reconstructed sections are read back and sliced byte-for-byte, so its .rsrc recovers byte-identical and its .text decrypts to full plaintext. The same emulator drives ASProtect, Morphine, nPack, NeoLite, PolyCryptor, Warzone Crypter, which sit one tier lower: the emulator is validated against spec-built stubs, and no vendor-packed sample in the corpus proves recovery on a real one.
Per-fixture recovery scores are pinned in corpus/native/packers/MANIFEST.toml.
Bytecode-VM devirtualization
disrobe native devirt targets the bytecode-VM tier rather than the compression tier. It locates the interpreter, fingerprints each handler's micro-op behaviorally by probing it through the in-tree x86 emulator (so a per-build handler permutation does not break the lift), recovers the handler-to-opcode table, reconstructs the VM CFG, and lifts the handler bytecode to a re-executable IR plus pseudo-code.
The lifter is validated end-to-end on a self-authored Tigress-shape bytecode VM: the recovered IR re-executes to the same outputs as the original across arithmetic, loop, and branch programs, lifted from machine code alone (vm_devirt_oracle.rs).
Limits
- FSG, NSPack, and Petite each ship one committed packed-and-original pair, and the published figures for them are measured on those pairs alone. Their larger samples, and the extra MPRESS and UPX megafiles beside them, are kept out of the tree on size or license; every such path is marked
localincorpus/native/packers/MANIFEST.tomlwith a recipe for rebuilding or refetching it, and no figure is published for any of them, because nothing in a checkout re-derives one. - Yoda's Protector is classified as detect-and-carve. Its original-assisted comparison carve reports surviving sections. On the committed fixtures, the
.yPemulator derives the image-resident RC4 key but halts beforeCryptDecrypt; replaying that key directly over the carved on-disk sections does not recover plaintext because they contain an RC4-encrypted compressed stream. No single-input route emits a recovered image for this family. - On UPX and NSPack the whole-image residual is the loader-rebuilt zone (bound import address table and base relocations): those addresses are resolved by the OS loader at run time and are not present in the packed stream, not a decoder gap.
- On VMProtect and Themida images,
disrobe autowrites each protected section (.vmp*,.themida,.winlice) verbatim ascarved/NN-<name>.bin, and the packer manifest recordsrecovery_mode: detect-and-carvewith each section's address, sizes and permissions. A section without file bytes, or an image with none, is refused with DR-NAT-0909. A.winliceimage handled by the Themida carver is reported as WinLicense. The carve does not reconstruct the original code, andnative unpackremains detect-only. - The direct Enigma Protector, WinLicense, PELock, PE-Protector, Armadillo, and Obsidium packer routes are detect-only and emit no recovered image. WinLicense can reach a carve only when the Themida route recognizes its
.winlicesection. - The generic VM lifter is validated on the Tigress-shape VM.
disrobeships no per-family devirtualizer that lifts these commercial protector families back to source.
Go
disrobe recovers symbols from stripped and garbled Go binaries across PE, ELF, and Mach-O by parsing the Go runtime's own metadata tables.
At a glance
| Layer | Coverage |
|---|---|
| Binary formats | PE, ELF, Mach-O, on little- and big-endian targets |
| Architectures | little-endian amd64/arm64 and big-endian s390x, ppc64, and mips, with the pclntab, type, and itab tables read in the image's own byte order |
| pclntab | Header eras go1.2, go1.16, go1.18, and go1.20, located structurally even when the magic word has been stomped |
| Symbol recovery | pclntab function table, moduledata, typelinks/itablinks type metadata, buildversion |
| Obfuscation | garble report graded None / Detected / Partial / Full, with per-scheme literal-recovery statistics |
| Embedded data | embed.FS maps located through the compiler's own slice header, every member recovered byte for byte and checked against its stored digest, plus //go:embed directive extraction |
| Debug info | DWARF report when the sections survive |
Commands
disrobe go recover app --out app-go.json
disrobe go info app
disrobe auto packed-app --out recovered/ # unpack the UPX layer first, then recover the Go symbols
recover writes the full analysis JSON (default ./out/<stem>-go.json); info prints the fingerprint without writing anything. Output shape (illustrative):
go recover: OK
input: app
image kind: elf
ptr size: 8
pclntab ver: go1.20
buildversion: go1.26.3
funcs: ...
packages: ...
garble: None
embed.FS: used=true directives=...
wrote: ./out/app-go.json
info adds the stripped-binary fingerprint: whether the symbol table was stripped, how many functions were still recovered from pclntab, and the stdlib-name ratio that feeds the garble grading.
UPX-on-Go chains automatically: disrobe auto unpacks the UPX layer first, then recovers the Go symbols underneath.
Coverage and fidelity
The garble report separates a real wall from a tooling boundary. garble -literals is handled separately from names. Simple rodata schemes are recovered by pairing adjacent key/data blobs and applying the inverse XOR/ADD/SUB or repeating-key operation. Full-key literals are recovered when their code and ciphertext are present: the thunk scanner follows bounded x86-64 init thunks or inline materializers, emulates the decrypt path, and accepts only UTF-8/readable plaintext. The tests assert the source strings are absent as cleartext before requiring byte-exact recovery, so the oracle is not circular.
An embed.FS map is located through the layout the Go compiler is required to emit rather than by
matching a pattern. The compiler writes the slice header and the file records into one symbol and
sets the records pointer to that symbol plus three pointer-sized words, so the header points at
itself and the length equals the capacity. Discovery keys on that identity, which also fixes the
record count from the header instead of reading records until one fails to parse. Ordering is not
assumed: real compiler output places frontend/dist/style.css before frontend/dist/assets/, so a
scanner that requires a sorted run rejects every genuine map.
Each file record carries the first sixteen bytes of a digest the compiler computed over the member contents, and the pass recomputes it. Members at or below 1024 bytes take a one-shot form and larger members take a streaming form, a boundary measured from real toolchain output rather than assumed. The toolchain generation is identified by which construction verifies the records, so no digest depends on trusting the version string an image reports, and a map whose members are all above the boundary is reported as unable to distinguish two generations rather than being assigned one. Recovery is graded against the exact files each fixture was built from, across PE, ELF, and Mach-O at both pointer widths, both byte orders, and both position-dependent and position-independent links. Go's internal linker materializes the record pointers even in a position-independent image, so the same discovery path serves both. A directory record, a zero-length member, and a member whose contents are not valid UTF-8 are all covered.
The pass is validated against a go1.26.3 fixture, and the test suite gates type-name recovery at >= 85% on that fixture; 838 of 838 type names (100%) are recovered at HEAD, a count the gate now pins by equality, since the typelinks and moduledata tables survive -s -w stripping. Big-endian recovery has its own oracle: a cross-built stripped linux/s390x binary is parsed as a big-endian ELF and its named type and itab pairs are recovered by back-searching the metadata tables, graded against the build (go_bigendian_recovery.rs).
Limits
- The deliverable is symbols, types, and embedded data, not source bodies.
- garble's hashed user identifiers are reported as a
name_recovery_wallwhen the required build seed or name mapping is unavailable. The pass does not infer original names from the hashes. Surviving standard-library names inpclntabare recovered. - The remaining limits on literal recovery are concrete: missing bytes, runtime-only key material, unsupported architectures, exhausted budgets, or ambiguous short plaintext.
Lua
disrobe decompiles compiled Lua chunks across every common dialect, peels the major Lua obfuscators, and devirtualizes custom-VM wrappers back to runnable Lua source.
At a glance
| Layer | Coverage |
|---|---|
| Dialects | Lua 5.1 / 5.2 / 5.3 / 5.4, LuaJIT 2.0 / 2.1, Luau, GLua |
| Luau opcode coverage | 86 of 88 opcodes in disrobe's declared table are lifted, with BREAK debugger instrumentation and NEWCLASSMEMBER decoded and reported rather than lifted; child-proto linking |
| Decompile output | Lua source plus a manifest recording the detected dialect, fidelity grade (Lossless / Lossy / BestEffort), and any warnings |
| Obfuscators (14) | IronBrew2, Prometheus, MoonSec V1 / V2 / V3, AztupBrew, DarkSec, Boronide, PSU, WeAreDevs, luaobfuscator.com, SLua, Hercules, Luraph |
| Chain catalog | 16 entries: the 14 obfuscator families above plus the Luau and GLua dialect detectors |
Peelers (--family) | prometheus, moonsec-v1, moonsec-v2, moonsec-v3, ironbrew2, wearedevs, slua; default auto detects first |
| VM devirtualization | IronBrew2 2.7.0 reversed on real committed output, graded by real-Lua execution differential (hello / arith / control / tables / edge in standard and MAX mode); MoonSec-shape recovery is pending a real sample |
Prometheus Vmify | Container dispatch tree lifted back to structured Lua, including a closure that captures a variable; up to four stacked Vmify layers unwrapped in one call; graded by real-Lua 5.1 execution differential against the original source |
Commands
disrobe lua decompile script.luac --out script.lua
disrobe lua detect script.luac
disrobe lua deobfuscate obfuscated.lua --out clean.lua
disrobe lua deobfuscate vmified.lua --family prometheus --out clean.lua
disrobe lua deobfuscate dumped.lua --family moonsec-v3 --i-have-authorization
disrobe lua opcode-map --canonical vanilla.luau --client client.luau --build-id 2026-08-24 --out 2026-08-24.json
disrobe lua decompile client.luau --opcode-map 2026-08-24.json --build-id 2026-08-24 --out recovered.lua
Build-keyed Luau opcode maps
lua opcode-map imports only observations proven by a supplied canonical/client pair. The pair must use the same supported bytecode version, have the same prototype tree and instruction counts, and retain every non-opcode and auxiliary instruction word. The map records the explicit client build identifier and bytecode version. lua decompile --opcode-map selects it only when both values match.
The importer accepts a conflict-free bijection for the opcode bytes it observes. It does not infer the remaining permutation. A missing entry causes decompilation to refuse at the instruction location; an incompatible, stale, or malformed map is not substituted with another build's map.
Opcode availability is validated against Luau's bytecode history at 367f9d83: version 3 adds FORGPREP and JUMPXEQK*, version 4 adds IDIV/IDIVK, version 5 adds SUBRK/DIVRK, version 6 adds FASTCALL3, version 9 adds userdata field access, version 10 adds NEWCLASSMEMBER, and version 11 adds CALLFB.
decompile writes the recovered source (default ./out/<stem>.lua) and a manifest.json recording the format, fidelity grade, and warnings. detect reports the dialect and header field summary (constant, proto, and code counts) without writing output. MoonSec v3 and IronBrew2 are commercial-tier wrappers; their peelers require the explicit --i-have-authorization flag.
Recovered Lua 5.x source wraps the main chunk in local function _main(...) and ends with return _main(...), so the file runs unchanged. Short-circuit conditions such as while a and (b or c) do, c and x or y value selection, elseif ladders with compound arms, and local x declarations that Lua 5.1 compiles to nothing are rebuilt as source. The re-execution grade compiles self-authored programs with luac -s (no debug names), decompiles the stripped bytecode, and requires the recovered file to print exactly what the original prints under the same interpreter and to create no global the original does not create (tests/reexec_diff_oracle.rs, Lua 5.1, 5.3 and 5.4 lanes). tests/generated_differential.rs applies the same check to seeded, generated programs on Lua 5.1 and 5.4.
Stripped bytecode carries no local names, so recovered locals are named from their register (v3) or role: numeric loop variables become i, j, k and generic loop variables k and v, unless a global or upvalue of that name is visible anywhere in the function, in which case the register name is kept. A temporary reused after its block ends is declared again with local rather than assigned as a global. A value that is read after its register is overwritten is kept in a local before the overwrite. while true do ... end loops left by break, and loops whose head runs statements before the test, are rebuilt as structured loops. Values selected by and/or chains, including (a or b) and c and chains whose operands are calls, are rebuilt as one expression or as a local assigned on every path; for a chain whose operands are calls, the Lua 5.1 and 5.3 output still contains a goto, which the Lua 5.1 parser rejects, so corpus/lua/behaviour/values.lua is graded on the Lua 5.4 lane only.
--family pins one peeler instead of letting auto choose. Auto-detection tries Prometheus first, so a Vmify container needs no flag. Pass --family prometheus when you want a file carrying no Prometheus signature to fail rather than fall through to another family.
Output shapes below are illustrative.
lua decompile: OK
input: script.luac
format: Lua54
fidelity: Lossless
warnings: 0
wrote: ./out/script.lua
manifest: ./out/script.manifest.json
lua deobfuscate: OK
family: Auto
detected: Prometheus (confidence=0.97)
passes run: 3
- string_decode
- bytecode_unwrap
- emit
recovered: 12 string(s)
fully peeled: true
residual: 0
wrote: ./out/obfuscated.peeled.lua
The deobfuscate report lists every pass that ran, recovered string constants, a fully peeled verdict, and any residual markers.
Coverage and fidelity
IronBrew2 and MoonSec ship their payload behind a custom register-VM: a permuted opcode-handler table and an embedded constant pool that a stock decompiler cannot read. The permutation is not stored in the loader; it is computed at load time inside the obfuscated bootstrap, then used to dispatch handlers and key the constant decryptor. disrobe reconstructs it the same way the loader does.
For IronBrew2 2.7.0, the devirtualizer parses the bootstrap's dispatch chain to derive the encoded -> canonical permutation and the XOR key, decodes the constant pool, and lifts the VM bytecode back to runnable Lua. The committed corpus/lua/ironbrew2 set carries real obfuscated bootstraps for five programs in both standard and MAX mode; each must produce byte-identical output to the original under a real lua binary (tests/ironbrew2_real_oracle.rs).
MAX mode adds three layers on top of standard: a control-flow-flattened dispatch (a nested binary search over the opcode enum, which the same handler walker un-flattens), comparison-polarity number-mutation (the EQ handler tests ~= and jumps on equality, captured as the literal operator plus jump direction), and fused super-operator handlers (one VM step covering several real ops, whose hoisted scratch locals are stripped after classification).
Prometheus Vmify
The Prometheus Vmify step rewrites a chunk into a register machine held inside one container function. Every original function becomes a numbered entry point in a shared dispatch tree, and every call becomes a jump through that tree. disrobe reads the container, rebuilds a control-flow graph for each entry point, and re-emits structured Lua. The pass appears as prometheus-vmify-container-devirt in the passes run list. Vmify applied over its own output is unwrapped layer by layer, up to four layers in one call. A chunk that needed more than one layer also carries a prometheus-vmify-nested-devirt-<n>-layers entry naming the layer count.
Vmify does not keep a captured variable as a Lua upvalue. It moves the variable into a store table shared by the whole chunk, hands each closure a list of slot indices into that store, and uses a reference count to decide when a slot is cleared. disrobe fingerprints the allocator and the release helper by their statement shape, which is how it tells the capture store apart from any other table in the chunk. It then gives each allocation one Lua local, named __vu0, __vu1, and so on in allocation order, and declares it once in the scope that allocates it. Every read and write of that slot is rewritten to the same local, both in the allocating function and in each closure that receives the slot, so the recovered closure captures the variable by reference the way the original source did.
The committed corpus/lua/prometheus/vmify_upvalue pair holds real Prometheus Vmify output for a counter factory whose inner function captures a local. The gate first requires that no Prometheus layer is left in the recovered source, then runs it under a real lua 5.1 binary and requires the output the clean file prints (tests/reexec_diff_oracle.rs). The obfuscated file itself is never run.
The Prometheus Weak preset (Vmify, ConstantArray and WrapInFunction) is graded on the Lua megafile. All 171 functions in its dispatch tree come back structured with no dispatch fallback, and 630 of the 630 reached handlers are lifted. The recovered program then runs under real Lua 5.1 and 5.4 against a driver that calls every export, and it must print the same 116 lines as the clean source (tests/real_prometheus_megafile.rs). A mutation that drops trailing nil results from calls turns that grade red.
Set DISROBE_DEBUG=lua to trace the capture analysis. It emits prometheus_vmify.box_model, naming the registers the capture helpers resolved to, and prometheus_vmify.captured_variables, the number of captured variables bound in the run.
The Hercules real-output grader covers 15 pinned outputs from Hercules 2.0.1. Fourteen recover to source that prints the same bytes as the authored programs under Lua 5.4. The remaining branches.maximum fixture reports its unrecovered VMGenerator layer. Each recovered case also has a changed-literal control that must differ from the original.
Limits
- Where
fully peeledisfalsethe report carries the residual marker names and the reason (runtime key, anti-tamper variant, unmodeled VM tier, or a refused Vmify recovery). - When a MoonSec v3 constant-pool key is available only at runtime,
disrobereturnsfully_recovered: falsewith aruntime keysresidual marker. - The MoonSec
emulate_perm_buildertests use a purpose-built bootstrap whose permutation is derived at runtime. These tests cover the table-builder algorithm; the corpus contains no captured MoonSec dump to establish end-to-end recovery.
Prometheus Vmify refusals
Vmify recovery refuses unsupported shapes instead of substituting placeholder functions for missing bodies. A refusal names its cause, and where the cause is a specific expression it names the byte offset of that expression in the text the layer was reading. The execution comparison below covers the committed Lua 5.1 Vmify fixtures.
A refusal takes one of two shapes.
- The whole container is refused.
fully peeledisfalse,prometheus-vmify-container-devirtis absent frompasses run, the output file holds the earlier peel stage rather than a devirtualized body, and a residual marker readsa Vmify container was found but recovery was refused rather than emitted partly wrong, followed by the reason. - Some layers recovered and a further layer is refused. The recovered source is written,
fully peeledisfalse, and a residual marker records how many layers recovered before the refusal, followed by the reason.
disrobe refuses these captured-variable shapes.
- A capture allocated on a cycle in the recovered control-flow graph, which is what a capture written inside a source loop becomes. Each iteration of such a loop captures a fresh variable, and one declaration at function scope would alias them into a single shared variable. The committed
corpus/lua/prometheus/vmify_loop_capturepair is a loop that builds three closures over three different values, anddisroberefuses it. The cycle search runs under a step budget, anddisroberefuses when the search exceeds it. - A chunk that creates a closure with a non-empty capture list, but whose reference-counted capture helpers do not match the shape
disrobefingerprints. The fingerprint accepts exactly one allocator and exactly one store bound to that allocator's reference-count table, so a chunk carrying more than one of either yields no model and no captured variable can be resolved to a real Lua variable. A chunk that captures nothing needs no model and is unaffected. - A register that receives a second capture inside one recovered function, because the register cannot then carry one stable name.
- A capture allocator referenced anywhere other than a plain allocation assignment.
- A store slot read or written through anything other than a register the same function allocated a capture into, or an entry of the closure's own capture list indexed by a positive whole-number literal. An index past the end of the supplied capture list is also refused.
- A closure-creation call whose capture list is not a table constructor, or whose capture list carries a keyed entry. A keyed entry has no stable position to match against the closure body.
- A closure-creation call whose entry point is not a literal number, because the closure body cannot then be located in the dispatch tree.
- One dispatch leaf shared by two closures with different captured variables, which would bind one expression to two different recovered values.
- A recovered body that still names the container's own capture machinery, meaning the capture table, the store, the allocator, or a slot register. At least one access went unresolved in that case, so the body is refused rather than emitted.
Recovery is graded against Prometheus output built for Lua 5.1 with Vmify as the only step. Other target dialects and other step combinations are not graded.
PHP
disrobe peels PHP eval chains, evaluates supported decode loops and literal-key ciphers, and extracts Phar members. It also identifies ionCube, SourceGuardian, and Zend Guard envelopes, recovers statically available legacy layers, and reports when loader-resident keys keep a payload sealed. These operations run locally without uploading the input.
At a glance
| Layer | Coverage |
|---|---|
| Commercial encoders | ionCube, SourceGuardian, Zend Guard: envelope detect and wall (the decrypt key is native-loader-resident); a partial op_array skeleton only for legacy statically-keyed cases (Zend legacy XOR), graded StructuralOnly otherwise |
| Phar archives | Manifest walker with path-sanitized extraction |
| Eval-chain layers | base64_decode, gzinflate, gzuncompress, gzdecode, bzdecompress, str_rot13, strrev, str_replace, urldecode / rawurldecode, hex and octal escapes, pack and unpack in the hex, byte and 16-bit and 32-bit word forms, chr() concatenation, uudecode, single-key XOR, create_function, nested eval, FOPO. A strtr in front of base64_decode covers the URL alphabet and any custom alphabet |
| Decode loops | for, while, do-while and foreach over str_split, with modulo, plain, reversed, stride, rotating and nested indices, and XOR, add and subtract with wraparound, rotate, negate, table substitution and index-parity byte operations. The key must be present in the file. A bounded interpreter runs the loop body under explicit step, wall-clock, output-size, heap, expression-depth, frame-depth and loop-count budgets, and refuses every call outside a pure-function allowlist |
| Block ciphers | openssl_decrypt in aes-128-cbc, aes-192-cbc, aes-256-cbc, aes-128-ecb, aes-192-ecb and aes-256-ecb, with raw or base64 input and PKCS#7 or zero padding. The passphrase is truncated or zero-extended to the key length, as php does. The key and the initialisation vector must both be present in the file |
| Constants | A key held in a define() constant, read as a bare name or through constant(). defined() is answered from the same table. The php OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING flags are known, and a file cannot redefine them |
| Decode helpers | A helper function declared at the top level of the file, called directly or through a variable holding its name, including recursion, mutual recursion, default arguments and array arguments. The helper runs in its own scope, as php runs it, so it reads only what it is passed |
| Recovery grading | EvalChainPeeled / OpArrayDecompiled / StructuralOnly / PlainSource |
Commands
disrobe php decode payload.php --out out/payload-php/
disrobe php decode payload.php --encoder ioncube --i-have-authorization
disrobe php deobfuscate obfuscated.php --out clean.php
disrobe php extract archive.phar --out extracted/
--encoder is auto (default), phar, ioncube, sourceguardian, or zendguard. Commercial encoders require the explicit --i-have-authorization flag. The output directory receives the decoded payload, a skeleton .php when an op_array was decompiled, and a manifest.json recording the encoder, version label, marker offset, ciphertext and plaintext byte counts, and the recovery stage.
Output shapes below are illustrative.
php decode: OK
input: payload.php
encoder: Ioncube
out dir: ./out/payload-php
manifest: ./out/payload-php/manifest.json
deobfuscate unwraps stacked eval() layers until the residue is plain PHP. The manifest counts each layer kind that was peeled and flags whether any eval remains in the residue.
php deobfuscate: OK
input: obfuscated.php
layers: 3
residual_eval:false
wrote: ./out/obfuscated.peeled.php
manifest: ./out/obfuscated.peeled.manifest.json
extract walks the Phar manifest and extracts every entry through a path-sanitizer (no .. escapes), writing a manifest.json with the entry count and API version.
php extract: OK
input: archive.phar
entries: 14
out dir: ./out/archive-phar
manifest: ./out/archive-phar/manifest.json
Coverage and fidelity
Every recovery carries an explicit stage in its manifest: EvalChainPeeled, OpArrayDecompiled, StructuralOnly, or PlainSource, so a caller can tell a fully peeled payload from an envelope parse.
Limits
- ionCube, SourceGuardian, and Zend Guard keys live in the native loader, not the file. Those envelopes are detected and walled. A partial
op_arrayskeleton is recovered only for legacy statically-keyed cases (Zend legacy XOR). - When an encoder's key lives only in its runtime loader, the decode is graded
StructuralOnlyand the manifest carries the residual ciphertext length rather than pretending at plaintext. - A decode loop whose key arrives at run time, from
$_GET,$_POST, a header or the network, is not statically recoverable. The loop is left in place and no plaintext is produced. - A helper declared inside a conditional or inside another function is not evaluated. Only a declaration at the top level of the file is, which matches where php makes a function callable before its own text.
- A helper taking a parameter by reference, or a variadic parameter, is not evaluated, because the interpreter models values rather than references.
- The interpreter reads a variable only when the file defines it. An undefined read, a call outside the pure-function allowlist, or any exceeded budget abstains and leaves the loop in place.
- An undefined constant abstains. A constant whose value comes from the file name, the request, or the environment is not resolved, because the value is not in the file.
- A cipher mode outside the listed AES set, including a stream or authenticated mode, is refused. The call is left in the source rather than decrypted by a different primitive.
- A division that does not divide exactly abstains. The interpreter models integer values only, so
strlen($d) / 3is not evaluated where php would produce a float. mcrypt_decryptis not evaluated. The extension was removed in php 7.2, so a loader that calls it cannot be graded against a real interpreter.
Ruby
disrobe analyzes Ruby artifacts and recovers source from YARV and mruby bytecode. The YARV benchmark recompiles recovered source with MRI and measures opcode-name overlap.
At a glance
| Layer | Coverage |
|---|---|
| Flavors detected | MRI source, YARV binary (YARB magic), mruby RITE, JRuby .class, TruffleRuby AOT, Ruby2Exe, Ocra |
| YARV | IBF reader (iseqs, object table, literals) plus a decompiler driven by per-version opcode tables for Ruby 2.6 through 3.4 |
| mruby | RITE reader covering format versions 0001-0007, 0030, 0200, and 0300, with irep disassembly and decompilation |
| Measured recovery | Original opcode-name multiset recall after recompilation: 100% on a greeter fixture and 100% on a mixed-construct megafile |
| Output | Analysis JSON; a .rb source file for YARV and recovered mruby bodies, with a YARV disassembly trailer when available |
Commands
disrobe ruby decompile app.bin --out app-ruby.json
disrobe ruby detect app.bin
decompile sniffs the flavor, runs the matching analyzer, and writes the analysis JSON (default ./out/<stem>-ruby.json). For YARV, or for mruby when a body is recovered, it also writes a .rb source file beside the JSON; YARV output includes a disassembly trailer when available. detect reports the flavor and exits without writing output.
Coverage and fidelity
For MRI source the summary reports token and definition counts. For YARV it adds the IBF header fields, iseq and object counts, instruction count, decompile fidelity, and statement count. For mruby it reports the compiler version string, irep count, instruction count, and whether a body was recovered.
The benchmark compiles the original and recovered sources with MRI, then counts opcode names across their instruction sequences. For each name, the smaller of the two counts contributes to the numerator; the denominator contains every original opcode occurrence. The stored results are 79 of 79 for the greeter and 23648 of 23966 for the megafile.
This comparison ignores instruction order, operands, constants, branch targets, and instruction ownership. Additional recovered instructions do not reduce the score. MRI compiles both sources without executing either program, so the result measures opcode-name recall rather than behavioral equivalence.
Ruby2Exe and Ocra self-extracting packages are detected as their own flavors. Analysis records their embedded-payload offsets and lengths; for Ocra opcode streams it also parses contained file records.
Limits
- JRuby
.classfiles are classified but not decompiled here. JVM-class material belongs to the JVM guide. - TruffleRuby AOT images are classified but not decompiled here. Their native code belongs to the native guide.
BEAM (Erlang / Elixir)
disrobe parses BEAM IFF files, recovers Erlang or Elixir source when debug chunks survive, lifts to Core Erlang otherwise, and disassembles the Code chunk per instruction.
At a glance
| Layer | Coverage |
|---|---|
| Chunks | AtU8 (short and long form), Code, StrT, Attr, CInf, Dbgi, Docs, ExpT, ImpT, LocT, FunT, Line, LitT (zlib-deflated on OTP 26 and earlier, raw on OTP 27+); unknown chunks are preserved verbatim |
| Source recovery | Erlang abstract code when present, Elixir source from a Dbgi form, best-effort Core Erlang lift as the floor; provenance is recorded in recovered_from |
| Disassembly | Per-instruction Code-chunk trace including the bs_match (opcode 182) command list; a flat .txt listing lands beside the JSON |
| Containers | .ez archives extract through the container layer |
Commands
disrobe beam parse module.beam --out ./out/module-beam.json
disrobe beam lift module.beam --out out/module-beam-lift/
disrobe beam disasm module.beam --out ./out/module-beam.disasm.json
Output shapes below are illustrative.
parse reports the module name, atom / export / import / fun counts, which optional chunks are present, and any unrecognized chunk names.
beam parse: OK
module: my_module
atoms: 42
exports: 8
imports: 15
funs: 3
wrote: ./out/module-beam.json
lift writes three files: <stem>.<ext> (recovered Erlang or Elixir source, extension derived from recovered_from), <stem>.surface.json (the surface record with provenance), and <stem>.core.json (lifted Core Erlang functions), plus a manifest.json linking them.
beam lift: OK
module: my_module
core fns: 8
recovered: AbstractCode
source: ./out/module-beam-lift/module.erl
surface: ./out/module-beam-lift/module.surface.json
core erlang: ./out/module-beam-lift/module.core.json
manifest: ./out/module-beam-lift/manifest.json
disasm emits the per-instruction Code-chunk trace as JSON and a flat .txt listing beside it.
beam disasm: OK
input: module.beam
instructions: 214
wrote: ./out/module-beam.disasm.json
listing: ./out/module-beam.disasm.txt
Coverage and fidelity
When a Dbgi chunk is present the original forms are recovered directly and labeled AbstractCode (Erlang) or ElixirDbgiForm (Elixir). Each lift records where its source came from in recovered_from, so a caller can tell a recovered original from a lift.
For stripped BEAM, 21 / 21 committed corpus entries recover to Core Erlang source that recompiles under Erlang/OTP 27.3.4, preserves the original export set, and returns the same result from the entry's committed test/0 battery. Each corpus entry is an Erlang module compiled from committed source; the gate removes both Dbgi and Docs before recovery so neither source path can participate.
The measurement covers each module's committed test/0 cases. erlc compiles the original and recovered source independently; the harness runs both with erl and compares exit status and stdout. A control replaces a recovered test/0 with one that raises, while preserving compilation and exports, and checks that the runtime comparison rejects it.
The Linux CI test leg pins OTP 27.3.4.15 and makes missing erlc or erl fatal. macOS and Windows retain explicit optional reporting when that toolchain is absent. Reproduce the Linux gate with:
DISROBE_REQUIRE_ERLANG=1 cargo test -p disrobe-pass-beam --test erlc_recompile_equivalence -- --nocapture
Limits
- Without a
Dbgichunk the original source is not in the file. The output is then a best-effort Core Erlang lift labeledCoreLifted, not the original text. - An opcode beyond the known table fails with an explicit
DR-BEAM-0012error naming the offending opcode rather than silently skipping bytes.
Swift / Objective-C
disrobe extracts the type metadata the Objective-C and Swift runtimes leave in a native binary, demangles it, parses SwiftShield rename mappings into a lookup for downstream use, and rebuilds the dylibs a dyld shared cache bundles into standalone Mach-O images.
At a glance
| Layer | Coverage |
|---|---|
| Objective-C metadata | __objc_classlist, __objc_catlist, __objc_protolist: classes, categories, protocols, ivars, properties, method selectors with type encodings |
| Swift metadata | __swift5_types, __swift5_fieldmd, __swift5_proto: type names, stored fields, conformances, symbols demangled |
| Containers | Single slice via disrobe swift classdump; raw thin and fat Mach-O binaries via disrobe macho classdump, which walks every slice |
| dyld shared cache | Header layouts legacy, local-symbols, slide-mappings, sub-caches, relocated-images; bundled dylibs rebuilt as standalone Mach-O images, per-image __LINKEDIT, slide info versions 1 to 5, sibling sub-cache and .symbols files |
| Rename obfuscators | SwiftShield mapping parser |
| String blobs | Explicit-key single-byte XOR blob decoding for model fixtures |
| Message dispatch | objc_msgSend, objc_msgSendSuper, objc_alloc, and objc_alloc_init sites resolved to selector, receiver class, and a rendered message expression |
| Mach-O surface | Header, load commands, segments, sections, fat slices, LC_ENCRYPTION_INFO records |
Commands
disrobe swift classdump App.app/App --out dump.json
disrobe swift shield-undo map.txt --out renames.json
disrobe swift xor-decrypt blob.bin --key 0x55 --out strings.json
disrobe macho classdump universal.bin --out dump
disrobe macho dump App.app/App
disrobe macho fat universal.bin
disrobe macho dyldcache dyld_shared_cache_arm64e --out ./out/cache-dylibs
disrobe macho dyldcache dyld_shared_cache_arm64e --image /usr/lib/libobjc.A.dylib
classdump reconstructs the type interface from the two metadata sources the runtime leaves in the binary. Beside the JSON, it writes a .swift declaration file with recovered type signatures when reflection metadata yields declarations; source-level function bodies do not survive in this metadata.
shield-undo parses a SwiftShield mapping. SwiftShield renames symbols to high-entropy identifiers and emits an obf ==> original mapping in the .dSYM. disrobe writes that mapping as a lookup for downstream use; class-dump does not apply it automatically. xor-decrypt decodes printable strings from a single-byte XOR blob when the caller supplies --key. Its tests cover hand-authored model fixtures, not SwiftConfidential output.
macho dump reports the header, load commands, segments, sections, and any LC_ENCRYPTION_INFO or LC_ENCRYPTION_INFO_64 records. macho fat walks a fat binary and reports each slice's CPU type, subtype, and offset.
macho dyldcache rebuilds every dylib the cache bundles and writes each one under --out at a path taken from its install name. A split cache reads its .01, .02, ... and .symbols subcaches from the directory of the file you name. --image <install-name> (repeatable) extracts only the named images and fails, naming each one, when the cache holds no image by that name. An image that cannot be rebuilt is listed by install name with its reason, and a subcache that is missing is listed with the file names it looked for; the summary line then reads partial instead of OK. The command writes compact images; use disrobe auto when you want images with a rebuilt __LINKEDIT.
Output shape (illustrative):
swift classdump: OK
input: App
cpu/bits: arm64 / Bits64
swift types: 24
reflected: 18
mangled syms: 312
demangled: 312
swift declarations: ./out/App-swift.swift
wrote: ./out/App-swift.json
Coverage and fidelity
The Objective-C side walks __objc_classlist, __objc_catlist, and __objc_protolist to recover classes, categories, protocols, ivars, properties, and method selectors with their type encodings. The Swift side parses the reflection sections (__swift5_types, __swift5_fieldmd, __swift5_proto) and demangles the symbols to recover type names, stored fields, and conformances.
The demangler recovers async functions, actor and distributed-actor entities, and opaque return types. It also recovers key-path and protocol-witness thunks, partial-apply forwarders, Objective-C bridging thunks, attached macro expansions, and cross-module protocol conformance descriptors and witness tables. Each arm is checked against a real swift-demangle run (arm_coverage.rs).
Objective-C calls compile to objc_msgSend, so a raw disassembly shows only indirect calls into the runtime. When the chain pipeline recovers native function bodies from a Mach-O (disrobe chain / disrobe auto over a Mach-O), each objc_msgSend, objc_msgSendSuper, objc_alloc, and objc_alloc_init call site is resolved back to its concrete selector, the receiver class where it is statically determinable, and a rendered Objective-C message expression such as [NSString stringWithUTF8String:x2]. The dispatch maps are built from the binary's __objc_selrefs and __objc_classrefs, the dyld bind opcodes, and the __stubs section, then a bounded per-call backward walk over an arm64 or x86-64 def-use model traces the selector and receiver into the call.
The resolution is graded on real clang-compiled fixtures for both arm64 and x86-64 stripped dylibs: every message send in the fixture recovers with the correct selector and receiver class and zero false positives, and the rendered expressions match the source (objc_dispatch_sends.rs).
dyld shared cache
A dyld shared cache packs many system dylibs into one file. disrobe claims a file that carries the dyld_v1 magic and whose header parses. A file that only starts with the magic is left to another pass.
The offset of the mapping table fixes which header layout the cache uses. disrobe names that layout legacy, local-symbols, slide-mappings, sub-caches, or relocated-images. It reads the image list from the legacy header fields when they are set, and from the relocated image fields otherwise. The cache report carries the layout beside the architecture, header size, UUID, platform, format version, the simulator and chained-fixups flags, the mapping, image, and sub-cache counts, the sub-cache entry kind, whether local symbols sit in a separate symbols file, one entry per slide region naming its version or the version number disrobe does not support, the mappings whose file range runs past the end of the file, the pairs of mappings whose address ranges overlap, and up to 4096 install names.
Each image is rebuilt from the mappings that cover its segment addresses, and its segment and section file offsets are rewritten to point at the recovered bytes. Compact output packs the segments back to back. Page-aligned output starts every segment on a 0x4000 boundary and replaces __LINKEDIT with one built for that image alone. A rebuilt __LINKEDIT holds a symbol table, an indirect symbol table, and a string table for that image, and it copies the image's dyld info blobs, chained-fixups blob, exports trie, function starts, and data-in-code table out of the cache file that holds them. The LC_CODE_SIGNATURE offset and size are set to zero, so a recovered image is unsigned. Dysymtab tables the image does not carry are zeroed instead of left pointing into the cache. Two runs over the same cache produce the same bytes.
The cache keeps each image's local symbol names in a run of its own. The legacy, local-symbols, and slide-mappings layouts use the narrow entry, which keys each run by the image's file offset in the primary file. The sub-caches and relocated-images layouts use the wide entry, which keys each run by the image's offset from the cache base, and they move the runs into a separate symbols file when the header carries a symbol-file UUID. disrobe reads both forms and appends the run for an image to the symbol table it builds for that image.
Slide info records the pointers the cache builder rewrote to cache addresses. disrobe reads versions 1, 2, 3, 4, and 5, and writes each pointer back to the value the image declares. An authenticated pointer is recorded with its key (IA, IB, DA, or DB), its diversity value, and its address-diversity bit, and the pointer in the recovered image holds the bare target. Each image records up to 65536 authenticated pointers and reports the full count beside a flag that states whether the list was cut. A slide-info version outside 1 to 5 stops the image, and the error names the version it found.
The cache container in the tests is written to the header layouts above, and the image inside it is a compiled Swift dylib committed to the corpus. Recovery is graded against that original file's segment bytes, symbol table, exported symbols, and function starts (dyld_cache_reconstruction.rs, dyld_cache_chain.rs). Slide info is graded end to end through a rebuilt image for versions 3 and 5, and at the page walk that decodes them for versions 1, 2, and 4.
Sibling cache files
A cache can declare sibling files that hold the rest of its mappings. disrobe locates them by computing names from the primary file you named. For sub-cache N it looks for <primary>.N, and for a single-digit index it also looks for the zero-padded <primary>.0N. For the unmapped local symbols it looks for <primary>.symbols. A file suffix declared inside the cache is never used as a path. Such a suffix is rejected before any file is opened when it holds .., a path separator, :, one of *, ?, ", <, >, |, or a byte outside graphic ASCII.
A missing .symbols file does not stop recovery. Each image keeps exactly the symbol table it declares, and the run continues.
A missing numbered sibling does stop recovery, because the segments it holds are unreachable. The chain refuses, and the error names the sibling it looked for, how many images it could not reach, and the segment that was out of reach for each one.
Recovered dylibs in the chain
disrobe auto and disrobe chain detect the cache, write the cache report as JSON, and emit each recovered dylib as a child artifact that continues through the chain. Both commands pass the input path down, which is how the sibling files are found. Children are page-aligned images with a rebuilt __LINKEDIT. A child keeps its install name as its relative path, with the leading separator and any . or .. component dropped. Every character outside graphic ASCII becomes _, and so does each of :, *, ?, ", <, >, and |. An install name that leaves nothing after that becomes dyld-cache-image.
disrobe auto dyld_shared_cache_arm64e --out ./out/cache-chain
The chain refuses a split cache when it has no path to compute sibling names from. It refuses in the same way when the path it is given is not a readable file.
Limits
- Swift and Objective-C compile to native machine code. Source-level function bodies are not part of the runtime metadata; native code can still be analyzed by the native pass. This pass recovers the metadata the runtimes need at run time.
- A dispatch site whose selector or class cannot be traced within the backward-walk window is left unannotated rather than guessed, so a spurious annotation counts as a soundness failure.
disrobe macho dyldcachewrites compact images. It does not rebuild__LINKEDIT, so a compact image keeps the symbol table offsets the cache gave it.- The chain handles a cache of at most 256 images. A cache above that count is refused whole, and the error points at
disrobe macho dyldcache, which carries the limits above. - One rebuilt image is capped at 512 MiB, one whole-cache run at 1 GiB, and one cache family at 12 GiB across its files. A cache that needs more than a cap is refused rather than truncated.
- A recovered image is unsigned.
disrobeclears theLC_CODE_SIGNATUREoffset and size whenever it rebuilds__LINKEDIT. - FairPlay-encrypted regions (App Store DRM) are reported detect-only via
LC_ENCRYPTION_INFO. Without the decryption key, the pass cannot recover class metadata from those encrypted regions.
ActionScript 3 / Flash
disrobe parses SWF files, disassembles their embedded ActionScript 3 bytecode (AVM2), and lifts method bodies back to readable AS3 pseudocode via operand-stack abstract interpretation.
At a glance
| Layer | Coverage |
|---|---|
| Container | Every SWF tag, with its TagCode, byte offset, and payload size |
| Bytecode | Every DoABC and DoABCDefine block, disassembled per instruction |
| Source lift | Class skeletons with expressions, calls, loops, conditionals, lookupswitch, exception regions, and residual goto control flow |
| Obfuscator detection | secureSWF, DoSWF, Kindi, Irrfuscator, swfLock, each finding with a confidence score |
Commands
disrobe as3 disasm movie.swf --out out/
disrobe as3 tags movie.swf
disasm walks every DoABC and DoABCDefine tag, emits a per-instruction AVM2 listing as <label>.disasm.txt beside the JSON, and reconstructs class skeletons with lifted method bodies as <label>.source.as3. tags lists every tag in the SWF: TagCode, byte offset, and payload size.
Output shape (illustrative):
as3 disasm: OK
input: movie.swf
swf version: 10
abc blocks: 2
classes: 6
methods: 24
instructions: 512
source files: 2
disasm files: 2
out dir: ./out
manifest: ./out/manifest.json
Coverage and fidelity
The source lifter reconstructs class skeletons with expressions, calls, loops, conditionals, forward lookupswitch regions, exception regions, and residual goto control flow by abstractly interpreting the operand stack. At each tracked forward lookupswitch join, it compares the stack height and values from every predecessor. Equal-height predecessors preserve an identical value or produce a named merge value and mark the method partial. Conflicting heights keep the raw control-flow form instead of selecting a value from the last case visited. A /// DR-AS3-PARTIAL: line identifies an unsupported opcode, opaque operand, dropped code, or internal control-flow residue detected by the lifter. The same line also marks a method or constructor body that failed to lift, followed by the lift error, for example an expression nested deeper than the lifter depth cap; such a body contains only that line. Absence of that line means only that these internal checks found none; it does not establish independent semantic or reference equivalence.
disrobe fingerprints commercial AS3 obfuscators (secureSWF, DoSWF, Kindi, Irrfuscator, swfLock) and flags techniques: string encryption, name mangling, control-flow flattening, register and stack shuffle, string-pool-rebuild candidates. Each finding carries a confidence score.
Limits
- Obfuscator handling is detection only. No decryption, pool rebuild, or unflattening is performed.
- ABC erases local variable names (non-parameter slots surface as
loc{n}) and the compiler erases generics before ABC. Both are hard ceilings. - FFDec is the mature full Flash decompiler and goes further on source-level recovery;
disrobecovers SWF parsing and AVM2 disassembly as part of its chain pass, not as a Flash-decompiler replacement.
Mobile (Hermes / Flutter)
disrobe detects the runtime inside a mobile package, extracts React Native and other bundles, lifts Hermes bytecode to a JavaScript surface, and recovers Dart source or disassembles the ARM64 AOT snapshot from Flutter artifacts.
At a glance
| Layer | Coverage |
|---|---|
| Runtimes detected | react-native-apk, react-native-ipa, hermes-raw-bytecode, flutter-libapp-so, flutter-dart-kernel, xamarin-apk, cordova-apk, capacitor-apk, nativescript-apk, ipa, android-apk-dex, unknown |
| Hermes | Bytecode versions v60 through v96 parse against the documented header layout; v62, v71, v74, v76, v83, v84, v89, and v96 lift to pseudo-JavaScript against builds of one sample by the real Hermes compiler |
| Dart kernel | .dill / kernel_blob.bin parsed to byte-exact original Dart bodies from the kernel source table |
| Dart AOT | libapp.so AArch64 bodies disassembled with resolved direct-call and branch targets, plus class table, library URIs, and string pool |
| Dart AOT declaration graph | full library/class/method/field inventory, with method parameter counts, from a libapp.so or four standalone snapshot blobs on a pinned Dart SDK snapshot version |
| Rename maps | Flutter obfuscation_map.json parsed into a typed original-to-obfuscated lookup |
Commands
disrobe mobile detect app.apk
disrobe mobile extract app.apk --out bundles/
disrobe mobile hermes index.android.bundle --out disasm/
disrobe mobile flutter libapp.so --out layout.json
disrobe hermes decompile index.android.bundle --out surface/
disrobe hermes disasm index.android.bundle --out disasm/
disrobe hermes info index.android.bundle
disrobe flutter dump libapp.so --out layout.json
disrobe flutter dump libflutter.so --format json --engine-symbol-map engine-symbols.json
disrobe flutter decompile libapp.so --out estimate.json
disrobe flutter kernel app.dill --out kernel.json
disrobe flutter disasm libapp.so --emit-listing
disrobe flutter map obfuscation_map.json --out map.json
disrobe flutter inventory libapp.so --out inventory.json
disrobe flutter inventory-standalone vm_data vm_instructions isolate_data isolate_instructions --out inventory.json
mobile detect classifies the package; mobile extract pulls bundles out of the container. It writes a manifest.json for React Native, Flutter, Cordova/Capacitor, NativeScript, and Xamarin extraction; Android APK/Dex and Android bundle paths write child files directly without a manifest.
hermes decompile lifts each function back to pseudo-JavaScript. hermes disasm emits a per-function summary without a JS surface. Pass --function <INDEX_OR_NAME> to select a zero-based index or exact function name, and add --json to receive the same instruction list as a structured document. Duplicate names require an index. hermes info prints the version, function count, string count, and identifier count.
flutter dump reports the four Dart snapshot sections and their sizes. With --format, an optional --engine-symbol-map accepts the versioned disrobe.flutter.engine-symbol-map JSON format. Disrobe applies those names only when the map's GNU build ID matches the ELF input and every address lies inside an image segment. The parser caps the map at 1 MiB and 10,000 unique addresses. flutter map parses a Flutter obfuscation_map.json into a typed original-to-obfuscated lookup.
{
"format": "disrobe.flutter.engine-symbol-map",
"version": 1,
"identity": {
"kind": "elf-build-id",
"value": "b71885094a73117bf90d3cfa05824129"
},
"symbols": [
{ "address": 4096, "name": "Dart_Invoke" }
]
}
address is an unsigned virtual address in the input image, not a file offset or image-relative offset. Addresses must be unique. A validated external entry replaces a symbol-table entry at the same address; all other local symbols remain. JSON exports record the map path, format, and matched build ID in provenance. The same map can be supplied to a single-file automatic run with disrobe auto <input> --format json --engine-symbol-map <map>.
Output shapes below are illustrative.
hermes decompile: OK
input: index.android.bundle
hermes ver: 96
functions: 8
with body: 8
identifiers: 24
strings: 12
opcode cov: 100.0% (312 reconstructed / 0 fallback)
if/loop/try: 3/2/1
source: ./out/index.android.bundle-hermes/index.android.bundle.js
manifest: ./out/index.android.bundle-hermes/manifest.json
flutter kernel: OK
input: app.dill
format ver: 130
libraries: 3
classes: 8
procedures: 21
fields: 14
bodies: 21 recovered (byte-exact Dart source from the kernel source table)
strings: 112
wrote: ./out/app-dart-kernel.json
dart source: ./out/app-dart-kernel.recovered.dart
Coverage and fidelity
decompile reads the header of Hermes bytecode versions v60 through v96 against the documented layout. Lifting each function back to pseudo-JavaScript is graded against builds of one sample by the real Hermes compiler at v62, v71, v74, v76, v83, v84, v89, and v96, each through the same JavaScript-engine behavior comparison; other versions in the v60-v96 band parse but are not graded against a real compiler. On a hermesc-built HBC v96 sample (8 functions, CI-gated) every function lifts at 0 fallback opcodes. A non-redistributable 66 MiB production bundle parsed the 122,633-function table with no parse failure (measured locally, not CI-gated).
Two distinct recovery paths cover two distinct Flutter artifacts.
Corpus provenance: self-authored sample. disrobe_sample/ is self-authored: Flutter
stable SDK, bundled Dart SDK 3.12.2 (windows_x64), kernel format version 130/132,
gen_snapshot android-arm64-release in product mode with no DWARF. Its source,
disrobe_aot_sample.dart, exercises:
- Classes with final fields, a
constconstructor, a computed getter, and an instance method that returns a new instance of its own class - A top-level recursive function and sequential
if/return control flow - Nullable types with
??and?., string interpolation, afor-in loop over aList, and a non-capturing lambda passed to.where()
It does not exercise async or generator functions, a user-defined generic class or
function, a closure that captures an enclosing variable, extension methods, mixins,
Future/Stream chains, or build_runner-generated code, so recovery of those constructs
is untested.
Corpus provenance: obfuscated builds. pinned_graph_fixture/ is a second
self-authored source built three times by the real flutter build apk --release
toolchain (Flutter 3.44.6, Dart 3.12.2): plain, with every class and field renamed, and
with --obfuscate --split-debug-info=build/symbols. The obfuscated build is graded, not
merely present: obfuscated_flutter_build_reports_structure_only and
obfuscated_auto_mode_never_claims_source_names require the declaration graph to report
StructureOnly with opaque names and never claim a source name it does not have.
A real third-party sample, local only.
crates/disrobe-pass-mobile/tests/real_flutter_rustdesk.rs fetches RustDesk 1.4.9's
arm64-v8a release APK (AGPL-3.0, 26,871,021 bytes, sha256 pinned in the test and in
corpus/mobile/flutter/MANIFEST.toml) and extracts lib/arm64-v8a/libapp.so and
libflutter.so from the zip in memory; the APK itself is never committed. Reproduce it
with:
mkdir -p "$TMPDIR/disrobe-scratch/rustdesk-flutter-cache"
curl -sSL -o "$TMPDIR/disrobe-scratch/rustdesk-flutter-cache/rustdesk-1.4.9-aarch64-signed.apk" \
"https://github.com/rustdesk/rustdesk/releases/download/1.4.9/rustdesk-1.4.9-aarch64-signed.apk"
cargo test -p disrobe-pass-mobile --test real_flutter_rustdesk
This result is [local]: no CI job populates the cache, so tests/optional.toml lists the
sample and a run without it writes a not-measured record instead of passing; without that
entry an absent cache fails the test by name. On this real build the RAW static path recovers
10,351 class-name strings, 28,952 method-name strings, and 1,489 library URIs, each
cross-checked against an independent whole-file package:*.dart string scan that finds
1,271 of its own. Every one of those counts is pinned by equality in the test, so a
figure that moves fails the gate rather than drifting silently. RustDesk's Dart snapshot
falls outside the pinned Dart 3.12.2 android-arm64 product tuple, so the
declaration-graph path (flutter inventory) reports unsupported-version on it rather
than guessing at a cluster layout it has no pin for.
Dart kernel (.dill / kernel_blob.bin). A kernel is the serialized Dart AST. disrobe parses the kernel binary format (magic 0x90abcdef): the footer component index, the string table, per-library class and procedure offset tables, and the embedded UriSource table. From the source table it recovers byte-exact original Dart bodies, sliced per procedure by the kernel file offsets. The recovered .dart source file is always written beside the JSON without needing --emit-source.
ARM64 AOT snapshot (libapp.so). The AOT snapshot is ordinary AArch64 machine code. disrobe locates the four _kDart*Snapshot* symbols, recovers class and method names from the isolate-data string table, scans frame prologues to bound functions, and disassembles each body to readable instructions with resolved direct-call and branch targets. flutter decompile also recovers the class table estimate, library URIs, and a string pool from the isolate image.
Beyond the disassembly, the release ARM64 path recovers class membership and method-to-class attribution, and lifts each function to nested if/else/while pseudocode through the shared structurer. That lift is gated by a source-free CFG round-trip: when the recovered structure does not round-trip to the same control-flow graph, the function falls back to a flat call list rather than presenting a shape the graph does not support.
Each call in that pseudocode carries its reconstructed argument list. disrobe tracks the Dart argument registers, the Dart stack slots that hold arguments past the register file, and the caller's frame slots across the call sequence, then renders each argument as an expression: an immediate, a null or boolean read from the null register, a value produced by an earlier call, a field load by offset, or an object-pool entry. A tail call renders the same way, as a returned call. Pool entries are inlined as literals. On a pinned snapshot version disrobe deserializes the object pool per slot, so a call that loads a string, a double, an integer, a list, or a declared name reads that value back at the call site. Inlining is depth-bounded and size-bounded, and a cyclic pool reference stops at the placeholder. An argument the tracker cannot resolve renders as ?, and an argument produced by a control-flow merge always renders as ? rather than one branch's value. A call whose arguments cannot be recovered at all keeps the opaque (...) form.
Declaration graph (flutter inventory / flutter inventory-standalone). The clustered object graph inside the snapshot data blobs carries the full library, class, method, and field declarations, keyed to the exact Dart SDK snapshot version and feature tuple that serialized them. disrobe reads that graph directly for the pinned Dart 3.12.2 Android arm64 build (both the plain product tuple and the --split-debug-info DWARF tuple): every class, method with its parameter count, and instance field name, cross-checked on real flutter build apk --release output against the snapshot's own cluster-header totals. A snapshot compatibility hash outside the pinned set reports unsupported-version rather than guessing at cluster offsets.
Detected runtimes
disrobe mobile detect|extract routes the packaged JavaScript and .NET runtimes out of an .apk or .ipa: React Native Hermes, Flutter, Xamarin, Cordova, Capacitor, and NativeScript, each handed to the pass that reads it.
Limits
- The Hermes path is a structured lifter, not a full decompiler. Variadic call arguments are marked
<arg?>where the Hermes frame-register layout is not modeled; unreconstructed opcodes appear in disasm form inline. - Exact Dart source for an optimized AOT function is not byte-recoverable from the machine code (register allocation and inlining are lossy). Use the kernel path for source bodies.
- Instance field names are not recovered by the ARM64 disassembly path (
flutter decompile/flutter disasm); they are only reachable through the declaration graph (flutter inventory), and only on a pinned Dart SDK snapshot version. - The declaration graph path recovers names, not values or optimized-body source; it never guesses a cluster layout for a snapshot compatibility hash it does not have pinned.
Python pickle
disrobe analyzes pickles statically so you can audit what a stream would do on load before it ever touches a real interpreter. It never unpickles, never calls __reduce__, never executes a REDUCE opcode.
Pickle is a code-execution format wearing a data format's clothes. Unpickling a crafted stream runs arbitrary code through __reduce__ / REDUCE, which makes weaponized .pkl and .pt files a recurring ML supply-chain vector.
At a glance
| Layer | Coverage |
|---|---|
| Protocols | 0 through 5 |
| Symbolic VM | Full object graph, memo, stack, and STOP result reconstructed with nothing executed |
| Reconstruction | Graph rendered back to re-executable Python assignments, including the listitems and dictitems extension streams |
| Safety grading | Three severity tiers, each finding tagged with a confidence tier |
| Containers | PyTorch, TorchScript, and numpy model files; zip, zip64, and tar polyglots |
| Bindings | The same static suite is available as a Python library |
Commands
disrobe pickle disasm model.pkl --out trace.txt
disrobe pickle decompile model.pkl --out graph.py
disrobe pickle safety model.pkl
disrobe pickle trace model.pkl
disrobe pickle polyglot suspicious.bin
disrobe pickle ml-detect model.bin
trace walks the opcode stream and reconstructs the object graph the same way a real unpickler would build it, but every operation is symbolic. A GLOBAL records a (module, name) reference without importing the module; a REDUCE records "this callable would be applied to these arguments" without calling it; the memo, stack, and STOP result are all inert values. The output is the full graph (objects, memo, resolved globals, reduce count) with nothing executed. decompile renders that graph back to equivalent Python assignments.
polyglot catches the trick of hiding a malicious pickle inside a zip, zip64, or tar that a model loader will open as an archive and then unpickle. ml-detect recognizes PyTorch, TorchScript, and numpy containers and lists every embedded pickle stream, so a multi-file .pt archive is enumerated rather than treated as one opaque blob.
The same static suite is available as a library. Nothing is ever unpickled.
from __future__ import annotations
from pathlib import Path
import disrobe
from disrobe import PickleSafety
payload: bytes = Path("model.pkl").read_bytes()
safety: PickleSafety = disrobe.pickle_safety(payload)
severity: str | None = safety.severity
finding_count: int = safety.finding_count
reduce_count: int | None = safety.reduce_count
listing: str = disrobe.pickle_disasm(payload)
Coverage and fidelity
The graph the symbolic VM builds is rendered back to re-executable Python, and the reduce protocol's listitems and dictitems extension streams are modeled, not dropped. That is what lets collections.deque, OrderedDict, and defaultdict reconstruct: a REDUCE that builds the container is followed by the item stream, which disrobe re-emits through extend/__setitem__ helpers so the rebuilt object is populated exactly as the original was, without ever running the pickle.
The reconstruction benchmark covers generated fixtures across protocols 0 through 5: primitives, containers, cyclic and shared references, __reduce__ objects, and the collection types above. CPython loads each original fixture and executes its reconstructed program; 470 / 470 reconstructed fixtures pass the comparison checks. These include type and value comparisons and identity checks for shared and cyclic container cases. These are trusted test fixtures. Disrobe's inspection and reconstruction commands do not execute their inputs.
disrobe pickle safety grades a stream into one of three severity tiers. Each finding is tagged with a confidence tier so a reviewer can tell a certain hit from an inference.
| Severity | Meaning |
|---|---|
benign | No dangerous import, no reduce against a risky callable, no memo abuse |
suspicious | A pattern that can be malicious in context (unusual import, opaque reduce, memo manipulation) |
overtly_malicious | A reduce against a known code-execution sink (os.system, subprocess.Popen, builtins.eval / exec, __import__) |
| Confidence | Meaning |
|---|---|
signature_certain | The finding follows directly from the opcodes (a GLOBAL os system then REDUCE) |
pattern_inferred | A heuristic shape, not a literal signature match |
context_dependent | Risky only depending on how the loader uses it |
The report also surfaces the resolved import list, the REDUCE count, and the unused-memo count (a common obfuscation tell), so a triage decision does not require reading the raw opcodes.
Limits
- Nothing is executed, by design: a
GLOBALrecords a reference without importing the module and aREDUCErecords an application without calling it. The report tells you what a load would do; it is not the loaded object. - Reconstruction may require a runtime
copyregregistry, out-of-band buffers, persistent IDs, or importable modules that the stream does not contain. The 470-fixture benchmark does not cover those dependencies. - A
pattern_inferredorcontext_dependentfinding is a shape, not a signature match. Treat it as a lead for review rather than a verdict.
Shell / PowerShell
disrobe deobfuscates supported PowerShell, Bash, Batch, VBScript, and VBA patterns. Its recovery paths cover the families listed below, VBA source from Office documents, VBA p-code with stomp detection, Excel 4.0 (XLM) macro formulas, and PDF maldoc analysis.
At a glance
| Dialect | Families |
|---|---|
| PowerShell | Invoke-Obfuscation (Token, AST, String, Encoding, Compress, Launcher; graded on from-spec generator output because Defender blocks the module), Invoke-Stealth, Chameleon, psobf; PowerHell and ISESteroids are detected by signature with no committed sample |
| Bash | Bashfuscator (Token, String, Obfuscate, Compress modes), indirection peeler |
| Batch | .bat / .cmd random-char and set-indirection patterns |
| VBA / VBScript | VBA module source recovery, VBScript WSH patterns |
| Other surface | Coverage |
|---|---|
| VBA p-code | 264-opcode table across VBA5 / VBA6 / VBA7 (32-bit and 64-bit) with identifier resolution, plus VBA-stomping detection |
| Excel 4.0 (XLM) | BIFF8 (.xls) and BIFF12 (.xlsb) macro sheets, full Ftab and Cetab function tables, shared-formula resolution, auto-run entry points |
| PDF maldocs | Both cross-reference forms, empty-password RC4 / AESV2 decrypt, embedded JavaScript and every Launch, URI, GoToR, SubmitForm, ImportData, and EmbeddedFile action |
Commands
disrobe shell deob payload.ps1 --out recovered.ps1
disrobe shell detect payload.ps1
disrobe shell deob book.xls # Excel 4.0 macro-sheet formulas from BIFF8 or BIFF12
disrobe auto payload.ps1 --out recovered/ # detect the dialect and route obfuscated shell automatically
deob auto-detects the dialect and obfuscator family, applies the right reversal, and writes the recovered source plus a manifest.json. detect reports the dialect, family, confidence score, and detection markers without writing output.
Output shape (illustrative):
shell deob: OK
input: payload.ps1
dialect: PowerShell
family: InvokeObfuscationToken
confidence: 0.94
markers: ["iex", "token-replace"]
wrote: ./out/payload.deob.ps1
manifest: ./out/payload.deob.manifest.json
Coverage and fidelity
VBA source and p-code
From a .docm / .xlsm / .bin Office container, disrobe parses the dir stream (MS-OVBA), maps each module to its stream and TextOffset, and MS-OVBA-decompresses the CompressedSourceCode at that offset to emit the original .bas / .cls text per module (multi-chunk compression and CopyToken bit-count edges handled). Validated against real Word and Excel documents authored via COM, byte-for-byte against the known module text.
The p-code decoder covers a 264-opcode table across VBA5, VBA6, and VBA7 in 32-bit and 64-bit forms, with identifier resolution. Tests compare its disassembly with pcodedmp dumps. Accepted differences are limited to four pinned classes of pcodedmp 1.2.6 defects: a shifted identifier-table index, an unresolved object name, a truncated declaration parameter chain, and a missing user-defined type name.
Source recovery has a separate comparison against the authored .bas files, preserving line order, operators, and operand order. The two committed modules recover 71 of 71 lines for SourceProbe and 552 of 552 for EdgeCases. These counts are enforced by regression tests. VBA-stomping detection compares compiled p-code with stored source, flags divergence, and recovers the compiled behavior from p-code.
Excel 4.0 (XLM) macros
disrobe shell deob book.xls recovers Excel 4.0 macro-sheet formulas from a BIFF8 (.xls) or BIFF12 (.xlsb) workbook. It decodes the Ptg RPN token stream back to formula text over the full Ftab and Cetab function tables, resolves shared-formula masters to per-cell absolute references, and flags the built-in auto-run names (Auto_Open, Auto_Close, Auto_Activate, Auto_Deactivate) as execution entry points, so a =EXEC("...") or =FORMULA(...) macro reads back in full. A token the decoder does not recognize is emitted as an explicit unknown marker, not as a guessed formula. Recovery is graded against hand-built BIFF fixtures with known formulas, covering BIFF12's wider reference fields, shared-formula relative-to-absolute resolution, and the Auto_Open entry point (xlm_fixtures.rs).
Haxe HashLink, Perl, R, and Tcl
The same scriptlang pass covers four runtimes that ship compiled or packaged rather than as plain source.
HashLink (.hl). The register bytecode is parsed byte-exact: type table, functions, natives, globals, and constants. Function bodies disassemble with reconstructed signatures, and source class and method names are recovered and graded against the original .hx. Haxe compiled to JavaScript or SWF routes to the JS and Flash stacks instead.
Perl. A B::Concise op-tree is read back, and ByteLoader-encoded scripts are decoded.
R. .rds serialized objects round-trip.
Tcl. A starkit extracts byte-identically.
PDF maldoc analysis
The shell pass carries a PDF analyzer (disrobe_pass_shell::analyze_pdf) for document-borne malware. It loads a PDF through both cross-reference forms (the classic xref table and cross-reference streams), transparently decrypts a Standard-security-handler document that uses RC4 or AESV2 under an empty user password (authenticating against /U per the PDF algorithms, with no password supplied), then walks the catalog, name trees, page annotations, and form fields to recover embedded JavaScript and every Launch, URI, GoToR, SubmitForm, ImportData, and EmbeddedFile action with its resolved target. Hex-escaped names, split or concatenated JavaScript strings, and Flate / LZW / ASCII85 filter chains are decoded along the way, and every decompression is bomb-bounded. It is graded against hand-crafted PDF fixtures that plant a known marker behind each path (classic-table and xref-stream JavaScript, RC4 and AESV2 empty-password decrypt, a launch target, an embedded file, name-tree and additional-action scripts), plus an RC4 published-vector check and an empty-password authentication test (pdf_fixtures.rs).
Limits
The XLM decoder is graded three ways that do not share a reading of the specification. Workbooks authored by real Microsoft Excel 16.0 are decoded and compared against the formulas as authored, across 99 cells in both directions so that a missing cell and an unexpected extra cell each fail, with every fixture pinned by length and sha256; a control flips one byte of the real =SUM(1,2) Ptg stream and must be rejected. The function tables are graded against an independent decoder's published snapshot, agreeing on 476 shared Ftab ids and 396 shared Cetab ids, which is what catches the wrong-index case where every CALL and EXEC an analyst reads would be renamed. Third, XLMMacroDeobfuscator 0.2.7 reads the same committed workbooks at test time and its formula text is compared cell by cell against the recovery, agreeing on 44 cells across two workbooks once three formatting conventions are folded: the reference renders a whole number as 1.0, spaces its argument separators, and quotes sheet names. Folding is string-aware, so a comma or a quote inside a literal is left alone, and the folding rules cannot rewrite a function name, a cell reference or a digit. Two of the four committed workbooks are outside that leg because the reference cannot read them: it stops at a ptgFuncVar function id it does not carry, and it refuses the Ftab probe sheet that deliberately carries index 0x00FF. Both refusals are recorded as named constants with their exact message, so a refusal that changes is a deliberate edit rather than a silent pass, and neither workbook is counted as graded.
A fourth leg grades the function tables at formula level rather than at name-table level. Each of the 476 Ftab and 396 Cetab ids is set into a real Excel-authored workbook, at four call sites that already exist in that workbook plus two synthesized call sites shaped to take four or five arguments, and the resulting file is read back by XLMMacroDeobfuscator 0.2.7. Of the 476 Ftab ids, 359 come back named by the reference and agree with the recovery; the remaining 117 are ids the reference's own parser table does not carry a name for at all, so they stay graded only against the name-table leg. All 396 Cetab ids come back named and agree. One divergence is recorded: 0x005C is SERIES and 0x019E is SERIESSUM, and the reference names both SERIESSUM, folding two distinct entries onto one name. Two mutation tests demonstrate the leg catches a wrong index rather than passing regardless of one: shifting 0x006E (the index the committed workbook already calls through EXEC) to its neighbor is reported, and so is shifting 0x0125, an id only the tables exercise. Two further tests walk the BIFF8 record and Ptg-class space each committed workbook actually carries, and state a reason for every declared record type and Ptg class no committed workbook carries.
Of the four committed workbooks, real_xlm_excel16.xls and real_xlm_ptgspread.xls are graded against formulas read back from real Microsoft Excel 16.0, not retyped from the byte layout. bench_biff12.xlsb and ftab_probe.xls are real Excel-produced bytes whose expected formulas are authored to the specification rather than confirmed by an Excel readback; both fixtures are recorded that way in the manifest test data reads, and the ftab-index sweep above grades every function table entry those two carry independently of that distinction, since it writes its own probe workbooks rather than trusting either fixture's expected values.
Two limits remain. Specification-assembled fixtures still cover shapes Excel will not author, and for those the same reading of the specification produces both the bytes and the expectation, so they catch a decoder that contradicts the specification but not a misreading shared by both sides. Breadth over arbitrary real-world workbooks is not graded, because the Excel-authored coverage comes from one producer version.
The VBA line-recovery measurement covers the two committed modules described above. Unrecognized XLM Ptg tokens appear as explicit unknown markers in the recovered formula.
Containers and archives
Before disrobe can decompile anything, it often has to get inside a container. The disrobe-binfmt layer detects every format below. Most use the generic member-byte extractor; LUKS1 uses a dedicated raw-volume-key route and reports a typed key wall when no key is supplied. Auto-detection, recursive chaining through nested layers, and shared zip-slip and decompression-bomb guards remain in effect. A committed input drives 30 generic extractors to member bytes that match an independent extractor (bsdtar, 7-Zip or the format's own decompressor), and the tracked LUKS1 fixture separately proves byte-exact decryption into the VHD extractor.
At a glance
| Surface | Support |
|---|---|
| Formats detected | 103 archive, installer, filesystem, firmware, and encrypted-volume formats; 102 use the generic extraction entry point and LUKS1 uses its bounded raw-volume-key entry point |
| Formats exercised | 30 of them write member bytes from an input this repository commits that match the members bsdtar 3.8.8, 7-Zip 26.02 or the format's own decompressor extracts from the same input (crates/disrobe-cli/tests/golden/container_breadth_reference.tsv, written by scripts/container_breadth_reference.py), measured by crates/disrobe-cli/tests/container_breadth.rs and pinned in crates/disrobe-cli/tests/golden/container_breadth.txt. 12 more write members that no installed reference tool confirms, the committed PAR2 input reaches detection only, and 59 generic routes have no committed input. The declared roster is a capability list rather than a measurement |
| Carve engine | A recursive scan with the magic-signature table that detect_container uses. It carves sixteen formats: zip, 7z, RAR 4 and 5, CAB, xz, gzip, zstd, bzip2, tar, squashfs, minidump, ISO 9660, WIM, UnityFS, cpio and ar (including deb). Each hit ends where its decoder stops or where its headers place the end of the archive, so a stream followed by another container yields both; a zip is carved only when its end-of-central-directory record lies within the last 64 KiB of the input that follows it. InstallShield, RPM, xar, VHD, VHDX, lzip, lz4 and compress (.Z) signatures are detected but not carved, because the carver cannot compute where they end, and formats recognised by structure rather than a fixed signature (FAT, ext4 and MSI, for example) are not carved out of a larger blob. It recurses by depth and uses entropy to separate code from padding |
| Nesting | Container-in-container chaining, governed by --max-depth (default 8) |
| Directory input | Batch-processed recursively, bounded by --batch-max-depth |
| Guards | Per-entry and aggregate size caps, recursion-depth cap, zip-slip path sanitization, on every format |
Supported formats
| Category | Formats |
|---|---|
| Archives and installers | ZIP (incl. ZIP64; an archive with encrypted members is refused, since no password can be supplied), tar.gz / tar.bz2 / tar.xz / tar.zst, 7z, RAR4 and RAR5 (stored members from both; RAR5 LZ "normal" method decoded in-tree; RAR 2.9/3.x LZ, PPMd, mixed LZ and PPMd blocks, and canonical delta and x86 filter programs decoded in-tree, with every decoded member checked against the CRC-32 its header declares; an encrypted member, a member split across volumes, and a stored member whose packed and unpacked sizes differ are each refused by name while the archive's other members still extract), .cab, MSI, MSIX / APPX, NSIS (each File entry's bytes from stored, zlib, BZip2 and LZMA data, solid and non-solid, with ANSI or Unicode names; installers that makensis 3.11 builds from corpus/installers/nsis/tide_viewer.nsi extract with every file's SHA-256 equal to its input in solid LZMA, zlib and BZip2, non-solid LZMA, zlib and BZip2, and ANSI solid LZMA builds; a file is named as its File command names it, without the SetOutPath directory, and the install script's other instructions are not decompiled), Inno Setup 4.0.9 through setup-data profile 7.0.0.3 (stored, zlib, BZip2, LZMA1, and LZMA2 members, including solid groups), InstallShield legacy cabinets (ISc( majors 0 and 5: stored members, u16-length chunk-framed raw DEFLATE, and full-flush raw DEFLATE, with obfuscated members decoded before inflate), .deb, .rpm (metadata), AppImage Type 1 (ISO 9660, Rock Ridge, and zisofs) and Type 2 (SquashFS), Flatpak, Snap |
| Bare compression streams | gzip, bzip2, xz, zstd, lzma, lzip, lz4-frame, zlib, .Z (Unix compress); concatenated gzip members, bzip2 streams, xz streams, and lzip members all decode, in order, both bare and under tar.gz / tar.bz2 / tar.xz |
| Legacy archives | ar, arj (methods 0-4 decoded, with header and member CRC32 verified; split volumes refused by name), arc (methods 1-9 decoded; independent byte checks cover methods 2 and 5-9; methods 8-9 use grouped dynamic LZW with exact declared-size and CRC checks; methods 10-11 refused), LZH header levels 0-3 (-lh0- through -lh7-, -lhx-, -lz4-, -lz5-, -lzs-, and -pm0- decoded; -lhd- directories retained; -lhd- symbolic links refused; -pm1- and -pm2- decoded in tree and reaching extraction, each member checked against the CRC-16 its archiver stored; byte, code-page, and UTF-16 paths recovered; missing split volumes refused), lzop, FreeBSD uzip, Xamarin xalz, par2, ELF appended-overlay carve, StuffIt (classic stored and methods 2, 5 LZAH, 8 MW, and 13 decoded for data and resource forks, with record-header and fork CRC validation; StuffIt 5 containers parsed and their Arsenic and stored forks decoded in tree, though extraction still carves a StuffIt 5 archive rather than writing its forks; classic method 6 and StuffIt 5 method 14 are not implemented and refuse by name because no archive using them was found to grade a decoder against; encrypted forks refused), partclone (decoded) |
| Embedded-linux filesystems | squashfs, cramfs, ext4, romfs, minixfs, jffs2, UBI + UBIFS, yaffs, erofs (full and compact indexes with lz4, deflate, zstd, and microlzma decoded), NTFS, android-sparse, btrfs-send |
| Disk images and partitions | GPT and MBR (partition tables parsed; each partition carved and recursed in-tree), VHD (fixed and dynamic BAT), VHDX (region table + BAT; logical disk materialized from the block-allocation table, then partition-carved and FAT12 / 16 / 32 walked to pull individual stored files), WIM (header resources with XPRESS / LZX / LZMS chunk payloads decompressed in-tree), FAT12 / 16 / 32 (boot sector, FAT chain walk, root and subdirectory traversal) |
| Encrypted volumes | LUKS1 with aes-cbc-plain, a 128-, 192-, or 256-bit raw volume key, and a SHA-1, SHA-256, or SHA-512 PBKDF2 header digest. The raw key is read from a bounded file or standard input, verified against the header digest, and zeroized after use before the decrypted payload enters the normal container pipeline. Keyless extraction succeeds with a typed wall that names the cipher, mode, digest, iteration count, and missing raw volume key |
| Apple | .dmg (UDIF: koly trailer + blkx mish chunks; ADC / zlib / bzip2 / LZFSE / LZMA chunk decoders; then HFS+ catalog walk extracts individual files, all in-tree), .pkg (xar TOC + gzip / bzip2 heap, extracted in-tree) |
| Vendor firmware | D-Link (SHRS / encrypted-img AES / alpha / fpkg), EnGenius XOR, Autel ECC table, QNAP PC1, plus CRC-verified Netgear (chk / trx), Xiaomi, Tesla, HP, Moxa, INSTAR, and Airoha carves; OTP-AES Airoha firmware is an information-theoretic wall and is carved verbatim |
| Standalone executables | Bun --compile binaries for Windows, Linux and macOS (the embedded module graph and sourcemaps; each module's bundled source is recovered as Bun embedded it, and module names lose the /$bunfs/root/ or B:/~BUN/root/ prefix), Unity AssetBundle (UnityFS), .NET single-file bundles (majors 1, 2 and 6; embedded assemblies routed to the CIL decompiler, native entries to the native pass), Enigma Virtual Box 10.70 Build 20240522 x86 built-in stored-file bundles with literal .enigma1 and .enigma2 section names |
| App / runtime | Electron .asar, Docker image tarball, OCI image manifest + layers, ISO 9660 with Joliet fallback, Rock Ridge names, ordered multi-extent files, and zisofs v1 (extracted in-tree) |
Commands
Most extraction happens implicitly inside disrobe auto, which detects a container, extracts it, and recurses into the contents. Archive-shaped inputs are also available directly:
disrobe py extract package.whl --out extracted/
disrobe auto firmware-dir/ --out extracted/ --batch-max-depth 6
disrobe extract crash.dmp --out carved/
disrobe extract volume.luks --luks1-raw-volume-key-file volume.key --out decrypted/
disrobe extract volume.luks --luks1-raw-volume-key-file - --out decrypted/
Directory inputs are batch-processed recursively; --batch-max-depth limits directory descent. Container nesting inside a detected artifact is governed by --max-depth (default 8).
For ZIP, TAR, ARC, RAR, ARJ, LZH, StuffIt, Inno Setup, InstallShield, RPM, AppImage, .NET single-file, EROFS, and UEFI firmware-volume inputs, disrobe extract and disrobe auto apply the same default quota policy and retain the same ordered, byte-identical archive members. Extractor-generated sidecars are tagged separately and remain direct-only; an archive-controlled name such as .disrobe-user.bin remains an archive member. When an independently indexed member has an unsafe path, exceeds a quota, or cannot be decoded, extraction skips it and continues with trustworthy siblings. The direct result records the ordered reasons in integrity_violations; the automatic chain writes the ordered prefix that fits the 64 KiB container.refusals bound. container.refusals_total, container.refusals_omitted, and container.refusals_truncated make any truncation explicit. A malformed directory or table that cannot identify the next member safely still refuses the whole container.
Coverage and fidelity
Windows crash dumps
disrobe extract crash.dmp (or disrobe auto crash.dmp) carves the loaded PE modules out of a Windows minidump. It parses the stream directory, reads the module and memory lists, and for each module rebuilds an in-memory PE image by copying whatever memory the dump actually captured into a buffer at the correct RVAs, rewriting each section's file-offset field to match its virtual address so downstream PE parsers read the result as a well-formed image. Coverage is reported per page: the summary records how many bytes were recovered, which ranges the dump truncated, and which it never captured, with a reason for each gap, so a partially captured module is never presented as complete. The carve is graded by wrapping a real on-disk PE into a minidump and confirming the carved .text comes back byte-identical (minidump_real_pe.rs); each carved module and a .disrobe-minidump.json coverage summary land in the output directory.
Deno eszip archives
The disrobe-binfmt eszip reader (disrobe_binfmt::containers::eszip) parses a Deno eszip module-graph archive, versions 2 through 2.3, including one embedded inside a deno compile standalone executable, and reconstructs the module graph: each module's specifier, kind, and source bytes, plus redirects and npm specifiers, with per-module source-hash verification that drops any module whose stored hash does not match. It is exercised by a build-then-parse round-trip that also confirms a corrupted source hash is rejected.
Safety guards
Every extractor shares the quota machinery in crates/disrobe-binfmt/src/quota.rs:
- Per-entry size cap and aggregate size cap defuse decompression bombs.
- Recursion-depth cap defuses container-in-container bombs.
- Zip-slip path sanitization (
sanitize_entry_path): every entry path is sanitized so no extraction can escape the output directory, on every format.
Bypasses of any of these are treated as security issues; see the security policy.
Limits
Where a format's payload is not decoded in-tree, the table above names it per entry rather than implying full extraction:
- LUKS1 recovery is limited to
aes-cbc-plainwith a caller-supplied raw volume key. Passphrases and keyslot unlocking, XTS modes, and LUKS2 are not accepted by this route. A detected keyless LUKS1 header produces a successful typed wall. A detached LUKS1 header is refused until its separately stored encrypted payload is supplied. VeraCrypt and TrueCrypt may not be identifiable without a key, and headerless dm-crypt has no on-disk header to detect. - RAR 2.9/3.x members carry their transforms as RARVM programs. disrobe identifies a program by exact length and CRC-32 and runs a native transform for the canonical delta, x86 e8, x86 e8/e9, itanium, rgb and audio programs. It does not interpret RARVM bytecode, so a member carrying any other program is refused by name. The corpus grades the delta and x86 e8/e9 transforms against a real archive. The plain x86 e8, itanium, rgb and audio transforms have no real archive in the corpus yet, so their output rests on the CRC-32 check every decoded member passes and on known-answer tests rather than on a graded fixture. The crate publishes this gap as
RAR3_FILTERS_WITHOUT_REAL_ARTIFACTandRAR3_FILTER_COVERAGE_NOTEindisrobe_binfmt::containers::rar. Encrypted members (the RAR4LHD_PASSWORDflag or a RAR5 file-encryption record), members split across volumes (the RAR4LHD_SPLIT_BEFOREandLHD_SPLIT_AFTERflags or the RAR5 volume-continuation header flags), and solid state carried from an earlier entry are refused by name, and the other members still extract. A stored member whose packed size differs from its declared unpacked size, and any member whose recovered length differs from its header, is refused rather than written short. - Cabinet (
.caband MSI-embedded) folders are decoded once each, in member-offset order, for stored, MSZIP, LZX, and LZMS folders, and each data block's checksum is verified when the cabinet sets one. Quantum folders, members that continue into another cabinet of a set, and members whose name appears more than once in the cabinet are refused by name. - In a solid 7z block, a member refused for its path is still read past, so the members after it keep their own bytes.
- Inno Setup follows finite version profiles from the loader through both metadata blocks, file and data records, solid groups, filters, and checksums. Unsupported profiles and encrypted content without a secret refuse by name.
- ARC methods 10-11 are refused.
- StuffIt 5 containers are parsed and their forks decode in tree, but extraction still carves the archive verbatim rather than writing each fork, so
disrobe autorecovers a StuffIt 5 archive as one blob. Classic StuffIt forks are unaffected and extract per fork. - OTP-AES Airoha firmware is an information-theoretic wall and is carved verbatim.
- A minidump only contains the memory it captured. Truncated and never-captured ranges are reported with a reason per gap instead of being filled in.
Global flags
These flags are accepted on every subcommand (they are declared global = true on the root parser).
Output and verbosity
| Flag | Effect |
|---|---|
-v, -vv, -vvv | Increase log verbosity. |
-q, --quiet | Suppress non-error output. |
--color <auto|always|never> | Control ANSI color in terminal output. |
--json | Emit a structured JSON document instead of human text. |
--ndjson | Emit newline-delimited JSON (streaming). |
--sarif | Emit SARIF 2.1.0 (GitHub code scanning, etc.). |
--progress <auto|always|never> | Progress-bar rendering. auto renders only on a TTY. |
Execution control
| Flag | Effect |
|---|---|
--config <PATH> | Load a .disrobe.toml config file. Without it, disrobe walks up from the CWD to discover one. See project configuration. |
--in-place | Rewrite the input file in place. |
--force | Overwrite existing outputs without prompting. |
-j, --threads <N> | Worker thread-pool size (defaults to detected CPU count). |
--no-cache | Bypass the .dr envelope cache. Output is identical with or without this; it is a performance toggle, not a correctness one. |
--dry-run | Report what would happen without writing any output. |
Debug tracing
| Variable | Effect |
|---|---|
DISROBE_DEBUG=<area> | Stream every offset, size, candidate, and classification a pass walked to stderr. Takes all or a comma-separated area list. |
DISROBE_DEBUG_FORMAT=json | Emit one JSON object per debug event instead of human text. |
Debug tracing is sample-sensitive. Only values emitted through explicitly guarded key/value events pass through the masking guard. After trimming surrounding whitespace, it masks a value only when the value is at least 20 characters, contains only ASCII letters, digits, _, -, +, /, or =, and mixes at least two of uppercase letters, lowercase letters, and digits. When the guard triggers, it preserves the first four trimmed characters and emits …<redacted N chars>, using a single Unicode ellipsis and the full trimmed character count. Ordinary messages, unguarded values, labels, and byte previews do not pass through this guard and may expose sample-derived data in either format. Review debug logs before sharing them.
This does not change scanner output: scan and frisk report full matched values by default. Pass --redact to replace detected secrets with stable truncated SHA-256 tokens in shareable output. The same setting can be stored as output.redact = true in .disrobe.toml.
Metadata sidecar flags
The metadata bundle flags are also global. They are accepted everywhere, but only the commands listed in which commands write a bundle act on them; every other subcommand ignores them, and disrobe auto rejects them with DR-CLI-0843. See metadata sidecar and provenance for the complete pack/category model. Summary:
| Flag | Effect |
|---|---|
--llm | Compatibility alias for --metadata-pack-4 (full bundle, auth-gated categories included). |
--metadata-pack-1 | Pack-1: ast + disasm + symbols + strings. |
--metadata-pack-2 | Pack-2: pack-1 + cfg + types + imports + provenance. |
--metadata-pack-3 | Pack-3: pack-2 + dfg + signatures + constants + roundtrip + sourcemap + manifest. |
--metadata-pack-4 | Pack-4: pack-3 + confidence + opcode-coverage + pii-map + decryption-keys. Only decryption-keys needs --i-have-authorization. |
--ast, --disasm, --cfg, --dfg | Add individual AST / disassembly / CFG / DFG categories. |
--symbols, --strings, --types, --imports | Add symbols / strings / recovered-types / imports categories. |
--constants, --signatures, --provenance | Add constants / function-signatures / provenance categories. |
--roundtrip-verdict, --source-map, --manifest-cat | Add roundtrip-verdict / source-map / manifest categories. |
--confidence, --opcode-coverage, --pii-map | Add confidence-scores / opcode-coverage / pii-map categories. |
--decryption-keys | Add decryption-keys category (requires --i-have-authorization). |
--metadata-include <cats> / --metadata-exclude <cats> | Toggle comma-separated categories after applying a pack preset. |
--metadata-out <PATH> | Override the bundle output path (default: <stem>.disrobe.llm.json next to the primary output). |
--metadata-format <json|jsonl|cbor|msgpack> | Bundle serialization format (default json). |
--llm-briefs | Also emit AGENTS.md and SKILL.md reconstruction briefs next to the bundle. |
--i-have-authorization | Unlocks auth-gated metadata categories and recovery paths that expose this gate. |
The authorization gate
--i-have-authorization is the explicit assertion used by legally sensitive paths that expose an authorization gate. The decryption-keys metadata category refuses without it (DR-CLI-0420); language-specific commercial-protector paths document their own gate behavior. Passing the flag is your assertion that you are authorized to analyze the input under the statutory framing in Legal.
Command reference
disrobe <command> --help is authoritative for the binary you are running; the surface changes with optional build features. This page maps the public command surface: how commands are shaped, the command groups and integrations, then every command by ecosystem. Output paths and --emit support are command-specific; the global flags page covers the options parsed at the top level.
Recovery support varies by format, version and backend. The language guides list supported variants and limitations; chain reports identify unsupported constructs in your input.
Command shape
Ecosystem command families nest an action:
disrobe <pass> <action> <input> [--out <path>] [flags]
Other operations take their arguments directly, for example auto, scan, query, taint, extract, webview and report. Unambiguous prefixes resolve: disrobe dec ... works when only one subcommand starts with dec.
disrobe --help # every subcommand
disrobe <pass> --help # actions and flags for one pass, e.g. `disrobe py --help`
disrobe passes # direct recovery families plus auto-chain pass IDs
disrobe catalog [ecosystem] # supported families and recovery tiers
disrobe explain DR-CLI-0030 # look up any error code
The standard recovery loop:
disrobe auto input.bin --out recovered/ --capture-stages
disrobe context --out recovered/
Output formats
The CLI accepts these global output flags. A command can reject a format that does not fit its output contract:
| Flag | Output |
|---|---|
| (default) | Human-readable text |
--json | A single structured JSON document |
--ndjson | Newline-delimited JSON (streaming) |
--sarif | SARIF 2.1.0, for GitHub code scanning and other SARIF consumers |
disrobe scan firmware.bin --sarif > findings.sarif
detect also supports JSON, NDJSON and SARIF. Its structured output includes each matching detector, confidence score and signature markers. SARIF records use note severity and identify the input file; a format detection alone does not establish a vulnerability.
Command groups
| Group | Root commands | Detailed guide |
|---|---|---|
| Automatic recovery and provenance | auto, chain, context, status, report, diff, guard | chain, reading a result, reports |
| Static triage and reporting | scan, ioc, indicators, frisk, strings, behavior, identify, detect, catalog, capabilities, taint, vulnmatch | catalog, Frisk, forensics safety |
| Containers and webview assets | extract, webview | containers, webview |
| Python and packaging | py, pyarmor, pyinstaller, pyfreeze (experimental), nuitka | Python |
| JavaScript and WebAssembly | js, wasm | JavaScript, WebAssembly |
| Native analysis and recovery | native, macho, go, swift, as3, semdiff | native, decompile, unpack, Go, Swift, AS3 |
| JVM, .NET, and mobile | jvm, apk, dotnet, hermes, flutter, mobile | JVM and Android, .NET, mobile |
| Script and bytecode languages | lua, php, shell, ruby, beam, pickle | Lua, PHP, shell, Ruby, BEAM, pickle |
| Structured artifacts and query | envelope, verify, query, yara, annot, rename | envelopes, query |
| Project tooling and service | serve, plugin, init, config, passes, doctor, install, install-deps, self-update, completions, man, explain, bug-report | service, config, plugins, LLM sidecar |
| Public collection | prowl | forensics safety |
Public integrations
| Integration | Entry point | Detailed guide |
|---|---|---|
| Rust library | core types and the pass registry | Library APIs |
| Python bindings | import disrobe | Python bindings |
| MCP over stdio | disrobe-mcp or disrobe serve --mcp | MCP |
| HTTP, gRPC, and LSP | disrobe serve | service |
| GitHub Action | action.yml | GitHub Action |
| Editor plugins | VS Code, IDA, Ghidra, Binary Ninja | editor plugins |
| Browser playground | browser UI and compiled Wasm worker | playground |
| pre-commit hook | hook ID disrobe | pre-commit |
| LLM sidecar | disrobe init --ide | LLM sidecar |
Nested commands are listed by ecosystem below. For measurements and their limits, start with the evidence index.
Python
| Command | Purpose |
|---|---|
disrobe py decompile <pyc> | Decompile a .pyc to source. --backend native (the only supported value). --no-roundtrip skips the recompile-equivalence check. |
disrobe py disasm <pyc> | Per-instruction disassembly (3.8-3.15 + PyPy/MicroPython/Jython/IronPython/Brython). |
disrobe py deob <src> | Peel a source obfuscator. --cleanup runs a ruff-AST fold. |
disrobe py extract <archive> | Extract a wheel / sdist / egg / .whl / .zip / any archive. |
disrobe py sourcedefender <pye> | Decrypt a SourceDefender .pye envelope. |
disrobe pyarmor unpack <py> | Unpack PyArmor v6-v9-pro. --allow-dynamic permits the dynamic-hook fallback (trusted/sandboxed samples only). --dynamic-timeout <SECS>. --mode auto|standard|super. --target <PYVER>. --allow-bcc. --strict. --no-cextract / --cextract-only. --all-emits writes stubs for all 12 emit kinds. --cache <DIR>. |
disrobe pyinstaller extract <exe> | Extract a PyInstaller build (2.x-6.20+, AES decrypt). |
disrobe pyinstaller detect <exe> | Report cookie / Python version / TOC offsets without extracting. |
disrobe pyfreeze extract <exe> | Extract cx_Freeze / py2exe / shiv / pex / PyOxidizer (experimental, unvalidated) / Briefcase. |
disrobe pyfreeze detect <exe> | Identify the freezer without extracting. |
disrobe nuitka detect|extract|symbols|decompile|const <input> | Nuitka flavor detect, --onefile extract, symbol scan, constants decompile, single .const decode. |
JavaScript / WebAssembly
| Command | Purpose |
|---|---|
disrobe js deob <js> | Deobfuscate (obfuscator.io, JS-Confuser, Jscrambler, esoteric encoders). |
disrobe js unbundle <js> | Split a bundle into per-module sources; the unbundler routes 11 catalogued bundler families. |
disrobe js v8 <blob> | Inspect V8 .jsc / Node SEA / nexe / nw.js / Electron .asar. |
disrobe webview <binary> | Statically recover Electron ASAR or embedded Tauri/Wails HTML, JavaScript, CSS, and assets to --out <DIR>. The standard CLI also routes supported Electron and Tauri inputs through webview.carve in auto; Wails uses go.classify. See Webview desktop frontends. |
disrobe wasm decompile <wasm> | Lift to --target json|rust|ts|wat|c. |
disrobe wasm deob <wasm> | Reverse Wasm obfuscator families. |
disrobe wasm component <wasm> | Parse a Component Model envelope. |
disrobe wasm types <wasm> | Recover the GC type graph. |
disrobe wasm lift-gc <wasm> | Lift the recovered GC type graph to typed Rust + TypeScript struct / array source. |
JVM / Android / .NET
| Command | Purpose |
|---|---|
disrobe jvm decompile <class|jar|dex|apk> | Run the in-house classfile, jar, DEX, or APK recovery path, and an installed external decompiler only when --backend cfr|vineflower|procyon|jd|krakatau|jadx|dex2-jar names it. Every input emits in-house source by default. A named backend that is missing or does not fit the input format fails. For a standalone DEX, --format ghidra|ida|json also writes its class, method, and field identifiers through the shared symbol exporter. The script formats find each original owner, member name, and descriptor in the loaded DEX database before applying the replacement name. IDAPython class renames require IDA 9.4 or later; method and field renames use older DEX record APIs. |
disrobe jvm dex2-jar <dex> | Translate a standalone DEX to deterministic .class files and classes.jar with Disrobe's in-house translator. This command does not invoke d2j-dex2jar; disrobe jvm decompile <dex> --backend dex2-jar remains the separate external-backend route. |
disrobe jvm extract <jar|apk> | Extract container + dump classfile inventory. |
disrobe jvm backends | Report JVM/Android backends on PATH. |
disrobe jvm retrace | Retrace an obfuscated stack frame back to class/method/line through a ProGuard/R8 mapping.txt (--mapping, --class, --method, --line). |
disrobe jvm jni <class|jar|dex|apk|aab|aar|apks|oat> | Link declared native methods across the DEX/classfile <-> .so/.dll/.dylib JNI boundary: static Java_ symbol matching, RegisterNatives triple recovery, and C prototype emission. --native <LIB> supplies a native library, or a split .apk/.apks, for a bare class/jar/dex/oat (repeatable); a self-contained apk/aab/aar/apks carries its own. An .aar scans jni/<abi>/*.so and its nested classes.jar. A raw .oat file locates its single embedded dex through the OAT header; a multi-dex .oat is refused rather than guessed. --json for machine output. |
disrobe apk <apk> | Decode the binary AndroidManifest.xml, map resource ids to names, dump each signer certificate's SHA-256, and link the embedded DEX against its embedded native libraries (the same JNI surface jvm jni prints). --out <DIR> writes the decoded manifest and resource table to disk. |
disrobe dotnet decompile <dll|exe> | Run the in-house CIL decompiler, and an installed external decompiler only when --backend ilspy|dnspy|dnspy-ex|de4dot names it. A named backend that is not installed fails. --language csharp|fsharp|vbnet selects the in-house surface language. |
disrobe dotnet deobfuscate|peel <dll|exe> | Detect the .NET protector and peel it: decrypt resources, recover constants/strings, classify renamable identifiers, strip watermarks. --protector <name> forces one. |
disrobe dotnet analyze <dll> | PE/CLR metadata, protector detection, R2R + NativeAOT probe. |
disrobe dotnet native-aot <image> | Recover NativeAOT names, types, method boundaries and managed signatures. Takes a PE, ELF or Mach-O image, not a managed assembly. |
disrobe dotnet backends | Report .NET backends on PATH. |
Native
| Command | Purpose |
|---|---|
disrobe native decompile <bin> | In-tree x86-64 -> C/Rust decompile and AArch64, ARM32 and MIPS32 -> pseudo-C decompile, default (--backend native --format c|rust). The manifest names the architecture it routed to in its architecture field. Only AArch64 has a whole-program engine and an image-leaf engine; ARM32 and MIPS32 recover each function through the p-code lift alone, so their functions_whole_program and functions_image_leaf counts stay zero. AArch64 whole-program call resolution is limited to linked ELF inputs; relocatable objects fail before output on every p-code architecture. --format rust and the types.json sidecar are x86-64 only. C output is graded against real gcc/clang and x86-64 Rust output against rustc. On the AArch64 path a symbolic devirtualizer folds proven-dead conditional arms before structuring (on by default; --no-devirt disables it). --backend ghidra drives ghidra-headless instead: --emit source,disasm,ast,cfg,ir,manifest,sourcemap,symbols,strings,imports,signatures,report. Every function recovered through the p-code lifter carries a decode object in the JSON result, and the run as a whole carries the same shape as decode_coverage. Both give decoded_instructions, the machine instructions the decoder split the code into; modelled_instructions, how many of those the lifter gave semantics to; unmodelled_instructions, the remainder; matched_instructions with matched_percent, counting every instruction the decoder recognised, which is the sum of the supported, callother and unsupported statuses; semantic_percent, the share that is supported alone; instructions_emitting_callother with its percent, counting instructions whose lifted body contains a callother operation, which is a different measure from the callother status and can differ from it in both directions; by_status, one entry per decode status with an instruction count and a percent of decoded, always listing all seven statuses so one that never occurs reads as zero rather than being absent; and unlifted_mnemonics, a map from mnemonic to occurrence count. matched_percent and semantic_percent do not sum to one hundred, and counts_note restates why in the output itself. A high matched figure beside a low semantic figure means the decoder recognised the instructions but the recovered source describes less of the function than its length suggests. The whole-run block adds lowest_covered_functions, the functions whose semantic share falls below the whole-run figure, worst first and tied names in alphabetical order, capped at ten with lowest_covered_functions_omitted counting any the cap dropped, so a high whole-binary figure cannot hide one badly covered function. Every percent is a string carrying exactly two fractional digits, so the human and JSON output agree digit for digit and no float printer can reformat them. |
disrobe native symbols <bin> | Dump symbols, sections, segments, imports, and debug info. |
disrobe native identify <bin> | Fingerprint compiler / packer / protector / installer, each routed to its pass. |
disrobe native unpack [bin] | Detect + unpack the 12 Implemented-tier families (Donut, sRDI, UPX, ASPack, Petite, MPRESS, FSG, PECompact, Yoda's Crypter, NSPack, MEW, kkrunchy) via in-house decoders + x86 stub emulator. Input is optional; --list shows all supported packers (the full detect catalog is 27 packers and protectors; Yoda's Protector needs the original image for a diff-based carve, and the commercial protector tier is reported without static recovery). When the image matches a known layering, such as UPX repacked inside ASPack, the command says so before it unpacks, names the layers in order with the confidence of the match, and prints why that combination is used. The notice appears even when the unpack itself cannot finish, which is the case where knowing the image is double-packed matters most. After a successful unpack it names the layers still present, because one pass removes one layer; run the command again on the recovered image to take the next one. |
disrobe native devirt <bin> | Devirtualize the bytecode-VM tier: recover the handler table, lift to a re-executable IR + pseudo-code. |
disrobe native export <bin> | Unpack, recover symbols, and export a backend-ready bundle: a rebuilt loadable PE + a Ghidra post-script / IDAPython / JSON symbol map. --format ghidra|ida|json (default ghidra). |
disrobe native disasm <bin> | Per-function listing / --emit cfg-dot CFG / --emit json / --raw linear sweep (--syntax nasm|intel|att|masm). Accepts a .dr envelope. |
disrobe native callgraph <bin> | Whole-program call graph as Graphviz DOT. |
disrobe native patch <bin> | Rewrite bytes at a VA (or nop a span) and revalidate the image. |
disrobe native sigmaker <bin> | Wildcarded byte signature from a function, uniqueness-tested. |
disrobe native diff <a> <b> | Match functions across two builds by content and CFG fingerprint. Native images only; for other languages use disrobe semdiff. Text output lists at most 25 added, removed, and changed rows by default. --limit <N> sets that shared listing limit for text, JSON, NDJSON, and SARIF; --limit 0 preserves the exact totals while withholding every row. Machine output remains complete when --limit is omitted. The listing object records the effective limit plus the exact shown and withheld counts. |
disrobe native match <a> <b> | Name the counterpart of every function across two stripped binaries: anchor on shared data references, then on a control-flow fingerprint, then propagate along the call graph. Each pair carries the stage and the evidence that produced it, and a refusal is reported with its candidates. --out <FILE>, or -o, writes the report as JSON. --limit <N> bounds the text listing, 25 by default, and also bounds the report when you give it; --limit 0 prints the counts and withholds every row. --stage data-reference|control-flow|propagation|refused selects one stage; without it the listing shows every matched row from A and the ambiguous rows from B, and the report keeps every verdict. --function <ADDRESS> prints one function's correspondences from both sides with their full evidence; it accepts decimal or 0x hex, cannot be combined with --stage, ignores --limit, and fails with DR-NATIVE-0208 when neither input carries that address. Every report row names the side it came from, and the listing block records the selection in force with the number of rows shown and withheld. This command is reachable only as a subcommand and is deliberately absent from disrobe auto: it answers a pairwise question about two inputs, while auto drives a chain over one sample, so there is no input for a second binary to arrive through. Use disrobe semdiff when the two builds are of the same program and you want correspondence by what each function computes. |
disrobe native entropy <bin> | 4KB sliding-window Shannon entropy; ASCII heat-strip + byte histogram + packed-region runs. --format text|json|svg (default text), --svg <out> for a dark-theme entropy map with section overlays. |
disrobe native signatures <bin> | Crypto-constant fingerprints (AES, SHA, ChaCha20). --flirt <sig> to match a FLIRT DB. |
disrobe native fingerprint <bin> | Aggregate crypto-constant + FLIRT + string-xref sidecar at .disrobe/fingerprints/<stem>.json. --flirt <sig>. |
disrobe native sbom <bin> | Emit a CycloneDX 1.5 SBOM from embedded cargo-auditable metadata. Pass --format spdx --timestamp YYYY-MM-DDTHH:MM:SSZ for SPDX 2.3 JSON. Both formats use the same component discovery result. SPDX output records the application and Cargo packages, their checksums and package URLs, and CONTAINS relationships. Unknown supplier and licence fields are omitted. |
disrobe native graph <bin> | Import/export table as Graphviz DOT. |
disrobe native pdb <pdb> | Read build provenance out of a Windows PDB: DBI stream version, GUID and age, and for every module the compiler records the linker wrote, with language, target machine, frontend and backend version, and the security-check, hot-patch and profile-guided optimization flags. Also lists the tool path, working directory, source path, command line, object path and environment strings each module recorded, keeping the raw bytes beside the text so a non-UTF-8 value is still readable. Writes <out>/<stem>.pdb.json. |
disrobe query <bin|.dr> <q...> | Queryable IR: functions, calls-to <sym>, xrefs-to <sym>, string-decoders, complexity-over <n>, capability <network|crypto|filesystem|process>. Accepts a raw binary or a Disasm- or Mir-rung .dr envelope. |
disrobe capabilities <bin|.dr> | Rule engine over the IR, mapping behaviors to MITRE ATT&CK + MBC with per-match evidence. |
disrobe taint <input> | Track a value from source calls to sink calls across the normalized IR (native / wasm / JVM / Dalvik / CIL / ABC / Ruby / Lua / BEAM / .pyc / .dr). --source <SYM> / --sink <SYM> override the built-in source/sink sets (repeatable). With --cfg, --dfg or a pack that names them it also writes the control-flow and data-flow metadata categories; see metadata sidecar. |
disrobe semdiff <base> <other> | Pair the functions of two builds by what they compute, not by name. Lifts both inputs to the normalized IR, matches leaf functions on an exact structural signature, then on a symbolic summary, then propagates along the call graph. Reports each pair with the tier that produced it and each refusal with a typed reason: no-candidate, ambiguous, round-budget-exhausted, function-count-cap-exceeded, duplicate-address, source-language-mismatch. Accepts every input the lifters accept (native / wasm / JVM / Dalvik / CIL / ABC / Ruby / Lua / BEAM / .pyc / .dr), which is the difference from native diff and native match: those read native images only. Inputs that lift to different source languages are refused per function with source-language-mismatch. Every native image lifts under one source language whatever its architecture, so that per-function guard cannot separate them; two native images of different machine architectures are instead refused up front with DR-CLI-0874. Pass --lineage with two or more OTHER builds to track each base function across all of them at once: the report groups correspondences into families, one per base function, each carrying a verdict for every variant, and says how many families are present in every variant. Without --lineage exactly one OTHER is allowed and a second is refused with DR-CLI-0872 rather than ignored; --lineage accepts at most 32 variants and refuses more with DR-CLI-0873 rather than dropping any. --limit <N> bounds the rows listed per section, 40 by default; totals stay exact. Inputs over 256 MiB are refused with DR-CLI-0871. |
disrobe vulnmatch <input> | Match reachability-aware vulnerability rules against a PE, ELF, Mach-O, COFF, or Disasm/Mir-rung .dr envelope while preserving reachable, reachability-unknown, present, and confirmed states. Pass --openvex --author <IDENTITY> --timestamp YYYY-MM-DDTHH:MM:SSZ to emit OpenVEX 0.2.0 JSON. Reachable and confirmed findings map to affected; a proven unreachable finding maps to not_affected; all unresolved states map to under_investigation. The command never emits fixed because static reachability analysis does not prove remediation. |
Other languages
| Command | Purpose |
|---|---|
disrobe go recover|info <bin> | Go symbol recovery / build fingerprint. |
disrobe lua decompile|deobfuscate|detect <chunk> | Lua decompile / obfuscator peel / dialect detect. |
disrobe php decode|deobfuscate|extract <input> | Encoder decode / eval-chain peel / Phar extract. |
disrobe shell deob|detect <input> | PowerShell / Bash / Batch / VBA deobfuscate (Invoke-Obfuscation, Invoke-Stealth, Bashfuscator, ...) and dialect / family detect. |
disrobe ruby decompile|detect <input> | Ruby artifact analysis / flavor detection. |
disrobe beam parse|lift|disasm <beam> | BEAM chunk parse / Core Erlang lift / Code disasm. |
disrobe pickle disasm|decompile|safety|trace|polyglot|ml-detect <input> | Pickle static analysis suite. |
disrobe swift classdump|shield-undo|xor-decrypt <input> | Swift/ObjC class-dump, SwiftShield mapping parser, explicit-key XOR blob decode. |
disrobe macho dump|classdump|fat <input> | Mach-O dump including .ipa; raw thin/fat Mach-O class-dump and slice inspection. |
disrobe as3 disasm|tags <swf> | AS3 DoABC disasm / SWF tag list. |
disrobe hermes decompile|disasm|info <bundle> | Hermes JS-surface lift / disasm / header. |
disrobe flutter dump|decompile|kernel|disasm|map|inventory|inventory-standalone <input> | Flutter Dart AOT + kernel inspection. flutter dump --format ghidra|ida|json emits recovered function names through the shared symbol exporter. --engine-symbol-map <path> adds externally supplied engine names only after the map's GNU build ID and bounded addresses match the ELF input. inventory and inventory-standalone recover the full library/class/method/field declaration graph on a pinned Dart snapshot version. |
disrobe mobile detect|extract|hermes|flutter|recon <input> | Mobile runtime pipeline. |
Chain, envelope, and forensics
| Command | Purpose |
|---|---|
disrobe extract <input> | Carve and extract a container or firmware image: detect every known format at any offset, recurse into nested archives, split unknown and padding regions, and report per-chunk entropy. --out <dir> names the directory for carved members, --recursive re-scans every extracted file up to --max-depth, and --luks1-raw-volume-key-file opens LUKS1 volumes. |
disrobe detect <input> | Run every obfuscator/packer catalog detector against a file and report each hit (pass, obfuscator, confidence, markers). |
disrobe identify <input> | Fingerprint the compiler / linker / packer / protector / installer of a PE / ELF / Mach-O with structural evidence and the pass that handles each (top-level shortcut for native identify; alias die). --coverage adds a byte-accounting map of the file. |
disrobe identify <input> --coverage | Account for every byte of a PE / ELF / Mach-O against the structures its format declares. Reports claimed_bytes (bytes a declared structure covers), slack_bytes (alignment padding between structures), unclaimed_bytes (bytes no structure covers, which is where an appended overlay shows up), truncated_bytes (bytes a structure declares past the end of the file), and coverage_ratio, which is claimed_bytes over the file length. complete is false when any byte is unclaimed or missing. The regions list tiles the whole file, so the region lengths sum to the file length. overlaps names each pair of structures that claim the same bytes. unbacked names a structure that declares a size the file does not store, and truncated names one whose declared end is past the end of the file. |
disrobe catalog [ecosystem] | List the supported obfuscator, packer, protector, freezer, and bundler registry by ecosystem. The default full build's live binary reports 169 families across 15 ecosystems. Builds that include the chain feature report the registry compiled into that binary. Filter with python, js, jvm, dotnet, native, go, wasm, ruby, lua, php, beam, as3, mobile, swift, or shell. --json emits { family_count, ecosystem_count, ecosystems[] }. |
disrobe auto <input> | Auto-detect + chain. --max-depth <N> (default 8), --capture-stages, --emit recovery, --dry-run, --redact, --timings. A run writes chain.json, recovery.json, anti-analysis.json, and report.json, the citable forensic summary that disrobe report <out-dir> renders; none of them records a duration, the worker count, or a clock. --timings also writes run.json with the start and end clocks, the worker count, and each node's duration. For a standalone DEX root, --format ghidra|ida|json adds exports/dalvik/symbols.ghidra.java, symbols.ida.py, or symbols.json without counting that presentation file as a recovered chain artifact. The request fails if the successful Dalvik node belongs to a nested container instead of the original input. --dry-run creates no export. --redact scrubs detected secrets from machine output and report files without changing recovered artifacts. A directory input is batch-processed recursively (--include <GLOB>, --exclude <GLOB>, --batch-max-depth <N>, --jobs <N>) into an aggregate manifest.json, and each per-file out directory holds its own report.json. |
disrobe chain <input> | Explicit pipeline. --chain 'auto:8' or 'pyarmor.unpack,py.decompile', with --capture-stages and --timings available. --chain-pin <pass-prefix> requires --chain auto[:N] and runs that prefix before automatic selection; it does not pin package versions. |
disrobe diff <left> <right> | Structurally diff two chain.json documents (passes, stage BLAKE3 hashes, sizes, verdicts). |
disrobe guard verify <subject> --reference <ref> | Verify a subject chain.json's per-stage output hashes against a committed reference. |
disrobe guard check <path> [--root <subtree>...] | Deny writes to ground-truth stage paths (out/**/stages, out/**/final, .disrobe-stage-lock). --root adds extra protected subtrees (repeatable). |
disrobe envelope create|inspect|verify|diff|migrate-check <dr> | .dr envelope operations; migrate-check takes source and target envelopes. |
disrobe verify <dr> | Alias for disrobe envelope verify. |
disrobe scan <path> | Scan one file for secret values. --redact replaces detected values in text, JSON, NDJSON, and SARIF output. Raw values remain the default. |
disrobe frisk <path> [--format text|json|sarif] | Scan files, directories, APKs, and recovered source for secrets, endpoints, buckets, manifest exposure, and IOCs. Rule packs use --pattern <FILE>, suppressions use --suppress <SUBSTR>, and baselines use --emit-baseline / --baseline <FILE>. --redact replaces detected secret values after suppression and baseline filtering. |
disrobe report <target> | Render text, JSON, Markdown, HTML, or SARIF from a chain or batch result. --redact scrubs detected secrets throughout the rendered document. |
disrobe prowl [target...] | Harvest URLs and IOCs from public archives and threat-intel feeds. Inputs can come from arguments, --targets-file, --stdin, or --recon-input. Sources are wayback, commoncrawl, otx, urlscan, crtsh, urlhaus, threatfox, and virustotal (vt alias). Filters include --subs, --blacklist, --from, --to, --mc, --fc, --mt, --ft, --ioc, --fp, and --no-iocs. Network controls include --proxy, --timeout, --concurrency, --per-host-rps, --max-pages, --max-urls, --max-iocs, and --retries. Keys resolve from --api-key provider=key, provider env vars, a permissions-checked TOML file, or disrobe prowl keyring set|get|rm|list <provider>. |
disrobe ioc <path> [--format text|json|sarif] [--defang] | Extract indicators of compromise (URLs, IPs, domains, emails, paths, registry keys, wallets, crypto constants); decodes one base64/hex layer. |
disrobe indicators <json...> [--targets-only] [--format text|json] | Merge frisk, ioc, and prowl JSON artifacts into disrobe.indicators/v0, deduplicate by class and value, retain source provenance, or print only network targets for prowl --targets-file. |
disrobe strings <path> [--min-len N] [--no-decode] | Cross-format string extraction: ASCII + UTF-16LE, with single-byte XOR / base64 / ROT-n / stack-string deobfuscation. |
disrobe behavior <path> | Behavior / capability summary across 7 categories, tagged with MITRE ATT&CK technique ids. --effects adds a per-effect instruction census. |
disrobe hermes disasm <input> --function <index-or-name> | Print the instructions of one function by its zero-based index or exact name, decoded through the opcode table for the bundle's own bytecode version. Add --json for the same instruction list as a structured document. Duplicate names require an index. Without --function, the command keeps writing the whole-bundle summary document. An index past the end is refused with the number of functions the bundle declares. |
disrobe behavior <path> --effects | Lift the input to the intermediate representation and report, for each hard effect, how many instructions carry it. Covers memory reads and writes, stack and register and flag writes, syscalls, import calls, indirect calls and jumps, returns, exception raise and catch, atomic read-modify-write, fences, and privileged instructions. Each count is paired with the evidence that assigned it: encoding when the instruction itself says so, resolved-import or resolved-syscall when a resolved target says so, and unknown when nothing did. instructions and functions give the denominators, effect_free counts instructions with no hard effect, and unmodelled counts instructions the effect model does not cover, so a low unmodelled is what makes the other counts meaningful. Accepts any input the intermediate representation accepts, which today is WebAssembly, JVM class files, Dalvik, .NET, ActionScript, Ruby, Lua, BEAM and Python bytecode. An input that does not lift is refused with an error rather than reported as having no effects. |
disrobe yara parse <path> | Parse a YARA ruleset into a typed AST (read-only, no matching). |
disrobe yara generate <input> [--name N] [--sha256 H] [--date D] | Generate a candidate YARA rule from an artifact; output round-trips through the parser. |
disrobe status | Summarize ./out/: per-stage counts, sizes, manifests. |
disrobe context --out <dir> | Summarize a recovery report (status, confidence, verdict, provenance), and the run's run.json timings when the directory holds one. |
disrobe context --out <dir> --fail-on <threshold> | Grade the worst chain verdict under the directory and exit non-zero when it reaches never, incomplete, failed or any. |
disrobe report <dir-or-input> [--format text|json|markdown|html|sarif] | Consolidate a completed run (or raw input) into a forensic summary: identity, topology, per-stage verdicts/scores, artifact inventory, the layers that stopped short with the input each one lacks, a cited byte range and blake3 digest for every artifact, and the steps to re-check them. --format html emits a self-contained, offline, dark-theme report (inline SVG bars, IOC + ATT&CK tables, XSS-escaped). --format sarif emits the same content as a SARIF 2.1.0 log that validates against the published schema: run.artifacts carries each digest, every result region cites a start offset plus a length in the artifact it indexes, and run.properties carries the disrobe document, a STIX 2.1 bundle when SOURCE_DATE_EPOCH is set, MAEC 5.0 behavior objects, the capability report, and the aggregated indicators. Every format, sarif included, is byte-identical across runs over one target: the render carries no clock unless SOURCE_DATE_EPOCH is set, and then every timestamp holds that date. |
Workspace and meta
| Command | Purpose |
|---|---|
disrobe init [--ide <flavor>] [--force] | Scaffold a .disrobe/ workspace and optional editor settings. It refuses, naming the files and writing nothing, when any file it would write already exists; --force overwrites them. Always: .disrobe/AGENTS.md, .disrobe/manifest.json. --ide claude adds .claude/settings.json, .claude/commands/disrobe-{verify,status,rename,diff}.md, .disrobe/skills/<pack>/SKILL.md for verify-decompilation, recover-symbol-names, reconstruct-imports, confidence-audit, escalate-to-dynamic, diff-against-pypi and patch-and-roundtrip, and .cursorrules, .windsurfrules and CLAUDE.md linked to .disrobe/AGENTS.md. --ide cursor, windsurf and aider add .cursorrules, .windsurfrules or .aider.conf.yml. |
disrobe config [show] | Print the resolved .disrobe.toml config (honors --json). See project configuration. |
disrobe config init [--out <path>] [--force] | Write a documented .disrobe.toml template. |
disrobe annot refresh|regenerate | Rebuild a symbol annotation file. |
disrobe rename <old> <new> [--note] | Record an append-only rename. |
disrobe passes | Print direct recovery-family summaries followed by the pass IDs reachable from disrobe auto in this build. |
disrobe plugin run <component> --trusted-key <pubkey> --out <file> [--input <file>] [--fuel N] [--wall-deadline-ms MS] [--memory-cap-bytes N] [--format text|json] | Verify and run a signed WebAssembly component plugin under the disrobe-plugin-host sandbox (fuel, wall-clock, and memory caps; deny-all imports). Reads input from stdin when --input is omitted. CLI-only: a plugin names an explicit local path an operator supplies, not a chain pass reachable from disrobe auto. |
disrobe plugin verify <component> --trusted-key <pubkey> [--format text|json] | Verify a signed WebAssembly component plugin's signature and capability manifest without running it. |
disrobe plugin list <dir> [--trusted-key <pubkey>] [--format text|json] | List plugin bundles (a <name>.wasm component beside its <name>.wasm.minisig signature and <name>.toml manifest) in a directory; verifies each bundle when --trusted-key is given. |
disrobe explain <code> | Look up a DR-* error code and print its description and common fixes. |
disrobe doctor [--auto-install] [-y] | Probe 46 to 51 optional external tools depending on the platform; report installed, missing, or stale. --auto-install installs every missing tool with a known install action and records every other missing tool as a skip with a typed reason (commercial-or-license-gated, ships-with-another-tool, platform-exclusive, preinstalled-by-the-operating-system, no-manager-models-its-install-path, or no-package-on-any-manager), in both text and --json output. |
disrobe install <tool> [--list] [-y] [--dry-run] | Install one optional tool via the native package manager. |
disrobe install-deps [<dep>] [--all] [--dry-run] | Install heavyweight deps (Ghidra) from upstream releases. |
disrobe serve [--bind <ADDR>] [--stdio|--mcp|--grpc] | Run the daemon. See the daemon. |
disrobe completions <shell> [--install] [--rc-file <PATH>] | Generate shell completions (bash, zsh, fish, PowerShell, elvish). |
disrobe man [--out <dir>] | Generate man pages (one .1 per subcommand). |
disrobe bug-report [--out <PATH|->] | Collect environment, manifests, and tooling versions into a markdown bug report. |
disrobe self-update [--check-only] [--dry-run] | Print update guidance: download the release archive from GitHub Releases (no network by default). |
Run the examples
Watch the chaptered CLI walkthrough and read its command transcript. The recording shows native unpacking, indicator extraction, automatic recovery, Lua, WebAssembly, and recovered source.
The feature capture records twelve commands and their output. It extracts three known indicators with their byte offsets, round-trips two ZIP members, recovers all 73,160 original code bytes from a UPX-packed greeting, decodes an APK manifest, compares a recovered Lua greeting with its baseline, and verifies an envelope before and after a one-byte payload change.
From the repository root, reproduce it with a full CLI build, Python 3.14 and Lua 5.1:
node docs/demo/capture-features.mjs --binary /path/to/disrobe --python /path/to/python --lua /path/to/lua
The Wasm quickstart, Python project example, and service examples cover automatic recovery, project briefs and the MCP, HTTP, gRPC and LSP interfaces. Each record names its inputs and binary so results can be compared across builds.
The public-collection example retrieves four archived example.org URLs from the Common Crawl index. It queries one archive, caps output at ten URLs, and makes no requests to the archived pages.
Project configuration (.disrobe.toml)
disrobe reads an optional .disrobe.toml so a project can set its own defaults instead of repeating the same global flags on every invocation.
Resolution order
Values are merged from three layers, lowest precedence first:
- Built-in defaults: what
disrobedoes with no config and no flags. .disrobe.toml: the discovered or explicitly named config file.- CLI flags: anything you type on the command line.
A flag you actually pass always wins over the config file; a flag you leave off falls back to the config value, and only then to the built-in default. "Did the user pass this flag" is decided by clap's value source, so there is no ambiguity between --json being absent and being false.
Discovery
- With
--config <PATH>, that file is loaded. A missing path is a hard error (DR-CLI-0332). - Without
--config,disrobewalks up from the current working directory looking for.disrobe.toml, exactly the way cargo findsCargo.toml. The first one found wins. If none exists, the built-in defaults are used.
Malformed TOML (DR-CLI-0330) and unknown keys are hard errors: a typo fails fast instead of being silently ignored.
The config command
| Command | Purpose |
|---|---|
disrobe config / disrobe config show | Print the resolved effective config and the file it came from. Honors --json. |
disrobe config init [--out <PATH>] [--force] | Write a fully documented .disrobe.toml template (default ./.disrobe.toml). |
Schema
[output]
dir = "out" # default output directory for chain/auto runs
emit = ["source", "manifest"] # default --emit kinds where a pass accepts them
json = false # default machine-output toggles (CLI flags still override)
ndjson = false
sarif = false
color = "auto" # auto | always | never
progress = "auto" # auto | always | never
verbosity = "warn" # warn | info | debug | trace
quiet = false
[execution]
threads = 8 # worker pool size (default: detected CPU count)
force = false
in_place = false
no_cache = false
cache_dir = "/var/cache/disrobe" # content-addressed .dr envelope cache (default: OS cache dir)
dry_run = false
seed = 42 # RNG seed for non-deterministic backends
max_depth = 8 # default chain depth for `auto`
[backends]
py = "native" # native (in-tree CPython 3.8..3.15 engine; the only supported value)
jvm = "cfr" # cfr | vineflower | procyon | jadx
dotnet = "ilspy" # ilspy | dnspy | dnspyex | de4dot
wasm = "wat" # json | rust | ts | wat | c
lua = "native"
[passes]
enable = ["pyarmor.unpack", "py.decompile"] # restrict chain runs to these passes
disable = ["native.packer-unpack"] # never run these passes
All tables and all keys are optional. An empty file is valid and resolves to the built-in defaults.
Batch directory processing
disrobe auto accepts a directory as well as a single file. Point it at a directory and it walks the tree, runs the auto-chain on every file, writes each file's outputs under out/<relative-stem>/, and emits one aggregate out/manifest.json.
Single-file behavior is unchanged: disrobe auto <file> still writes chain.json + recovery.json into a single out dir.
Usage
disrobe auto ./samples
disrobe auto ./samples --out ./out/triage --include '**/*.pyc' --exclude '*_test.*' --jobs 4
If --out is omitted, batch output lands in ./out/<dir-name>-batch/.
Flags (batch-only)
| Flag | Effect |
|---|---|
--batch-max-depth <N> | Maximum directory recursion depth (default: unlimited). Depth 0 is the directory itself; depth 1 is its immediate children. |
--include <GLOB> | Only process files matching this glob. Repeatable. With no include, all files are in scope. |
--exclude <GLOB> | Skip files matching this glob. Repeatable. Exclude wins over include. |
--jobs <N> | Bounded worker concurrency. Default is 1, kept conservative because chains can be memory-heavy. Raise it on machines with headroom. |
The --max-depth <N> (default 8), --capture-stages, --emit recovery, --timings, and global flags continue to apply. --max-depth is the per-file chain depth; --batch-max-depth is the directory recursion depth.
Glob syntax
Globs match against the slash-normalized path relative to the root.
| Token | Matches |
|---|---|
* | Any run of characters within a single path segment (does not cross /). |
** | Any run including / (spans directories). |
? | Exactly one non-/ character. |
[abc], [a-z], [!0-9] | A character class, with !/^ negation and a-z ranges. |
A bare pattern with no / (for example *.bin) also matches files in subdirectories, so the common "all .bin files" case works without writing **/.
manifest.json
Schema disrobe.batch.manifest/v2:
{
"schema": "disrobe.batch.manifest/v2",
"tool_version": "0.10.5",
"root": "samples",
"out_root": "out/samples-batch",
"chain": "auto:8",
"summary": { "processed": 12, "recovered": 9, "detect_only": 2, "errors": 1 },
"entries": [
{
"input": "samples/app.pyc",
"relative": "app.pyc",
"size": 4096,
"detected_format": "Python",
"chain": ["py.decompile"],
"verdict": "Complete",
"recovery_score": 0.67,
"output_dir": "out/samples-batch/app.pyc",
"error": null
}
]
}
- recovery_score is the mean per-pass confidence-tier rank across the chain, normalized to
[0, 1](skeleton 0, partial 0.33, semantic 0.67, exact 1.0), ornullwhen no pass ran. - A file that fails (unreadable, or its chain errors) is recorded with a non-null
errorand counted undersummary.errors; one bad file never aborts the batch. - Files with no pass in their chain are counted as
detect_only. - The manifest records no duration and no worker count, so
--jobs 1and--jobs 4over one directory write the same bytes.--timingswritesrun.jsonbeside the manifest, with the start and end clocks, the worker count, the whole run's duration, and each file's duration, and arun.jsonin each file's directory with that file's per-node durations.
The human-readable summary line mirrors the manifest: N processed, M recovered, K detect-only, E errors.
Run reports (disrobe report)
disrobe report consolidates a completed run into a single forensic summary: input identity, chain topology, per-stage verdicts and recovery scores, the layers that stopped short, the recovered-artifact inventory, a cited byte range and digest for every artifact the run read, and the steps that re-check each one. It is the read-side companion to auto and chain.
Usage
disrobe report ./out/sample-auto # a completed single-file run
disrobe report ./out/samples-batch # a completed batch run
disrobe report ./malware.bin # raw input: runs auto first, then reports
disrobe report ./out/sample-auto --format markdown
disrobe report ./out/sample-auto --format html > report.html # self-contained, offline
disrobe report ./out/sample-auto --format sarif > report.sarif
--out <DIR> chooses where a derived run is written when the target is a raw input or a raw directory. Without it the derived run lands in ./out/<stem>-auto/ or ./out/<name>-batch/ under the working directory. The flag has no effect when the target is already a completed run.
Target resolution
The single positional argument can be:
| Target | Behavior |
|---|---|
A directory with manifest.json | Read it and render a batch report. |
A directory with chain.json + recovery.json | Read them and render a single-run report. |
| A raw input file | Run auto into ./out/<stem>-auto/ first, then report. |
| A raw directory (not an out dir) | Run a batch into ./out/<dir>-batch/ first, then report. |
A run document that is missing, unreadable, or truncated stops the command with a typed error. Nothing is partly rendered.
| Condition | Code |
|---|---|
| The target path does not exist | DR-CLI-0350 |
chain.json cannot be read | DR-CLI-0351 |
chain.json is not a valid chain document | DR-CLI-0352 |
recovery.json cannot be read | DR-CLI-0353 |
recovery.json is not a valid recovery document | DR-CLI-0354 |
manifest.json cannot be read | DR-CLI-0355 |
manifest.json is not a valid batch manifest | DR-CLI-0356 |
| A raw input file cannot be read | DR-CLI-0358 |
SOURCE_DATE_EPOCH is set but is not a whole number of seconds up to 9999-12-31 | DR-CLI-0318 |
The report a run writes
disrobe auto and disrobe chain write report.json into the output directory, beside chain.json, recovery.json, and anti-analysis.json. It holds the single-run document described below, so a run is citable without a second command. The document auto writes and the document disrobe report <out-dir> --format json prints are the same, except that the command's JSON adds a report_kind discriminator.
A batch run writes an aggregate report.json beside manifest.json; it is the same JSON document that disrobe report <batch-out> --format json prints. Each file also leaves its own single-run report.json in its per-file output directory.
Formats
--format text|json|markdown|html|sarif (default text). A global machine-output flag (--json, --ndjson, or --sarif) forces JSON output. --format sarif overrides that and renders SARIF.
text: an aligned human report for the terminal.markdown: a report with tables, ready to paste into an issue or PR.json: the machine-readabledisrobe.report/v2document. It records no duration, no worker count, and no clock.html: a single self-contained HTML file (printed to stdout; redirect to a.html). CSS is inlined from the shared docs theme token file, with no JavaScript and no external/CDN reference, so it renders offline when double-clicked. Sections include input identity, a chain-topology flow, per-stage verdicts with generated recovery bars, a generated tier histogram, walls and failures, capabilities, recovered artifacts, the evidence table, the reproduction steps, and, when the input is still readable, defanged IOC plus behavior / MITRE ATT&CK tables. Every interpolated value is HTML-escaped, and the renderer uses no clock or randomness, so identical report data produces byte-stable HTML.sarif: a SARIF 2.1.0 log printed to stdout. See SARIF output.
Single-run report contents
- Input identity: path, size, BLAKE3, detected format chain, final format.
- Topology and verdict: linear or tree, and the overall chain verdict.
- Recovery score: the mean per-stage confidence-tier rank normalized to
[0, 1], plus a tier label (skeleton / partial / semantic / exact). - Tier histogram: exact / semantic / partial / skeleton counts.
- Per-stage table: index, pass id, confidence, score.
- Walls: every layer that stopped short, with the input it lacks.
- Capabilities: ATT&CK- and MBC-tagged rule matches with addresses and evidence scope. Text, JSON, markdown, HTML, and SARIF consume the same result.
- Failures: every layer that returned an error, with its message.
- Recovered-artifact inventory: the union of artifact names produced by the stages.
- Evidence: one cited entry per artifact the report read, with its digest and byte range.
- Reproduction: the command that rebuilds the report and the steps that re-check it.
- Notes: detect-only, skeleton-tier, and artifact-walk truncation caveats.
Batch report contents
- The aggregate counts (
processed,recovered,detect-only,errors) and mean recovery score. The mean is null when no file carried a score. - A per-file table: file, detected format, score, and status (recovered / detect-only / error).
A batch report aggregates per-file manifests and holds no analysis-target bytes. Its SARIF render therefore reports the STIX, MAEC, capability, and indicator blocks as unavailable, each with that reason.
Walls and failures
A wall is a layer that stopped because a named input is missing. A wall is not a failure and is never rendered as an error. Each wall records its kind, the node id, the stage index when the layer maps to one, the pass, the input format, the BLAKE3 and size of the artifact it could not advance, and a sentence naming what it lacked.
| Kind | The layer stopped because |
|---|---|
no-pass-accepted | No registered detector claimed the artifact. |
empty-pass-output | A pass accepted the format and returned no output bytes. |
repeated-artifact | The output repeats an artifact already seen on the branch. |
depth-cap-reached | The chain reached its depth cap. |
not-executed | The run was a dry run, so the selected pass was never executed. |
branches-incomplete | At least one branch of a fan-out did not reach a recovered format. |
A layer that returned an error is recorded as a failure instead. A failure carries the node id, the stage index when the layer maps to one, the pass, the recorded message, and the BLAKE3 and size of its input.
When no individual node recorded a wall or a failure, the overall chain verdict still produces one wall against the root node if that verdict is stalled, cycle, cap-reached, dry-run, or fan-out-partial. A run that recovered nothing reports the wall rather than an empty success.
Evidence and digests
Every report cites the artifacts it read. An evidence entry carries a role, an artifact URI, a byte offset, a byte length, a BLAKE3 digest, and where that digest came from.
The roles are analysis-target, stage-input, stage-output, and recovered-artifact.
| Digest source | Meaning |
|---|---|
chain-document | The digest is the one chain.json recorded, for the analysis target or for a stage input or output. |
recomputed-from-file | disrobe report opened the file in the run directory and hashed its bytes. The byte length is the file length. |
unavailable | No digest could be produced. The entry carries an unavailable_reason naming why. |
Only recovered artifacts read off disk carry recomputed-from-file. An artifact a dry run would have written, a file that is not on disk under the run directory, and a file that cannot be opened are each cited with unavailable and a reason rather than dropped from the report.
An artifact on disk is cited by a file:// URI, or by its percent-encoded relative path when the recorded path is relative. An intermediate the chain held in memory is cited as ni:///blake3;<digest>. That names the artifact a byte range indexes; it is not a file you can open.
Every evidence entry starts at byte offset 0 and spans the whole artifact. Sub-ranges inside the analysis target come from the indicator results in the SARIF render.
The recovered-artifact inventory combines the artifact names the stages recorded with the files under extracted/ in the run directory. That walk skips symbolic links, stops at directory depth 32, and stops after 4096 files. Either stop is recorded as a note in the report, naming what is not cited.
Reproduction steps
A single-run report carries the command that rebuilds it and the steps a third party follows to re-check it:
- Hash the analysis target with BLAKE3 and compare it with
input.blake3. - Hash each evidence entry marked
recomputed-from-fileand compare each digest with the recorded one. - Read each
ni:///blake3;evidence entry as the digest of an intermediate the chain held in memory. - Re-run the reported command and compare the output.
- Set
SOURCE_DATE_EPOCHto a Unix timestamp to date the SARIF render and emit its STIX bundle; without it the render carries no clock.
When any entry carries no digest, a further step counts those entries and points at their unavailable_reason.
SARIF output
--format sarif prints a SARIF 2.1.0 log to stdout. Its $schema is the stable OASIS 2.1.0 Errata 01 URI, and the CLI test suite validates the emitted log against the matching schema vendored under crates/disrobe-cli/tests/schemas/.
run.artifacts is the artifact table. Each entry carries its URI, a description, the byte length when the report knows it, its SARIF roles, and a blake3 hash when the report has one. An entry with no digest carries no hash. The roles follow the evidence roles: the analysis target becomes analysisTarget, a recovered artifact becomes resultFile, and a stage input or output becomes unmodified.
Every result location names an artifact URI and its index in run.artifacts. A region cites a byte offset and a byte length. A span whose offset plus length would leave the artifact is dropped rather than cited, so a cited range always reads back inside the artifact it indexes.
Results carry one of these rule ids. A rule is declared in tool.driver.rules only when the run produced at least one result for it.
| Rule id | One result per |
|---|---|
disrobe.stage | Executed chain layer. |
disrobe.wall | Layer that stopped because a named input is missing. |
disrobe.failure | Layer that returned an error. |
disrobe.evidence | Cited artifact. |
disrobe.indicator | Value read out of the analysis target. |
disrobe.behavior | Behavior category matched in the analysis target. |
disrobe.batch-file | File of a batch run. |
Only two results are reported as level: error with kind: fail: a failure, and a batch entry whose manifest recorded an error. A wall is level: none with kind: review, so a layer that stopped short never reaches a code-scanning gate as an error. A behavior is kind: review. An evidence entry whose digest is unavailable is kind: review. Every other evidence entry, every stage, every indicator, and every batch entry that ran is kind: informational.
An indicator result records the offset and length of the value inside the analysis target, and a range_within_target flag. When a recorded offset lies outside the target, the result is kept, the flag is false, and the message says the range lies outside the analysis target.
run.invocations[0].commandLine holds the reproduction command. executionSuccessful is false when a single run recorded a failure, or when a batch manifest recorded an error. endTimeUtc appears only when SOURCE_DATE_EPOCH is set, and then holds that date.
run.properties
| Key | Contents |
|---|---|
generated_at | The value of SOURCE_DATE_EPOCH as an RFC 3339 timestamp. Absent when the variable is unset. |
disrobe | The disrobe.report/v2 document. |
stix | A STIX 2.1 bundle when SOURCE_DATE_EPOCH is set; otherwise available: false with a reason that names the variable. |
maec | A MAEC 5.0 package of behavior objects, or available: false with a reason. |
capabilities | The capability report for the analysis target, or available: false with a reason. |
indicators | The aggregated indicator bundle, or available: false with a reason. |
reproduction | The command and the steps. Single-run reports only. |
standards | The standards this render targets, and the ones it excludes. |
STIX 2.1 requires created, modified, and valid_from on its objects, and a render without SOURCE_DATE_EPOCH carries no clock to put there, so the bundle is emitted only when the variable is set; every STIX date then equals it. The bundle carries an identity object for the tool and a malware-analysis object for the run. Its result field stays unknown, because disrobe performs static recovery and does not classify a sample. Identifiers are derived from the first 16 bytes of BLAKE3 over a stable seed, stamped with the RFC 9562 version 4 and variant bits, so repeated runs over one input produce one identifier.
URL, domain, IPv4, IPv6, email, and registry indicators become STIX indicator objects. Hash, ASN, wallet, path, secret, and other indicators have no STIX pattern object path. They are counted by class in standards.stix.unmapped_indicator_classes and stay in the SARIF results only.
The standards block records SARIF 2.1.0, STIX 2.1, MAEC 5.0, and CycloneDX 1.5, and names OpenIOC 1.1 and CybOX 2.x as excluded with a reason for each.
What the enriched blocks need
The STIX, MAEC, capability, and indicator blocks read the original analysis target. The report opens it at the path chain.json recorded, resolved against the working directory. Capability analysis is limited to 256 MiB and verifies the bytes against the recorded BLAKE3 before attaching results. If the chain document records no path, the sample has moved or changed, the target exceeds the limit, or you run the command from another directory, the affected block reports available: false and names the reason. The rest of the report still renders.
Determinism
Text, JSON, markdown, HTML, and SARIF output is byte-identical across renders of one run, and the documents a run writes are byte-identical at any --jobs value. No document records a duration, the worker count, or the time of the run; auto --timings writes those to run.json instead.
Without SOURCE_DATE_EPOCH the SARIF render holds no timestamp at all: generated_at, endTimeUtc, and the MAEC behavior timestamps are left out, the STIX block reports itself unavailable, and standards.timestamp.source reads none. Set SOURCE_DATE_EPOCH to a Unix timestamp to date the render: every timestamp in the document then holds that value, the STIX bundle is emitted, and standards.timestamp.source reads source-date-epoch. A value that is not a whole number of seconds is refused with DR-CLI-0318 rather than replaced by the clock.
Analysis-depth commands
A set of static-analysis primitives that make disrobe useful as a triage and reverse-engineering tool, not only a decompiler. Each one operates on raw bytes and (where relevant) on the strings/source a chain has already recovered, so they compose with the rest of the pipeline. None of them execute the sample.
| Command | What it does |
|---|---|
disrobe scan | Scan raw bytes for leaked credentials and secrets. |
disrobe identify | Fingerprint compiler, packer, protector, and installer. |
disrobe prowl | Harvest URLs and IOCs from public archives and threat-intel feeds. |
disrobe ioc | Pull indicators of compromise out of an artifact. |
disrobe indicators | Merge frisk, ioc, and prowl JSON into one versioned bundle. |
disrobe strings | Cross-format string extraction with single-byte XOR / base64 / ROT brute-forcing. |
disrobe yara generate | Synthesize a candidate YARA rule from an artifact. |
disrobe behavior | Summarize what a binary does, tagged with MITRE ATT&CK technique IDs. |
Credential scan
disrobe scan firmware.bin
disrobe scan firmware.bin --json
disrobe scan firmware.bin --sarif > findings.sarif
disrobe scan scans the target's raw bytes for leaked credentials: cloud provider keys (AWS, GCP, Azure, GitHub, Stripe, and others), VCS tokens, JWTs, PEM and SSH private keys, and other high-confidence secret patterns.
Unlike disrobe ioc, scan focuses exclusively on secrets that represent an immediate credential exposure rather than general network or host indicators. Output is text (one finding per line) or SARIF 2.1.0.
Format identification
disrobe identify sample.exe
disrobe identify sample.exe --json
disrobe identify fingerprints what built or packed a PE, ELF, or Mach-O binary. It reports the compiler, linker, packer, protector, and installer if detected, with structural evidence and the disrobe pass that handles each detected layer. The output is the same as disrobe native identify but works as a top-level command without routing through the native subcommand tree.
Prowl harvest
disrobe prowl example.com --subs --sources wayback,commoncrawl,urlscan --format json > prowl.json
disrobe prowl --targets-file targets.txt --proxy http://127.0.0.1:8080 --max-urls 50000
disrobe prowl --recon-input frisk.json --ioc domain,ipv4,email
disrobe prowl keyring set virustotal
disrobe prowl is the explicit network recon command. It queries Wayback, Common Crawl, OTX, urlscan, crt.sh, URLhaus, ThreatFox, and VirusTotal. Inputs can be command-line targets, a targets file, stdin, or a prior disrobe recon/IOC JSON report. The output schema is disrobe.prowl/v0 and contains the requested targets, selected sources, URL records, IOC records, and per-provider status.
The source labels are wayback, commoncrawl, otx, urlscan, crtsh, urlhaus, threatfox, and virustotal (vt alias). API keys resolve in this order: --api-key provider=key, provider environment variable (PROWL_<PROVIDER>_API_KEY or the provider's conventional variable), OS keyring, then a permissions-checked TOML config. Required-key providers without a key are skipped with a provider status rather than failing the whole harvest.
Filters are bounded and deterministic: --blacklist drops extensions, --from/--to constrain Wayback dates, --mc/--fc include or exclude HTTP status codes, --mt/--ft include or exclude MIME substrings, --ioc keeps selected IOC classes, --fp collapses URLs that differ only by query values, and --no-iocs suppresses derived IOC extraction. --timeout, --concurrency, --per-host-rps, --max-pages, --max-urls, --max-iocs, and --retries cap network and memory use.
IOC extraction
disrobe ioc suspicious.bin
disrobe ioc suspicious.bin --format json
disrobe ioc suspicious.bin --defang # hxxp://, 1[.]2[.]3[.]4 for safe reporting
disrobe ioc malware.exe --format sarif # GitHub code-scanning ingest
disrobe ioc scans the target's bytes and any UTF-16 / ASCII text inside it for:
- Network: URLs (
http/https/ftp/ftps/smb/file), bare domains, IPv4, IPv6, email addresses. - Host artifacts: Windows file paths, registry keys (
HKLM\...,HKEY_CURRENT_USER\...), Unix paths under well-known roots (/etc,/usr,/var,/Users, ...). - Crypto wallets: Bitcoin (legacy
1/3and bech32bc1), Ethereum (0x...40), Monero (4...). - Crypto constants: AES S-box and inverse S-box, MD5 / SHA-1 / SHA-256 / SHA-512 init vectors, ChaCha20 sigma/tau, and the standard/URL base64 alphabets.
When the input is a native PE/ELF/Mach-O binary, the import table (library!symbol) is folded into the scan so DLL- and symbol-borne indicators surface too.
Encoding recursion
Base64 and hex blobs in the input are decoded and re-scanned one level deep. An indicator found inside a decoded blob is tagged with its encoding (base64 or hex) so you can tell a plaintext URL from one that was hidden behind a layer of encoding. The recursion is intentionally single-level to keep the scan bounded.
Output
- Text (default): one indicator per line,
kind<TAB>encoding<TAB>@offset<TAB>value, followed by a count. - JSON (
--format jsonor the global--json): thedisrobe.ioc/v0document,{ schema, uri, byte_len, total, indicators[] }, each indicator carryingkind,value,offset,encoding, and an optionalcontextwindow. - SARIF (
--format sarifor the global--sarif): SARIF 2.1.0 with one result per indicator and aDR-IOC-<KIND>rule id, for GitHub code scanning.
--defang rewrites URLs, domains, IPs, and emails into a non-clickable form (hxxp://, 1[.]2[.]3[.]4, user@host[.]tld) in every format.
Safety and determinism
Every pattern is bounded (explicit upper repetition counts) so adversarial input cannot trigger catastrophic regex backtracking, and the indicator set is deduplicated and offset-sorted, so the same bytes always produce the same report. The library logic lives in disrobe_core::ioc and is reused by the daemon and by disrobe report.
Indicator aggregation
disrobe indicators frisk.json ioc.json prowl.json --format json > indicators.json
disrobe indicators frisk.json prowl.json --targets-only > targets.txt
disrobe prowl --targets-file targets.txt --format json > expanded-prowl.json
disrobe indicators ingests disrobe.recon/v0, disrobe.ioc/v0, and disrobe.prowl/v0 JSON. It normalizes every URL, domain, IP, email, hash, ASN, path, and registry value into disrobe.indicators/v0, deduplicates by (class, value), and preserves the source list that produced each value.
--targets-only prints bare domains and IPs, one per line, so an offline frisk/IOC pass can seed an explicit prowl --targets-file run.
String extraction
disrobe strings sample.bin
disrobe strings sample.bin --min-len 6
disrobe strings sample.bin --no-decode # plain ASCII / UTF-16 only
disrobe strings sample.bin --json
An in-house FLOSS-style extractor. It pulls printable ASCII and UTF-16LE runs at or above --min-len (default 4), then runs a set of deobfuscation passes and tags each result by how it was recovered:
| Tag | Meaning |
|---|---|
plain / plain:wide | Printable ASCII run / UTF-16LE run. |
xor:0xKK | Recovered by brute-forcing single-byte XOR key KK over a printable run; kept only when the decoded text clears a printable-ratio bar and hits at least two dictionary words. |
base64 | A base64 token whose decoded bytes are printable text. |
rot:N | A run that, rotated by N (ROT13 and other ROT-n), becomes dictionary-rich text. |
stack-string | A run reconstructed from interleaved-NUL / fragmented bytes characteristic of compiler-built stack strings. |
The XOR, ROT, and stack-string heuristics are deliberately conservative: they require dictionary hits, trading recall for precision so the output stays signal, not noise. Results are deduplicated by (value, tag) and offset-sorted.
Output is text (tag<TAB>@offset<TAB>value) or the disrobe.strings/v0 JSON document via --json. The library logic lives in disrobe_core::strings.
YARA rule generation
disrobe yara generate sample.bin
disrobe yara generate sample.bin --name Trojan_Foo_2026
disrobe yara generate sample.bin --sha256 <hash> --date 2026-06-10
disrobe yara generate sample.bin --json
Synthesizes a candidate YARA rule from an artifact. It selects high-signal strings (long, multi-character-class, non-dictionary, and any that were XOR/base64/ROT-recovered get a scoring bonus), detects the file's magic / format header, and emits a leading $magic hex pattern, producing a well-formed:
rule <name> : disrobe generated {
meta:
generated_by = "disrobe <version>"
schema = "disrobe.yara.generated/v0"
format = "pe"
sha256 = "..." // only when --sha256 is given
date = "..." // only when --date is given
strings:
$magic = { 4D 5A 90 00 ... }
$s0 = "..." ascii
...
condition:
$magic at 0 and N of ($s*)
}
The condition combines an anchored magic check (when a format was recognized) with an "N of" string threshold (half the selected strings, rounded up).
Provenance
Pass --sha256 and --date to include those values in the rule's metadata. Both fields are omitted by default; the analysis core does not read the system clock.
Self-verification
Every generated rule is parsed back through the in-house YARA parser (the same one behind disrobe yara parse) before it is returned. If the emitter ever produced something the parser could not read, generation fails loudly with DR-YARAGEN-0001 rather than emitting a broken rule. The library logic lives in disrobe_core::yara_gen.
Rule matching
Beyond generating and parsing rules, disrobe_core::yara_match evaluates a parsed ruleset against a byte buffer. It compiles the rule strings into an Aho-Corasick atom prefilter, then checks each rule's condition. It supports text strings (nocase, fullword, ascii, wide), hex strings (nibble wildcards, jumps, and alternation), a subset of regular expressions, and the common condition forms ($s at an offset or in a range, #s counts, N of, all / any / none of, filesize, and boolean and arithmetic operators). A rule that uses a feature outside that set is returned as unevaluated with a reason rather than reported as a false match or a false miss. The matcher is a library capability today with no CLI verb; it is graded by differential testing against the real yara command-line tool across a battery of text, hex, regex, and condition cases (yara_match_oracle.rs).
Behavior summary
disrobe behavior sample.exe
disrobe behavior sample.exe --json
disrobe behavior answers "what does this binary do?" by classifying it across seven categories:
| Category | Covers |
|---|---|
network | Sockets, WinHTTP/WinINet, DNS lookups, downloads. |
filesystem | File create/read/write/delete, directory enumeration. |
process_exec | Process / command execution, remote-thread injection. |
registry_persistence | Registry writes, Run keys, scheduled tasks, services. |
crypto | CryptoAPI / BCrypt / embedded crypto constants. |
anti_analysis | Debugger checks, timing checks, sandbox evasion. |
dynamic_code | LoadLibrary/GetProcAddress, VirtualProtect, dlopen, RWX memory. |
Signals come from four sources, each tagged in the evidence list:
import: the native import table (PE/ELF/Mach-O), parsed when the input is a binary.string: API / symbol names found in the extracted strings (including XOR/base64-recovered ones), so signals survive light obfuscation.ioc: network/host/crypto indicators from the IOC extractor.anti_analysis: a detected verdict from the anti-analysis scan reported alongside.
An API name matches only its own family: the exact name, plus the A, W, Ex, ExA and ExW variants for Win32 APIs. SystemTimeToTzSpecificLocalTime is not system, and ConnectEx is not connect.
MITRE ATT&CK mapping
A MITRE ATT&CK technique id is attached only when the evidence shows the technique itself, not a capability every runtime links:
| Evidence | Technique |
|---|---|
A CurrentVersion\Run or RunOnce key path | T1547.001 |
A schtasks command | T1053.005 |
The CreateService API | T1543.003 |
The RegSetValue, RegCreateKey or RegDeleteKey API | T1112 |
The URLDownloadToFile API | T1105 |
The WriteProcessMemory and CreateRemoteThread pair | T1055 |
| An anti-debug or anti-attach verdict | T1622 |
| An anti-VM, anti-sandbox or anti-tool verdict | T1497.001 |
| A timing-evasion verdict | T1497.003 |
APIs that ordinary programs import, such as LoadLibrary, GetProcAddress, CreateProcess, WriteFile, Sleep and IsDebuggerPresent, and indicators such as an embedded URL, place the binary in a category without a technique id. The aggregate attack_ids list at the end of the report is the union across all categories, ready to paste into a triage ticket. The library logic lives in disrobe_core::behavior and is reusable by disrobe report.
Scope
This is a static summary: disrobe never executes the sample. A signal means the capability is present in the binary's imports/strings, not that it necessarily fires at runtime. Treat it as a lead, not a verdict.
Diff and guard tooling
disrobe treats recovered artifacts as a forensic baseline you can diff across versions and protect against tampering. Two command families support this: disrobe diff and disrobe guard.
disrobe diff: structural chain diff
disrobe diff left/chain.json right/chain.json
Structurally diffs two chain.json documents, the topology descriptors written by disrobe auto / disrobe chain. It compares the passes that ran, each stage's BLAKE3 output hash, byte sizes, and per-stage verdicts. This is how you answer "did upgrading the PyArmor pass change what we recover from this sample?" without eyeballing two output trees.
A parallel disrobe envelope diff works on two .dr envelopes directly. It compares version, rung, flags, root hash, producer, capability set, and provenance.
disrobe guard: ground-truth protection
In a recovery workspace, the exact stage records (out/**/stages, out/**/final) are provenance inputs. Do not edit them in place because that would corrupt the recorded chain. disrobe guard enforces this boundary.
guard verify: hash verification
disrobe guard verify subject/chain.json --reference reference/chain.json
Verifies that a subject chain.json's per-stage output hashes match a committed reference. Use it in CI to assert that a recovery is reproducible: re-run the chain, then verify the new chain.json against the checked-in reference.
guard check: edit denial
disrobe guard check out/final/module.py
disrobe guard check some/path --root extra/protected/subtree --root other/protected
Decides whether a path about to be written or edited is inside a protected ground-truth subtree. It denies writes to out/**/stages, out/**/final, and any .disrobe-stage-lock-marked path, and allows writes elsewhere. --root adds extra protected subtrees; it is repeatable and also accepts comma-separated values.
disrobe init --ide claude writes a settings file whose hook calls disrobe guard check. That hook does not yet protect the stage directories: the variable it reads is not one Claude Code sets, so treat guard check as a command you run yourself.
The daemon: HTTP, gRPC, LSP, MCP
disrobe serve exposes byte classification and envelope operations over HTTP and gRPC,
classification and error lookup over LSP, and pass-specific analysis, recovery, and workspace
tools over MCP. Requests carry input bytes inline.
The protocol example records MCP initialization and an indicator query, LSP classification, and HTTP/gRPC health and classification requests. All three classification transports agree on the Wasm fixture's byte count, route, and BLAKE3 hash.
disrobe serve
disrobe serve --grpc
disrobe serve --stdio
disrobe serve --mcp
Flags
| Flag | Default | Effect |
|---|---|---|
--bind <ADDR> | 127.0.0.1:7373 | HTTP bind address. |
--stdio | off | Serve LSP JSON-RPC over stdin/stdout instead of HTTP. |
--mcp | off | Serve the MCP companion over stdio instead of HTTP/LSP. |
--grpc | off | Expose the gRPC surface alongside HTTP (binds to <bind-ip>:<bind-port+1>). |
--cors-origin <ORIGIN> | (none) | Additional CORS origin to allow. Repeatable. With no origins, all origins are allowed. |
--max-body-size <N> | 52428800 (50 MiB) | Maximum request body size in bytes. |
HTTP
The default surface. Binds to loopback (127.0.0.1:7373) by default; a non-loopback bind emits a warning at startup.
The API is versioned: /v1/* and /v2/* are aliases. The spec is served at /openapi.json.
| Method | Path | Description |
|---|---|---|
GET | /v1/health | Server liveness ({ status, version }). |
GET | /v1/version | Tool name, version, and API level ({ name, version, api }). |
GET | /v1/passes | List registered passes ({ passes: [{ name, description }] }). |
POST | /v1/analyze | Classify and route bytes. Body: { bytes_b64, hint? }. Returns: { routed_action, bytes_read, blake3_hash, reason, candidates }. |
POST | /v1/explain/{code} | Look up a DR-* error code. Returns: { code, known, title?, description?, crate_path? }. |
POST | /v1/envelope/verify | Verify a .dr envelope. Body: { bytes_b64 }. Returns: { verified, version, rung, hot_bytes, cold_bytes, root_hash_blake3 }. |
POST | /v1/envelope/create | Wrap raw bytes into a Raw-rung .dr envelope. Body: { bytes_b64, source_label?, produced_by?, detected_format? }. Returns: { envelope_b64, envelope_bytes, bytes_in, root_hash_blake3, source_hash_blake3 }. |
WS | /v1/stream | WebSocket NDJSON stream (upgrade with Sec-WebSocket-Protocol: disrobe-stream.v1). Bytes are sent bytes_b64-only; the server never reads from disk. |
GET | /openapi.json | OpenAPI 3 spec for the HTTP surface. |
gRPC
Exposed alongside HTTP with --grpc. The gRPC server binds to the same IP as --bind but at <port> + 1 (default 127.0.0.1:7374). Includes health and reflection services.
LSP over stdio
--stdio speaks JSON-RPC over stdin/stdout using the LSP framing and initialize handshake. It does not implement the standard textDocument surface. It advertises two custom methods under capabilities.experimental.disrobe:
| Method | Description |
|---|---|
disrobe/analyze | Params: { bytes_b64, label? }. Returns the same classification payload as POST /v1/analyze. |
disrobe/explain | Params: { code }. Returns the error-code lookup payload. |
Unknown fields in params are rejected (hard error). A path field is specifically rejected; all bytes are transmitted inline.
MCP companion
--mcp runs the rmcp-based Model Context Protocol companion, exposing disrobe's analysis, workspace, and navigation capabilities as MCP tools. Navigation includes call_graph, xrefs, function_summary, and neighborhood over content-bound function ids and bounded paginated responses. The standalone disrobe-mcp binary is equivalent. See the dedicated MCP server integration page for the full tool catalog and client registration.
Security posture
HTTP, gRPC, LSP, and WebSocket analysis requests carry sample bytes inline and do not accept a sample path. The MCP analysis tools use the same bytes_b64 model. Its workspace tools are deliberately path-aware: annot reads a client-selected target only after resolving it beneath the current workspace, then writes its sidecar under .disrobe/annotations/; rename reads and writes the fixed .disrobe/notes/renames.json file. JSON request structs reject unknown fields via deny_unknown_fields. Escaping those workspace bounds, or making an inline-byte analysis surface read a client-selected path, is a high-severity vulnerability under the security policy. Run the daemon on loopback unless you have a specific reason not to.
Signed WebAssembly plugins
disrobe plugin runs a third-party analysis component through the disrobe-plugin-host sandbox.
A plugin never runs with disrobe's own privileges: it is a WebAssembly component, signed by a key
you name explicitly, executed under a fuel budget, a wall-clock deadline, and a memory cap, with
every import denied unless a manifest grants it.
disrobe plugin verify my-plugin.wasm --trusted-key operator.pub
disrobe plugin run my-plugin.wasm --trusted-key operator.pub --out result.bin < input.bin
disrobe plugin list ./plugins --trusted-key operator.pub
Bundle shape
A plugin bundle is three sibling files sharing one stem:
| File | Purpose |
|---|---|
<name>.wasm | The signed WebAssembly component. |
<name>.wasm.minisig | A minisign signature over the component bytes. |
<name>.toml | The manifest: declared name, version, and the capability set the component may import. |
There is no registry and no distribution mechanism. --trusted-key always names an operator-
supplied minisign public key file, never one disrobe embeds.
Commands
| Command | Purpose |
|---|---|
disrobe plugin run <component> --trusted-key <pubkey> --out <file> [--input <file>] [--fuel N] [--wall-deadline-ms MS] [--memory-cap-bytes N] [--format text|json] | Verify and run the component. Reads input from stdin when --input is omitted; writes output bytes to --out. |
disrobe plugin verify <component> --trusted-key <pubkey> [--format text|json] | Verify the signature and capability manifest without running the component. |
disrobe plugin list <dir> [--trusted-key <pubkey>] [--format text|json] | List every bundle in a directory. Each bundle is also signature- and capability-verified when --trusted-key is given. |
--fuel, --wall-deadline-ms, and --memory-cap-bytes each override the sandbox's default, and
are always clamped to its compiled-in ceiling regardless of what is requested.
Guest contract
A component exports one function, run: func(list<u8>) -> list<u8>. It receives the input bytes
and returns output bytes; nothing else crosses the boundary. The component linker stays empty, so
a manifest capability grant permits validation but never actually supplies a host function to call.
Provenance: authenticated versus declared
--format json reports two kinds of fields, and labels which is which:
- Authenticated, derived from the verified bytes: the component's BLAKE3 hash and the trusted signing key's id.
- Declared, not authenticated: the manifest's
nameandversion. The signature covers the component bytes only, never the manifest, so an attacker who can place files next to a validly signed component can edit its declared name or version without invalidating the signature.run's JSON output carriesmanifest_version_authenticated: falsealongside those fields rather than presenting them as fact.
Rejections
Every rejection is a distinct typed error surfaced before the guest ever executes: unsigned, wrong
key, over-size component, over-size signature, non-UTF-8 signature, missing manifest, malformed
manifest, an ungranted capability, a missing run export, or a wrongly typed one. At runtime, the
fuel, wall-clock, and memory caps each independently terminate a runaway guest.
Scope
CLI-only today: a plugin invocation names an explicit local path an operator supplies, unlike
disrobe's own passes, so it is not reachable from disrobe auto, the MCP surface, or the python
bindings. See the security policy for the full trust model, including what
resource sandboxing does and does not guarantee about a plugin's output correctness.
Use it as a library
Use Disrobe through its Rust crates, Python bindings, or service protocols. The CLI and bindings share the same Rust implementations.
Rust
Ecosystem recovery code is split across dedicated crates over shared artifact and IR types, so a library consumer can select only the surfaces it needs. A crate may expose multiple direct operations or chain passes. The pass registry and chain state machine live in disrobe-core; disrobe-passes assembles the feature-selected registry used by disrobe auto.
| Crate | What you get |
|---|---|
disrobe-core | Shared types: Artifact, Rung, confidence tiers, error codes, the chain registry and state machine, the Pass/Detector traits, and the obfuscator-catalog traits. |
disrobe-ir | The five-rung IR ladder, the .dr envelope (rkyv hot payload + postcard cold sidecar + BLAKE3 root), and the transcode registry. |
disrobe-nir, disrobe-nir-lift | Normalized MIR and bytecode front ends for AVM2, BEAM, CIL, Dalvik, JVM, Lua, Python, WebAssembly, and YARV. |
disrobe-binfmt | Container detection, in-tree format extractors, recursive carving, and shared extraction quotas. |
disrobe-passes | The single construction site for a feature-selected PassRegistry. |
disrobe-prowl | Typed URL and IOC harvest reports, source filters, bounded async provider fan-out, and API-key resolution for the prowl CLI. |
disrobe-pass-py-decompile, disrobe-pass-jvm, disrobe-pass-native, disrobe-pass-dotnet, ... | One crate per ecosystem, each exposing a typed Pass plus direct entry points (for example the Python decompiler's PY_DECOMPILE_PASS and roundtrip_native). |
disrobe-pass-webview | Static Electron ASAR and embedded Tauri/Wails frontend recovery with typed reports and extraction quotas. |
disrobe-query, disrobe-capabilities | The queryable-IR layer and the ATT&CK/MBC rule engine over the disassembled native code. |
disrobe-taint | Source-to-sink flow analysis over normalized native, WebAssembly, JVM, Dalvik, and .dr inputs. |
Add the crates you want to a workspace member or an external project that pins the published versions:
[dependencies]
disrobe-core = "0.10"
disrobe-ir = "0.10"
disrobe-pass-py-decompile = "0.10"
For a runnable example, inspect a WebAssembly module and emit WAT directly through the Rust API:
cargo run --locked -p disrobe-pass-wasm-deob --example inspect_module -- playground/public/samples/add.wasm
The example source reads at most 16 MiB, calls analyze_module and lift_module_faithful_wat, then prints the function inventory and recovered text. It does not execute the module.
For the bundled add.wasm, it reports one function, no imports, and the add export.
The captured output
includes the emitted WAT and hashes of the fixture, example source, and executable.
Chain passes implement the shared Pass trait. Each exposes a Detector and a run method that transforms an Artifact into a new artifact. Enable the pass crate's chain feature when using this interface.
The Python decompiler exposes roundtrip_native, which recompiles recovered source on the matching interpreter and returns a RoundtripOutcome with a PERFECT, SEMANTIC or CODE_DIFF verdict. Its Rust comparison retains operands and jump targets. The published stdlib measurement uses separate normalized opcode-structure rules.
Because every chain pass speaks the same Artifact dialect, PassRegistry can re-detect the current bytes after each stage and select the highest-confidence, highest-precedence verdict without a per-pair compatibility table. The registry contains only the passes compiled and registered by the caller. The standard CLI uses disrobe-passes as its assembly point; disrobe passes shows what that build exposes to auto. The shape of the Pass trait and the selection mechanism is in Passes and pass selection.
Python
import disrobe loads a pyo3 abi3 module for Python 3.9+, built with maturin from crates/disrobe-python. It includes a .pyi stub and py.typed marker. Analysis functions accept bytes and return typed reports. Most analysis functions leave file I/O to the caller. Container extraction and an explicitly selected Flutter engine-symbol cache write to caller-supplied directories.
from __future__ import annotations
from pathlib import Path
import disrobe
from disrobe import (
CanonicalSource,
Capabilities,
ChainReport,
CodeObject,
Instruction,
Symbol,
)
chain: ChainReport = disrobe.auto(Path("sample.bin").read_bytes())
print(chain.to_json())
recovered: CanonicalSource = disrobe.decompile(
"python-bytecode", Path("module.pyc").read_bytes()
)
source: str | None = recovered.source
caps: Capabilities = disrobe.capabilities(Path("packed.exe").read_bytes())
print(caps.matched_rules, caps.match_count)
obj: CodeObject = CodeObject.from_dr(Path("module.dr").read_bytes())
obj.add_symbol(Symbol(0x401000, "decrypt_config"))
obj.add_instruction(Instruction(0x401000, "xor", ["eax", "eax"]))
patched_dr: bytes = obj.to_dr()
The surface spans auto, typed entry points for every major ecosystem, a generic disasm/parse/compile/decompile dispatch, a mutable CodeObject you load from a .dr envelope, edit, and re-serialize, and a register_pass/register_consumer registry for your own stages. The full function list and conventions are in the Python-bindings reference.
Daemon
disrobe serve exposes HTTP and gRPC endpoints. disrobe serve --stdio provides LSP over standard input and output, and disrobe serve --mcp exposes MCP tools. Their operation sets differ; see the service reference and MCP tool list.
Python bindings
Use Disrobe's recovery engines from Python to decompile bytecode, analyze native
code, deobfuscate scripts, and extract packaged files. The disrobe module uses
the same Rust implementations as the CLI and provides typed report objects.
It supports Python 3.9+ through PyO3's stable ABI.
Most analysis calls leave file I/O to the caller. The optional Flutter engine-symbol
cache reads and writes the directory passed as cache_dir. Build the bindings from
source; wheels are not published to PyPI.
The WebAssembly example shows an addition function recovered as WAT. The 0.10.5 compatibility results cover 60 API checks for typed results, error payloads, artifact round trips, and CLI surface mappings.
Install
Install Python 3.9+, the repository's Rust toolchain, and the target's native
compiler and linker. Windows MSVC builds require the Visual C++ build tools,
Windows SDK, and a Python installation that includes python3.lib. See the
source build prerequisites.
Create a virtual environment:
git clone https://github.com/1-3-7/disrobe
cd disrobe/bindings/python
python -m venv .venv
Activate it with source .venv/bin/activate on Linux or macOS, or
.\.venv\Scripts\Activate.ps1 in Windows PowerShell. Then install the build tool
and compile the extension into that environment:
python -m pip install "maturin>=1.5,<2.0"
maturin develop --release
For a redistributable wheel:
maturin build --release --out dist
python -m pip install --no-index --find-links dist disrobe
The pyproject.toml requires maturin>=1.5,<2.0, takes the version from the Rust
workspace, sets module-name = "disrobe.disrobe", and points at
crates/disrobe-python/Cargo.toml. On
Windows the crate's build.rs searches PYO3_PYTHON, an active
VIRTUAL_ENV, and standard install locations; set PYO3_PYTHON=<path-to-python.exe>
if none is found. A py.typed marker and a .pyi stub provide type information for the documented
report attributes.
from __future__ import annotations
import disrobe
version: str = disrobe.__version__
Report model
Analysis functions generally return concrete report classes. Some functions return
text, bytes, collections, or tuples; the function table gives each return type.
The stub's _Report base describes the serialization methods shared by report
objects.
_Report
| Member | Signature | Notes |
|---|---|---|
raw | @property -> dict[str, Any] | Full underlying record; no detail dropped |
to_json | () -> str | Compact JSON string |
from_json_str | classmethod(text: str) -> Self | Rebuild from a to_json string |
from_obj | classmethod(obj: dict[str, Any]) -> Self | Wrap an already-decoded dict |
Reports compare equal when their underlying records are equal (== / !=).
_LlmReport
Subclasses _Report. Adds one property:
| Member | Signature | Notes |
|---|---|---|
llm | @property -> LlmBundle | None | Populated when metadata output was requested; None otherwise |
Metadata-wired passes: py_decompile, py_disasm, py_deob, pyarmor_detect,
pyarmor_unpack. Functions that build a metadata bundle accept
pack: Pack | None where Pack = Literal["pack-1", "pack-2", "pack-3", "pack-4"].
LlmBundle
A TypedDict mirroring the disrobe.metadata.llm.v2 on-disk schema. The type name is stable; the schema id changes only when the bundle shape breaks compatibility. The payload is deterministic metadata, not model output.
Every top-level key except generated_at is always present, and the categories present depend on which pack was requested. Pipeline steps record no durations. generated_at appears only when SOURCE_DATE_EPOCH is set, as an RFC 3339 UTC timestamp; a value that is not a whole number of seconds up to 9999-12-31T23:59:59Z raises DisrobeError.
The LlmBundle name describes a type in the stub; it is not a runtime export.
To retain a complete report and its metadata, serialize the report:
from __future__ import annotations
from pathlib import Path
import disrobe
pyc_bytes: bytes = Path("module.pyc").read_bytes()
report: disrobe.PyDisasmReport = disrobe.py_disasm(pyc_bytes, pack="pack-2")
metadata_json: str = report.to_json()
print(metadata_json)
Literal type aliases
These names are defined in the type stub, not exported by the runtime module. Pass the documented string values to functions; do not import the aliases at runtime.
| Alias | Values |
|---|---|
Pack | "pack-1", "pack-2", "pack-3", "pack-4" |
RoundtripStatus | "perfect", "semantic", "code-diff", "no-interpreter", "recompile-failed", "skipped" |
PyarmorUnpackStatus | "functional", "bcc-partial", "detect-only", "skeleton" |
ChainVerdict | "ok", "complete", "fan-out", "fan-out-partial", "stalled", "cycle", "cap-reached", "extracted", "error", "dry-run" |
ChainVerdictGrade | "ok", "incomplete", "failed" |
ContainerListing | "enumerated", "requires-extraction", "unreadable" |
SymbolKind | "function", "data", "label", "export", "import" |
InstructionFlow | "sequential", "call", "indirect-call", "conditional-branch", "unconditional-branch", "indirect-branch", "return", "interrupt" |
SourceLanguage | "python", "py", "python3" |
JsLanguage | "javascript", "js", "typescript", "ts" |
ByteLanguage | "python-bytecode", "pyc", "jvm-class", "class", "dex", "beam", "hermes", "hermes-bundle", "hbc", "wasm" |
ParseByteLanguage | "go", "swift", "objc", "objective-c", "kotlin", "ruby", "lua", "php" |
DisasmByteLanguage | "ruby", "ruby-bytecode", "yarv", "mruby", "php", "php-bytecode" |
DecompileLanguage | "python-bytecode", "pyc", "jvm-class", "class", "java", "kotlin", "lua", "ruby", "php", "php-bytecode", "javascript", "js", "typescript", "ts" |
Exception hierarchy
| Class | Base | Raised when |
|---|---|---|
DisrobeError | Exception | An underlying recovery or analysis operation fails |
UnsupportedLanguage | DisrobeError | disasm/parse/compile/decompile for a language with no backing implementation; message includes a hint |
Invalid Python argument types can also raise standard Python exceptions.
Module-level functions: full surface
| Category | Function | Returns |
|---|---|---|
| Auto chain | auto(input, *, max_depth=8, path_hint=None) | ChainReport |
| Generic dispatch | decompile(language, source) | CanonicalSource |
disasm(language, source) | str | |
parse(language, source) | typed report or dict[str, Any] | |
compile(language, source, *, version=None) | bytes | |
| Custom pass | register_pass(name, callable) | None |
register_consumer(name, callable) | None | |
registered_passes() | list[str] | |
registered_consumers() | list[str] | |
unregister(name) | bool | |
run_pass(name, data) | Any | |
run_chain(names, data) | Any | |
emit(name, result, **context) | Any | |
| Analysis | strings_extract(data, *, min_len=4, decode=True) | StringsReport |
ioc_extract(data) | IocReport | |
behavior_analyze(data) | BehaviorReport | |
identify(data) | IdentifyReport | |
secret_scan(data, *, redact=False) | SecretScanReport | |
capabilities(binary_bytes) | Capabilities | |
extract(data, out_dir) | ExtractionResult | |
extract_recursive(data, *, source_label='inline', max_depth=8) | OverlayReport | |
yara_parse(ruleset_source) | YaraReport | |
yara_generate(data, *, name=None) | YaraReport | |
| Native | native_symbols(data) | SymbolsReport |
native_disasm(data) | DisasmPayload | |
native_callgraph(data) | CallGraph | |
native_imports_dot(data) | str | |
native_entropy(data) | EntropyReport | |
native_sbom(data) | SbomReport | |
native_fingerprint(data, *, flirt=None) | FingerprintReport | |
native_signatures(data, *, flirt=None) | SignatureReport | |
native_sigmaker(data, at) | SigmakerReport | |
native_diff(a, b) | DiffReport | |
native_match(a, b, *, stage=None, function=None, limit=None) | NativeMatch | |
native_patch(data, *, at, replacement=None, nop_start=None, nop_end=None) | tuple[bytes, PatchReport] | |
native_format(binary_bytes) | NativeFormat | |
native_detect(binary_bytes) | DetectionList | |
native_probe_backends() | BackendList | |
native_deobfuscate(code, *, bits=64, base=0, entry=0) | NativeDeobfuscation | |
| Query IR | query_functions(dr_bytes) | FunctionList |
query_calls_to(dr_bytes, target) | QueryReport | |
query_xrefs_to(dr_bytes, symbol) | QueryReport | |
query_string_decoders(dr_bytes) | QueryReport | |
query_complexity_over(dr_bytes, threshold) | QueryReport | |
query_capability_sites(dr_bytes, capability) | QueryReport | |
query_call_graph(dr_bytes) | CallGraph | |
| Envelope | envelope_create(payload, *, source_label='inline', produced_by=None, detected_format=None) | bytes |
envelope_verify(envelope_bytes) | EnvelopeReport | |
| LLM renders | agents_md(result) | str |
skill_md(result) | str | |
provenance(result) | Provenance | |
| Python decompile | py_decompile(pyc_bytes, *, roundtrip=False, pack=None) | PyDecompileReport |
py_disasm(pyc_bytes, *, pack=None) | PyDisasmReport | |
| Python deobfuscate | py_deob(source, *, cleanup=True, pack=None) | PyDeobReport |
py_deob_detect(source) | PyDeobDetection | |
py_deob_list_passes() | list[ObfuscatorPass] | |
py_deob_detect_pass(source, pass_id) | PyDeobDetection | |
| PyArmor | pyarmor_detect(source, *, pack=None) | PyarmorDetection |
pyarmor_unpack(payload, *, runtime=None, pack=None) | PyarmorUnpack | |
pyarmor_classify(source, payload) | PyarmorClassification | |
| PyInstaller | pyinstaller_extract(image_bytes) | PyInstallerArchive |
pyinstaller_entry_bytes(image_bytes, entry_name) | bytes | |
| Nuitka | nuitka_detect(image_bytes) | NuitkaDetection |
nuitka_extract(image_bytes) | NuitkaExtraction | |
| Hermes | hermes_disasm(bundle_bytes) | HermesDisassembly |
hermes_lift(bundle_bytes) | HermesLift | |
hermes_info(bundle_bytes) | HermesInfo | |
| Flutter | flutter_engine_symbols(input, engine_symbol_map=None, *, source=None, cache_dir=None, no_cache=False) | FlutterEngineSymbols |
| Mach-O | macho_dump(macho_bytes) | MachoReport |
swift_analyze(macho_bytes) | SwiftReport | |
| JVM / Android | jvm_parse_class(class_bytes) | JvmClass |
jvm_parse_dex(dex_bytes) | DexFileReport | |
jvm_decompile_class(class_bytes) | JvmDecompiledClass | |
jvm_decompile_dex(dex_bytes) | JvmDecompiledDex | |
jvm_detect(class_bytes) | DetectionList | |
jvm_backends() | JvmBackends | |
apk_resources(apk_bytes) | ApkResources | |
jvm_jni_link(dex_bytes, native_libs) | JniLink | |
| .NET | dotnet_parse_pe(pe_bytes) | DotnetPe |
dotnet_parse_metadata(pe_bytes) | DotnetMetadata | |
dotnet_detect(pe_bytes) | DotnetDetection | |
dotnet_analyze(pe_bytes) | DotnetAnalysis | |
dotnet_decompile(pe_bytes) | DotnetDecompilation | |
dotnet_recover_decoders(pe_bytes) | DotnetDecoders | |
dotnet_native_aot(image_bytes) | DotnetNativeAot | |
dotnet_backends() | BackendList | |
| WebAssembly | wasm_analyze(wasm_bytes) | WasmAnalysis |
wasm_detect(wasm_bytes) | WasmDetection | |
wasm_lift(wasm_bytes, *, target) | WasmLift | |
| JavaScript | js_detect(js_source) | JsDetection |
js_unminify(js_source) | JsUnminify | |
js_unbundle(js_source, *, bundler=None) | JsUnbundle | |
| Lua | lua_detect(bytecode) | LuaDetection |
lua_decompile(bytecode) | LuaDecompilation | |
lua_deobfuscate(source, *, authorize=False) | LuaDeobfuscation | |
| Go | go_analyze(binary_bytes) | GoAnalysis |
go_symbols(binary_bytes) | GoSymbols | |
go_pclntab(binary_bytes) | GoPclntab | |
go_garble(binary_bytes) | GarbleReport | |
| Ruby | ruby_detect(ruby_bytes, *, source_path=None) | RubyDetection |
ruby_decompile(ruby_bytes, *, source_path=None) | RubyAnalysis | |
| PHP | php_detect(php_bytes) | PhpDetection |
php_scan(php_bytes) | PhpScan | |
php_decode(php_bytes, *, max_depth=None) | PhpDecode | |
| Shell | batch_deobfuscate(script, *, args=None) | BatchDeobReport |
powershell_detect(script) | PowershellDetection | |
powershell_deobfuscate(script) | PowershellDeobfuscation | |
| Containers | byte_coverage(image_bytes) | ByteCoverage |
container_detect(container_bytes) | ContainerDetection | |
container_members(container_bytes) | ContainerMembers | |
| Pickle | pickle_disasm(pickle_bytes) | str |
pickle_decompile(pickle_bytes) | PickleDecompilation | |
pickle_safety(pickle_bytes) | PickleSafety | |
pickle_trace(pickle_bytes) | PickleTrace | |
pickle_polyglot(file_bytes) | PicklePolyglot | |
pickle_ml_detect(file_bytes) | PickleMlReport |
Auto chain
from __future__ import annotations
from pathlib import Path
import disrobe
chain: disrobe.ChainReport = disrobe.auto(Path("sample.bin").read_bytes(), max_depth=8)
passes: list[str] = chain.passes
verdict: disrobe.ChainVerdict | None = chain.verdict
grade: disrobe.ChainVerdictGrade | None = chain.verdict_grade
print(chain.node_count, chain.pass_count, passes, verdict, grade)
full_plan_json: str = chain.to_json()
print(full_plan_json)
auto runs the chain detector against raw bytes and returns a ChainReport
carrying the full chain.json plan the CLI produces; it does not write stage
outputs to disk. max_depth must be 1-16. Other values in the unsigned-byte
range raise DisrobeError; values below 0 or above 255 raise OverflowError.
The registered pass tree covers pyarmor, pyinstaller, nuitka,
py-decompile, py-deob, container, js, jvm, dotnet, wasm, mobile, swift-objc,
and the native packer detector.
The accessors read the disrobe.chain/v2 document. to_json() returns the
complete plan, including per-node hashes, detector picks, and statistics. The
document carries no clock and no duration, so one input gives the same JSON on
every call.
| Accessor | Value |
|---|---|
spec: str | None | The raw chain specification, such as "auto:8" |
node_count: int | Length of nodes, including the root input node and extracted children |
pass_count: int | Number of nodes whose pass is set |
passes: list[str] | Those pass ids in node order, such as ["native.packer-unpack"] |
verdict: ChainVerdict | None | The chain-level verdict |
verdict_grade: ChainVerdictGrade | None | The grade the core assigns to that verdict; None for an unrecognised verdict |
final_format: str | None | The final format tag, when the chain reached one |
The earlier terminated accessor was removed because the document has no
termination field; read verdict and verdict_grade instead.
Generic dispatch
Language-keyed entry points that fan out to the per-language passes.
decompile
def decompile(language: str, source: str | bytes) -> CanonicalSource: ...
Wired families: python-bytecode/pyc (py-decompile), jvm-class/class/java/kotlin
(JVM lifter), lua (register lifter), ruby (YARV/mruby recovery),
php/php-bytecode (eval-chain peel/op-array skeleton),
javascript/js/typescript/ts (unminify). Binary-only targets (go,
swift, wasm) have no single source body; call their structural binding or
parse instead.
from __future__ import annotations
from pathlib import Path
import disrobe
recovered: disrobe.CanonicalSource = disrobe.decompile(
"python-bytecode", Path("module.pyc").read_bytes()
)
source: str | None = recovered.source
language: str | None = recovered.language
produced_by: str | None = recovered.produced_by
confidence: float | None = recovered.confidence
CanonicalSource accessors
| Property | Type |
|---|---|
source | str | None |
language | str | None |
produced_by | str | None |
confidence | float | None |
disasm
def disasm(language: str, source: str | bytes) -> str: ...
Returns a rendered instruction listing as text. Wired: python/pyc,
jvm-class/class, dex, beam, hermes, wasm,
ruby/yarv/mruby, and php/php-bytecode. For Lua use
decompile('lua', ...) or parse('lua', ...) instead.
parse
def parse(language: str, source: str | bytes) -> (
dict[str, Any]
| GoAnalysis
| SwiftReport
| JvmClass
| RubyAnalysis
| LuaDecompilation
| PhpDecode
| JsUnminify
): ...
Returns a typed report for structural-recovery languages: go -> GoAnalysis,
swift/objc/objective-c -> SwiftReport, kotlin -> JvmClass,
ruby -> RubyAnalysis, lua -> LuaDecompilation, php -> PhpDecode,
javascript/js/typescript/ts -> JsUnminify. Container and bytecode
formats (pyc, jvm-class, dex, wasm, hermes, beam) return a nested
dict[str, Any] because their full parse records have no single typed shape.
For a classfile report with typed attributes, use the dedicated parser:
from __future__ import annotations
from pathlib import Path
import disrobe
class_bytes: bytes = Path("Hello.class").read_bytes()
parsed: disrobe.JvmClass = disrobe.jvm_parse_class(class_bytes)
method_count: int = parsed.method_count
print(method_count)
compile
def compile(language: str, source: str, *, version: str | None = None) -> bytes: ...
Implemented for Python only; returns raw marshal.dumps bytes (no .pyc
header) via the host interpreter. lua, ruby, and php raise
UnsupportedLanguage with a hint pointing at the CLI subcommand or toolchain.
from __future__ import annotations
import disrobe
blob: bytes = disrobe.compile("python", "x: int = 1 + 2\n")
listing: str = disrobe.disasm("python", "x: int = 1 + 2\n")
Custom pass plugin protocol
Register and compose named passes and output consumers in the host process.
Named passes can return different Python objects. Check a registry result before using operations specific to its expected type.
from __future__ import annotations
import disrobe
def reverse_bytes(data: bytes) -> bytes:
return data[::-1]
def print_result(result: object, **context: object) -> None:
print(result, context)
disrobe.register_pass("reverse", reverse_bytes)
disrobe.register_consumer("print", print_result)
try:
output: object = disrobe.run_chain(["reverse", "reverse"], b"hello")
if not isinstance(output, bytes):
raise TypeError("the reverse chain must return bytes")
restored: bytes = output
disrobe.emit("print", restored, source="example")
finally:
disrobe.unregister("reverse")
disrobe.unregister("print")
Pass and OutputConsumer protocols
These protocols describe callables in the stub. They are not exported as runtime classes; register ordinary Python functions with the corresponding signatures.
| Protocol | Signature |
|---|---|
Pass | __call__(self, data: Any) -> Any |
OutputConsumer | __call__(self, result: Any, **context: Any) -> Any |
Analysis
strings_extract
def strings_extract(data: bytes, *, min_len: int = 4, decode: bool = True) -> StringsReport: ...
Extracts ASCII and UTF-16 strings from a binary blob.
ioc_extract
def ioc_extract(data: bytes) -> IocReport: ...
Harvests indicators of compromise from bytes and recovered strings.
behavior_analyze
def behavior_analyze(data: bytes) -> BehaviorReport: ...
Behavioral summary by category with MITRE ATT&CK IDs.
identify
def identify(data: bytes) -> IdentifyReport: ...
Compiler/linker/packer/protector/installer fingerprint. A signed PE's Authenticode certificate validity is judged at the time SOURCE_DATE_EPOCH names, or at the current time when it is unset; a value that is not a whole number of seconds raises DisrobeError.
secret_scan
def secret_scan(data: bytes, *, redact: bool = False) -> SecretScanReport: ...
Set redact=True to replace detected values, previews, messages, and URI credentials with stable redaction tokens. The default report retains the matched values. Redaction preserves the finding count and byte offsets.
Leaked-credential scan over raw bytes.
capabilities
def capabilities(binary_bytes: bytes) -> Capabilities: ...
Capability rule-set matches for a native binary.
extract
def extract(data: bytes, out_dir: str) -> ExtractionResult: ...
Carves container/firmware members to out_dir.
extract_recursive
def extract_recursive(
data: bytes, *, source_label: str = "inline", max_depth: int = 8
) -> OverlayReport: ...
Recursive multi-magic carve; classifies every chunk by entropy and nesting.
yara_parse / yara_generate
def yara_parse(ruleset_source: str) -> YaraReport: ...
def yara_generate(data: bytes, *, name: str | None = None) -> YaraReport: ...
Parse a YARA ruleset AST or generate a candidate rule from a binary blob.
from __future__ import annotations
from pathlib import Path
import disrobe
data: bytes = Path("suspect.bin").read_bytes()
strings: disrobe.StringsReport = disrobe.strings_extract(data, min_len=6)
string_count: int = strings.string_count
iocs: disrobe.IocReport = disrobe.ioc_extract(data)
indicator_count: int = iocs.indicator_count
behavior: disrobe.BehaviorReport = disrobe.behavior_analyze(data)
category_count: int = behavior.category_count
ident: disrobe.IdentifyReport = disrobe.identify(data)
fmt: str | None = ident.format
finding_count: int = ident.finding_count
caps: disrobe.Capabilities = disrobe.capabilities(data)
match_count: int = caps.match_count
overlay: disrobe.OverlayReport = disrobe.extract_recursive(data, max_depth=4)
chunks_total: int | None = overlay.chunks_total
bytes_carved: int | None = overlay.bytes_carved
rule: disrobe.YaraReport = disrobe.yara_generate(data, name="suspect")
rule_count: int = rule.rule_count
Analysis report classes
| Class | Notable typed accessors |
|---|---|
StringsReport | string_count: int |
IocReport | indicator_count: int |
BehaviorReport | category_count: int |
IdentifyReport | format: str | None, finding_count: int |
SecretScanReport | finding_count: int |
Capabilities | match_count: int (entries in capabilities), matched_rules: int |
ExtractionResult | kind: str | None, entry_count: int, integrity_violation_count: int |
OverlayReport | max_depth: int | None, nodes_visited: int | None, chunks_total: int | None, bytes_carved: int | None |
YaraReport | rule_count: int |
Native binary
Functions
| Function | Returns | Notes |
|---|---|---|
native_symbols(data) | SymbolsReport | Symbols, sections, imports, debug info |
native_disasm(data) | DisasmPayload | Full disassembly: functions, stream, symbols |
native_callgraph(data) | CallGraph | Whole-program call graph |
native_imports_dot(data) | str | GraphViz DOT of the import graph |
native_entropy(data) | EntropyReport | Sliding-window Shannon entropy map |
native_sbom(data) | SbomReport | CycloneDX 1.5 SBOM from cargo-auditable section |
native_fingerprint(data, *, flirt=None) | FingerprintReport | Crypto-constant + FLIRT + string-xref sidecar |
native_signatures(data, *, flirt=None) | SignatureReport | Crypto-primitive signatures and FLIRT matches |
native_sigmaker(data, at) | SigmakerReport | Wildcarded byte signature for a VA |
native_diff(a, b) | DiffReport | Function-level diff of two binaries |
native_patch(data, *, at, ...) | tuple[bytes, PatchReport] | Rewrite bytes and revalidate |
native_format(binary_bytes) | NativeFormat | Format: kind, bitness, subsystem |
native_detect(binary_bytes) | DetectionList | Packer/protector detection hits |
native_probe_backends() | BackendList | Probe for installed external tools |
native_deobfuscate(code, *, bits=64, base=0, entry=0) | NativeDeobfuscation | x86 OLLVM/Tigress deflattening |
from __future__ import annotations
from pathlib import Path
import disrobe
data: bytes = Path("binary.elf").read_bytes()
syms: disrobe.SymbolsReport = disrobe.native_symbols(data)
symbol_count: int = syms.symbol_count
section_count: int = syms.section_count
import_count: int = syms.import_count
disasm_payload: disrobe.DisasmPayload = disrobe.native_disasm(data)
function_count: int = disasm_payload.function_count
instruction_count: int = disasm_payload.instruction_count
entropy: disrobe.EntropyReport = disrobe.native_entropy(data)
mean: float | None = entropy.mean
sig: disrobe.SigmakerReport = disrobe.native_sigmaker(data, at=0x1000)
ida_pattern: str | None = sig.ida_pattern
patched_bytes: bytes
patch_report: disrobe.PatchReport
patched_bytes, patch_report = disrobe.native_patch(
data, at=0x1234, nop_start=0x1234, nop_end=0x1240
)
bytes_written: int | None = patch_report.bytes_written
edit_count: int = patch_report.edit_count
code: bytes = Path("function.x86.bin").read_bytes()
deob: disrobe.NativeDeobfuscation = disrobe.native_deobfuscate(
code, bits=64, base=0x400000
)
recovered_blocks: int | None = deob.recovered_blocks
covered_states: int | None = deob.covered_states
dispatcher_states: int | None = deob.dispatcher_states
fully_recovered: bool = deob.fully_recovered
Native report classes
| Class | Notable typed accessors |
|---|---|
SymbolsReport | symbol_count: int, section_count: int, import_count: int |
DisasmPayload | function_count: int, instruction_count: int |
CallGraph | node_count: int, edge_count: int |
EntropyReport | window_count: int, mean: float | None, min: float | None, max: float | None |
SbomReport | component_count: int, bom_format: str | None, spec_version: str | None |
FingerprintReport | crypto_hit_count: int |
SignatureReport | signature_count: int |
SigmakerReport | ida_pattern: str | None, byte_count: int |
DiffReport | added: int, removed: int, changed: int |
PatchReport | at: int | None (first applied edit), bytes_written: int | None, edit_count: int, format: str | None, image_base: int | None |
NativeFormat | kind: str | None, bits: int | None, subsystem: str | None |
DetectionList | count: int |
BackendList | count: int, available_count: int |
NativeDeobfuscation | bits: int | None, recovered_blocks: int | None, original_blocks: int | None, dispatcher_states: int | None, covered_states: int | None, fully_recovered: bool |
Query IR
The query functions operate on a Disasm- or Mir-rung .dr envelope (raw bytes). See
Editable IR objects for how to produce and consume .dr
envelopes programmatically.
| Function | Returns | Notes |
|---|---|---|
query_functions(dr_bytes) | FunctionList | All recovered functions |
query_calls_to(dr_bytes, target) | QueryReport | Call sites targeting a symbol name |
query_xrefs_to(dr_bytes, symbol) | QueryReport | Data/code cross-references to a symbol |
query_string_decoders(dr_bytes) | QueryReport | Functions with string-decode patterns |
query_complexity_over(dr_bytes, threshold) | QueryReport | Functions with cyclomatic complexity above threshold |
query_capability_sites(dr_bytes, capability) | QueryReport | Sites exercising a named capability |
query_call_graph(dr_bytes) | CallGraph | Whole-program call graph from IR |
from __future__ import annotations
from pathlib import Path
import disrobe
dr: bytes = Path("module.dr").read_bytes()
functions: disrobe.FunctionList = disrobe.query_functions(dr)
fn_count: int = functions.count
callers: disrobe.QueryReport = disrobe.query_calls_to(dr, "malloc")
match_count: int = callers.match_count
complex_fns: disrobe.QueryReport = disrobe.query_complexity_over(dr, threshold=20)
graph: disrobe.CallGraph = disrobe.query_call_graph(dr)
edge_count: int = graph.edge_count
Query report classes
| Class | Notable typed accessors |
|---|---|
FunctionList | kind: str | None, count: int |
QueryReport | kind: str | None, match_count: int |
CallGraph | node_count: int, edge_count: int |
Envelope
envelope_create wraps a payload as a Raw-rung .dr envelope and returns the
encoded bytes. envelope_verify decodes and verifies, returning an
EnvelopeReport.
from __future__ import annotations
import disrobe
envelope: bytes = disrobe.envelope_create(
b"payload",
source_label="inline",
produced_by="my-tool",
)
report: disrobe.EnvelopeReport = disrobe.envelope_verify(envelope)
ok: bool = report.verified
root_hash: str | None = report.root_hash
rung: str | None = report.rung
hot_bytes: int | None = report.hot_bytes
cold_bytes: int | None = report.cold_bytes
version: int | None = report.version
EnvelopeReport accessors
| Property | Type |
|---|---|
verified | bool |
rung | str | None |
version | int | None |
hot_bytes | int | None |
cold_bytes | int | None |
root_hash | str | None |
The sidecar DrEnvelope TypedDict (bindings/python/dr-envelope.pyi) mirrors
the raw on-disk header shape: magic, version, rung, flags, hot_len,
cold_len, root_hash.
Metadata renders
agents_md and skill_md render the AGENTS.md and SKILL.md reconstruction
briefs for a report with metadata attached (or a bare bundle dict), returning
a str. provenance extracts tool/selection/input metadata as a typed
Provenance. Each accepts a typed report or its raw dict and returns the same
result for both. Passing a report whose llm slot is None raises DisrobeError;
passing any other kind of object raises TypeError.
from __future__ import annotations
from pathlib import Path
import disrobe
report: disrobe.PyDecompileReport = disrobe.py_decompile(
Path("module.pyc").read_bytes(), pack="pack-2"
)
agents_brief: str = disrobe.agents_md(report)
skill_brief: str = disrobe.skill_md(report)
prov: disrobe.Provenance = disrobe.provenance(report)
generated_at: str | None = prov.generated_at
schema: str | None = prov.schema
schema_version: str | None = prov.schema_version
Provenance accessors
| Property | Type |
|---|---|
schema | str | None |
schema_version | str | None |
generated_at | str | None |
generated_at is None unless SOURCE_DATE_EPOCH was set when the bundle was built.
Python passes
See also Python decompiler for the full decompiler design.
py_decompile
Decompiles a .pyc with its header to source. Normalized opcode-structure agreement
on the fixed 574-module CPython 3.14 core population is
200-module corpus is 97.66% (6139 of 6286, regression threshold 97.66%).
The 574-module population excludes idlelib and turtledemo. The structural
comparison omits jump targets, most operands and __annotate__ code objects;
see the comparison rules.
from __future__ import annotations
from pathlib import Path
import disrobe
report: disrobe.PyDecompileReport = disrobe.py_decompile(
Path("module.pyc").read_bytes(), roundtrip=True
)
source: str | None = report.source
marshal_version: str | None = report.marshal_version
decompile_version: str | None = report.decompile_version
recovered_directly: bool = report.recovered_directly
fallback_reason: str | None = report.fallback_reason
status: disrobe.RoundtripStatus | None = report.roundtrip_status
roundtrip_detail: str | None = report.roundtrip_detail
interpreter_path: str | None = report.interpreter_path
interpreter_version: str | None = report.interpreter_version
if status == "perfect":
print("recompiled bytecode matched")
Round-tripping (when roundtrip=True) invokes a matching host interpreter to
compile the recovered source and compare bytecode. It does not execute the
recovered program.
py_disasm
from __future__ import annotations
from pathlib import Path
import disrobe
result: disrobe.PyDisasmReport = disrobe.py_disasm(Path("module.pyc").read_bytes())
marshal_version: str | None = result.marshal_version
instruction_count: int = result.instruction_count
text: str | None = result.text
py_deob, py_deob_detect, py_deob_list_passes, py_deob_detect_pass
from __future__ import annotations
import disrobe
obfuscated: str = "exec(__import__('base64').b64decode('cHJpbnQoMSk='))\n"
deob: disrobe.PyDeobReport = disrobe.py_deob(obfuscated, cleanup=True)
peeled_source: str | None = deob.peeled_source
cleanup_source: str | None = deob.cleanup_source
layer_count: int = deob.layer_count
detection: disrobe.PyDeobDetection = disrobe.py_deob_detect(obfuscated)
match_count: int = detection.match_count
passes: list[disrobe.ObfuscatorPass] = disrobe.py_deob_list_passes()
first_id: str | None = passes[0].id if passes else None
if first_id is not None:
per_pass: disrobe.PyDeobDetection = disrobe.py_deob_detect_pass(
obfuscated, first_id
)
print(per_pass.match_count)
py_deob_detect_pass raises DisrobeError for an unknown pass_id.
Python pass report classes
| Class | Notable typed accessors |
|---|---|
PyDecompileReport | source, marshal_version, decompile_version, recovered_directly, fallback_reason, roundtrip_status, roundtrip_detail, interpreter_path, interpreter_version, llm |
PyDisasmReport | marshal_version: str | None, instruction_count: int, text: str | None, llm |
PyDeobReport | peeled_source: str | None, cleanup_source: str | None, layer_count: int, llm |
PyDeobDetection | match_count: int (matched markers), confidence: float | None, llm |
ObfuscatorPass | id: str | None |
PyArmor
pyarmor_detect
Parses a PyArmor wrapper from source text.
from __future__ import annotations
from pathlib import Path
import disrobe
detection: disrobe.PyarmorDetection = disrobe.pyarmor_detect(
Path("wrapped.py").read_text(encoding="utf-8")
)
version: str | None = detection.version
protection: str | None = detection.protection
confidence: str | None = detection.confidence
serial: str | None = detection.serial
python_major: int | None = detection.python_major
python_minor: int | None = detection.python_minor
payload_offset: int | None = detection.payload_offset
payload_size: int | None = detection.payload_size
pyarmor_unpack
Accepts the binary payload extracted from a PyArmor wrapper: the bytes literal
passed as the third argument of __pyarmor__, not the wrapper source. The
earlier keyword wrapper_bytes= is accepted as an alias for payload; passing
both raises TypeError.
Without runtime, v8/v9 payloads return detection metadata and status
"detect-only". Pass the bytes of the matching pyarmor_runtime extension
module as runtime to decrypt the payload statically; the runtime is parsed,
not loaded or executed. A runtime the core cannot parse raises DisrobeError.
The report describes the result and does not expose plaintext bytes. There is
no --allow-dynamic equivalent.
The core static path, supplied with the matching runtime, decrypts each body and
decodes one complete root CodeObject from its header-anchored marshal stream on
the 72 / 72 manifest-named v8/v9 default-trial wrappers.
That structural check does not compare source, emitted .pyc bytes, semantic or
execution behavior, or external-tool output.
from __future__ import annotations
from pathlib import Path
import disrobe
unpacked: disrobe.PyarmorUnpack = disrobe.pyarmor_unpack(
Path("payload.bin").read_bytes(),
runtime=Path("pyarmor_runtime_000000/pyarmor_runtime.pyd").read_bytes(),
)
status: disrobe.PyarmorUnpackStatus | None = unpacked.status
pyarmor_version: str | None = unpacked.pyarmor_version
protection_kind: str | None = unpacked.protection_kind
plaintext_len: int | None = unpacked.plaintext_len
digest: str | None = unpacked.plaintext_blake3_hex
bcc_blob_count: int | None = unpacked.bcc_blob_count
inner_cipher_recovered_co: int | None = unpacked.inner_cipher_recovered_co
pyarmor_classify
from __future__ import annotations
from pathlib import Path
import disrobe
payload: bytes = Path("payload.bin").read_bytes()
classification: disrobe.PyarmorClassification = disrobe.pyarmor_classify(
Path("wrapped.py").read_text(encoding="utf-8"), payload
)
script_type: str | None = classification.script_type
bootstrap_import: str | None = classification.bootstrap_import
disposition: str | None = classification.disposition
rft_enabled: bool = classification.rft_enabled
ecc_enabled: bool = classification.ecc_enabled
The sidecar PyarmorDetection TypedDict (bindings/python/pyarmor-detection.pyi)
names the confidence and protection Literal values used in the raw dict.
PyArmor report classes
| Class | Notable typed accessors |
|---|---|
PyarmorDetection | version, protection, confidence, serial, python_major, python_minor, payload_offset, payload_size, llm |
PyarmorUnpack | status, pyarmor_version, protection_kind, plaintext_len, plaintext_blake3_hex, bcc_blob_count, inner_cipher_recovered_co, llm |
PyarmorClassification | script_type, bootstrap_import, disposition, rft_enabled, ecc_enabled |
PyInstaller and Nuitka
pyinstaller_extract / pyinstaller_entry_bytes
from __future__ import annotations
from pathlib import Path
import disrobe
image: bytes = Path("app.exe").read_bytes()
archive: disrobe.PyInstallerArchive = disrobe.pyinstaller_extract(image)
entry_count: int = archive.entry_count
encrypted: bool = archive.encrypted
encryption_key_present: bool = archive.encryption_key_present
python_major: int | None = archive.python_major
python_minor: int | None = archive.python_minor
archive_json: str = archive.to_json()
print(archive_json)
Use an entry name from the archive report to recover its bytes:
from __future__ import annotations
from pathlib import Path
import disrobe
image: bytes = Path("app.exe").read_bytes()
entry_name: str = "main"
main_payload: bytes = disrobe.pyinstaller_entry_bytes(image, entry_name)
print(len(main_payload))
nuitka_detect / nuitka_extract
from __future__ import annotations
from pathlib import Path
import disrobe
image: bytes = Path("app.exe").read_bytes()
det: disrobe.NuitkaDetection = disrobe.nuitka_detect(image)
flavor: str | None = det.flavor
version: str | None = det.version
wheel_marker: str | None = det.wheel_marker
onefile_payload_offset: int | None = det.onefile_payload_offset
onefile_payload_compressed: bool = det.onefile_payload_compressed
extraction: disrobe.NuitkaExtraction = disrobe.nuitka_extract(image)
variant: str | None = extraction.variant
The sidecar FreezerManifest TypedDict (bindings/python/freezer-manifest.pyi)
describes the manifest schema for cx-freeze/py2exe/shiv/pex/py-oxidizer/briefcase
freezer families; reach it via report.raw.
PyInstaller/Nuitka report classes
| Class | Notable typed accessors |
|---|---|
PyInstallerArchive | entry_count: int, encrypted: bool, encryption_key_present: bool, python_major: int | None, python_minor: int | None, llm |
NuitkaDetection | flavor: str | None, version: str | None, wheel_marker: str | None, onefile_payload_offset: int | None, onefile_payload_compressed: bool, llm |
NuitkaExtraction | variant: str | None, llm |
Hermes (React Native)
All 8 functions in the committed hermesc-built HBC v96 sample lift at 100% op-coverage with 0 fallback ops. A 122,633-function production React Native bundle parses with no module-parse failure in the local scale harness.
from __future__ import annotations
from pathlib import Path
import disrobe
bundle: bytes = Path("index.android.bundle").read_bytes()
disasm_result: disrobe.HermesDisassembly = disrobe.hermes_disasm(bundle)
function_count: int = disasm_result.function_count
identifier_count: int = disasm_result.identifier_count
string_count: int = disasm_result.string_count
lift: disrobe.HermesLift = disrobe.hermes_lift(bundle)
function_surface_count: int = lift.function_surface_count
info: disrobe.HermesInfo = disrobe.hermes_info(bundle)
version: int | None = info.version
header_size: int | None = info.header_size
Hermes report classes
| Class | Notable typed accessors |
|---|---|
HermesDisassembly | function_count: int, identifier_count: int, string_count: int, llm |
HermesLift | function_surface_count: int, string_count: int, identifier_count: int, llm |
HermesInfo | version: int | None, function_count: int | None, string_count: int | None, header_size: int | None, llm |
Mach-O and Swift
from __future__ import annotations
from pathlib import Path
import disrobe
data: bytes = Path("universal.dylib").read_bytes()
macho: disrobe.MachoReport = disrobe.macho_dump(data)
kind: str | None = macho.kind
fat_entry_count: int = macho.fat_entry_count
slice_count: int = macho.slice_count
swift: disrobe.SwiftReport = disrobe.swift_analyze(data)
container: str | None = swift.container
swift_fat_entry_count: int = swift.fat_entry_count
swift_slice_count: int = swift.slice_count
Mach-O report classes
| Class | Notable typed accessors |
|---|---|
MachoReport | kind: str | None, fat_entry_count: int, slice_count: int, llm |
SwiftReport | container: str | None, fat_entry_count: int, slice_count: int, llm |
JVM and Android
131 of 131 JVM methods recompile error-free under javac (CI floor 131 of 131,
JDK 25). 100% of verifier-presented committed DEX classes pass -Xverify:all, with 37 of 155 classes link-skipped and never reaching the verifier.
from __future__ import annotations
from pathlib import Path
import disrobe
cls: disrobe.JvmClass = disrobe.jvm_parse_class(Path("Hello.class").read_bytes())
major_version: int | None = cls.major_version
minor_version: int | None = cls.minor_version
method_count: int = cls.method_count
field_count: int = cls.field_count
constant_pool_count: int = cls.constant_pool_count
dex: disrobe.DexFileReport = disrobe.jvm_parse_dex(Path("classes.dex").read_bytes())
class_count: int = dex.class_count
dex_method_count: int = dex.method_count
decompiled: disrobe.JvmDecompiledClass = disrobe.jvm_decompile_class(
Path("Hello.class").read_bytes()
)
source: str | None = decompiled.source
fully_lifted_methods: int = decompiled.fully_lifted_methods
fallback_methods: int = decompiled.fallback_methods
decompiled_dex: disrobe.JvmDecompiledDex = disrobe.jvm_decompile_dex(
Path("classes.dex").read_bytes()
)
dex_source: str | None = decompiled_dex.source
source_count: int = decompiled_dex.source_count
dex_fully_lifted_methods: int = decompiled_dex.fully_lifted_methods
dex_fallback_methods: int = decompiled_dex.fallback_methods
detections: disrobe.DetectionList = disrobe.jvm_detect(Path("obf.class").read_bytes())
detection_count: int = detections.count
backends: disrobe.JvmBackends = disrobe.jvm_backends()
jvm_count: int = backends.jvm_count
android_count: int = backends.android_count
apk: disrobe.ApkResources = disrobe.apk_resources(Path("app.apk").read_bytes())
package: str | None = apk.package
manifest_xml: str | None = apk.manifest_xml
resource_entry_count: int = apk.resource_entry_count
certificate_count: int = apk.certificate_count
dex_count: int = apk.dex_count
jvm_backends and dotnet_backends probe the host for installed external
tools but never shell out to them. Counts are informational only.
JVM/Android report classes
| Class | Notable typed accessors |
|---|---|
JvmClass | major_version: int | None, minor_version: int | None, method_count: int, field_count: int, constant_pool_count: int, llm |
DexFileReport | string_count: int, type_count: int, class_count: int, method_count: int, llm |
JvmDecompiledClass | source: str | None, method_count: int, field_count: int, fully_lifted_methods: int, fallback_methods: int |
JvmDecompiledDex | source: str | None, source_count: int, class_count: int, method_count: int, fully_lifted_methods: int, fallback_methods: int |
DetectionList | count: int |
JvmBackends | jvm_count: int, android_count: int, llm |
ApkResources | package: str | None, manifest_xml: str | None, resource_entry_count: int, certificate_count: int, dex_count: int, llm |
.NET
from __future__ import annotations
from pathlib import Path
import disrobe
pe_bytes: bytes = Path("Sample.dll").read_bytes()
pe: disrobe.DotnetPe = disrobe.dotnet_parse_pe(pe_bytes)
bitness: str | None = pe.bitness
machine: int | None = pe.machine
section_count: int = pe.section_count
entry_point_rva: int | None = pe.entry_point_rva
metadata: disrobe.DotnetMetadata = disrobe.dotnet_parse_metadata(pe_bytes)
version: str | None = metadata.version
major_runtime_version: int | None = metadata.major_runtime_version
stream_count: int = metadata.stream_count
detection: disrobe.DotnetDetection = disrobe.dotnet_detect(pe_bytes)
primary: str | None = detection.primary
match_count: int = detection.match_count
analysis: disrobe.DotnetAnalysis = disrobe.dotnet_analyze(pe_bytes)
pe_bitness: str | None = analysis.pe_bitness
is_native_aot: bool = analysis.native_aot
primary_protector: str | None = analysis.primary_protector
opcode_spec_coverage_pct: int | None = analysis.opcode_spec_coverage_pct
decompilation: disrobe.DotnetDecompilation = disrobe.dotnet_decompile(pe_bytes)
module_name: str | None = decompilation.module_name
methods_decompiled: int | None = decompilation.methods_decompiled
methods_bodyless: int | None = decompilation.methods_bodyless
methods_failed: int | None = decompilation.methods_failed
decoders: disrobe.DotnetDecoders = disrobe.dotnet_recover_decoders(pe_bytes)
pure_decoders_found: int | None = decoders.pure_decoders_found
constants_recovered: int = decoders.constants_recovered
image_bytes: bytes = Path("HelloAppAot.exe").read_bytes()
native_aot: disrobe.DotnetNativeAot = disrobe.dotnet_native_aot(image_bytes)
runtime_label: str | None = native_aot.runtime_label
method_count: int = native_aot.method_count
methods_with_code_range: int = native_aot.methods_with_code_range
managed_signature_count: int = native_aot.managed_signature_count
register_signature_count: int = native_aot.register_signature_count
backend_list: disrobe.BackendList = disrobe.dotnet_backends()
available_count: int = backend_list.available_count
dotnet_native_aot reads an ahead-of-time compiled .NET image rather than a
managed assembly, so it accepts PE, ELF and Mach-O input. It never raises on a
file that is not a NativeAOT image: is_native_aot is then false and every
count is zero.
managed_signature_count and register_signature_count partition the method
bodies disrobe recovered. A body counts as managed when its prototype was
reattached from the image's own managed signature. It counts as registers when
reattachment abstained and the body kept the types the machine-code lifter
inferred from register use, which happens for generics, varargs, a hidden
struct return, and the other cases the pass declines rather than guesses. The
two counts separate a prototype disrobe sourced from metadata from one it could
only infer, so read them as a pair.
.NET report classes
| Class | Notable typed accessors |
|---|---|
DotnetPe | bitness: str | None, machine: int | None, section_count: int, entry_point_rva: int | None, llm |
DotnetMetadata | version: str | None, major_runtime_version: int | None, stream_count: int, llm |
DotnetDetection | primary: str | None, match_count: int, llm |
DotnetAnalysis | pe_bitness: str | None, clr_runtime_version: str | None, native_aot: bool, primary_protector: str | None, opcode_spec_coverage_pct: int | None, llm |
DotnetDecompilation | module_name: str | None, methods_decompiled: int | None, methods_bodyless: int | None, methods_failed: int | None, llm |
DotnetDecoders | pure_decoders_found: int | None, constants_recovered: int, llm |
DotnetNativeAot | is_native_aot: bool, runtime_label: str | None, recovered_symbol_count: int, recovered_name_count: int, eager_class_constructors: int | None, type_count: int, method_count: int, methods_with_entrypoint: int, methods_with_code_range: int, methods_with_body: int, managed_signature_count: int, register_signature_count: int, llm |
WebAssembly
1034 of 1034 opcodes lowered across the 38 parseable corpus modules (133 of 133
functions), against an instruction inventory wasm-tools produced rather than
disrobe. 57 of 57 execution-eligible functions are execution-equivalent under
wasmtime.
from __future__ import annotations
from pathlib import Path
import disrobe
wasm_bytes: bytes = Path("module.wasm").read_bytes()
analysis: disrobe.WasmAnalysis = disrobe.wasm_analyze(wasm_bytes)
import_count: int = analysis.import_count
export_count: int = analysis.export_count
func_count: int | None = analysis.func_count
code_size_bytes: int | None = analysis.code_size_bytes
has_dwarf: bool = analysis.has_dwarf
detection: disrobe.WasmDetection = disrobe.wasm_detect(wasm_bytes)
obfuscator: str | None = detection.obfuscator
confidence: float | None = detection.confidence
has_name_section: bool = detection.has_name_section
function_count: int | None = detection.function_count
WebAssembly report classes
| Class | Notable typed accessors |
|---|---|
WasmAnalysis | import_count: int, export_count: int, func_count: int | None, code_size_bytes: int | None, has_dwarf: bool, llm |
WasmDetection | obfuscator: str | None, confidence: float | None, has_name_section: bool, function_count: int | None, llm |
JavaScript
Detects 11 bundlers. The explicit target hint accepts auto, webpack4,
webpack5/webpack, vite, rollup, esbuild, turbopack, and bun.
An unrecognized hint string raises DisrobeError.
from __future__ import annotations
from pathlib import Path
import disrobe
source: str = Path("main.js").read_text(encoding="utf-8")
detection: disrobe.JsDetection = disrobe.js_detect(source)
family: str | None = detection.family
confidence: float | None = detection.confidence
marker_count: int = detection.marker_count
unminified: disrobe.JsUnminify = disrobe.js_unminify(source)
recovered_source: str | None = unminified.source
bundle_source: str = Path("bundle.js").read_text(encoding="utf-8")
unbundled: disrobe.JsUnbundle = disrobe.js_unbundle(bundle_source)
module_count: int = unbundled.module_count
bundler: str | None = unbundled.bundler
unbundled_hinted: disrobe.JsUnbundle = disrobe.js_unbundle(
bundle_source, bundler="webpack5"
)
JavaScript report classes
| Class | Notable typed accessors |
|---|---|
JsDetection | family: str | None, confidence: float | None, marker_count: int, llm |
JsUnminify | source: str | None, llm |
JsUnbundle | module_count: int, bundler: str | None, llm |
Lua
Detects, decompiles, and deobfuscates 14 Lua obfuscator families, with 16 catalog entries once Luau and GLua dialect detectors are included. IronBrew2 2.7.0 is reversed against real committed output with a Lua execution differential.
from __future__ import annotations
from pathlib import Path
import disrobe
bytecode: bytes = Path("chunk.luac").read_bytes()
det: disrobe.LuaDetection = disrobe.lua_detect(bytecode)
lua_format: str | None = det.format
decompiled: disrobe.LuaDecompilation = disrobe.lua_decompile(bytecode)
decompiled_source: str | None = decompiled.source
fidelity: str | None = decompiled.fidelity
warning_count: int = decompiled.warning_count
deob: disrobe.LuaDeobfuscation = disrobe.lua_deobfuscate(
Path("obf.lua").read_text(encoding="utf-8"), authorize=True
)
obfuscator: str | None = deob.obfuscator
deobfuscated: str | None = deob.deobfuscated
fully_recovered: bool = deob.fully_recovered
passes_run_count: int = deob.passes_run_count
recovered_string_count: int = deob.recovered_string_count
Lua report classes
| Class | Notable typed accessors |
|---|---|
LuaDetection | format: str | None, llm |
LuaDecompilation | source: str | None, fidelity: str | None, warning_count: int, llm |
LuaDeobfuscation | obfuscator: str | None, deobfuscated: str | None, fully_recovered: bool, passes_run_count: int, recovered_string_count: int, llm |
Go
85%+ type-name recovery on stripped go1.26 fixtures; 838 of 838 measured, pinned by the gate.from __future__ import annotations
from pathlib import Path
import disrobe
go_bytes: bytes = Path("binary").read_bytes()
analysis: disrobe.GoAnalysis = disrobe.go_analyze(go_bytes)
image_kind: str | None = analysis.image_kind
pclntab_version: str | None = analysis.pclntab_version
buildversion: str | None = analysis.buildversion
ptr_size: int | None = analysis.ptr_size
symbols: disrobe.GoSymbols = disrobe.go_symbols(go_bytes)
version_label: str | None = symbols.version_label
function_count: int = symbols.function_count
source_file_count: int = symbols.source_file_count
package_count: int = symbols.package_count
pclntab: disrobe.GoPclntab = disrobe.go_pclntab(go_bytes)
version: str | None = pclntab.version
func_count: int | None = pclntab.func_count
garble: disrobe.GarbleReport = disrobe.go_garble(go_bytes)
quality: str | None = garble.quality
detection_score: int | None = garble.detection_score
recovered_string_count: int = garble.recovered_string_count
Go report classes
| Class | Notable typed accessors |
|---|---|
GoAnalysis | image_kind: str | None, pclntab_version: str | None, buildversion: str | None, ptr_size: int | None, llm |
GoSymbols | version_label: str | None, function_count: int, source_file_count: int, package_count: int, llm |
GoPclntab | version: str | None, ptr_size: int | None, func_count: int | None, image_kind: str | None, llm |
GarbleReport | quality: str | None, detection_score: int | None, recovered_string_count: int, llm |
Ruby
from __future__ import annotations
from pathlib import Path
import disrobe
ruby_bytes: bytes = Path("hello.rb.enc").read_bytes()
det: disrobe.RubyDetection = disrobe.ruby_detect(ruby_bytes, source_path="hello.rb.enc")
flavor: str | None = det.flavor
analysis: disrobe.RubyAnalysis = disrobe.ruby_decompile(
ruby_bytes, source_path="hello.rb.enc"
)
ruby_flavor: str | None = analysis.flavor
source_path: str | None = analysis.source_path
input_len: int | None = analysis.input_len
Ruby report classes
| Class | Notable typed accessors |
|---|---|
RubyDetection | flavor: str | None, llm |
RubyAnalysis | flavor: str | None, source_path: str | None, input_len: int | None, llm |
PHP
from __future__ import annotations
from pathlib import Path
import disrobe
php_bytes: bytes = Path("obfuscated.php").read_bytes()
det: disrobe.PhpDetection = disrobe.php_detect(php_bytes)
kind: str | None = det.kind
confidence: str | None = det.confidence
open_tag_offset: int | None = det.open_tag_offset
has_halt_compiler: bool = det.has_halt_compiler
scan: disrobe.PhpScan = disrobe.php_scan(php_bytes)
hit_count: int = scan.hit_count
family_count: int = scan.family_count
decoded: disrobe.PhpDecode = disrobe.php_decode(php_bytes, max_depth=10)
php_source: str | None = decoded.source
layer_count: int = decoded.layer_count
residual_eval: bool = decoded.residual_eval
PHP report classes
| Class | Notable typed accessors |
|---|---|
PhpDetection | kind: str | None, confidence: str | None, open_tag_offset: int | None, has_halt_compiler: bool, llm |
PhpScan | hit_count: int, family_count: int, llm |
PhpDecode | source: str | None, layer_count: int, residual_eval: bool, llm |
Shell
from __future__ import annotations
from pathlib import Path
import disrobe
batch_script: str = Path("dropper.bat").read_text(encoding="utf-8")
batch_result: disrobe.BatchDeobReport = disrobe.batch_deobfuscate(
batch_script, args=["/run"]
)
output: str | None = batch_result.output
embedded_payload_count: int = batch_result.embedded_payload_count
decrypted_stage_count: int = batch_result.decrypted_stage_count
commands_emulated: int | None = batch_result.commands_emulated
ps_script: str = Path("obf.ps1").read_text(encoding="utf-8")
ps_det: disrobe.PowershellDetection = disrobe.powershell_detect(ps_script)
obfuscator: str | None = ps_det.obfuscator
ps_confidence: float | None = ps_det.confidence
marker_count: int = ps_det.marker_count
ps_deob: disrobe.PowershellDeobfuscation = disrobe.powershell_deobfuscate(ps_script)
ps_output: str | None = ps_deob.output
level: str | None = ps_deob.level
transformation_count: int = ps_deob.transformation_count
Shell report classes
| Class | Notable typed accessors |
|---|---|
BatchDeobReport | output: str | None, embedded_payload_count: int, decrypted_stage_count: int, commands_emulated: int | None, llm |
PowershellDetection | obfuscator: str | None, confidence: float | None, marker_count: int, llm |
PowershellDeobfuscation | output: str | None, level: str | None, transformation_count: int, llm |
Containers
103 container families are detected. Of these, 102 carry a generic in-tree extractor and LUKS1 carries a bounded raw-volume-key extraction route. 30 of them write member bytesfrom a committed input that match an independent extractor. See container docs for the full family list.
from __future__ import annotations
from pathlib import Path
import disrobe
container_bytes: bytes = Path("archive.zip").read_bytes()
det: disrobe.ContainerDetection = disrobe.container_detect(container_bytes)
detected: bool = det.detected
kind: str | None = det.kind
is_zip_family: bool = det.is_zip_family
members: disrobe.ContainerMembers = disrobe.container_members(container_bytes)
fmt: str | None = members.format
size: int | None = members.size
listing: disrobe.ContainerListing | None = members.listing
entry_count: int = members.entry_count
Container report classes
| Class | Notable typed accessors |
|---|---|
ContainerDetection | detected: bool, kind: str | None, is_zip_family: bool, llm |
ContainerMembers | format: str | None, size: int | None, listing: ContainerListing | None, entry_count: int, llm |
Pickle
Nothing is ever unpickled; the VM is symbolic.
from __future__ import annotations
from pathlib import Path
import disrobe
pkl: bytes = Path("model.pkl").read_bytes()
listing: str = disrobe.pickle_disasm(pkl)
decompilation: disrobe.PickleDecompilation = disrobe.pickle_decompile(pkl)
pkl_source: str | None = decompilation.source
safety: disrobe.PickleSafety = disrobe.pickle_safety(pkl)
severity: str | None = safety.severity
finding_count: int = safety.finding_count
import_count: int = safety.import_count
reduce_count: int | None = safety.reduce_count
trace: disrobe.PickleTrace = disrobe.pickle_trace(pkl)
protocol: int | None = trace.protocol
memo_count: int | None = trace.memo_count
max_stack_depth: int | None = trace.max_stack_depth
global_ref_count: int = trace.global_ref_count
trace_reduce_count: int | None = trace.reduce_count
polyglot: disrobe.PicklePolyglot = disrobe.pickle_polyglot(pkl)
is_pickle: bool = polyglot.is_pickle
is_polyglot: bool = polyglot.is_polyglot
kind_count: int = polyglot.kind_count
ml_report: disrobe.PickleMlReport = disrobe.pickle_ml_detect(
Path("model.pt").read_bytes()
)
fmt: str | None = ml_report.format
framing: str | None = ml_report.framing
embedded_count: int = ml_report.embedded_count
Pickle report classes
| Class | Notable typed accessors |
|---|---|
PickleDecompilation | source: str | None, llm |
PickleSafety | severity: str | None, finding_count: int, import_count: int, reduce_count: int | None, llm |
PickleTrace | protocol: int | None, memo_count: int | None, max_stack_depth: int | None, global_ref_count: int, reduce_count: int | None, llm |
PicklePolyglot | is_pickle: bool, is_polyglot: bool, kind_count: int, llm |
PickleMlReport | format: str | None, framing: str | None, embedded_count: int, llm |
Editable IR objects
CodeObject, Instruction, and Symbol let you load a Disasm- or Raw-rung
.dr envelope, modify it in Python, and write a fresh integrity-hashed .dr.
Instruction
from __future__ import annotations
import disrobe
instr: disrobe.Instruction = disrobe.Instruction(
offset=0,
mnemonic="mov",
operands=["rax", "rbx"],
bytes=b"\x48\x89\xd8",
)
instr.branch_target = None
flow: disrobe.InstructionFlow = instr.flow
text: str = instr.text()
| Member | Type | Notes |
|---|---|---|
offset | int | Mutable |
mnemonic | str | Mutable |
operands | list[str] | Mutable |
bytes | bytes | Mutable |
branch_target | int | None | Mutable |
flow | @property InstructionFlow | Read-only |
text() | -> str | Rendered disassembly line |
Symbol
from __future__ import annotations
import disrobe
sym: disrobe.Symbol = disrobe.Symbol(address=0x1000, name="entry", kind="function")
sym.name = "main"
sym.kind = "export"
| Member | Type | Notes |
|---|---|---|
address | int | Mutable |
name | str | Mutable |
kind | SymbolKind | Mutable |
CodeObject
from __future__ import annotations
from pathlib import Path
import disrobe
co: disrobe.CodeObject = disrobe.CodeObject.from_dr(Path("module.dr").read_bytes())
instruction_count: int = co.instruction_count
symbol_count: int = co.symbol_count
source_hash: str = co.source_hash
produced_by: str = co.produced_by
instrs: list[disrobe.Instruction] = co.instructions
syms: list[disrobe.Symbol] = co.symbols
metadata: dict[str, str] = co.metadata
capabilities: list[str] = co.capabilities
new_sym: disrobe.Symbol = disrobe.Symbol(
address=0x2000, name="renamed_fn", kind="function"
)
co.add_symbol(new_sym)
co.set_metadata("analysis", "patched")
co.add_capability("NETWORK_CONNECT", 1)
fresh_dr: bytes = co.to_dr()
Path("module_patched.dr").write_bytes(fresh_dr)
CodeObject.from_dr parses a Disasm- or Raw-rung .dr envelope. to_dr produces a
fresh envelope with a recomputed integrity hash. The set_instructions and
set_symbols methods replace the full list; add_instruction / add_symbol
append. set_metadata(key, value) sets a single string key; clear_metadata
resets all. set_llm(sidecar) attaches or removes the metadata sidecar dict.
| Member | Signature | Notes |
|---|---|---|
from_dr | staticmethod(dr_bytes: bytes) -> CodeObject | Parse existing envelope |
instructions | @property -> list[Instruction] | |
set_instructions | (instructions: list[Instruction]) -> None | Replace |
add_instruction | (instruction: Instruction) -> None | Append |
symbols | @property -> list[Symbol] | |
set_symbols | (symbols: list[Symbol]) -> None | Replace |
add_symbol | (symbol: Symbol) -> None | Append |
instruction_count | @property -> int | |
symbol_count | @property -> int | |
source_hash | str | Mutable attribute |
produced_by | str | Mutable attribute |
metadata | @property -> dict[str, str] | |
set_metadata | (key: str, value: str) -> None | |
clear_metadata | () -> None | |
capabilities | @property -> list[str] | |
add_capability | (name: str, major: int) -> None | |
llm | @property -> dict[str, Any] | None | |
set_llm | (sidecar: dict[str, Any] | None) -> None | |
to_dr | () -> bytes | Produce fresh integrity-hashed envelope |
Scope
autoreturns the plan document without writing stage trees.extract(data, out_dir)writes container members, andflutter_engine_symbolscan use an explicit cache directory.- External backend tools (
jvm_backends,dotnet_backends,native_probe_backends) are probed for availability but never executed. - AS3, BEAM (beyond
disasm/parse), and the freezer family beyond PyInstaller/Nuitka have no dedicated bindings in this release. - No SARIF/NDJSON emitters and no
servedaemon; drive the CLI or daemon directly.
Browser playground
The playground analyzes files in your browser using the WebAssembly build of Disrobe. Your input stays on your device. Analysis runs in a worker, with results displayed beside the input.
Start with a sample
Find a mode by typing its language, name, or operation in the sidebar search. On a narrow screen, type in the mode picker and use the arrow keys and Enter to select a result. Each runnable mode loads its example and starts analysis. Use Sample to restore it, Upload to choose a file, or drop a file into the input panel. Once you upload or edit an input, switching modes keeps that input. Browser Back and Forward restore the selected mode without discarding it. Sample explicitly replaces it with the mode's example.
Text inputs can be edited directly; Run or Ctrl+Enter analyzes the current input. Binary uploads retain their original bytes, including when used with string or indicator analysis. Recovered source and inspection reports can be downloaded.
Use Stop to cancel analysis and sample downloads. Switching modes or editing the input
also stops pending work and clears its result. Sample downloads and analyses each time out
after 30 seconds. The playground accepts files up to 64 MiB; use the CLI for larger inputs
or longer runs. The analysis engine has a 512 MiB WebAssembly memory limit. A stopped or
failed engine is discarded; the next request starts a fresh worker. The engine is a 32-bit
wasm32 build, so offsets and sizes are 32-bit words there. The parsers use checked
arithmetic on file-controlled values in both builds, but the hostile-input fuzz and
parse-resilience suites run only on 64-bit hosts; the playground's parsers are not fuzzed at
32 bits.
APK inspection accepts up to 4096 archive entries, 32 MiB of decoded data per entry, and 128 MiB across the archive. The decoded manifest is limited to 2 MiB. Resource-only APKs are supported. Recovered manifests, resource XML, and reconstructed values files have individual downloads; the JSON report retains the remaining metadata. APK signing blocks are parsed without verifying signatures.
PHAR archives have a member selector, binary downloads, and Use as input to route an extracted member to another pass. Extraction handles one member at a time, up to 32 MiB. The archive list accepts up to 4096 members and 1 MiB of member names. Duplicate or colliding names are rejected. The shared parser also limits declared aggregate output to 256 MiB. Archive checksums and flags are metadata, not signature verification.
Dart Kernel recovery lists embedded source files individually, with Dart highlighting and a download for each file. The JSON report includes libraries, classes, and procedures. The browser accepts up to 4096 source records. Components with no recovered source retain their structure report.
Go inspection accepts executables up to 16 MiB and exposes build information, searchable functions, runtime types, and complete JSON downloads. Addresses use hexadecimal strings to preserve all 64 bits. The browser accepts up to 65,536 function and source-file records, 16,384 type and interface links, and 131,072 nested type records. JSON results are limited to 32 MiB; long previews are shortened while downloads retain the complete report. Garble recovery, DWARF, and embedded-file extraction use the CLI. The bundled Go example includes the Go runtime; its license accompanies the sample.
PyArmor module recovery pairs a wrapper of up to 1 MiB with its runtime of up to 16 MiB. Support covers standard PyArmor versions 8 and 9 outer modules. The result includes code-object counts, names, strings, and downloads of the outer module, its marshal payload, and the JSON report. Inner bytecode is unchanged. Replacing a sample wrapper clears its bundled runtime; choose the runtime distributed with your input. Both files stay in the browser.
Source-map recovery accepts a JSON map or JavaScript with an inline map, up to 1 MiB. It lists embedded originals with highlighted previews and exact file downloads, including empty files. Indexed maps retain each section's source root and ignored-file metadata. Missing originals are listed separately. External map references require an uploaded map file; the browser does not fetch them. Recovery accepts up to 4096 sources, 1024 sections, 16 nesting levels, and 65,536 mapping segments. Shortened previews retain complete downloads.
JavaScript unbundling accepts bundles up to 1 MiB. Search module and chunk names, inspect highlighted source, and download individual modules or the full JSON report. The browser limits extraction to its configured module-count capacity and 8 MiB of module data; JSON output also has an 8 MiB limit. Module bodies retain the bundler's transformations. Use source-map recovery for embedded originals. The example was built with Webpack 5 from the geometry and inventory fixtures in the repository.
Source formatting supports JavaScript, JSX, TypeScript and TSX with Prettier 3.9.6. Choose the matching language to retain JSX and TypeScript syntax. Files up to 1 MiB are formatted in a worker with a 30-second deadline and an 8 MiB output limit. Downloads contain the complete output, including retained comments. Formatting does not lint or type-check the code. Embedded languages inside template strings are unchanged.
Keyboard users can select Skip to analysis to bypass navigation. The binary viewer supports arrow keys, Home, End, Page Up, Page Down, and Shift to extend a selection.
JVM class recovery accepts individual .class files up to 8 MiB. Inspect recovered
Java, select a method's bytecode, or download the full metadata report. The report
retains exception ranges, bodyless methods, fallback counts, and decoding errors.
Java downloads use the emitted class name. The bundled example comes from
Hierarchy.java.
Browser limits are 1024 methods, 4096 fields, 16,384 constant-pool slots, 16,384
instructions per method, and 65,536 instructions per class. Each method may have
up to 256 exception handlers and 2048 branch targets. JSON output is capped at
8 MiB. JAR traversal and related-class discovery use the CLI.
.NET inspection accepts managed DLLs and executables up to 8 MiB. Select a method
to inspect its CIL or recovered C#, F#, and Visual Basic body. Each language retains
its emitted, bodyless, and failed method counts. Downloads contain the complete
selected method or assembly report, including exception regions and metadata.
Integer operands remain exact decimal text; floating-point operands retain their
bit patterns. The example comes from
Shapes.cs.
The browser accepts 512 types, 4096 fields, 1024 methods, and 32,768 metadata rows.
It rejects malformed definition signatures and repeated member tokens. Instruction,
exception, and branch limits match the JVM workspace; combined recovered source
and serialized JSON each have an 8 MiB limit. External .NET backends use the CLI.
The theme control offers Dark and Light. Dark is the default. Your selection is saved locally when browser storage is available.
Browser checks
The browser suite passes 310 desktop and mobile checks across 57 sample modes, including single-classfile JVM recovery and managed .NET assembly recovery. Each sample mode is analyzed again through Run and checked in both themes. The 228 catalog accessibility scans report no critical or serious violations.
Performance was measured on the PHP detection screen by editing its sample, running analysis, and switching themes. On a Ryzen 9 9950X3D2 host with Chromium at 4× CPU slowdown and the cache disabled, the desktop and mobile runs measured LCP at 608 and 308 ms, CLS at 0.00065 and 0, and INP at 144 and 48 ms. These are two local preview runs over an unthrottled loopback connection. The browser results include the cases, conditions, report hashes, and reproduction commands.
Available modes
| Input or task | Operations |
|---|---|
| General triage | File-signature identification, route suggestions, strings, indicators, behavior, anti-analysis signals, secrets, entropy, and YARA rule generation |
Python .pyc | Disassembly and source recovery |
JVM .class | Java recovery, method bytecode, class metadata, and complete source/report downloads |
Managed .dll and .exe | C#, F#, and Visual Basic method recovery, CIL listings, and assembly metadata |
| Go executables | Build information, functions, source paths, runtime types, interface tables, and JSON downloads |
| PyArmor wrappers | Header inspection, version and protection detection, mode classification, and paired-runtime outer-module recovery |
| JavaScript and TypeScript | JS/JSX/TS/TSX formatting, bundle detection, module extraction, embedded originals from source maps, indexed sections, ignored-file metadata, source filtering, and individual downloads |
| Hermes bytecode | Recovered JavaScript structure, per-function instructions, recovery counts, and indexed strings with identifier kinds |
| Python pickle | Safety classification, disassembly, source rendering, symbolic trace, and polyglot detection |
| WebAssembly | Module analysis, obfuscator detection, WAT, Rust/TypeScript/C lifts, control-flow graphs, signatures, GC types, exception handling, memories, component manifests, source maps, and runtime preludes |
| Lua | Dialect detection and source recovery |
| PHP | Detection and supported wrapper peeling |
| PHAR | Member listing, selected-file extraction, binary downloads, and reuse as input |
| Dart Kernel | Embedded source files, individual downloads, and program structure |
| Ruby | YARV and mruby source recovery, YARV instructions, and artifact analysis |
| Android APK | Manifest and resource XML, reconstructed values, native library metadata, and signing blocks |
| Erlang and Elixir BEAM | Source recovery |
| Flash / ActionScript | ABC decompilation |
| Scripted languages | Artifact analysis |
| Shell and batch | Detection and deobfuscation |
| Mobile bundles | Bundle detection |
| Swift and Objective-C | Mach-O architecture, named types and fields, protocols, selectors, and symbol metadata |
Output varies by mode: decoded source, instructions, graphs, metadata, or findings. A detection result identifies a format or protection mechanism; it does not mean the original source was recovered.
Execution and scope
The browser passes inspect input bytes. Pickle tracing reconstructs an object graph symbolically
without importing its globals or invoking __reduce__. Python and WebAssembly recovery parse and
lower bytecode. The browser build excludes the PyArmor dynamic-capture path and native BCC lift.
Use the CLI for directories, recursive archive workflows, automatic recovery chains, native executable decompilation, external backends, and offline forensic reports. Recompilation and runtime comparisons use separate host toolchains; they are not performed by the playground. See the command reference and library APIs for those entry points.
Forensics and malware-safety posture
Analysts run disrobe against hostile input that must not detonate. Everything below states what executes and what does not, so you can decide what to run inside a sandbox.
No native or host-interpreter sample execution by default
By default, disrobe does not execute a sample natively or through a host interpreter. Default paths parse bytes, decode bytecode, walk structures, and emit derived artifacts. They do not unpickle, call __reduce__, run a packed binary, or invoke a sample's entry point.
The native CLI's wasm feature also enables a bounded in-process Wasmtime probe for recognized wasm-mixer decryptors. The probe has 100,000,000 fuel, a 2-second epoch deadline, a 64 MiB linear-memory cap, one instance, a bounded table, and no host functions; unknown imports trap. The browser facade and analysis-only consumers do not include this probe.
This holds for the entire pickle suite in particular. disrobe pickle trace runs a symbolic VM: it walks the opcode stream and builds the object graph without instantiating a single real object or resolving a single real global. disrobe pickle safety grades danger statically. You can audit a downloaded .pt or .pkl for what it would do on load without ever letting it load.
Opt-in gated paths
Only --allow-dynamic executes sample code. --allow-bcc enables additional static analysis. Neither path is enabled by default.
| Path | Gate | What it does |
|---|---|---|
| PyArmor v6/v7 dynamic-hook | --allow-dynamic | Runs the obfuscated wrapper in a watched subprocess to capture marshal streams. Watchdog timeout via --dynamic-timeout (default 60s). On timeout or exit the wrapper's whole process tree is killed: on Windows a Job Object holds every descendant; on Unix the process group is killed, so a descendant that leaves its group (for example through setsid) is not contained. |
| PyArmor BCC native-body analysis | --allow-bcc | Parses extracted BCC objects in-process and attempts x86-64 pseudo-C analysis. It does not execute the sample or invoke Ghidra. |
Once wrapper and runtime discovery succeeds, omitting --allow-bcc makes a detected BCC unpack return DR-PYARM-0050 before version-specific unpacking. Native builds use the Microsoft x64 ABI for Windows x86-64, the System V ABI for Linux x86-64, and AAPCS64 for Darwin ARM64. Unknown architecture IDs produce a typed refusal instead of selecting an ABI. Wasm builds record that native lifting is unavailable. The dedicated command and path-aware automatic extraction publish the same bounded recovery JSON, pseudo-C, and recovered Python skeleton. Each unmodeled function retains its native disassembly and typed reason.
If you must use --allow-dynamic, do it inside an isolated sandbox (a disposable VM or container with no network and no access to anything you care about). disrobe gives you the watchdog timeout and a captured-marshal manifest, but a dynamic hook is, by definition, executing adversarial code. The non-BCC v8/v9 paths remain static and need no execution opt-in. BCC analysis is also static but separately gated.
Subprocess backends
The optional external backends (Ghidra, CFR, Vineflower, jadx, ILSpy, dnSpy, de4dot, Rizin) run as subprocesses over the artifact, not by executing the sample's own logic. Command lines are constructed from configuration and sometimes user input; command injection or argument smuggling there is in scope for the security policy.
Hardened parsing surface
disrobe parses adversarial binary input constantly, so the parsing surface is hardened deliberately:
- Format decoders avoid
unsafe. The remaining unsafe code is limited to audited boundary code such as C interop, WASM exports, archive/io shims, build/install helpers, and native-loader interfaces. Any panic or abort on adversarial input that is not a cleanResult::Erris a bug. - Zip-bombs, decompression bombs, container-recursion bombs, and malformed-length-field bombs are defused by the shared quota machinery in
crates/disrobe-binfmt/src/quota.rs, whose per-entry ratio the phar reader mirrors in-crate rather than calling (per-entry cap, aggregate cap, recursion-depth cap). - zip-slip and equivalent path traversals are sanitized on every container extraction path.
- The
.drenvelope decoder is fuzzed. Read-past-end, integer overflow, and BLAKE3-mismatch acceptance are all in scope. - A depth cap (default 8) and content-hash cycle detection stop a malicious input from making a chain recurse forever.
Reporting
A way to make a default path execute a sample, escape a container, or crash the parser is a security issue. Report it privately, never as a public issue. See Security.
Threat model
This page is the explicit trust-boundary analysis for disrobe. It states what the tool treats as untrusted, where the boundaries are drawn, what each boundary defends against, and what is deliberately out of scope. It complements the operational Security policy and the Forensics and malware-safety posture: the security policy says how to report a problem and what is in scope for a report; this page says what the design assumes an attacker can do and where the walls are.
Disrobe treats every input byte as attacker-controlled. The analyst is trusted to select the input and analysis boundary; parsing packed executables, protected code, or obfuscated bytecode must stay within that boundary.
Trust boundaries at a glance
| Boundary | Untrusted input |
|---|---|
| Sample parsing | File bytes, inline bytes, or stdin |
| Envelope decoding | Cached or peer-supplied .dr artifacts |
| Daemon requests | Requests over an enabled server transport |
| Backend execution | External tools and separately authorized sample execution |
The four boundaries apply according to the selected command: sample parsing, envelope decoding, daemon requests, and subprocesses or dynamic execution. Network collection also occurs through disrobe prowl. External backends can run under a command's default auto selection policy; execution of a sample's own logic requires the separate dynamic opt-in described below.
Boundary 1: untrusted sample bytes
Trusted side: the disrobe process, the host, the analyst's intent.
Untrusted side: the sample. It arrives as a filesystem path, a bytes_b64 blob over the daemon, or stdin. The parser must assume every length field, offset, opcode, and nested container is chosen by an adversary to break it.
What this boundary defends against, and how:
| Threat | Defense | Where |
|---|---|---|
| Memory-corruption via the parser | Rust-first decoders with unsafe excluded from format parsing; remaining unsafe code is isolated to audited boundary code such as C interop, WASM exports, archive/io shims, build/install helpers, and native-loader interfaces. | workspace lint config |
| Panic / abort on adversarial input | Any non-Result::Err failure on hostile bytes is a bug. Decoders return errors, they do not unwrap. | every disrobe-pass-* decoder |
| Decompression and zip bombs | Per-entry cap, aggregate cap, and an observed-ratio ceiling in the shared quota machinery. | crates/disrobe-binfmt/src/quota.rs |
| Path traversal (zip-slip and kin) | Every container extraction path routes through sanitize_entry_path and siblings before any write. | crates/disrobe-binfmt/src/quota.rs |
| Container-recursion bombs | Recursion-depth cap plus content-hash cycle detection in the chain runner (default depth 8). | chain runner |
| Malformed-length-field bombs | Length fields are validated against remaining buffer length before allocation; no length field is trusted to size an allocation. | binfmt + envelope decoder |
| Signature defeat (scrambled magic, renamed sections, corrupted markers) | Detection falls back from magic to validated internal structure for supported formats. | crates/disrobe-binfmt/src/structural.rs |
The envelope decoder and the container layer are the two most-exposed parsing surfaces and are fuzzed.
Signature defeat and header scrambling
A damaged magic value or renamed section can prevent a signature-based detector from identifying a format. When the internal tables remain coherent, Disrobe can recognize supported damaged headers and attempt static recovery.
disrobe identifies a format by magic on the fast path, then falls back to structural validation when the magic is absent or wrong. The fallback parses far enough into the format's own header tables to confirm they refer to one another consistently, which keeps false positives low (a loose pattern match would not satisfy a full cross-referenced walk):
- PE. Resolve
e_lfanewto aPE\0\0signature, then a COFF header with a known machine type, a PE32/PE32+ optional header, and a section table that fits the file. A corruptede_lfanewitself is recovered by scanning for thePE\0\0whose following headers validate, so a flippedMZand a manglede_lfanewtogether still parse. - ELF. Validate the class / endianness / version bytes and confirm the program- and section-header table offsets, entry sizes, and counts are self-consistent against the declared entry sizes and the file length. A zeroed
\x7fELFdoes not move any of those fields. - Mach-O. Walk the load-command stream (
ncmds/sizeofcmdsand eachcmdsize) for a single-arch image, or the arch offset/size table for a fat image, accepting only when the run lands exactly at its declared end. - Native packers (UPX). Detect and unpack by the decompressor stub's
PackHeader(a known method id, self-consistent compressed/uncompressed lengths, a plausible version) located by structural scan rather than by theUPX!marker, and resolve packed-section data through the structural PE header rather than a literalMZ. A renamed-section, corrupted-marker UPX still unpacks byte-identically. - ZIP and zip-family archives. Anchor on the End-of-Central-Directory record (the format's authoritative trailer) and confirm its central-directory offset and size land on a record carrying the central-directory-header signature. A scrambled first local header does not move the EOCD.
- DEX. Confirm
header_size == 0x70, a legal endian tag, and string / type / proto / method / class section sizes and offsets self-consistent againstfile_sizeand the byte length; a zeroeddex\n0XX\0magic still parses, defaulting the version when the version triple is unreadable. - JVM class file. Confirm a major version in the JVM-known range and walk the constant pool (Utf8 lengths, long/double double-slots) to its end; a scrambled
0xCAFEBABEstill parses. - wasm. Confirm a version word of 1 and that the section id/size LEB128 stream validates end to end, terminating exactly at end of file; a scrambled
\0asmstill lifts.
The structural detector is shared (identify_by_structure) so the central sniffer (classify.rs), the container detector, and the native packer and identity passes all benefit from the same validated logic, and every validator is bounds-checked against deliberately malformed input. Python .pyc / marshal detection is handled on a separate path and is not part of this fallback. The behavior is proven by adversarial tests that take real committed corpus samples, scramble their magic bytes, section names, and markers, and assert disrobe still detects the correct format and, where it unpacks or parses, still produces the correct recovered output.
Boundary 2: untrusted .dr envelopes
The .dr envelope is content-addressed (BLAKE3-rooted, rkyv hot payload + postcard cold sidecar). A cache hit, a peer-supplied envelope, or a downstream stage all cross this boundary. An envelope is not trusted merely because it claims a hash.
What this boundary defends against:
- Read-past-end. The zero-copy rkyv access path is bounds-checked at decode; an envelope whose declared lengths exceed its actual bytes is rejected, not read past.
- Integer overflow in length math. Offset and length arithmetic is checked; an envelope cannot induce a wrapping add that yields an in-bounds-looking slice.
- BLAKE3-mismatch acceptance. The root hash is recomputed over the payload and compared; an envelope whose content does not match its claimed root is rejected. This is the property that makes
--no-cachean optimization toggle and not a correctness toggle: a cache hit is provably the same bytes.
The decoder lives in crates/disrobe-ir/src/envelope.rs and is fuzzed against exactly these three attacks.
Boundary 3: the network surface (disrobe serve)
HTTP, gRPC, LSP, WebSocket, and MCP requests cross a client trust boundary. Analysis methods take inline bytes; MCP workspace methods have a separate, bounded filesystem contract.
- Analysis requests accept inline sample bytes rather than a sample path. MCP
annotresolves a target beneath the current workspace before reading it and writing a sidecar;renamereads and writes the fixed.disrobe/notes/renames.jsonfile. See the daemon security posture. - All request bodies reject unknown fields via
#[serde(deny_unknown_fields)], closing field-smuggling and forward-compat-confusion attacks. - A non-loopback HTTP bind emits a
tracing::warn!banner at startup, so an operator who exposes the daemon beyond localhost is told so explicitly.
The daemon is intended for localhost / trusted-network use; it is not an authenticated multi-tenant service, and exposing it publicly is an operator decision the warning banner flags.
Boundary 4: subprocess backends and optional sample execution
This is the boundary an analyst can choose to not cross at all. Two distinct sub-cases:
Subprocess backends over the artifact (not the sample's logic). Optional external tools (Ghidra, CFR, Vineflower, jadx, ILSpy, dnSpy, de4dot, Rizin) run as subprocesses over the derived artifact. They never execute the sample's own entry point. The exposure here is command-line construction: command lines are built from configuration and sometimes from user input, so command injection and argument smuggling are the in-scope threats, mitigated by constructing argument vectors directly rather than shelling out through a string.
Dynamic execution of the sample. One path can run adversarial code. It is not enabled by default and sits behind a named flag:
| Path | Gate | What runs |
|---|---|---|
| PyArmor v6/v7 dynamic-hook | --allow-dynamic | The obfuscated wrapper, in a watched subprocess, to capture marshal streams. Watchdog via --dynamic-timeout (default 60s). Its process tree is killed on timeout or exit: a Job Object on Windows, the process group on Unix, which does not reach a descendant that leaves its group. |
--allow-bcc is a separate static-analysis gate and does not cross this execution boundary. Once wrapper and runtime discovery succeeds, omitting the flag makes the unpack return DR-PYARM-0050 before version-specific unpacking. With the flag, native builds analyze extracted BCC objects in process without executing the sample or invoking Ghidra. Windows x86-64 uses the Microsoft x64 ABI, Linux x86-64 uses the System V ABI, and Darwin ARM64 uses AAPCS64. Unknown architecture IDs and unavailable native targets produce typed refusals. The dedicated command and path-aware automatic extraction publish the same bounded recovery JSON, pseudo-C, and recovered Python skeleton. Unmodeled functions remain present with native disassembly and a typed reason.
The default static paths (the pickle symbolic VM and non-BCC v8/v9 PyArmor peels) need no execution opt-in: they parse and walk, they do not detonate. BCC analysis is also static but separately gated. When dynamic execution is unavoidable, run it inside a disposable, network-isolated sandbox. disrobe gives you a watchdog and a captured-marshal manifest, but a dynamic hook is, by definition, executing attacker code.
Non-execution stance (restated as an invariant)
The default-static stance is a design invariant, not a configuration default that can drift:
disrobedoes not unpickle.disrobe pickle tracewalks the opcode stream symbolically, building the object graph without instantiating a single real object or resolving a single real global;disrobe pickle safetygrades danger statically.disrobedoes not call__reduce__, does not run a packed binary, does not invoke a sample's entry point on any default path.- Any way to make a default path execute a sample is a vulnerability, in scope for the Security policy.
Plugin and WASM isolation
The signed plugin host executes WebAssembly components in Wasmtime with fuel metering, a wall-clock deadline, and a linear-memory cap. Its component linker supplies no ambient filesystem or network imports. These limits constrain guest execution; they do not establish the correctness of a plugin's analysis output.
Supply chain
The integrity of the binary the analyst runs is its own boundary:
- Fixture provenance. The native packer manifest at
corpus/native/packers/MANIFEST.tomldistinguishes committed inputs from local and unavailable inputs and records their acquisition recipes. Fixture bytes remain untrusted. - Artifact signing. The release workflow signs archives and software bills of materials with cosign. Verification commands are in the Security policy.
- Dependency checks. CI runs
cargo denyfor dependency advisories, bans, licenses, and sources, alongside warnings-denied Clippy. The checks are defined under.github/workflows/.
Explicitly out of scope
The threat model deliberately does not defend against:
- Decompilation-output correctness on adversarial bytecode.
disrobewill sometimes emit wrong source for hostile input; the round-trip metric exists to flag this. A non-byte-perfect decompile is correctness work, not a security boundary. - Expensive inputs within resource limits. A 66 MiB Hermes bundle can take substantial time to decompile. Bounded work proportional to input complexity falls outside this threat model. Small inputs that trigger unbounded work remain in scope under Boundary 1.
- Vulnerabilities inside wrapped third-party tools. Ghidra, jadx, CFR, and friends have their own security channels; we forward where we can identify the upstream.
- Trusting the analyst.
disrobeassumes the operator is authorized and acting in good faith; paths that expose--i-have-authorizationrequire that assertion, but the tool does not, and cannot, adjudicate authorization.
Reporting
If you find a way to make a default path execute a sample, escape a container or MCP workspace boundary, accept a hash-mismatched envelope, or make an inline-byte analysis method read a client-selected path, report it privately through the Security policy.
GitHub Action
disrobe ships a composite GitHub Action that downloads the matching release binary, runs the selected command against one path, validates the emitted SARIF, and uploads that report to GitHub code scanning. It runs in the runner shell without a Docker image or source build.
The recorded local example runs the Action's detect and auto steps against the 69-byte WebAssembly fixture. It includes the emitted SARIF, step outputs and recovery grade. Reproduce it with capture-action.mjs.
Quick start
Add a workflow that scans build artifacts on every push and surfaces findings in the Security -> Code scanning tab.
name: disrobe-scan
on:
push:
pull_request:
permissions:
contents: read
security-events: write
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: 1-3-7/disrobe@v0.10.6
with:
path: dist/
command: auto
fail-on: failed
The security-events: write permission lets the upload step publish SARIF to code scanning. A workflow without that permission must set upload-sarif: false or the upload step will fail.
What it does
- Resolves the runner OS/arch to a release target triple (
x86_64-unknown-linux-gnu,aarch64-apple-darwin,x86_64-pc-windows-msvc, and the rest of the release matrix). - Downloads
disrobe-<version>-<target>.tar.zst(or.zipon Windows) plusSHA256SUMSfrom this repository's Releases, and verifies the archive againstSHA256SUMSbefore extracting. A checksum mismatch fails the step. - Runs
disrobe <command> <args> <path> --sarif --out <out-dir>, capturing the SARIF document. - Rejects a failed analyzer process or missing, malformed, or non-Disrobe SARIF output.
- Uploads validated SARIF to code scanning and the recovered-artifact directory as a workflow artifact.
Inputs
| Input | Default | Description |
|---|---|---|
path | (required) | One file or directory path to analyze. Passed as one argument without shell expansion. |
command | auto | disrobe subcommand (auto, scan, behavior, ...). |
args | "" | Extra arguments inserted after the command and before the path (for example --max-depth 12). |
version | action ref, then latest | Release tag to download (v0.10.6, latest). |
fail-on | never | Fail the step at or above a verdict: never, incomplete, failed, any. |
sarif-file | disrobe.sarif | Path the action writes the SARIF to. |
out-dir | disrobe-out | Directory disrobe writes recovered artifacts into. |
upload-sarif | true | Upload SARIF to GitHub code scanning. |
upload-artifact | true | Upload the recovered-artifact directory. |
token | ${{ github.token }} | Token used to download the release asset. |
Outputs
| Output | Description |
|---|---|
sarif | Path to the SARIF file the action produced. |
verdict | Worst verdict observed (ok, incomplete, failed). |
summary | One-line human-readable run summary. |
Pinning the version
Pin a tag for reproducible CI:
- uses: 1-3-7/disrobe@v0.10.6
with:
path: suspect.bin
version: v0.10.6
Leaving version unset downloads the release matching the action ref, falling back to the rolling latest release. Pin a tag in production so a new release cannot change your scan results silently.
Gating recovery failures
Fail the step when recovery is incomplete or fails:
- uses: 1-3-7/disrobe@v0.10.6
with:
path: build/
command: auto
args: --max-depth 12
fail-on: incomplete
fail-on: failed rejects failed recovery reports. fail-on: incomplete and fail-on: any also reject incomplete recovery reports. These thresholds grade the chain recovery verdict; a SARIF finding or a detected packed format does not by itself cross the threshold. Use code-scanning rules when a pull request must be blocked on selected findings. Analyzer execution errors and invalid SARIF always fail the Action, regardless of fail-on.
When fail-on rejects a valid recovery report, the Action still uploads its validated SARIF before returning the failed result. Analyzer errors and invalid SARIF do not produce an upload path.
Security posture
The action verifies every download against SHA256SUMS before extracting it, and every release archive additionally carries a cosign signature bundle you can verify out of band. disrobe itself performs pure static analysis by default; see the forensics and malware-safety posture.
pre-commit hook
The pre-commit hook scans staged files and rejects a commit when a configured detector identifies a packed or protected artifact. Analysis errors also reject the commit.
Setup
Add the hook to a consuming project's .pre-commit-config.yaml:
repos:
- repo: https://github.com/1-3-7/disrobe
rev: v0.10.6
hooks:
- id: disrobe
Then install it:
pre-commit install
The hook requires Bash and the disrobe binary on PATH (see installation), or an explicit Disrobe path in DISROBE_BIN. It uses python3 to parse the chain report. Set DISROBE_PYTHON to select another Python 3 executable.
On Windows, use Git Bash or add Git for Windows' bin directory to the shell's PATH. For a default installation and a project virtual environment:
$env:PATH = "C:\Program Files\Git\bin;$env:PATH"
$env:DISROBE_PYTHON = (Resolve-Path .venv/Scripts/python.exe).Path
pre-commit run --all-files
What it detects
For each staged file, the hook runs disrobe auto <file> --json with a temporary output directory and checks the chain's chosen detector picks. The default configuration blocks these passes:
| Detector pass | Blocks |
|---|---|
native.packer-unpack | UPX, Petite, kkrunchy, and other native packers |
pyarmor.unpack | PyArmor-protected Python |
pyinstaller.extract | PyInstaller one-file / one-dir builds |
sourcedefender.decrypt | SourceDefender-encrypted Python |
nuitka.extract | Nuitka-compiled binaries |
pyfreeze.extract | Frozen-Python blobs |
Source-level obfuscation detectors are excluded from the default configuration.
Tuning
Environment variables configure the gate:
| Variable | Default | Effect |
|---|---|---|
DISROBE_BIN | disrobe | Path to the disrobe binary. |
DISROBE_PYTHON | python3 | Path to a Python 3 executable. |
DISROBE_BLOCK_PASSES | the six passes above | Comma-separated detector pass-ids to block. |
DISROBE_BLOCK_FAMILIES | (empty) | Comma-separated detector families to additionally block. |
The family override is broader but noisier. disrobe's source-level obfuscation classifiers (js.deob, lua.deob, py.deob) are tuned to attempt recovery aggressively, so they can fire at high confidence on ordinary text and markdown. Enabling DISROBE_BLOCK_FAMILIES=obfuscator-wrapper,packer-archive will catch source-level obfuscation but expect false positives on benign files; scope it with the hook's files:/exclude: patterns.
repos:
- repo: https://github.com/1-3-7/disrobe
rev: v0.10.6
hooks:
- id: disrobe
files: '\.(exe|dll|so|dylib|pyc|pyz|bin)$'
Bypassing
A legitimately-committed protected artifact can skip the hook for one commit:
SKIP=disrobe git commit -m "vendor signed third-party binary"
Security posture
The hook runs disrobe auto, which performs pure static analysis by default; it does not execute the staged file. See the forensics and malware-safety posture. The scan writes recovered artifacts only into a temporary directory that the hook deletes on exit; your working tree is never modified.
MCP server
disrobe ships a Model Context Protocol server so MCP clients can drive deobfuscation and decompilation directly as tools. It speaks MCP over stdio via rmcp.
Analysis tools take inline base64 bytes and return structured JSON. Workspace and provenance tools also accept metadata such as symbol names or provenance maps. The annot workspace tool resolves its target beneath the current workspace before reading it and writing an annotation sidecar; rename uses the fixed .disrobe/notes/renames.json file. See the security posture for these path boundaries and the inline-byte analysis contract.
Running it
Two equivalent entry points:
disrobe serve --mcp
disrobe-mcp
Registering with an MCP client
Most clients accept a JSON server entry. Point command at disrobe (or disrobe-mcp) and run over stdio:
{
"mcpServers": {
"disrobe": {
"command": "disrobe",
"args": ["serve", "--mcp"]
}
}
}
Tool catalog
| Tool | Input | Output |
|---|---|---|
auto | bytes_b64, optional max_depth | Chain verdict, detected formats, and per-pass recovery summary. Auto-detects and chains disrobe's Python + native-packer passes. |
secret_scan | bytes_b64, optional redact | Secret findings with byte offsets. redact: true replaces detected values throughout the response. Raw values remain the default. |
decompile | bytes_b64, optional max_depth | Every terminal recovered-source artifact (language-keyed text), for example a .pyc decompiled to Python. |
native_match | a_bytes_b64, b_bytes_b64, optional stage, function, limit | Function matches between two native images. |
wasm_lift | bytes_b64, target | WebAssembly source lift with instruction coverage; available in builds with the wasm feature. |
ioc | bytes_b64 | Indicators of compromise: URLs, domains, IPs, emails, paths, registry keys, wallet addresses, crypto constants (one decode layer of base64/hex). |
behavior | bytes_b64, optional imports | Static capability summary across network, filesystem, process-exec, registry-persistence, crypto, anti-analysis, and dynamic-code categories, with MITRE ATT&CK ids. |
strings | bytes_b64, optional min_len, decode | Printable ASCII + UTF-16 strings, optionally decoding base64/rot/stack-string obfuscation, tagged with their encoding. |
coverage | bytes_b64 | Claimed, slack, unclaimed, and truncated byte ranges in an executable image, including overlaps and a coverage ratio. |
verify | bytes_b64 | Verify a .dr envelope: blake3 root hash, rung, hot/cold sizes. |
rename | old, new, optional note | Append a symbol-rename record to .disrobe/notes/renames.json. |
annot | target | Regenerate and validate an annotation sidecar under .disrobe/annotations/. |
provenance_lookup | map_json, line | Look up the provenance entry for a line in a provenance-map document. |
call_graph | bytes_b64, optional token_budget, optional cursor | Page through function summaries and classified calls. Direct calls distinguish function starts, function interiors, non-function symbols, unresolved addresses, ambiguous overlaps, and indirect calls. |
xrefs | bytes_b64, function_id, optional token_budget, optional cursor | Return cross-references to the function identified by a content-bound id. |
function_summary | bytes_b64, function_id, optional token_budget | Return address, extent, export state, instruction and block counts, complexity, and incoming, outgoing, and indirect-call counts. |
neighborhood | bytes_b64, entry_ids, depth, optional direction, optional token_budget, optional cursor | Page through a cycle-safe caller, callee, or bidirectional neighborhood. |
The four navigation tools accept a Disasm- or Mir-rung .dr envelope. A function id binds the envelope source hash to the function address and adds a content-derived discriminator when multiple functions share that address, so an id or cursor from another input is rejected. Each response mirrors its structured JSON in a text content block for MCP client compatibility. The complete tool result enforces a 2,048 to 32,768-byte serialized UTF-8 ceiling and declares the corresponding o200k_base budget. Every o200k_base token encodes at least one byte, so the byte ceiling also bounds the token count; the round-trip tests hold call_graph to the ceiling across two pages of a large committed image. A row that cannot fit the selected ceiling returns DR-MCP-0662 instead of replaying the same cursor.
The committed recovery grade covers direct calls in one stripped x86-64 ELF against its distinct unstripped toolchain twin. Other architectures, executable formats, indirect-target recovery methods, and optimized call forms remain unmeasured by that grade. Disasm and Mir envelopes from those sources are accepted as typed input, but the server does not infer a missing format or architecture from the envelope payload.
The auto and decompile tools cover disrobe's Python and native-packer surface (PyArmor, PyInstaller, SourceDefender, Nuitka, PyFreeze, .pyc disassembly + decompilation, native packers, and container formats). Use the CLI for the full language matrix. The HTTP daemon provides classification, routing information and envelope operations.
Example call
A client calls decompile with the base64 of a .pyc and receives the recovered Python:
{
"name": "decompile",
"arguments": { "bytes_b64": "4w0NCgAAAAA..." }
}
{
"schema": "disrobe.decompile/v1",
"verdict": "Complete",
"recovered": [
{ "pass": "py.decompile", "language": "Python", "formatted": true, "source": "x = a + b\n..." }
]
}
Security posture
The server performs pure static analysis by default and never executes the supplied bytes. It rejects empty or malformed base64 with a typed error, and rejects unknown JSON fields on every tool. Analysis tools do not accept filesystem paths for sample input, so a client cannot redirect analysis to an arbitrary local file by passing a path-like string. See the forensics and malware-safety posture and the threat model.
Editor plugins
The editors/ directory contains plugins for VS Code, IDA Pro, Ghidra, and Binary Ninja. Each calls an installed Disrobe binary. The VS Code plugin also starts the LSP service when enabled in its settings.
Plugin sources, manifests, and installers are generated by xtask plugins and checked by xtask sync --check. The VS Code build dependencies are pinned in its npm lockfile.
Auto-installer
Clone the repository and run the auto-installer script for your platform:
Linux / macOS (bash):
bash editors/install.sh vscode
bash editors/install.sh ida
bash editors/install.sh ghidra
bash editors/install.sh binja
bash editors/install.sh ida --ida-dir /path/to/ida/plugins
bash editors/install.sh ghidra --ghidra-scripts ~/my-scripts
Windows (PowerShell):
.\editors\install.ps1 vscode
.\editors\install.ps1 ida
.\editors\install.ps1 ghidra
.\editors\install.ps1 binja
.\editors\install.ps1 ida -IDADir 'C:\IDA\plugins'
.\editors\install.ps1 ghidra -GhidraScripts 'C:\ghidra_scripts'
The VS Code installer requires Node.js 20 or later, npm, and the code command on PATH. It downloads the locked build dependencies, compiles a VSIX, and installs it through VS Code. The other installers copy plugin sources to the selected editor directory.
Visual Studio Code
Requirements: VS Code 1.85 or later. Build disrobe from source and add the binary to your PATH, or set disrobe.executablePath in VS Code settings.
Manual install steps:
Run these commands from editors/vscode:
npm ci --ignore-scripts
npm run package
code --install-extension disrobe.vsix --force
Reload VS Code after installation. You can also choose Extensions: Install from VSIX and select disrobe.vsix. Local installation requires no Marketplace account.
The extension activates automatically and starts disrobe serve --stdio when disrobe.lsp.enable is true (the default). This requires a Disrobe build with the server feature. Set the option to false to use only the CLI commands.
All commands appear under the disrobe category in the Command Palette. The seven file-analysis commands also appear in the editor right-click menu for files on disk. They read the saved file, so save pending edits before running them.
Settings:
| Setting | Default | Description |
|---|---|---|
disrobe.executablePath | "disrobe" | Path to the disrobe binary. |
disrobe.lsp.enable | true | Start the LSP daemon on activation. |
disrobe.lsp.trace | "off" | LSP trace level: off, messages, or verbose. |
disrobe.auto.outDir | "" | Output directory for disrobe auto. |
Commands:
| Command | Description |
|---|---|
disrobe.auto | Auto: run full deobfuscation pipeline |
disrobe.detect | Detect: identify obfuscator / packer |
disrobe.strings | Strings: extract and deobfuscate strings |
disrobe.ioc | IOC: extract indicators of compromise |
disrobe.behavior | Behavior: summarize binary capabilities (MITRE) |
disrobe.identify | Identify: compiler / packer / protector fingerprint |
disrobe.scan | Scan: leak credentials scanner |
disrobe.startServer | Manually start the LSP daemon |
disrobe.stopServer | Stop the LSP daemon |
disrobe.showOutput | Open the disrobe output channel |
IDA Pro
Requirements: IDA Pro 7.6 or later with IDAPython 3 backend. disrobe binary on your PATH.
Manual install steps:
- Copy
editors/ida/disrobe_ida.pyto your IDA plugins directory:- Linux/macOS:
~/.idapro/plugins/ - macOS (app):
~/Library/Application Support/hex-rays/ida pro/plugins/ - Windows:
%APPDATA%\Hex-Rays\IDA Pro\plugins\
- Linux/macOS:
- Restart IDA Pro.
The plugin registers all disrobe subcommands as menu actions under Edit > Plugins > disrobe and assigns default hotkeys. Invoking an action runs disrobe <subcommand> <input_file_path> on the file IDA has open and prints the output to the IDA output window.
Actions and default hotkeys:
| Action | Hotkey |
|---|---|
| Auto: run full deobfuscation pipeline | Alt-Shift-A |
| Detect: identify obfuscator / packer | Alt-Shift-D |
| Strings: extract and deobfuscate strings | Alt-Shift-S |
| IOC: extract indicators of compromise | Alt-Shift-I |
| Behavior: summarize binary capabilities (MITRE) | Alt-Shift-B |
| Identify: compiler / packer / protector fingerprint | Alt-Shift-F |
| Scan: leak credentials scanner | Alt-Shift-C |
Ghidra
Requirements: Ghidra 10.3 or later. disrobe binary on your PATH.
Manual install steps:
- Copy
editors/ghidra/DisrobeAnalyzer.javato a directory listed in Ghidra's Script Manager search paths:- Default location:
~/ghidra_scripts/ - Or add a custom path via
Window > Script Manager > Manage Script Directories.
- Default location:
- In Ghidra:
Window > Script Manager, click the refresh icon to pick up the new script. - Double-click
DisrobeAnalyzerin the script list to run it.
When run, the script reads the path of the currently loaded program, shows a dialog to choose a disrobe action, shells out to the disrobe binary, and prints the output to the Ghidra console.
To assign a keybinding, right-click DisrobeAnalyzer in the script list and choose Assign Key Binding.
Binary Ninja
The plugin requires a Binary Ninja edition with Python plugin support. Binary Ninja Free does not support plugins.
Run the installer with binja, then restart Binary Ninja. Commands appear under Plugins > disrobe and operate on the current file. Set DISROBE_BINARY in the installed __init__.py if the Disrobe executable is not on PATH. See the plugin instructions for manual installation paths.
Contributing
This guide covers building, testing, and extending Disrobe, including the evidence required for recovery claims.
Building and testing
Use the Rust toolchain pinned in rust-toolchain.toml; rustup selects it automatically in the checkout:
cargo build --release
cargo test -p <crate> --features <the crate's test features>
Building the Python bindings requires Python on PATH; set PYO3_PYTHON to select a specific interpreter.
With lefthook installed, run cargo xtask setup-hooks once to install the Git hooks. The pre-push
hook checks changed crates with cargo xtask prepush; use cargo xtask prepush --full to check the
whole workspace.
The JVM decompiler can be memory-intensive on adversarial input. Prefer per-crate test runs over a bare workspace-wide
cargo test --workspacewhen iterating locally.
The pre-push hook batches changed crates under cargo-nextest 0.9.115 or newer. Install it with
cargo install cargo-nextest --locked. The pre-push profile runs independent tests concurrently,
allows at most two external-toolchain tests at once, disables retries, terminates a test after ten
minutes for measured heavy crates and two minutes otherwise, and fails when a child retains the
test's output handles for more than two seconds. Because nextest does not run doctests, the hook
follows it with one scoped cargo test --doc invocation over the same crates.
Push CI also runs the fixed grader allowlist in xtask/data/push_graders.toml on Ubuntu, with a
30-minute job limit. Its 11 targets each cite a reference test and a mutation control; the manifest
names six ecosystems without an eligible grader and gives a reason for each. Run
cargo run --locked -p xtask --no-default-features -- push-graders check to validate the manifest
and citations. Run
cargo run --locked -p xtask --no-default-features -- push-graders run to list and execute every
selected test locally. It fails if any test is skipped or the listed, run, and passed counts differ.
Name the features a crate hides its tests behind
Some crates keep test-bearing modules behind a non-default feature. A per-crate run must name the feature that exposes its selected test target:
cargo test -p disrobe-cli --no-default-features --features auto --test it -- auto_dalvik_feature_gate::
cargo test -p disrobe-pass-mobile --features native-image --test flutter_engine_fallback_identity
cargo test -p disrobe-nir-lift --features as3,beam,dotnet,jvm,lua,python,ruby
cargo test -p disrobe-pass-py-disasm --features alt-runtimes-native
The CLI form covers a refusal that exists only when auto is enabled and jvm is disabled.
The Flutter engine identity test requires native-image for ELF parsing.
cargo run -p xtask -- health enforces this. It reads every crate's default feature set, finds
every test-bearing file the default set removes, and fails when a crate hides tests that no entry in
HIDDEN_TEST_SURFACE in xtask/src/feature_gated_tests.rs declares. It also reads every per-crate
test command written in the README, in docs/src, and in the workflows, and fails when one of them
names a test target the command's own feature set compiles away, or names no feature for a crate
that hides tests. The failure names the crate and prints the command to use instead.
The quality bar
Every commit on main must pass the workspace clippy gate with zero warnings:
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt -p <crate> -- --check
The workspace lints are strict by design: unwrap_used is denied, expect_used is treated as a defect in production paths, and todo! and unimplemented! are denied. New code is fully type-annotated and self-documenting; the codebase carries durable context in dedicated docs rather than inline comments. Unsafe code is restricted to audited boundary code and does not belong in ordinary parsing or recovery paths.
README graphs
The dark-theme benchmark and architecture SVGs in the README are generated, not drawn by hand. The data lives in xtask/data/*.json (every plotted value cites its source gate or harness inline), and xtask renders deterministic SVGs into docs/assets/:
cargo run -p xtask -- graphs # regenerate docs/assets/*.svg
cargo run -p xtask -- graphs --check # fail if committed SVGs are stale (CI runs this)
After changing a number in xtask/data/, rerun graphs and commit the regenerated SVGs; the graphs CI job rejects any drift. Numbers must identify their committed test gate or local measurement harness, comparison rule, and denominator. Distinguish independent comparisons from self-reported coverage; no competitor recovery percentage is plotted.
Docs and the wiki
These pages under docs/src are the single source of truth. The GitHub wiki is generated from them by scripts/wiki_sync.py and the wiki-sync workflow, which runs on every push to main that touches docs/. Do not edit the wiki directly; it is overwritten on the next sync. Edit the page here, then preview the generated wiki locally:
python scripts/wiki_sync.py --out ./.wiki-build # build the wiki tree
python scripts/wiki_sync.py --check --out ./.wiki-build # fail on drift
Adding a pass
A new ecosystem pass is a new disrobe-pass-<name> crate that:
- Implements the shared
Passtrait with an ID, detector, output kind, and artifact transformation. - Uses the IR representation appropriate to its output; raw-to-raw extraction is a valid transition.
- Ships a
pass_run_envelope_roundtriptest and at least one real-fixture integration test incrates/disrobe-cli/tests/. - Wires its standardized emits, returning explicit
applicable: falsestubs for emits it cannot produce.
Every capability claim must be backed by a fixture in corpus/ and a passing test; nothing aspirational ships as done. Fixtures are baked locally from known-good inputs by corpus/generate.{sh,ps1}; copyrighted third-party obfuscated bytecode is never committed to the public corpus.
Recovery evidence
Test recovery against independently produced corpus artifacts and the upstream format specification. Hand-built fixtures should cover boundaries and failure cases as well. Record the input versions, recovered members, and remaining losses; distinguish detection from recovery in the command output and documentation.
Contributor license
Keep pull requests focused. Write each commit subject as a lowercase Conventional Commit with a
module scope, such as fix(pass-lua): bound constant pool reads, and use a GitHub noreply address
if you want to keep your email private. Preserve existing legal attribution; do not add unrelated
authorship or co-author credits.
Contributions are accepted only under the Disrobe Contributor Assignment and License Agreement, which implements Section 8 of the LICENSE. Before a pull request can be merged, post the complete acceptance statement from that agreement as a comment on the pull request, from the account that authored the commits it covers. Opening a pull request grants no rights in Disrobe beyond the LICENSE.
Reporting bugs
Generate an environment report to attach to an issue:
disrobe bug-report --out report.md
disrobe bug-report --out - # write to stdout
For security issues, do not open a public issue; use the private advisory channel. See Security.
Security
Report a vulnerability privately through GitHub's advisory channel, never in a public issue: https://github.com/1-3-7/disrobe/security/advisories/new. Include a description and its impact, a minimal reproducer (input bytes, command line, expected and observed behaviour), the disrobe --version output, and your OS and architecture.
The full policy lives in SECURITY.md: supported versions, response times, what is in and out of scope, the hardening posture, the attack-surface inventory, and how to verify release signatures.
Input bounds
Every parser treats its input as hostile. Counts, sizes, recursion depth, work and output are capped by named constants. cargo xtask regen generates this page from every module-level constant in crates/*/src whose name starts with MAX_ or ends with _LIMIT, _BUDGET or _CAP, and cargo xtask regen --check fails when it is stale. The kind column is derived from the constant name.
The exceeded column states what happens when input goes past the bound. It comes from a syntax-tree scan of the defining crate's non-test sources: each read of the constant is traced through comparisons, local bindings, struct fields, same-crate function parameters, function results and derived constants to the branch taken when the bound is exceeded. The column reports the strongest outcome over all reads, in this order:
- error: a typed error is returned. The column names the error variant and its
DR-diagnostic code when the variant carries one;untypedmarks a string error. - recorded: the input is truncated or refused and a flag or refusal record says so.
- panic: an assertion or panic fires.
- delegated: the bound is passed to a function the scan could not follow.
- silent: a loop stops, a value is clamped or work is skipped with no error and no record.
- unclassified: the scan found a read but could not attribute an outcome to it.
- allocation: the bound only sizes a buffer or a capacity reservation.
- unused: the defining crate never reads the constant.
The scan does not resolve types or trait dispatch, so an outcome names the construct it found rather than proving the behaviour.
2225 bounds (count 217, other 1039, output 67, recursion 228, size 488, work 186).
Exceeded: error 900, recorded 191, panic 0, delegated 49, silent 1026, unclassified 18, allocation 33, unused 8.
| Crate | Constant | Kind | Exceeded | Type | Value | File |
|---|---|---|---|---|---|---|
disrobe-binfmt | SCAN_HIT_CAP | other | silent: while condition in scan_magics | usize | 1 << 20 | crates/disrobe-binfmt/src/carve.rs |
disrobe-binfmt | STREAM_DECODE_CAP | other | silent: .take() in decode_validate; return in bzip2_exact_extent; return in gzip_exact_extent; 1 more | u64 | 4 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/carve.rs |
disrobe-binfmt | TOTAL_WORK_CHUNK_CAP | work | recorded: flag exhausted | usize | 1 << 16 | crates/disrobe-binfmt/src/carve.rs |
disrobe-binfmt | MAX_MEMBER_COUNT | count | error: CoreError::PassFailure (DR-CORE-0003); untyped format! | usize | 100_000 | crates/disrobe-binfmt/src/chain_detector.rs |
disrobe-binfmt | MAX_STREAM_BYTES | size | error: CoreError::PassFailure (DR-CORE-0003); untyped format! | u64 | 4 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/chain_detector.rs |
disrobe-binfmt | MAX_OMAP_ENTRIES | count | silent: break in omap_leaf_mappings; for range in walk_fs_tree_leaf | usize | 5_000_000 | crates/disrobe-binfmt/src/containers/apfs.rs |
disrobe-binfmt | MAX_BASIC_HEADER | other | error: Error::Arj (DR-BINFMT-0054) | usize | 2600 | crates/disrobe-binfmt/src/containers/arj.rs |
disrobe-binfmt | MAX_EXT_HEADER_BLOCKS | other | error: Error::Arj (DR-BINFMT-0054) | usize | 256 | crates/disrobe-binfmt/src/containers/arj.rs |
disrobe-binfmt | MAX_EXT_HEADER_BYTES | size | error: Error::Arj (DR-BINFMT-0054) | usize | 8 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/arj.rs |
disrobe-binfmt | LZMA_ALONE_DETECT_DICT_LIMIT | other | unclassified: stored in memlimit with no read found | usize | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/bare_stream.rs |
disrobe-binfmt | MAX_ASSEMBLIES | other | error: blazor_err() | usize | 100_000 | crates/disrobe-binfmt/src/containers/blazor_webcil.rs |
disrobe-binfmt | MAX_BOOT_MANIFEST_LEN | size | error: Error::QuotaExceeded (DR-BINFMT-0009); blazor_err() | usize | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/blazor_webcil.rs |
disrobe-binfmt | MAX_WASM_DATA_SEGMENTS | other | error: blazor_err() | u64 | 1024 | crates/disrobe-binfmt/src/containers/blazor_webcil.rs |
disrobe-binfmt | MAX_WEBCIL_SECTIONS | other | error: blazor_err() | usize | 96 | crates/disrobe-binfmt/src/containers/blazor_webcil.rs |
disrobe-binfmt | MAX_REPLAY_FILES | count | recorded: notes | usize | 500_000 | crates/disrobe-binfmt/src/containers/btrfs_send.rs |
disrobe-binfmt | BACK_SCAN_LIMIT | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 8 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/bun.rs |
disrobe-binfmt | MAX_MODULES | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 200_000 | crates/disrobe-binfmt/src/containers/bun.rs |
disrobe-binfmt | MAX_NAME_BYTES | size | error: Error::Cab (DR-BINFMT-0018) | usize | 256 | crates/disrobe-binfmt/src/containers/cab.rs |
disrobe-binfmt | MAX_CRAMFS_DEPTH | recursion | silent: break in walk_cramfs | usize | 256 | crates/disrobe-binfmt/src/containers/cramfs.rs |
disrobe-binfmt | MAX_CRAMFS_FILES | count | silent: break in walk_cramfs | usize | 500_000 | crates/disrobe-binfmt/src/containers/cramfs.rs |
disrobe-binfmt | MAX_DOC_LEN | size | silent: .min() clamp in read_c_string; .take() in find_doc_starting_with | usize | 16384 | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_FILETABLE_ENTRIES | count | silent: for range in recover_source_files | usize | 4096 | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_MODULE_NAME_LEN | size | silent: return in module_name_from_init; no action in locate_module_init | usize | 512 | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_NAME_LEN | size | silent: .min() clamp in read_c_string; return in is_valid_identifier; skipped in scan_source_strings | usize | 256 | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_SOURCE_FILES | count | silent: skipped in push_unique | usize | 512 | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_STRUCTURAL_RECORDS | count | silent: return in recover_structural | usize | 65536 | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_STRUCTURAL_SCAN_ATTEMPTS | other | silent: return in recover_structural | usize | 2_000_000 | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_TABLE_ENTRIES | count | silent: while condition in walk_method_table | usize | 8192 | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_STUB_BYTES | size | silent: return in render_cython_stub | usize | 4 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/cython_stub.rs |
disrobe-binfmt | MAX_MAGIC_CANDIDATES | other | silent: .take() in magic_offsets | usize | 4096 | crates/disrobe-binfmt/src/containers/deno_compile.rs |
disrobe-binfmt | MAX_MEDIA_TYPE | other | error: malformed() | u8 | 20 | crates/disrobe-binfmt/src/containers/deno_compile.rs |
disrobe-binfmt | MAX_CHUNKS | other | silent: return in parse_mish_chunks | usize | 5_000_000 | crates/disrobe-binfmt/src/containers/dmg.rs |
disrobe-binfmt | MAX_CHUNK_PREALLOC | other | allocation: with_capacity in adc_decompress; with_capacity in new; with_capacity in read_limited_chunk | usize | 4 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/dmg.rs |
disrobe-binfmt | MAX_IMAGE_BYTES | size | error: Error::Decompression (DR-BINFMT-0007); dmg_chunk_cap_error(); untyped format! | u64 | 8 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/dmg.rs |
disrobe-binfmt | DEPS_JSON_PARSE_CAP | other | error: Error::QuotaExceeded (DR-BINFMT-0009) | u64 | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/dotnet_bundle.rs |
disrobe-binfmt | MAX_EMBEDDED_FILES | count | error: bundle_err() | usize | 1_000_000 | crates/disrobe-binfmt/src/containers/dotnet_bundle.rs |
disrobe-binfmt | MAX_PATH_LEN | size | error: untyped format! | usize | 64 * 1024 | crates/disrobe-binfmt/src/containers/dotnet_bundle.rs |
disrobe-binfmt | MAX_PLAUSIBLE_MAJOR_VERSION | other | silent: return in header_is_plausible | u32 | 64 | crates/disrobe-binfmt/src/containers/dotnet_bundle.rs |
disrobe-binfmt | MAX_MAGIC_CANDIDATES | other | error: unsupported() | usize | 64 | crates/disrobe-binfmt/src/containers/enigma.rs |
disrobe-binfmt | MAX_NAME_UNITS | other | error: unsupported() | usize | 2048 | crates/disrobe-binfmt/src/containers/enigma.rs |
disrobe-binfmt | NESTING_LIMIT | recursion | error: Error::UnsupportedContainer (DR-BINFMT-0012) | &str | "Enigma Virtual Box directory nesting exceeds the supported depth" | crates/disrobe-binfmt/src/containers/enigma.rs |
disrobe-binfmt | PE_SECTION_LIMIT | other | silent: return in pe_has_enigma_sections | usize | 96 | crates/disrobe-binfmt/src/containers/enigma.rs |
disrobe-binfmt | MAX_DEPTH | recursion | error: Error::Erofs (DR-BINFMT-0048) | usize | 256 | crates/disrobe-binfmt/src/containers/erofs.rs |
disrobe-binfmt | MAX_FILES | count | error: Error::Erofs (DR-BINFMT-0048) | usize | 500_000 | crates/disrobe-binfmt/src/containers/erofs.rs |
disrobe-binfmt | MAX_FULL_INDEX_ENTRIES | count | error: Error::Erofs (DR-BINFMT-0048) | usize | 1 << 20 | crates/disrobe-binfmt/src/containers/erofs.rs |
disrobe-binfmt | MAX_LZMA_DICTIONARY | other | error: Error::Erofs (DR-BINFMT-0048) | u32 | 8 << 20 | crates/disrobe-binfmt/src/containers/erofs.rs |
disrobe-binfmt | MAX_PCLUSTER_DECODED | other | error: Error::Erofs (DR-BINFMT-0048) | usize | 12 << 20 | crates/disrobe-binfmt/src/containers/erofs.rs |
disrobe-binfmt | MAX_PCLUSTER_ENCODED | other | error: Error::Erofs (DR-BINFMT-0048) | usize | 1 << 20 | crates/disrobe-binfmt/src/containers/erofs.rs |
disrobe-binfmt | MAX_CANDIDATE_OFFSETS | other | silent: .truncate() in candidate_offsets; break in scan_magic_offsets | usize | 4096 | crates/disrobe-binfmt/src/containers/eszip.rs |
disrobe-binfmt | MAX_EXT4_DEPTH | recursion | recorded: refusals | usize | 256 | crates/disrobe-binfmt/src/containers/ext4.rs |
disrobe-binfmt | MAX_EXT4_FILES | count | recorded: refusals | usize | 500_000 | crates/disrobe-binfmt/src/containers/ext4.rs |
disrobe-binfmt | MAX_EXTENT_DEPTH | recursion | error: Error::Ext4 (DR-BINFMT-0040) | usize | 8 | crates/disrobe-binfmt/src/containers/ext4.rs |
disrobe-binfmt | MAX_DIR_ENTRIES | count | unclassified: stored in entries_budget with no read found | usize | 1 << 20 | crates/disrobe-binfmt/src/containers/fat.rs |
disrobe-binfmt | MAX_DIR_RECURSION | recursion | silent: return in walk_dir | u32 | 64 | crates/disrobe-binfmt/src/containers/fat.rs |
disrobe-binfmt | MAX_PART_OUTPUT | output | silent: .take() in decompress_xz | u64 | 2 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/flatpak.rs |
disrobe-binfmt | MAX_STATIC_DELTA_PART_BYTES | size | delegated: ostree::read_file_bounded()? | u64 | 512 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/flatpak.rs |
disrobe-binfmt | MAX_STATIC_DELTA_SUPERBLOCK_BYTES | size | delegated: ostree::read_file_bounded()? | u64 | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/flatpak.rs |
disrobe-binfmt | MAX_FILES | count | silent: return in walk_leaf_records | usize | 2_000_000 | crates/disrobe-binfmt/src/containers/hfsplus.rs |
disrobe-binfmt | MAX_FORK_EXTENTS | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 1 << 16 | crates/disrobe-binfmt/src/containers/hfsplus.rs |
disrobe-binfmt | MAX_NODES | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 5_000_000 | crates/disrobe-binfmt/src/containers/hfsplus.rs |
disrobe-binfmt | MAX_OVERFLOW_RECORDS | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 1 << 20 | crates/disrobe-binfmt/src/containers/hfsplus.rs |
disrobe-binfmt | MAX_INNO_FILE_NAME_BYTES | size | error: inno_err() | usize | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/innosetup.rs |
disrobe-binfmt | MAX_INNO_HEADER_STRING | other | silent: return in read_inno_string; return in skip_inno_string | usize | 16 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/innosetup.rs |
disrobe-binfmt | MAX_INNO_OUTPUT | output | error: Error::Decompression (DR-BINFMT-0007); dmg_chunk_cap_error(); inno_err(); 2 more | u64 | 4 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/innosetup.rs |
disrobe-binfmt | MAX_INNO_TABLE_ENTRIES | count | error: inno_err(); untyped format! | u32 | 1 << 20 | crates/disrobe-binfmt/src/containers/innosetup.rs |
disrobe-binfmt | MAX_INNO_TOTAL_ENTRIES | count | error: inno_err() | u32 | 4_000_000 | crates/disrobe-binfmt/src/containers/innosetup.rs |
disrobe-binfmt | CHUNK_OUTPUT_LIMIT | output | allocation: with_capacity in decode_framed_deflate; with_capacity in decode_full_flush_deflate; buffer length in decode_framed_deflate; 1 more | usize | 64 * 1024 | crates/disrobe-binfmt/src/containers/installshield.rs |
disrobe-binfmt | MAX_FILE_GROUPS | other | silent: while condition in read_file_groups | usize | 4096 | crates/disrobe-binfmt/src/containers/installshield.rs |
disrobe-binfmt | MAX_NAME_BYTES | size | delegated: CStrOptions::terminated()? | usize | 4096 | crates/disrobe-binfmt/src/containers/installshield.rs |
disrobe-binfmt | MAX_TABLE_ENTRIES | count | error: Error::InstallShield (DR-BINFMT-0037) | usize | 1_000_000 | crates/disrobe-binfmt/src/containers/installshield.rs |
disrobe-binfmt | MAX_CE_DEPTH | recursion | error: Error::Decompression (DR-BINFMT-0007) | usize | 8 | crates/disrobe-binfmt/src/containers/iso.rs |
disrobe-binfmt | MAX_DIRECTORIES | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 100_000 | crates/disrobe-binfmt/src/containers/iso.rs |
disrobe-binfmt | MAX_DIR_DEPTH | recursion | error: Error::Decompression (DR-BINFMT-0007) | usize | 64 | crates/disrobe-binfmt/src/containers/iso.rs |
disrobe-binfmt | MAX_EXTENTS | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 200_000 | crates/disrobe-binfmt/src/containers/iso.rs |
disrobe-binfmt | MAX_PATH_BYTES | size | error: Error::Decompression (DR-BINFMT-0007) | usize | 16 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/iso.rs |
disrobe-binfmt | MAX_RECORDS | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 100_000 | crates/disrobe-binfmt/src/containers/iso.rs |
disrobe-binfmt | MAX_SUSP_BYTES | size | error: Error::Decompression (DR-BINFMT-0007) | usize | 1 << 20 | crates/disrobe-binfmt/src/containers/iso.rs |
disrobe-binfmt | MAX_ZISOFS_BLOCK_POINTERS | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 131_073 | crates/disrobe-binfmt/src/containers/iso.rs |
disrobe-binfmt | MAX_FILES | count | silent: continue in walk_jffs2 | usize | 500_000 | crates/disrobe-binfmt/src/containers/jffs2.rs |
disrobe-binfmt | MAX_NODES | count | recorded: notes | usize | 2_000_000 | crates/disrobe-binfmt/src/containers/jffs2.rs |
disrobe-binfmt | MAX_LUKS1_DIGEST_ITERATIONS | work | error: Error::Luks1KdfCost (DR-BINFMT-0077); Error::Luks1Malformed (DR-BINFMT-0076) | u32 | 1_000_000 | crates/disrobe-binfmt/src/containers/luks1.rs |
disrobe-binfmt | MAX_LUKS1_KEY_BYTES | size | error: Error::Luks1Malformed (DR-BINFMT-0076) | usize | 4096 | crates/disrobe-binfmt/src/containers/luks1.rs |
disrobe-binfmt | MAX_LUKS1_PAYLOAD_BYTES | size | error: Error::Luks1PayloadTooLarge (DR-BINFMT-0083) | usize | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/luks1.rs |
disrobe-binfmt | MAX_LUKS1_PAYLOAD_OFFSET_BYTES | size | error: Error::Luks1PayloadOffsetTooLarge (DR-BINFMT-0084) | u64 | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/luks1.rs |
disrobe-binfmt | MAX_LZH_HEADER_BYTES | size | error: Error::Lzh (DR-BINFMT-0056) | usize | 1024 * 1024 | crates/disrobe-binfmt/src/containers/lzh.rs |
disrobe-binfmt | MAX_LZH_MEMBERS | count | error: Error::Lzh (DR-BINFMT-0056); Error::QuotaExceeded (DR-BINFMT-0009); inno_err() | usize | 65_535 | crates/disrobe-binfmt/src/containers/lzh.rs |
disrobe-binfmt | MAX_CARVE_STEPS | work | error: Error::Minidump (DR-BINFMT-0068); untyped format! | u64 | 1 << 26 | crates/disrobe-binfmt/src/containers/minidump/carve.rs |
disrobe-binfmt | MAX_MEMORY_REGIONS | other | error: Error::Minidump (DR-BINFMT-0068); untyped format! | u64 | 8_000_000 | crates/disrobe-binfmt/src/containers/minidump/mod.rs |
disrobe-binfmt | MAX_MODULES | other | error: Error::Minidump (DR-BINFMT-0068); untyped format! | u32 | 262_144 | crates/disrobe-binfmt/src/containers/minidump/mod.rs |
disrobe-binfmt | MAX_MODULE_NAME_BYTES | size | silent: return in read_minidump_string | u32 | 64 * 1024 | crates/disrobe-binfmt/src/containers/minidump/mod.rs |
disrobe-binfmt | MAX_PDB_PATH_BYTES | size | error: CoffLayoutError::BigObjVersion; CoreError::PassFailure (DR-CORE-0003); Error::Arc (DR-BINFMT-0055); 52 more | usize | 4096 | crates/disrobe-binfmt/src/containers/minidump/mod.rs |
disrobe-binfmt | MAX_SIZE_OF_IMAGE | size | error: Error::Minidump (DR-BINFMT-0068); untyped format! | u64 | 2 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/minidump/mod.rs |
disrobe-binfmt | MAX_STREAMS | other | error: Error::Minidump (DR-BINFMT-0068); untyped format! | u32 | 65_536 | crates/disrobe-binfmt/src/containers/minidump/mod.rs |
disrobe-binfmt | MAX_DEPTH | recursion | silent: break in walk_minixfs | usize | 256 | crates/disrobe-binfmt/src/containers/minixfs.rs |
disrobe-binfmt | MAX_FILES | count | silent: break in walk_minixfs | usize | 500_000 | crates/disrobe-binfmt/src/containers/minixfs.rs |
disrobe-binfmt | MAX_CONTAINER_METADATA_BYTES | size | delegated: super::admit_metadata_bytes()? | usize | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/mod.rs |
disrobe-binfmt | MAX_STREAM_BYTES | size | silent: .take() in read_msi_extractable | u64 | 4 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/msi.rs |
disrobe-binfmt | APPX_MANIFEST_READ_CAP | other | error: Error::ZipEntry (DR-BINFMT-0004) | u64 | 1 << 20 | crates/disrobe-binfmt/src/containers/msix.rs |
disrobe-binfmt | LZMA_PROPS_LIMIT | work | error: nsis_err() | u8 | 9 * 5 * 5 | crates/disrobe-binfmt/src/containers/nsis.rs |
disrobe-binfmt | MAX_ENTRIES | count | error: nsis_err() | usize | 1_000_000 | crates/disrobe-binfmt/src/containers/nsis.rs |
disrobe-binfmt | MAX_FILE_BYTES | size | error: Error::Nsis (DR-BINFMT-0033); Error::other(); nsis_err(); 1 more | u64 | 2 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/nsis.rs |
disrobe-binfmt | MAX_HEADER_BYTES | size | error: nsis_err() | usize | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/nsis.rs |
disrobe-binfmt | MAX_SOLID_BYTES | size | error: Error::Nsis (DR-BINFMT-0033); Error::other(); nsis_err(); 1 more | u64 | 8 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/nsis.rs |
disrobe-binfmt | MAX_DEPTH | recursion | silent: break in walk_ntfs | usize | 256 | crates/disrobe-binfmt/src/containers/ntfs.rs |
disrobe-binfmt | MAX_FILES | count | silent: break in walk_ntfs | usize | 500_000 | crates/disrobe-binfmt/src/containers/ntfs.rs |
disrobe-binfmt | MAX_FILEZ_CONTENT | other | silent: .take() in inflate_raw_deflate | u64 | 2 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/ostree.rs |
disrobe-binfmt | MAX_OSTREE_DEPTH | recursion | error: Error::Flatpak (DR-BINFMT-0042); untyped format! | u32 | 64 | crates/disrobe-binfmt/src/containers/ostree.rs |
disrobe-binfmt | MAX_OSTREE_DIR_ENTRIES | count | silent: .take() in collect_refs_recursive; .take() in count_objects; .take() in reconstruct_delta_dirs | usize | 4096 | crates/disrobe-binfmt/src/containers/ostree.rs |
disrobe-binfmt | MAX_OSTREE_FILES | count | error: Error::Flatpak (DR-BINFMT-0042); untyped format! | usize | 200_000 | crates/disrobe-binfmt/src/containers/ostree.rs |
disrobe-binfmt | MAX_OSTREE_OBJECT_BYTES | size | error: Error::Flatpak (DR-BINFMT-0042); untyped format! | u64 | 512 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/ostree.rs |
disrobe-binfmt | MAX_OSTREE_TEXT_BYTES | size | error: Error::Flatpak (DR-BINFMT-0042); untyped format! | u64 | 1024 * 1024 | crates/disrobe-binfmt/src/containers/ostree.rs |
disrobe-binfmt | PM1_TREE_WALK_LIMIT | other | silent: for range in read_byte_decode_index | usize | 5 | crates/disrobe-binfmt/src/containers/pmarc.rs |
disrobe-binfmt | MAX_ENTRIES | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 1_000_000 | crates/disrobe-binfmt/src/containers/rar.rs |
disrobe-binfmt | MAX_FILTER_INVOCATIONS | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 8_192 | crates/disrobe-binfmt/src/containers/rar_filters.rs |
disrobe-binfmt | MAX_FILTER_PROGRAMS | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 8_192 | crates/disrobe-binfmt/src/containers/rar_filters.rs |
disrobe-binfmt | MAX_PROGRAM_LENGTH | size | error: Error::Decompression (DR-BINFMT-0007) | u32 | 0x0001_0000 | crates/disrobe-binfmt/src/containers/rar_filters.rs |
disrobe-binfmt | MAX_RECORD_LENGTH | size | error: Error::Decompression (DR-BINFMT-0007) | usize | 0xffff | crates/disrobe-binfmt/src/containers/rar_filters.rs |
disrobe-binfmt | MAX_FREQ | other | delegated: passed to .copy_from_slice | u8 | 124 | crates/disrobe-binfmt/src/containers/rar_ppmd.rs |
disrobe-binfmt | MAX_BLOCKS_PER_MEMBER | other | error: Error::Decompression (DR-BINFMT-0007) | u32 | 8_192 | crates/disrobe-binfmt/src/containers/rar_unpack3.rs |
disrobe-binfmt | MAX_FILTER_RECORD | other | allocation: with_capacity in read_filter_record_lz; with_capacity in read_filter_record_ppm | usize | 0xffff | crates/disrobe-binfmt/src/containers/rar_unpack3.rs |
disrobe-binfmt | MAX_LENGTH | size | silent: for range in make_decode_table; while condition in decode_number | usize | 15 | crates/disrobe-binfmt/src/containers/rar_unpack3.rs |
disrobe-binfmt | MAX_FILTERS | other | error: Error::Decompression (DR-BINFMT-0007) | usize | 1 << 20 | crates/disrobe-binfmt/src/containers/rar_unpack5.rs |
disrobe-binfmt | MAX_FILTER_BLOCK_SIZE | size | error: .to_owned(); Error::Ar (DR-BINFMT-0053); Error::Arc (DR-BINFMT-0055); 53 more | u64 | 0x40_0000 | crates/disrobe-binfmt/src/containers/rar_unpack5.rs |
disrobe-binfmt | MAX_LENGTH | size | silent: for range in make_decode_table; while condition in decode_number | usize | 15 | crates/disrobe-binfmt/src/containers/rar_unpack5.rs |
disrobe-binfmt | MAX_ROMFS_DEPTH | recursion | silent: continue in walk_romfs | usize | 256 | crates/disrobe-binfmt/src/containers/romfs.rs |
disrobe-binfmt | MAX_ROMFS_FILES | count | silent: return in walk_romfs | usize | 500_000 | crates/disrobe-binfmt/src/containers/romfs.rs |
disrobe-binfmt | MAX_HEADER_ENTRIES | count | error: Error::Rpm (DR-BINFMT-0017) | usize | 65_535 | crates/disrobe-binfmt/src/containers/rpm.rs |
disrobe-binfmt | MAX_HEADER_STORE | other | error: Error::Rpm (DR-BINFMT-0017) | usize | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/rpm.rs |
disrobe-binfmt | MAX_TAG_VALUES | other | error: Error::Rpm (DR-BINFMT-0017) | usize | 65_535 | crates/disrobe-binfmt/src/containers/rpm.rs |
disrobe-binfmt | MAX_RAW_IMAGE | other | error: Error::Sparse (DR-BINFMT-0046) | u64 | 8 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/sparse.rs |
disrobe-binfmt | MAX_METADATA_BLOCK | other | silent: return in read_metadata_block_at; while condition in read_metadata_at | usize | 8192 | crates/disrobe-binfmt/src/containers/squashfs.rs |
disrobe-binfmt | MAX_PATH_DEPTH | recursion | silent: break in walk_squashfs | usize | 256 | crates/disrobe-binfmt/src/containers/squashfs.rs |
disrobe-binfmt | MAX_WALK_FILES | count | silent: break in walk_squashfs | usize | 500_000 | crates/disrobe-binfmt/src/containers/squashfs.rs |
disrobe-binfmt | MAX_CD_ENTRIES | count | error: .to_owned(); Error::Zip (DR-BINFMT-0003); untyped format! | usize | 1_000_000 | crates/disrobe-binfmt/src/containers/squirrel.rs |
disrobe-binfmt | MAX_COMMENT | other | error: .to_owned(); Error::Zip (DR-BINFMT-0003); untyped format! | usize | 0xFFFF | crates/disrobe-binfmt/src/containers/squirrel.rs |
disrobe-binfmt | SEARCH_BUDGET | work | error: .to_owned(); Error::Zip (DR-BINFMT-0003); untyped format! | usize | MAX_COMMENT + EOCD_FIXED_LEN + 4 | crates/disrobe-binfmt/src/containers/squirrel.rs |
disrobe-binfmt | MAX_FOLDER_DEPTH | recursion | error: stuffit_error() | usize | 256 | crates/disrobe-binfmt/src/containers/stuffit.rs |
disrobe-binfmt | MAX_PATH_BYTES | size | error: stuffit_error() | usize | 4096 | crates/disrobe-binfmt/src/containers/stuffit.rs |
disrobe-binfmt | MAX_RECORDS | count | error: stuffit_error() | usize | 65_535 | crates/disrobe-binfmt/src/containers/stuffit.rs |
disrobe-binfmt | MAX_ENTRIES | count | error: sit5_error() | usize | 65_535 | crates/disrobe-binfmt/src/containers/stuffit5.rs |
disrobe-binfmt | MAX_FOLDER_DEPTH | recursion | error: sit5_error() | usize | 256 | crates/disrobe-binfmt/src/containers/stuffit5.rs |
disrobe-binfmt | MAX_PATH_BYTES | size | error: sit5_error() | usize | 4096 | crates/disrobe-binfmt/src/containers/stuffit5.rs |
disrobe-binfmt | MAX_PEBS | other | error: Error::Ubifs (DR-BINFMT-0052) | usize | 1_000_000 | crates/disrobe-binfmt/src/containers/ubifs.rs |
disrobe-binfmt | MAX_FFS_FILES | count | recorded: notes; flag truncated | usize | 500_000 | crates/disrobe-binfmt/src/containers/uefi_fv.rs |
disrobe-binfmt | MAX_FV_DEPTH | recursion | error: Error::UefiFirmwareVolume (DR-BINFMT-0070); untyped format! | usize | 16 | crates/disrobe-binfmt/src/containers/uefi_fv.rs |
disrobe-binfmt | MAX_SECTIONS_PER_FILE | other | error: Error::UefiFirmwareVolume (DR-BINFMT-0070); untyped format! | usize | 100_000 | crates/disrobe-binfmt/src/containers/uefi_fv.rs |
disrobe-binfmt | MAX_BLOCK_COUNT | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 1 << 20 | crates/disrobe-binfmt/src/containers/unityfs.rs |
disrobe-binfmt | MAX_NODE_COUNT | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 1 << 20 | crates/disrobe-binfmt/src/containers/unityfs.rs |
disrobe-binfmt | MAX_STRING_SCAN | other | delegated: .peek_bytes()? | usize | 4096 | crates/disrobe-binfmt/src/containers/unityfs.rs |
disrobe-binfmt | MAX_UZIP_PREALLOC | other | allocation: with_capacity in read_block_to_exact | usize | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/uzip.rs |
disrobe-binfmt | MAX_UZIP_PREALLOC_U64 | other | allocation: with_capacity in parse_uzip | u64 | 64 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/uzip.rs |
disrobe-binfmt | MAX_BAT_ENTRIES | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 1 << 22 | crates/disrobe-binfmt/src/containers/vhd.rs |
disrobe-binfmt | MAX_DENTRY_COUNT | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 1_000_000 | crates/disrobe-binfmt/src/containers/wim_image.rs |
disrobe-binfmt | MAX_TREE_DEPTH | recursion | error: Error::Decompression (DR-BINFMT-0007) | u32 | 512 | crates/disrobe-binfmt/src/containers/wim_image.rs |
disrobe-binfmt | MAX_FILES | count | error: Error::Decompression (DR-BINFMT-0007) | usize | 2_000_000 | crates/disrobe-binfmt/src/containers/xar.rs |
disrobe-binfmt | MAX_MEMBER_BYTES | size | delegated: passed to .copy_from_slice | u64 | 8 * 1024 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/xar.rs |
disrobe-binfmt | MAX_TOC_BYTES | size | error: Error::Decompression (DR-BINFMT-0007) | u64 | 256 * 1024 * 1024 | crates/disrobe-binfmt/src/containers/xar.rs |
disrobe-binfmt | MAX_FILES | count | recorded: notes | usize | 500_000 | crates/disrobe-binfmt/src/containers/yaffs.rs |
disrobe-binfmt | MAX_SECTION_NAME | other | silent: return in section_name | usize | 512 | crates/disrobe-binfmt/src/coverage/elf.rs |
disrobe-binfmt | MAX_LOAD_COMMANDS | other | error: Error::Coverage (DR-BINFMT-0072); untyped format! | u64 | 65_536 | crates/disrobe-binfmt/src/coverage/macho.rs |
disrobe-binfmt | MAX_SLICES | other | error: Error::Coverage (DR-BINFMT-0072); untyped format! | u64 | 4_096 | crates/disrobe-binfmt/src/coverage/macho.rs |
disrobe-binfmt | MAX_COVERAGE_REGIONS | other | error: Error::Coverage (DR-BINFMT-0072); untyped format! | usize | 65_536 | crates/disrobe-binfmt/src/coverage/mod.rs |
disrobe-binfmt | MAX_OVERLAP_RECORDS | count | error: Error::Coverage (DR-BINFMT-0072); untyped format! | usize | 4_096 | crates/disrobe-binfmt/src/coverage/mod.rs |
disrobe-binfmt | DIRECTORY_LIMIT | other | error: untyped error | u32 | 16 | crates/disrobe-binfmt/src/coverage/pe.rs |
disrobe-binfmt | MAX_DEBUG_DIRECTORY_ENTRIES | count | error: Error::Coverage (DR-BINFMT-0072); untyped format! | u64 | 4_096 | crates/disrobe-binfmt/src/coverage/pe.rs |
disrobe-binfmt | MAX_U32_LEB_BYTES | size | error: Error::Coverage (DR-BINFMT-0072); untyped format! | usize | 5 | crates/disrobe-binfmt/src/coverage/wasm.rs |
disrobe-binfmt | MAX_DT_STRSZ | other | silent: return in parse_elf_dynamic | u64 | 0x100_0000 | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_DYNAMIC_ENTRIES | count | silent: return in parse_elf_dynamic | usize | 0x10_0000 | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_DYNAMIC_STRING_OUTPUT | output | silent: return in resolve_bounded_string | usize | 0x100_0000 | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_NEEDED | other | silent: return in push_needed_offset | usize | 0x1_0000 | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_PROGRAM_HEADERS | other | silent: return in parse_elf_dynamic | usize | 0x1_0000 | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_STRING_LEN | size | silent: .min() clamp in read_cstr | usize | 0x1_0000 | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_CAPTURE_OUTPUT | output | error: Error::Io (DR-BINFMT-0001) | usize | 4 * 1024 * 1024 | crates/disrobe-binfmt/src/external_wrap.rs |
disrobe-binfmt | MAX_DISK_NESTING_DEPTH | recursion | silent: return in recurse_into_filesystem | u32 | 4 | crates/disrobe-binfmt/src/extract.rs |
disrobe-binfmt | MAX_ITERATED_RECORDS | work | error: ne_error() | usize | 65_536 | crates/disrobe-binfmt/src/ne.rs |
disrobe-binfmt | MAX_RELOCATION_CHAIN_STEPS | work | error: ne_error() | usize | 1_000_000 | crates/disrobe-binfmt/src/ne.rs |
disrobe-binfmt | MAX_RELOCATION_RECORDS | count | error: ne_error() | usize | 65_536 | crates/disrobe-binfmt/src/ne.rs |
disrobe-binfmt | MAX_RESOURCE_RECORDS | count | error: ne_error() | usize | 65_536 | crates/disrobe-binfmt/src/ne.rs |
disrobe-binfmt | MAX_TOTAL_ITERATED_BYTES | work | error: ne_error() | usize | 16 * 1024 * 1024 | crates/disrobe-binfmt/src/ne.rs |
disrobe-binfmt | MAX_UNIQUE_IMPORTS | other | error: ne_error() | usize | 65_536 | crates/disrobe-binfmt/src/ne.rs |
disrobe-binfmt | MAX_ENTRY_COMPONENT_BYTES | size | recorded: note() | usize | 255 | crates/disrobe-binfmt/src/quota.rs |
disrobe-binfmt | MAX_ENTRY_PATH_BYTES | size | error: Error::Rpm (DR-BINFMT-0017); Error::Tar (DR-BINFMT-0005); malformed() | usize | 4096 | crates/disrobe-binfmt/src/quota.rs |
disrobe-binfmt | MAX_NOTES_PER_SEGMENT | other | silent: for range in find_build_ids | usize | 1_024 | crates/disrobe-binfmt/src/rewrite/elf.rs |
disrobe-binfmt | MAX_NOTE_SEGMENT_BYTES | size | error: rewrite_error() | u64 | 1 << 20 | crates/disrobe-binfmt/src/rewrite/elf.rs |
disrobe-binfmt | MAX_EDITS | other | error: Error::Rewrite (DR-BINFMT-0074); untyped format! | usize | 4_096 | crates/disrobe-binfmt/src/rewrite/mod.rs |
disrobe-binfmt | MAX_FAT_SLICES | other | error: Error::CoverageUnsupported (DR-BINFMT-0073); Error::RewriteUnsupported (DR-BINFMT-0075); untyped format! | u64 | 4_096 | crates/disrobe-binfmt/src/rewrite/mod.rs |
disrobe-binfmt | MAX_LOAD_COMMANDS | other | error: Error::CoverageUnsupported (DR-BINFMT-0073); Error::RewriteUnsupported (DR-BINFMT-0075); untyped format! | u64 | 65_536 | crates/disrobe-binfmt/src/rewrite/mod.rs |
disrobe-binfmt | MAX_PLAN_STRUCTURES | other | error: Error::Rewrite (DR-BINFMT-0074); untyped format! | usize | 65_536 | crates/disrobe-binfmt/src/rewrite/mod.rs |
disrobe-binfmt | MAX_TABLE_ENTRIES | count | error: Error::CoverageUnsupported (DR-BINFMT-0073); Error::RewriteUnsupported (DR-BINFMT-0075); untyped format! | u64 | 262_144 | crates/disrobe-binfmt/src/rewrite/mod.rs |
disrobe-binfmt | MAX_DIRECTORY_SLOTS | other | silent: .min() clamp in plan | u64 | 8_192 | crates/disrobe-binfmt/src/rewrite/pe.rs |
disrobe-bytes | MAX_ENTRY_PREALLOC | other | allocation: with_capacity in new; with_capacity in read_to_limit | usize | 64 * 1024 * 1024 | crates/disrobe-bytes/src/quota.rs |
disrobe-capabilities | MAX_FILE_STRING_FEATURES | other | silent: .take() in push_file_strings_with_limits | usize | 4096 | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | MAX_FILE_STRING_FEATURE_BYTES | size | silent: continue in push_file_strings_with_limits | usize | 4096 | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | MAX_FILE_STRING_SCAN_BYTES | size | silent: .min() clamp in push_file_strings_with_limits | usize | 16 * 1024 * 1024 | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | MAX_NUMBER_FEATURES_PER_INSN | other | silent: skipped in instruction_features | usize | 4 | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | PE_HEADER_SCAN_CAP | other | silent: .min() clamp in embedded_pe_offset | usize | 1 << 20 | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | MAX_IMPORT_ENTRIES | count | silent: break in from_elf; break in from_pe | usize | 1 << 17 | crates/disrobe-capabilities/src/imports.rs |
disrobe-capabilities | MAX_STUB_SPAN | other | silent: .min() clamp in name_at_thunk | u64 | 0x10 | crates/disrobe-capabilities/src/imports.rs |
disrobe-capabilities | MAX_LOWER_STEPS | work | error: LoadError::TooComplex | usize | 100_000 | crates/disrobe-capabilities/src/yaml_rules/load.rs |
disrobe-capabilities | MAX_NODE_DEPTH | recursion | error: LoadError::TooDeep | usize | 24 | crates/disrobe-capabilities/src/yaml_rules/load.rs |
disrobe-capabilities | MAX_REGEX_PATTERN_LEN | size | error: LoadError::RegexTooLong | usize | 512 | crates/disrobe-capabilities/src/yaml_rules/load.rs |
disrobe-cfg | MAX_FLOW_NODES | count | error: CfgError::TooManyNodes; FlowError::NodeCountExceedsCapacity | usize | (u32::MAX - 1) as usize | crates/disrobe-cfg/src/flow.rs |
disrobe-cfg | RETURN_TAIL_NODE_CAP | other | silent: return in private_return_tail | usize | 64 | crates/disrobe-cfg/src/lib.rs |
disrobe-cfg | MAX_RECONVERGENCE_CLONES | other | silent: .min() clamp in tight_for_reconvergence | usize | 64 | crates/disrobe-cfg/src/reconverge.rs |
disrobe-cli | RESOURCE_PREVIEW_LIMIT | other | silent: .min() clamp in render_resources | usize | 50 | crates/disrobe-cli/src/cli/apk.rs |
disrobe-cli | MAX_EVIDENCE_SHOWN | other | silent: .take() in push_anti_analysis_evidence_lines; .take() in render_text; no action in push_anti_analysis_evidence_lines; 1 more | usize | 6 | crates/disrobe-cli/src/cli/behavior.rs |
disrobe-cli | MAX_NAMESPACE_ATTEMPTS | other | error: untyped miette! | usize | 1024 | crates/disrobe-cli/src/cli/chain_materialization.rs |
disrobe-cli | MAX_SIDECAR_REDACTION_BYTES | size | silent: return in sidecar_shape | usize | 64 << 20 | crates/disrobe-cli/src/cli/chain_v1.rs |
disrobe-cli | MAX_REPORTS_GRADED | other | silent: break in find_reports | usize | 4096 | crates/disrobe-cli/src/cli/context.rs |
disrobe-cli | MAX_REPORT_SEARCH_DEPTH | recursion | silent: for range in find_reports | usize | 4 | crates/disrobe-cli/src/cli/context.rs |
disrobe-cli | MAX_CYCLONEDX_COMPONENTS | other | error: CycloneDxError::TooManyComponents | usize | MAX_CYCLONEDX_PACKAGES + 1 | crates/disrobe-cli/src/cli/cyclonedx.rs |
disrobe-cli | MAX_CYCLONEDX_COMPONENT_TEXT_BYTES | size | error: CycloneDxError::ComponentTextTooLong | usize | 24 * 1024 * 1024 | crates/disrobe-cli/src/cli/cyclonedx.rs |
disrobe-cli | MAX_CYCLONEDX_OUTPUT_BYTES | output | error: CycloneDxError::OutputTooLong; Error::other() | usize | 24 * 1024 * 1024 | crates/disrobe-cli/src/cli/cyclonedx.rs |
disrobe-cli | MAX_CYCLONEDX_PACKAGES | other | error: CycloneDxError::TooManyComponents; CycloneDxError::TooManyPackages | usize | 16_384 | crates/disrobe-cli/src/cli/cyclonedx.rs |
disrobe-cli | MAX_BUNDLE_ASSEMBLIES | other | error: untyped miette! | usize | 512 | crates/disrobe-cli/src/cli/dotnet.rs |
disrobe-cli | MAX_INSTALL_LOG_ENTRIES | count | silent: no action in trim_install_log; slice in trim_install_log | usize | 500 | crates/disrobe-cli/src/cli/install/mod.rs |
disrobe-cli | MAX_GHIDRA_ARCHIVE_ENTRIES | count | error: untyped miette! | usize | 200_000 | crates/disrobe-cli/src/cli/install_deps.rs |
disrobe-cli | MAX_GHIDRA_DOWNLOAD_BYTES | size | error: untyped miette! | u64 | 2 * 1024 * 1024 * 1024 | crates/disrobe-cli/src/cli/install_deps.rs |
disrobe-cli | MAX_GHIDRA_ENTRY_UNCOMPRESSED_BYTES | size | error: untyped miette! | u64 | 2 * 1024 * 1024 * 1024 | crates/disrobe-cli/src/cli/install_deps.rs |
disrobe-cli | MAX_GHIDRA_TOTAL_UNCOMPRESSED_BYTES | size | error: untyped miette! | u64 | 8 * 1024 * 1024 * 1024 | crates/disrobe-cli/src/cli/install_deps.rs |
disrobe-cli | NWJS_ZIP_ENTRY_BYTES_CAP | size | error: untyped miette! | u64 | 512 * 1024 * 1024 | crates/disrobe-cli/src/cli/js.rs |
disrobe-cli | NWJS_ZIP_ENTRY_COUNT_CAP | count | error: untyped miette! | usize | 65_535 | crates/disrobe-cli/src/cli/js.rs |
disrobe-cli | NWJS_ZIP_TOTAL_BYTES_CAP | size | error: untyped miette! | u64 | 4 * 1024 * 1024 * 1024 | crates/disrobe-cli/src/cli/js.rs |
disrobe-cli | MAX_IN_HOUSE_DEX_CLASSES | other | recorded: flag omitted | usize | 65_536 | crates/disrobe-cli/src/cli/jvm.rs |
disrobe-cli | MAX_IN_HOUSE_DEX_INPUT_BYTES | size | error: untyped miette! | usize | 64 * 1024 * 1024 | crates/disrobe-cli/src/cli/jvm.rs |
disrobe-cli | MAX_IN_HOUSE_DEX_OUTPUT_BYTES | output | error: untyped miette! | usize | 128 * 1024 * 1024 | crates/disrobe-cli/src/cli/jvm.rs |
disrobe-cli | DELPHI_LIST_LIMIT | other | silent: .take() in render_delphi_classes; .take() in render_delphi_forms; .take() in render_delphi_types; 3 more | usize | 20 | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | DEVIRT_FUNCTION_LIMIT | other | unclassified: compound assignment in decompile_native_pcode; value in decompile_native_pcode | usize | 2048 | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | DIFF_DEFAULT_LISTING_LIMIT | other | error: untyped miette! | usize | 25 | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | LOWEST_COVERED_CAP | other | silent: .truncate() in lowest_covered | usize | 10 | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | MAX_CAPTURE_OUTPUT | output | delegated: subprocess::run_captured()? | usize | 4 * 1024 * 1024 | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | MAX_NATIVE_SBOM_INPUT_BYTES | size | error: untyped miette! | u64 | 256 * 1024 * 1024 | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | SYMBOL_PREVIEW_LIMIT | other | silent: .min() clamp in render_cxx_class_rows; .min() clamp in render_import_rows; .min() clamp in render_symbol_rows | usize | 40 | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | LITERAL_PREVIEW_LIMIT | work | silent: .take() in preview; return in preview | usize | 64 | crates/disrobe-cli/src/cli/native_match.rs |
disrobe-cli | MAX_DEEP_ANALYZE_LIB_BYTES | size | error: untyped miette! | usize | 16 * 1024 * 1024 | crates/disrobe-cli/src/cli/nuitka.rs |
disrobe-cli | MAX_TARGETS | other | error: untyped miette! | usize | 65_536 | crates/disrobe-cli/src/cli/prowl/harvest.rs |
disrobe-cli | MAX_TARGET_INPUT_BYTES | size | error: untyped miette! | u64 | 16 * 1024 * 1024 | crates/disrobe-cli/src/cli/prowl/harvest.rs |
disrobe-cli | MAX_JVM_QUERY_INPUT_BYTES | size | error: untyped miette! | usize | 64 * 1024 * 1024 | crates/disrobe-cli/src/cli/query.rs |
disrobe-cli | MAX_REJECTED_ARTIFACT_DIAGNOSTICS | other | recorded: JvmHierarchyDiagnostic::RejectedArtifactDiagnosticLimit; flag rejected_artifacts_truncated | usize | 1_024 | crates/disrobe-cli/src/cli/query.rs |
disrobe-cli | MAX_REJECTED_ARTIFACT_DIAGNOSTIC_BYTES | size | recorded: JvmHierarchyDiagnostic::RejectedArtifactDiagnosticLimit; flag rejected_artifacts_truncated | usize | 65_536 | crates/disrobe-cli/src/cli/query.rs |
disrobe-cli | MAX_ARTIFACT_WALK_DEPTH | recursion | recorded: flag truncated | u32 | 32 | crates/disrobe-cli/src/cli/report.rs |
disrobe-cli | MAX_CITED_ARTIFACTS | other | recorded: flag truncated | usize | 4_096 | crates/disrobe-cli/src/cli/report.rs |
disrobe-cli | MAX_REPORT_ANALYSIS_INPUT_BYTES | size | error: untyped format! | u64 | 256 * 1024 * 1024 | crates/disrobe-cli/src/cli/report.rs |
disrobe-cli | MAX_BEHAVIOR_EVIDENCE | other | silent: .take() in render_behavior_row; no action in render_behavior_row | usize | 6 | crates/disrobe-cli/src/cli/report_html.rs |
disrobe-cli | MAX_IOC_ROWS | other | silent: .take() in render_indicators; no action in render_indicators | usize | 200 | crates/disrobe-cli/src/cli/report_html.rs |
disrobe-cli | DEFAULT_LISTING_LIMIT | other | error: untyped miette! | usize | 40 | crates/disrobe-cli/src/cli/semdiff.rs |
disrobe-cli | MAX_SEMDIFF_INPUT_BYTES | size | error: untyped miette! | u64 | 256 * 1024 * 1024 | crates/disrobe-cli/src/cli/semdiff.rs |
disrobe-cli | MAX_DOCUMENT_OUTPUT_BYTES | output | error: Error::other(); StructuredDocumentError::OutputTooLong | usize | 24 * 1024 * 1024 | crates/disrobe-cli/src/cli/structured_document.rs |
disrobe-cli | MAX_NAVIGATION_CALLS | other | unclassified: stored in calls with no read found | usize | 32_768 | crates/disrobe-cli/src/cli/taint.rs |
disrobe-cli | MAX_NAVIGATION_CANDIDATE_RECORDS | count | unclassified: stored in candidate_records with no read found | usize | 65_536 | crates/disrobe-cli/src/cli/taint.rs |
disrobe-cli | MAX_NAVIGATION_FUNCTIONS | other | error: CycloneDxError::AllocationFailed; CycloneDxError::ArithmeticOverflow; OpenVexError::NoFindings; 1 more | usize | 8_192 | crates/disrobe-cli/src/cli/taint.rs |
disrobe-cli | MAX_NAVIGATION_INSTRUCTIONS | other | error: OpenVexError::NoFindings; untyped miette! | usize | 262_144 | crates/disrobe-cli/src/cli/taint.rs |
disrobe-cli | MAX_NAVIGATION_RETAINED_BYTES | size | unclassified: stored in retained_bytes with no read found | usize | 64 * 1024 * 1024 | crates/disrobe-cli/src/cli/taint.rs |
disrobe-cli | MAX_ANALYSIS_DEPTH | recursion | error: OpenVexError::NoFindings; untyped miette! | usize | 128 | crates/disrobe-cli/src/cli/vulnmatch.rs |
disrobe-cli | MAX_ANALYSIS_NODES | count | error: OpenVexError::NoFindings; untyped miette! | usize | 50_000 | crates/disrobe-cli/src/cli/vulnmatch.rs |
disrobe-cli | MAX_ANALYSIS_STEPS | work | error: OpenVexError::NoFindings; untyped miette! | usize | 2_000_000 | crates/disrobe-cli/src/cli/vulnmatch.rs |
disrobe-cli | MAX_VULNMATCH_INPUT_BYTES | size | error: untyped miette! | u64 | 256 * 1024 * 1024 | crates/disrobe-cli/src/cli/vulnmatch.rs |
disrobe-core | ANTI_ANALYSIS_SCAN_CAP | other | silent: slice in scan_with_chain | usize | 96 * 1024 * 1024 | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | CODE_SCAN_BUDGET | work | recorded: flag budget | usize | 16 * 1024 * 1024 | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | MAX_EXEMPLARS_PER_KIND | other | silent: .take() in cap_evidence; no action in cap_evidence | usize | 5 | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | MAX_MACHO_LOAD_CMDS | other | silent: .min() clamp in macho_code_layout | usize | 4096 | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | MAX_PARSED_SECTIONS | other | silent: .min() clamp in elf_code_layout; .min() clamp in macho_segment_sections; .min() clamp in pe_code_layout | usize | 96 | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | MAX_CACHE_ENTRY_BYTES | size | silent: .take() in read_entry_file; return in read_entry_file | u64 | 512 * 1024 * 1024 | crates/disrobe-core/src/cache.rs |
disrobe-core | MAX_CACHE_ENTRY_PREALLOC | other | allocation: with_capacity in read_entry_file | usize | 8 * 1024 * 1024 | crates/disrobe-core/src/cache.rs |
disrobe-core | DEFAULT_CAP | other | unclassified: stored in cap with no read found | u8 | 8 | crates/disrobe-core/src/chain/spec.rs |
disrobe-core | MAX_CAP | other | error: ChainSpecError::CapOutOfRange (DR-CORE-0105) | u8 | 16 | crates/disrobe-core/src/chain/spec.rs |
disrobe-core | MAX_AES_INPUT | other | error: DecodeError::TooLarge | usize | 1 << 26 | crates/disrobe-core/src/codec/aes_cbc.rs |
disrobe-core | MAX_BIGNUM_RADIX_INPUT | other | error: DecodeError::TooLarge | usize | 1 << 16 | crates/disrobe-core/src/codec/alphabets.rs |
disrobe-core | MAX_RADIX_INPUT | other | error: DecodeError::TooLarge | usize | 1 << 24 | crates/disrobe-core/src/codec/alphabets.rs |
disrobe-core | MAX_BASE64_INPUT | other | error: DecodeError::TooLarge | usize | 1 << 26 | crates/disrobe-core/src/codec/base64.rs |
disrobe-core | MAX_CIPHER_INPUT | other | error: DecodeError::TooLarge | usize | 1 << 26 | crates/disrobe-core/src/codec/cipher.rs |
disrobe-core | JOSE_HEADER_DECODE_CAP | other | silent: return in decode_base64url; return in decode_jose_header | usize | 4096 | crates/disrobe-core/src/codec/crypto_wall.rs |
disrobe-core | MAX_SCAN | other | silent: slice in classify | usize | 1 << 20 | crates/disrobe-core/src/codec/crypto_wall.rs |
disrobe-core | MAX_STATIC_PASSPHRASES | other | silent: break in static_passphrase_candidates; while condition in push_label_passphrases | usize | 32 | crates/disrobe-core/src/codec/crypto_wall.rs |
disrobe-core | MAX_FRAMED_INPUT | other | error: DecodeError::TooLarge | usize | 1 << 26 | crates/disrobe-core/src/codec/framed.rs |
disrobe-core | MAX_ENTITY_NAME | other | silent: fallback value in html_entity_decode_with_scan | usize | 32 | crates/disrobe-core/src/codec/web_escape.rs |
disrobe-core | MAX_PUNYCODE_LABEL_OUTPUT | output | error: DecodeError::TooLarge | usize | 1024 | crates/disrobe-core/src/codec/web_escape.rs |
disrobe-core | MAX_WEB_INPUT | other | error: DecodeError::TooLarge | usize | 1 << 24 | crates/disrobe-core/src/codec/web_escape.rs |
disrobe-core | MS_CAP | other | silent: return in pretty_duration | u128 | 5 * MS_PER_D | crates/disrobe-core/src/provenance.rs |
disrobe-core | MAX_NOTE_LINES | other | error: ProvenanceMapError::NoteTooManyLines (DR-CORE-PMAP-0001) | usize | 2 | crates/disrobe-core/src/provenance_map.rs |
disrobe-core | MAX_HISTORY_BLOBS | other | silent: break in report_git | usize | 1_000_000 | crates/disrobe-core/src/recon/git_history.rs |
disrobe-core | MAX_HISTORY_BLOB_BYTES | size | silent: continue in report_git | usize | 16 << 20 | crates/disrobe-core/src/recon/git_history.rs |
disrobe-core | MAX_HISTORY_COMMITS | other | silent: break in report_git | usize | 100_000 | crates/disrobe-core/src/recon/git_history.rs |
disrobe-core | MAX_BLOB_DECODE | other | silent: continue in decode_and_recurse; continue in decode_codecs_and_recurse | usize | 1 << 20 | crates/disrobe-core/src/recon/ioc.rs |
disrobe-core | MAX_CODEC_TOKEN | other | silent: continue in decode_codecs_and_recurse | usize | 1 << 20 | crates/disrobe-core/src/recon/ioc.rs |
disrobe-core | MAX_INDICATORS | other | silent: break in extract_with_work; break in scan_text_layer; return in collect_domains; 7 more | usize | 100_000 | crates/disrobe-core/src/recon/ioc.rs |
disrobe-core | MAX_FIELDS | other | recorded: flag budget | usize | 4096 | crates/disrobe-core/src/recon/malware_config.rs |
disrobe-core | ARCHIVE_MEMBER_PREALLOC_CAP | other | allocation: with_capacity in read_archive_member | u64 | 1 << 20 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_BASE64_DECODED_TOTAL | other | silent: break in base64_decode_findings; continue in base64_decode_findings | usize | 16 << 20 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_BASE64_DEPTH | recursion | silent: return in base64_decode_findings | u8 | 4 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_BASE64_RUNS | other | silent: break in base64_decode_findings | usize | 4096 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_CODEC_DECODED_TOTAL | other | silent: break in codec_cascade_findings; return in codec_peel_token | usize | 16 << 20 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_CODEC_DEPTH | recursion | silent: return in codec_cascade_findings | u8 | 3 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_CODEC_RUN | other | silent: return in codec_output_advances; return in codec_peel_token | usize | 1 << 20 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_CONTAINER_DEPTH | recursion | silent: skipped in scan_blob | usize | 8 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_DECODED_TOTAL_BYTES | size | delegated: passed to .set | u64 | 1 << 30 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_FILE_BYTES | size | silent: .take() in read_scan_file; return in read_scan_file | u64 | 64 << 20 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_TREE_FILES | count | silent: break in walk_with_limit | usize | 200_000 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_WIDE_RUNS | other | silent: break in merge_runs; return in push_narrow_run; return in push_wide_run; 2 more | usize | 1 << 16 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_ZIP_ENTRIES | count | silent: .min() clamp in scan_zip_bytes; break in scan_tar_bytes | usize | 50_000 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_ZIP_ENTRY_BYTES | size | delegated: passed to .set | u64 | 64 << 20 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_ZIP_TOTAL_BYTES | size | delegated: passed to .set | u64 | 1 << 30 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | REGEX_SIZE_LIMIT | size | delegated: .dfa_size_limit()?; .size_limit()? | usize | 16 << 20 | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_SERIALIZED_DEPTH | recursion | error: RedactionError::DepthLimit | usize | 64 | crates/disrobe-core/src/recon/redact.rs |
disrobe-core | MAX_SERIALIZED_NODES | count | error: RedactionError::NodeLimit | usize | 1_048_576 | crates/disrobe-core/src/recon/redact.rs |
disrobe-core | MAX_SERIALIZED_STRING_BYTES | size | error: RedactionError::StringBytesLimit | usize | 64 * 1024 * 1024 | crates/disrobe-core/src/recon/redact.rs |
disrobe-core | MAX_RUNS | other | silent: break in merge_runs; return in push_narrow_run; return in push_wide_run; 2 more | usize | 4096 | crates/disrobe-core/src/recon/string_emu.rs |
disrobe-core | MAX_RUN_BYTES | size | silent: continue in unit_runs_wide; no action in collect_narrow_runs; slice in text_runs | usize | 64 << 10 | crates/disrobe-core/src/recon/string_emu.rs |
disrobe-core | MAX_DECODE_RECURSE_LEN | recursion | silent: continue in recover_base64; continue in recover_codec | usize | 1 << 16 | crates/disrobe-core/src/strings.rs |
disrobe-core | MAX_PE_SECTIONS | other | silent: return in pe_header_is_valid | usize | 96 | crates/disrobe-core/src/structural.rs |
disrobe-core | ZIP_SEARCH_BUDGET | work | silent: while condition in find_eocd | usize | ZIP_MAX_COMMENT + ZIP_EOCD_FIXED_LEN + 4 | crates/disrobe-core/src/structural.rs |
disrobe-core | MAX_STRINGS | other | silent: break in select_strings | usize | 20 | crates/disrobe-core/src/yara_gen.rs |
disrobe-core | MAX_STRING_LEN | size | delegated: passed to .sort_by | usize | 96 | crates/disrobe-core/src/yara_gen.rs |
disrobe-core | HEX_WORK_BUDGET | work | silent: return in hex_matches_at | u64 | 1 << 20 | crates/disrobe-core/src/yara_match/atoms.rs |
disrobe-ir | MAX_DECODED_ENVELOPE_BYTES | size | error: EnvelopeError::EnvelopeTooLarge | usize | 1 << 30 | crates/disrobe-ir/src/envelope.rs |
disrobe-ir | READ_PREALLOC_CAP | other | allocation: with_capacity in read_from_path | usize | 1 << 20 | crates/disrobe-ir/src/io.rs |
disrobe-ir | MAX_RECORDS | count | error: WitnessError::RecordLimit | usize | 1 << 16 | crates/disrobe-ir/src/witness.rs |
disrobe-irsummary | MAX_CFG_BLOCKS | other | recorded: flag truncated | usize | 200_000 | crates/disrobe-irsummary/src/llm.rs |
disrobe-irsummary | MAX_CFG_EDGES | other | recorded: flag truncated | usize | 400_000 | crates/disrobe-irsummary/src/llm.rs |
disrobe-irsummary | MAX_DFG_SITES | other | recorded: flag truncated | usize | 400_000 | crates/disrobe-irsummary/src/llm.rs |
disrobe-irsummary | MAX_FIXPOINT_ROUNDS | work | silent: for range in optimize_graph | usize | 16 | crates/disrobe-irsummary/src/optimize.rs |
disrobe-irsummary | MAX_BLOCKS | other | silent: return in build_region; return in collect_leaders | usize | 64 | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_BLOCK_INSNS | other | silent: return in build_block; return in collect_leaders | usize | 256 | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_INSNS | other | silent: return in summarize_function | usize | 2048 | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_JOINS | other | silent: return in summarize_region | usize | 64 | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_OUTPUTS | output | silent: return in finalize | usize | 64 | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_STACK_DEPTH | recursion | silent: return in push | usize | 256 | crates/disrobe-irsummary/src/symexec.rs |
disrobe-lift-x86 | MAX_X86_BLOCK_BYTES | size | silent: .min() clamp in decode_block; .min() clamp in invalid_bitness_block; fallback value in with_limits | usize | 1024 * 1024 | crates/disrobe-lift-x86/src/lib.rs |
disrobe-lift-x86 | MAX_X86_INSTRUCTIONS | other | silent: while condition in decode_block; fallback value in with_limits | usize | 65_536 | crates/disrobe-lift-x86/src/lib.rs |
disrobe-llm-metadata | MAX_ANNOTATIONS | other | error: AnnotationError::TooManyAnnotations | usize | 4096 | crates/disrobe-llm-metadata/src/annotation.rs |
disrobe-llm-metadata | MAX_FILE_BYTES | size | error: AnnotationError::FieldTooLong | usize | 4096 | crates/disrobe-llm-metadata/src/annotation.rs |
disrobe-llm-metadata | MAX_KIND_BYTES | size | error: AnnotationError::FieldTooLong | usize | 128 | crates/disrobe-llm-metadata/src/annotation.rs |
disrobe-llm-metadata | MAX_NOTE_BYTES | size | error: AnnotationError::FieldTooLong | usize | 4096 | crates/disrobe-llm-metadata/src/annotation.rs |
disrobe-llm-metadata | MAX_NOTE_LINES | other | error: AnnotationError::NoteTooLong | usize | 2 | crates/disrobe-llm-metadata/src/annotation.rs |
disrobe-llm-metadata | MAX_SYMBOL_BYTES | size | error: AnnotationError::FieldTooLong | usize | 1024 | crates/disrobe-llm-metadata/src/annotation.rs |
disrobe-llm-metadata | MAX_DECRYPTION_KEY_ENTRIES | count | error: LlmMetadataError::Serialization | usize | 4096 | crates/disrobe-llm-metadata/src/bundle.rs |
disrobe-llm-metadata | MAX_PIPELINE_STEPS | work | error: LlmMetadataError::Serialization | usize | 1024 | crates/disrobe-llm-metadata/src/bundle.rs |
disrobe-llm-metadata | MAX_PROVENANCE_CHAIN_ENTRIES | count | error: LlmMetadataError::Serialization | usize | 16_384 | crates/disrobe-llm-metadata/src/bundle.rs |
disrobe-llm-metadata | MAX_PII_ENTRIES | count | silent: .min() clamp in scan | usize | 4096 | crates/disrobe-llm-metadata/src/pii.rs |
disrobe-llm-metadata | MAX_SCAN_BYTES | size | silent: .min() clamp in scan | usize | 1024 * 1024 | crates/disrobe-llm-metadata/src/pii.rs |
disrobe-llm-metadata | MAX_DECLARED_TYPE_BYTES | size | silent: return in parse_declared_type | usize | 256 | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-llm-metadata | MAX_FUNCTIONS | other | silent: skipped in add_function | usize | 65_536 | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-llm-metadata | MAX_OBSERVATIONS_PER_VAR | other | unused: no use in the crate | usize | 16_384 | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-llm-metadata | MAX_OBSERVATIONS_PER_VAR_U32 | other | silent: skipped in observe | u32 | 16_384 | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-llm-metadata | MAX_VARIABLES_PER_FN | other | silent: skipped in add_local; skipped in add_parameter | usize | 4_096 | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-mba | BFS_TABLE_BUDGET | work | silent: return in minimal_bitwise_for_table | usize | 1usize << 14 | crates/disrobe-mba/src/bitwise_synth.rs |
disrobe-mba | MAX_BITWISE_SYNTH_VARS | other | silent: return in synthesize_bitwise_masked; no action in simplify_l0_l5 | u32 | 4 | crates/disrobe-mba/src/bitwise_synth.rs |
disrobe-mba | MAX_BOOLEAN_ATOMS | other | silent: return in boolean_minimization_candidate; return in collect_boolean_atoms; return in collect_predicate_atoms; 2 more | usize | 8 | crates/disrobe-mba/src/boolean.rs |
disrobe-mba | MAX_BOOLEAN_PRIMES | other | silent: return in minimize_sop | usize | 64 | crates/disrobe-mba/src/boolean.rs |
disrobe-mba | MAX_BOOLEAN_SEARCH_STEPS | work | recorded: flag exhausted | usize | 100_000 | crates/disrobe-mba/src/boolean.rs |
disrobe-mba | MAX_CFF_BLOCKS | other | silent: return in devirtualize_cheap; return in devirtualize_table_dispatch; return in devirtualize_traced | usize | 4_096 | crates/disrobe-mba/src/cff/detect.rs |
disrobe-mba | MAX_REGION_NODES | count | silent: return in run | u32 | 512 | crates/disrobe-mba/src/cff/detect.rs |
disrobe-mba | CHEAP_LOOP_CAP | other | silent: for range in cheap_initial; for range in cheap_resolve_block; return in cheap_initial; 1 more | u32 | 8 | crates/disrobe-mba/src/cff/mod.rs |
disrobe-mba | MAX_APPLICATIONS | other | recorded: StopReason::ApplicationLimit | usize | 12_000 | crates/disrobe-mba/src/egraph.rs |
disrobe-mba | MAX_CLASSES | other | recorded: Refusal::ClassBudgetExhausted; StopReason::ClassLimit | usize | 2000 | crates/disrobe-mba/src/egraph.rs |
disrobe-mba | MAX_INPUT_NODES | count | recorded: Refusal::NodesAboveCap; Saturation::Refused | usize | 48 | crates/disrobe-mba/src/egraph.rs |
disrobe-mba | MAX_ITERATIONS | work | recorded: StopReason::IterationLimit | u32 | 10 | crates/disrobe-mba/src/egraph.rs |
disrobe-mba | MAX_LEAVES | other | error: BuildStop::LeafBudget | usize | 32 | crates/disrobe-mba/src/egraph.rs |
disrobe-mba | BANK_CAP | other | silent: skipped in offer | usize | 128 | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | GEN_BUDGET | work | silent: return in expand_layer; return in grow; return in offer | u64 | 60_000 | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_ATOMS | other | silent: return in push_atom | usize | 3 | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_CANDIDATE_NODES | count | silent: .min() clamp in synthesize | usize | 16 | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_CONSTS | other | silent: .truncate() in build_consts | usize | 8 | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_ROUNDS | work | silent: for range in grow | u32 | 4 | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_VARS | other | silent: return in synthesize | u32 | 4 | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | VERIFY_BUDGET | work | silent: no action in offer | u32 | 32 | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_EXHAUSTIVE_EVALS | other | recorded: OpaqueVerdict::OutOfBudget; flag exhaustive | u128 | 1 << 24 | crates/disrobe-mba/src/expr.rs |
disrobe-mba | MAX_MBA_DEPTH | recursion | recorded: MixedRefusal::DepthLimit; MixedSimplification::Refused; OpaqueVerdict::OutOfBudget; 2 more | usize | 256 | crates/disrobe-mba/src/expr.rs |
disrobe-mba | MAX_CERTIFICATE_DEGREE | other | silent: return in composition_is_identity; return in polynomial_is_zero_function | usize | 1 << 16 | crates/disrobe-mba/src/finite_diff.rs |
disrobe-mba | MULTIVAR_EVAL_BUDGET | work | silent: return in multivar_induces_zero | u128 | 1 << 22 | crates/disrobe-mba/src/finite_diff.rs |
disrobe-mba | MAX_TABLE_ENTRIES | count | silent: .min() clamp in solver_resolve; return in solver_resolve; return in try_resolve_vsa | u64 | 4_096 | crates/disrobe-mba/src/jumptable/mod.rs |
disrobe-mba | MAX_BASIS_VARS | other | silent: return in synthesize_linear_basis | u32 | 3 | crates/disrobe-mba/src/linear_mba.rs |
disrobe-mba | MAX_SOLVER_VARS | other | silent: return in solve_linear_mba; return in verify_equivalent; no action in simplify_l0_l5 | u32 | 8 | crates/disrobe-mba/src/linear_solver.rs |
disrobe-mba | MAX_SUBSET_COMBOS | other | silent: return in subset_combinations | usize | 60_000 | crates/disrobe-mba/src/linear_solver.rs |
disrobe-mba | MAX_SUBSET_SEARCH_VARS | other | silent: skipped in solve_linear_mba | u32 | 5 | crates/disrobe-mba/src/linear_solver.rs |
disrobe-mba | MAX_MIXED_MBA_NODES | count | recorded: MixedRefusal::NodeLimit; MixedSimplification::Refused | usize | 16_384 | crates/disrobe-mba/src/mixed_mba.rs |
disrobe-mba | MAX_MIXED_MBA_VARS | other | error: MixedRefusal::VariableLimit | u32 | 6 | crates/disrobe-mba/src/mixed_mba.rs |
disrobe-mba | MAX_MIXED_MBA_WORK | work | error: MixedRefusal::WorkLimit | usize | 1_024 | crates/disrobe-mba/src/mixed_mba.rs |
disrobe-mba | MAX_MIXED_RECURSION_DEPTH | recursion | error: MixedRefusal::DepthLimit | usize | 256 | crates/disrobe-mba/src/mixed_mba.rs |
disrobe-mba | MAX_POLYNOMIAL_PAIR_WORK | work | error: MixedRefusal::WorkLimit | usize | 8_192 * 8_192 | crates/disrobe-mba/src/mixed_mba.rs |
disrobe-mba | MAX_PROOF_PAIR_WORK | work | error: MixedRefusal::WorkLimit | usize | 4_096 * 4_096 | crates/disrobe-mba/src/mixed_mba.rs |
disrobe-mba | BIT_BUDGET | work | recorded: OpaqueVerdict::OutOfBudget | u32 | 22 | crates/disrobe-mba/src/opaque.rs |
disrobe-mba | MAX_EXHAUSTIBLE | other | recorded: OpaqueVerdict::OutOfBudget | Width | Width::W16 | crates/disrobe-mba/src/opaque.rs |
disrobe-mba | MAX_OPAQUE_VARS | other | recorded: OpaqueVerdict::OutOfBudget | u32 | 3 | crates/disrobe-mba/src/opaque.rs |
disrobe-mba | MAX_ATOM_DEGREE | other | silent: return in to_falling_factorial; return in to_power_basis | u32 | 32 | crates/disrobe-mba/src/poly_mba.rs |
disrobe-mba | MAX_POLY_ATOMS | other | silent: return in intern_atom | usize | 24 | crates/disrobe-mba/src/poly_mba.rs |
disrobe-mba | MAX_POLY_MBA_VARS | other | silent: return in polynomial_solver_work; return in solve_polynomial_mba; no action in simplify_l0_l5 | u32 | 4 | crates/disrobe-mba/src/poly_mba.rs |
disrobe-mba | MAX_POLY_MONOMIALS | other | silent: return in multiply_poly; return in substitute_axis | usize | 8192 | crates/disrobe-mba/src/poly_mba.rs |
disrobe-mba | MAX_CERTIFICATE_ATOMS | other | silent: return in congruent_to_constant; return in induces_zero_over_free_atoms | usize | 8 | crates/disrobe-mba/src/poly_oracle.rs |
disrobe-mba | MAX_MONOMIALS | other | silent: return in multiply | usize | 4096 | crates/disrobe-mba/src/poly_oracle.rs |
disrobe-mba | MAX_MONOMIAL_DEGREE | other | silent: return in multiply_monomials | u32 | 128 | crates/disrobe-mba/src/poly_oracle.rs |
disrobe-mba | MAX_REWRITE_PASSES | other | silent: for range in canonicalize | u32 | 64 | crates/disrobe-mba/src/rewrite.rs |
disrobe-mba | MAX_PROVENANCE_BYTES | size | error: EgraphRuleError::ProvenanceTooLong | usize | 256 | crates/disrobe-mba/src/rules/egraph_rules.rs |
disrobe-mba | MAX_RULES | other | error: EgraphRuleError::TooManyRules | usize | 256 | crates/disrobe-mba/src/rules/egraph_rules.rs |
disrobe-mba | MAX_RULE_CAPTURES | other | error: EgraphRuleError::TooManyCaptures | usize | 8 | crates/disrobe-mba/src/rules/egraph_rules.rs |
disrobe-mba | MAX_RULE_FILE_BYTES | size | error: EgraphRuleError::TooLarge | usize | 128 * 1024 | crates/disrobe-mba/src/rules/egraph_rules.rs |
disrobe-mba | MAX_RULE_NAME_BYTES | size | error: EgraphRuleError::RuleNameTooLong | usize | 128 | crates/disrobe-mba/src/rules/egraph_rules.rs |
disrobe-mba | MAX_TERM_BYTES | size | error: TermError::TooLong | usize | 512 | crates/disrobe-mba/src/rules/egraph_rules.rs |
disrobe-mba | MAX_TERM_DEPTH | recursion | error: TermError::TooDeep | usize | 16 | crates/disrobe-mba/src/rules/egraph_rules.rs |
disrobe-mba | MAX_TERM_NODES | count | error: TermError::TooManyNodes | usize | 64 | crates/disrobe-mba/src/rules/egraph_rules.rs |
disrobe-mba | MAX_TEMPLATE_NODES | count | error: ApplyError::DepthExceeded | usize | 4096 | crates/disrobe-mba/src/rules/engine.rs |
disrobe-mba | MAX_CAPTURE_NAME_BYTES | size | error: LoadError::CaptureNameTooLong | usize | 64 | crates/disrobe-mba/src/rules/loader.rs |
disrobe-mba | MAX_CONDITIONS_PER_RULE | other | error: LoadError::TooManyConditions | usize | 64 | crates/disrobe-mba/src/rules/loader.rs |
disrobe-mba | MAX_PATTERN_NODES | count | error: LoadError::PatternTooLarge | usize | 4096 | crates/disrobe-mba/src/rules/loader.rs |
disrobe-mba | MAX_RULES | other | error: LoadError::TooManyRules | usize | 1024 | crates/disrobe-mba/src/rules/loader.rs |
disrobe-mba | MAX_RULE_NAME_BYTES | size | error: LoadError::RuleNameTooLong | usize | 128 | crates/disrobe-mba/src/rules/loader.rs |
disrobe-mba | MAX_RULE_TEXT_BYTES | size | error: LoadError::TooLarge | usize | 256 * 1024 | crates/disrobe-mba/src/rules/loader.rs |
disrobe-mba | MAX_TEMPLATE_NODES | count | error: LoadError::TemplateTooLarge | usize | 4096 | crates/disrobe-mba/src/rules/loader.rs |
disrobe-mba | MAX_BASIS_VARS | other | silent: no action in simplify_l0_l5 | u32 | 3 | crates/disrobe-mba/src/simplify.rs |
disrobe-mba | MAX_LINEAR_VARS | other | silent: skipped in simplify_l0_l5 | u32 | 4 | crates/disrobe-mba/src/simplify.rs |
disrobe-mba | MAX_TEMPLATE_VARS | other | silent: skipped in simplify_l0_l5 | u32 | 2 | crates/disrobe-mba/src/simplify.rs |
disrobe-mba | CERT_NODE_BUDGET | work | error: EncodeExhausted | usize | 1usize << 20 | crates/disrobe-mba/src/smt.rs |
disrobe-mba | CERT_NODE_BUDGET | work | error: EncodeExhausted | usize | 1usize << 18 | crates/disrobe-mba/src/symexec/solver.rs |
disrobe-mba | EVAL_NODE_BUDGET | work | silent: return in eval_term | usize | 1usize << 18 | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_ENUM_ASSIGNMENTS | other | silent: return in enumeration_domain | u64 | 1u64 << 12 | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_ENUM_STEPS | work | silent: .min() clamp in enumerate_conjunction | usize | 1usize << 15 | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_ENUM_VARS | other | silent: return in enumeration_domain | usize | 6 | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_ENUM_VAR_BITS | other | silent: return in enumeration_domain | u32 | 16 | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_WIDTH_BITS | other | error: ApplyError::CaptureKindMismatch; ApplyError::MissingCapture; BuildStop::ClassBudget; 29 more | u16 | 64 | crates/disrobe-mba/src/symexec/value.rs |
disrobe-mba | DEFAULT_NODE_BUDGET | work | error: EncodeExhausted; MixedRefusal::VariableLimit | usize | 1usize << 20 | crates/disrobe-mba/src/verify.rs |
disrobe-mba | DEFAULT_OP_BUDGET | work | recorded: flag exhausted; flag truncated | usize | DEFAULT_NODE_BUDGET * 8 | crates/disrobe-mba/src/verify.rs |
disrobe-mba | MAX_COUNTEREXAMPLE_SLOTS | count | silent: return in expand_counterexample | usize | 1024 | crates/disrobe-mba/src/verify.rs |
disrobe-mba | MAX_INPUT_BITS | other | recorded: OpaqueVerdict::OutOfBudget | usize | 512 | crates/disrobe-mba/src/verify.rs |
disrobe-mba | POLY_NODE_BUDGET | work | recorded: AbstainReason::SolverBudget; CffAbstain::Budget; JumpTableAbstain::SolverBudget | usize | 4096 | crates/disrobe-mba/src/verify.rs |
disrobe-mcp | MAX_CHAIN_DEPTH | recursion | error: untyped format! | u8 | 64 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_COVERAGE_REGIONS | other | recorded: flag regions_truncated | usize | 512 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_IMPORTS | other | error: untyped format! | usize | 4096 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_IMPORT_BYTES | size | error: untyped format! | usize | 4096 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_INLINE_BASE64_CHARS | other | error: untyped format! | usize | 22 * 1024 * 1024 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_INLINE_DECODED_BYTES | size | error: untyped format! | usize | 16 * 1024 * 1024 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_INLINE_JSON_BYTES | size | error: untyped format! | usize | 4 * 1024 * 1024 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_PROVENANCE_LINES | other | error: untyped format! | usize | 262_144 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_RENAMES_FILE_BYTES | size | error: untyped format! | u64 | 4 * 1024 * 1024 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_RENAME_FIELD_BYTES | size | error: untyped format! | usize | 4096 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_RENAME_NOTE_BYTES | size | error: untyped format! | usize | 8192 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_RENAME_RECORDS | count | error: untyped format! | usize | 16_384 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_STRINGS_MIN_LEN | size | error: untyped format! | usize | 4096 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_WASM_LIFT_SOURCE_BYTES | size | unclassified: stored in wasm_lift() with no read found | usize | 16 * 1024 * 1024 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | MAX_WORKSPACE_READ_BYTES | work | error: untyped format! | u64 | 16 * 1024 * 1024 | crates/disrobe-mcp/src/lib.rs |
disrobe-mcp | DEFAULT_TOKEN_BUDGET | work | error: row_too_large(); untyped format! | usize | 4_096 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_AMBIGUOUS_CANDIDATES | other | silent: .take() in call_outcome_out | usize | 8 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_ANALYSIS_CALLS | other | error: cursor_error() | usize | 32_768 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_ANALYSIS_CANDIDATE_RECORDS | count | unclassified: stored in candidate_records with no read found | usize | 65_536 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_ANALYSIS_FUNCTIONS | other | unclassified: pattern binding in call_graph; pattern binding in neighborhood; stored in max_nodes with no read found; 2 more | usize | 8_192 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_ANALYSIS_INSTRUCTIONS | other | unclassified: stored in instructions with no read found | usize | 262_144 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_ANALYSIS_RETAINED_BYTES | size | delegated: .bounded_navigation_xrefs_to_function()? | usize | 64 * 1024 * 1024 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_CURSOR_BYTES | size | error: untyped format! | usize | 256 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_CURSOR_OFFSET | other | error: cursor_error() | usize | 1_000_000 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_ENTRY_IDS | other | error: untyped format! | usize | 64 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_NEIGHBORHOOD_DEPTH | recursion | error: untyped format! | u8 | 32 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_OUTPUT_TEXT_BYTES | output | recorded: flag truncated | usize | 160 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_TOKEN_BUDGET | work | error: untyped format! | usize | 32_768 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MAX_XREFS | other | delegated: .bounded_navigation_xrefs_to_function()? | usize | 32_768 | crates/disrobe-mcp/src/navigation.rs |
disrobe-mcp | MIN_TOKEN_BUDGET | work | error: untyped format! | usize | 2_048 | crates/disrobe-mcp/src/navigation.rs |
disrobe-nir | MAX_EFFECT_MODELS | other | error: EffectContextError::ModelLimit | usize | 65_536 | crates/disrobe-nir/src/effects.rs |
disrobe-nir | MAX_EFFECT_ROWS | other | error: EffectTableError::RowLimit; NirProvenanceError::ByteLimit | usize | 1_048_576 | crates/disrobe-nir/src/effects.rs |
disrobe-nir | MAX_WIRE_EFFECT_LABELS | other | error: EffectTableError::EffectLabelLimit | usize | 64 | crates/disrobe-nir/src/effects.rs |
disrobe-nir | MAX_EMITTED_BYTES | output | error: EmitError::DepthExceeded; EmitError::OutputLimitExceeded | usize | 1_048_576 | crates/disrobe-nir/src/emit.rs |
disrobe-nir | MAX_EMIT_DEPTH | recursion | error: EmitError::DepthExceeded | usize | 128 | crates/disrobe-nir/src/emit.rs |
disrobe-nir | MAX_INDENT_DEPTH | recursion | silent: .min() clamp in write_indent | usize | 32 | crates/disrobe-nir/src/emit.rs |
disrobe-nir | MAX_REGION_DEPTH | recursion | recorded: StructureFailure::RegionDepthExceeded | usize | 128 | crates/disrobe-nir/src/hir.rs |
disrobe-nir | MAX_SHORT_CIRCUIT_CLONE_BYTES | size | silent: ? on a checked operation in charge_condition_clone | usize | 1024 * 1024 | crates/disrobe-nir/src/hir.rs |
disrobe-nir | MAX_SHORT_CIRCUIT_TESTS | other | silent: return in resolve_condition_edge; return in short_circuit_candidate | usize | 64 | crates/disrobe-nir/src/hir.rs |
disrobe-nir | MAX_SHORT_CIRCUIT_WORK | work | error: NirProvenanceError::WorkLimit | usize | 65_536 | crates/disrobe-nir/src/hir.rs |
disrobe-nir | MAX_SPLIT_NODES | count | error: SplitRefusal::GraphTooLarge | usize | 4096 | crates/disrobe-nir/src/reducible.rs |
disrobe-nir | MAX_SURFACE_DEPTH | recursion | recorded: flag complete | usize | 128 | crates/disrobe-nir/src/surface.rs |
disrobe-nir | MAX_NIR_ELEMENTS | other | error: NirProvenanceError::ElementLimit; NirProvenanceError::WorkLimit | usize | MAX_SOURCE_UNITS | crates/disrobe-nir/src/types.rs |
disrobe-nir | MAX_NIR_RETAINED_BYTES | size | error: NirProvenanceError::RetainedByteLimit | usize | 256 * 1024 * 1024 | crates/disrobe-nir/src/types.rs |
disrobe-nir | MAX_NIR_STRING_BYTES | size | error: NirProvenanceError::StringByteLimit | usize | MAX_SOURCE_BYTES | crates/disrobe-nir/src/types.rs |
disrobe-nir | MAX_NIR_WORK | work | error: NirProvenanceError::WorkLimit | usize | 8 * MAX_NIR_ELEMENTS | crates/disrobe-nir/src/types.rs |
disrobe-nir | MAX_SOURCE_BYTES | size | error: EffectTableError::RowLimit; NirProvenanceError::ByteLimit; NirProvenanceError::StringByteLimit | usize | 64 * 1024 * 1024 | crates/disrobe-nir/src/types.rs |
disrobe-nir | MAX_SOURCE_UNITS | other | error: NirProvenanceError::ElementLimit; NirProvenanceError::UnitLimit; NirProvenanceError::WorkLimit | usize | 1_048_576 | crates/disrobe-nir/src/types.rs |
disrobe-nir-lift | MAX_BIG_DECIMAL_BYTES | size | silent: return in big_to_decimal | usize | 1024 | crates/disrobe-nir-lift/src/beam.rs |
disrobe-nir-lift | MAX_LUA_PROTOS | other | error: LiftError::AstSizeExceeded | usize | 262_144 | crates/disrobe-nir-lift/src/lua.rs |
disrobe-nir-lift | MAX_LUA_PROTO_DEPTH | recursion | error: LiftError::DepthExceeded | usize | 256 | crates/disrobe-nir-lift/src/lua.rs |
disrobe-nir-lift | MAX_REGISTERS | other | allocation: buffer length in new | usize | 256 | crates/disrobe-nir-lift/src/lua.rs |
disrobe-nir-lift | MAX_REPORTED_GAPS | other | silent: .take() in block_gaps | usize | 4096 | crates/disrobe-nir-lift/src/pcode/arch.rs |
disrobe-nir-lift | MAX_FOLD_DEPTH | recursion | silent: return in resolve | usize | 64 | crates/disrobe-nir-lift/src/pcode/flags.rs |
disrobe-nir-lift | MAX_REACHING_ANALYSIS_ELEMENTS | other | silent: return in compute_entries; return in eliminate_dead_values | usize | 8_388_608 | crates/disrobe-nir-lift/src/pcode/flags.rs |
disrobe-nir-lift | MAX_IDENTIFIER_BYTES | size | error: LiftError::InvalidPcode | usize | 4096 | crates/disrobe-nir-lift/src/pcode/mod.rs |
disrobe-nir-lift | MAX_PCODE_INSTRUCTIONS | other | error: LiftError::PcodeInstructionLimit | usize | 65_536 | crates/disrobe-nir-lift/src/pcode/mod.rs |
disrobe-nir-lift | MAX_PCODE_OPERATIONS | other | error: LiftError::PcodeOperationLimit | usize | 1_048_576 | crates/disrobe-nir-lift/src/pcode/mod.rs |
disrobe-nir-lift | MAX_CALLOTHER_INPUTS | other | error: invalid() | usize | 4096 | crates/disrobe-nir-lift/src/pcode/ops.rs |
disrobe-nir-lift | MAX_CALLOTHER_NAME_BYTES | size | error: invalid() | usize | 4096 | crates/disrobe-nir-lift/src/pcode/ops.rs |
disrobe-nir-lift | MAX_SPEC_NAME_BYTES | size | error: invalid() | usize | 128 | crates/disrobe-nir-lift/src/pcode/spec.rs |
disrobe-nir-lift | MAX_SPEC_REGISTERS | other | error: invalid() | usize | 4096 | crates/disrobe-nir-lift/src/pcode/spec.rs |
disrobe-nir-lift | MAX_REGISTER_CELLS | other | error: invalid() | usize | 4096 | crates/disrobe-nir-lift/src/pcode/varnode.rs |
disrobe-nir-lift | MAX_VARNODE_BYTES | size | error: invalid() | u32 | 4096 | crates/disrobe-nir-lift/src/pcode/varnode.rs |
disrobe-nir-lift | MAX_AST_NODES | count | error: LiftError::AstSizeExceeded | usize | 262_144 | crates/disrobe-nir-lift/src/python.rs |
disrobe-nir-lift | MAX_EMIT_DEPTH | recursion | error: LiftError::DepthExceeded | usize | 512 | crates/disrobe-nir-lift/src/python.rs |
disrobe-nir-lift | MAX_WASM_OPERATORS_PER_FUNCTION | other | error: LiftError::Source | usize | 1 << 18 | crates/disrobe-nir-lift/src/wasm.rs |
disrobe-pass-as3 | MULTINAME_RENDER_BUDGET | work | silent: return in render_multiname_bounded | u32 | 4096 | crates/disrobe-pass-as3/src/abc.rs |
disrobe-pass-as3 | MAX_DUP_EXPR_NODES | count | silent: return in scope_node_count_capped; return in walk; fallback value in dup_clone | usize | 1024 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_EXPR_DEPTH | recursion | error: Error::ExprDepthExceeded (DR-AS3-0021) | usize | 2048 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_LOOSE_DISPATCH_CONDITIONS | other | error: SWITCH_ANALYSIS_BUDGET_MARKER | usize | 256 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_MERGE_DEFINITIONS | other | silent: continue in merge_tracked_values | usize | 4096 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_NEGATION_DEPTH | recursion | silent: return in negate_without_introducing_not | usize | 32 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_OR_GUARD_TESTS | other | silent: return in or_guard_shared_target | usize | 64 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_STRUCTURE_DEPTH | recursion | error: SWITCH_ANALYSIS_BUDGET_MARKER | usize | 256 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_SWITCH_ANALYSIS_FUEL | work | recorded: flag exhausted | usize | 65_536 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_TERNARY_FOLDS | other | silent: for range in resolve_ternary | usize | 64 | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_ARCHNAME_BYTES | size | silent: slice in is_byteloader_stream | usize | 64 | crates/disrobe-pass-as3/src/other_langs.rs |
disrobe-pass-as3 | MAX_BYTELOADER_LINE_BYTES | size | silent: slice in skip_line | usize | 64 | crates/disrobe-pass-as3/src/other_langs.rs |
disrobe-pass-as3 | MAX_RUNTIME_SYMBOL_SCAN_BYTES | size | silent: slice in detect_with_symbol_scan_limit | usize | 64 << 20 | crates/disrobe-pass-as3/src/other_langs.rs |
disrobe-pass-as3 | MAX_SHEBANG_LINE_BYTES | size | silent: slice in skip_line | usize | 256 | crates/disrobe-pass-as3/src/other_langs.rs |
disrobe-pass-as3 | MAX_DECOMPRESSED_BODY | other | error: Error::SwfDecompress (DR-AS3-0005); Error::SwfTruncated (DR-AS3-0003) | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-as3/src/swf.rs |
disrobe-pass-as3 | MAX_DECOMPRESS_PREALLOC | other | delegated: passed to .kv | usize | 4 * 1024 * 1024 | crates/disrobe-pass-as3/src/swf.rs |
disrobe-pass-as3 | MAX_LZMA_MEMLIMIT | other | delegated: Stream::new_lzma_decoder()? | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-as3/src/swf.rs |
disrobe-pass-as3 | MAX_SPRITE_NESTING | recursion | delegated: passed to Self::accumulate_counts | usize | 256 | crates/disrobe-pass-as3/src/swf.rs |
disrobe-pass-as3 | MAX_SWF_VERSION | other | error: Error::SwfUnsupportedVersion (DR-AS3-0004) | u8 | 40 | crates/disrobe-pass-as3/src/swf.rs |
disrobe-pass-beam | MAX_EXPR_NODES | count | recorded: flag degraded | usize | 1024 | crates/disrobe-pass-beam/src/body_lift/expr.rs |
disrobe-pass-beam | MAX_JOIN_INSTRUCTIONS | other | silent: return in build | usize | 200_000 | crates/disrobe-pass-beam/src/body_lift/join.rs |
disrobe-pass-beam | MAX_JOIN_PASSES | other | silent: for range in post_dominators | u32 | 64 | crates/disrobe-pass-beam/src/body_lift/join.rs |
disrobe-pass-beam | MAX_INTEGER_PROOF_DEPTH | recursion | silent: return in yields_integer | u32 | 32 | crates/disrobe-pass-beam/src/body_lift/mod.rs |
disrobe-pass-beam | MAX_LABEL_VISITS | other | silent: return in enter_label | u32 | 32 | crates/disrobe-pass-beam/src/body_lift/mod.rs |
disrobe-pass-beam | MAX_WALK_CALLS | other | recorded: flag degraded | u32 | 20_000 | crates/disrobe-pass-beam/src/body_lift/mod.rs |
disrobe-pass-beam | MAX_ARMS | other | silent: return in collect; return in descend; return in split_receive_arms | usize | 32 | crates/disrobe-pass-beam/src/body_lift/receive_clauses.rs |
disrobe-pass-beam | MAX_CONJUNCTS | other | silent: return in split_receive_arms | usize | 24 | crates/disrobe-pass-beam/src/body_lift/receive_clauses.rs |
disrobe-pass-beam | MAX_TERM_DEPTH | recursion | silent: return in cannot_raise; return in is_guard_safe; return in is_literal; 1 more | u32 | 16 | crates/disrobe-pass-beam/src/body_lift/receive_clauses.rs |
disrobe-pass-beam | MAX_TREE_DEPTH | recursion | silent: return in collect | u32 | 24 | crates/disrobe-pass-beam/src/body_lift/receive_clauses.rs |
disrobe-pass-beam | MAX_TYPE_ENTRIES | count | silent: return in decode_table | u32 | 1 << 20 | crates/disrobe-pass-beam/src/body_lift/types.rs |
disrobe-pass-beam | MAX_FUN_ARITY | other | error: CoreError::PassFailure (DR-CORE-0003); Error::BadAtomIndex (DR-BEAM-0009); Error::EzUnsafePath (DR-BEAM-0022); 3 more | u32 | 1024 | crates/disrobe-pass-beam/src/chunks.rs |
disrobe-pass-beam | MAX_DISASM_DEPTH | recursion | error: Error::DepthExceeded (DR-BEAM-0023) | usize | 500 | crates/disrobe-pass-beam/src/disasm.rs |
disrobe-pass-beam | MAX_SCAN_DEPTH | recursion | silent: return in enforced_keys_in; return in find_enforced_keys; return in find_struct_list; 1 more | u32 | 256 | crates/disrobe-pass-beam/src/elixir.rs |
disrobe-pass-beam | MAX_RENDER_DEPTH | recursion | silent: fallback value in enter | u32 | 256 | crates/disrobe-pass-beam/src/elixir_quoted.rs |
disrobe-pass-beam | MAX_RENDER_DEPTH | recursion | silent: fallback value in enter | u32 | 256 | crates/disrobe-pass-beam/src/erlang_abstract.rs |
disrobe-pass-beam | MAX_ATOM_SCALARS | other | error: Error::AtomTooLong (DR-BEAM-0025) | usize | 255 | crates/disrobe-pass-beam/src/etf.rs |
disrobe-pass-beam | MAX_DEPRECATED_ATOM_LATIN1_CHARS | other | error: Error::AtomTooLong (DR-BEAM-0025) | usize | 255 | crates/disrobe-pass-beam/src/etf.rs |
disrobe-pass-beam | MAX_ETF_CONTAINER_PREALLOC | other | allocation: with_capacity in decode_term_after_first | usize | 1 << 16 | crates/disrobe-pass-beam/src/etf.rs |
disrobe-pass-beam | MAX_ETF_DEPTH | recursion | error: Error::DepthExceeded (DR-BEAM-0023) | usize | 500 | crates/disrobe-pass-beam/src/etf.rs |
disrobe-pass-beam | MAX_ETF_INFLATE | other | error: Error::Zlib (DR-BEAM-0016) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-beam/src/etf.rs |
disrobe-pass-beam | MAX_OPCODE | other | error: Error::UnknownOpcode (DR-BEAM-0012) | u32 | 191 | crates/disrobe-pass-beam/src/opcodes.rs |
disrobe-pass-dotnet | EAGER_CCTOR_SCAN_CAP | other | silent: while condition in detect | u32 | 512 | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_DYNAMIC_RELOCATIONS | other | error: Error::AotContainerRead (DR-DOTNET-0033) | usize | 1_048_576 | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_NAME_LEN | size | silent: return in read_metadata_name | usize | 256 | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_PROFILE_MAJOR | other | silent: continue in declared_profile | u16 | 64 | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_READY_TO_RUN_SECTIONS | other | silent: return in read_ready_to_run_header | u16 | 1024 | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_RECOVERED_NAMES | other | silent: break in recover_names_at_threshold; while condition in recover_names_at_threshold | usize | 65536 | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_INVOKE_MAP_BUCKETS | other | error: invalid() | usize | 65_536 | crates/disrobe-pass-dotnet/src/aot/invoke_map.rs |
disrobe-pass-dotnet | MAX_INVOKE_MAP_BYTES | size | error: invalid() | usize | 16 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/aot/invoke_map.rs |
disrobe-pass-dotnet | MAX_INVOKE_MAP_ENTRIES | count | error: invalid() | usize | 1_048_576 | crates/disrobe-pass-dotnet/src/aot/invoke_map.rs |
disrobe-pass-dotnet | MAX_METADATA_COLLECTION | other | error: invalid_metadata() | usize | 65_536 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METADATA_OUTPUT_BYTES | output | error: invalid_metadata() | usize | 16_777_216 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METADATA_RECORDS | count | error: invalid_metadata() | usize | 65_536 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METADATA_STRING_BYTES | size | error: invalid_metadata() | usize | 4_096 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METADATA_STRING_RECORDS | count | error: invalid_metadata() | usize | 131_072 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METADATA_STRING_STORAGE_BYTES | size | error: invalid_metadata() | usize | 16_777_216 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METADATA_TYPE_SIGNATURE_DEPTH | recursion | error: invalid_metadata() | usize | 256 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METADATA_TYPE_SIGNATURE_WORK | work | error: invalid_metadata() | usize | 1_048_576 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METADATA_VALUES | other | error: invalid_metadata() | usize | 1_048_576 | crates/disrobe-pass-dotnet/src/aot/metadata_records.rs |
disrobe-pass-dotnet | MAX_METHOD_BODY_INPUT_BYTES | size | error: refused() | usize | 1024 * 1024 | crates/disrobe-pass-dotnet/src/aot/method_bodies.rs |
disrobe-pass-dotnet | MAX_METHOD_BODY_OUTPUT_BYTES | output | recorded: refused() | usize | 1024 * 1024 | crates/disrobe-pass-dotnet/src/aot/method_bodies.rs |
disrobe-pass-dotnet | MAX_REFUSAL_BYTES_PER_METHOD | size | error: invalid(); untyped error | usize | 128 | crates/disrobe-pass-dotnet/src/aot/method_bodies.rs |
disrobe-pass-dotnet | MAX_TOTAL_BODY_INPUT_BYTES | size | error: refused() | usize | 16 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/aot/method_bodies.rs |
disrobe-pass-dotnet | MAX_TOTAL_BODY_OUTPUT_BYTES | output | error: invalid(); untyped error | usize | 8 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/aot/method_bodies.rs |
disrobe-pass-dotnet | MAX_UNIQUE_METHOD_BODIES | other | error: refused() | usize | 65_536 | crates/disrobe-pass-dotnet/src/aot/method_bodies.rs |
disrobe-pass-dotnet | MAX_EXCEPTION_DIRECTORY_BYTES | size | error: invalid() | usize | 16 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/aot/method_boundaries.rs |
disrobe-pass-dotnet | MAX_RUNTIME_FUNCTIONS | other | error: invalid() | usize | 1_048_576 | crates/disrobe-pass-dotnet/src/aot/method_boundaries.rs |
disrobe-pass-dotnet | MAX_BACKEND_CAPTURE | other | delegated: subprocess::run_captured()? | usize | 4 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/backends.rs |
disrobe-pass-dotnet | MAX_NATIVE_AOT_QUALIFIED_NAME_BYTES | size | error: CoreError::PassFailure (DR-CORE-0003) | usize | MAX_NATIVE_AOT_SYMBOL_ARTIFACT_BYTES | crates/disrobe-pass-dotnet/src/chain_detector.rs |
disrobe-pass-dotnet | MAX_NATIVE_AOT_SYMBOL_ARTIFACT_BYTES | size | error: .to_owned(); .to_string(); AotSignatureAbstention::ArgumentPositionsExceeded; 36 more | usize | 16 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/chain_detector.rs |
disrobe-pass-dotnet | MAX_NATIVE_AOT_SYMBOL_WORK_ITEMS | work | error: CoreError::PassFailure (DR-CORE-0003) | usize | 1_048_576 | crates/disrobe-pass-dotnet/src/chain_detector.rs |
disrobe-pass-dotnet | MAX_NATIVE_AOT_TYPE_NESTING_DEPTH | recursion | error: CoreError::PassFailure (DR-CORE-0003) | usize | 256 | crates/disrobe-pass-dotnet/src/chain_detector.rs |
disrobe-pass-dotnet | MAX_CIL_INSTRUCTIONS | other | error: Error::CilInstructionCountExceeded (DR-DOTNET-0030) | usize | 65_536 | crates/disrobe-pass-dotnet/src/cil.rs |
disrobe-pass-dotnet | MAX_ARRAY | other | error: EmulationError::OutOfBounds | usize | 16 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/cil_emulator.rs |
disrobe-pass-dotnet | MAX_EMULATED_INSTRUCTIONS | other | error: EmulationError::OutOfBounds | usize | 16_384 | crates/disrobe-pass-dotnet/src/cil_emulator.rs |
disrobe-pass-dotnet | MAX_HEAP | other | error: EmulationError::OutOfBounds | usize | 4096 | crates/disrobe-pass-dotnet/src/cil_emulator.rs |
disrobe-pass-dotnet | MAX_HEAP_BYTES | size | error: EmulationError::OutOfBounds | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/cil_emulator.rs |
disrobe-pass-dotnet | MAX_SWITCH_TARGETS | other | error: EmulationError::OutOfBounds | usize | 65_536 | crates/disrobe-pass-dotnet/src/cil_emulator.rs |
disrobe-pass-dotnet | STEP_LIMIT | work | error: EmulationError::StepLimitExceeded | u64 | 4_000_000 | crates/disrobe-pass-dotnet/src/cil_emulator.rs |
disrobe-pass-dotnet | MAX_CIL_EVALUATION_STACK | other | error: Reject::new() | usize | 64 | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_CIL_EXPRESSION_DEPTH | recursion | silent: return in append_output_expression; return in binary; return in expression_contains_stack_input | u8 | 32 | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_CIL_EXPRESSION_NODES | count | silent: return in binary | u8 | 64 | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_CIL_HANDLER_BODY_BYTES | size | error: Reject::new() | usize | 4_096 | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_CIL_HANDLER_INSTRUCTIONS | other | silent: return in summarize_cil_handler | usize | 512 | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_LOWERED_EFFECTS | other | error: Reject::new() | usize | 1_024 | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_EAZVM_MODELS | other | error: ExtractError::ProgramTooLarge | usize | 1_024 | crates/disrobe-pass-dotnet/src/devirt/extract.rs |
disrobe-pass-dotnet | MAX_EAZVM_MODEL_INSTRUCTIONS | other | error: ExtractError::ProgramTooLarge | usize | 4_096 | crates/disrobe-pass-dotnet/src/devirt/extract.rs |
disrobe-pass-dotnet | MAX_EAZVM_MODEL_INSTRUCTIONS_TOTAL | other | error: ExtractError::ProgramTooLarge | usize | 65_536 | crates/disrobe-pass-dotnet/src/devirt/extract.rs |
disrobe-pass-dotnet | MAX_LIFT_STACK | other | error: Reject::new() | usize | 1_024 | crates/disrobe-pass-dotnet/src/devirt/lift.rs |
disrobe-pass-dotnet | MAX_DOTNET_MBA_NODES | count | silent: .min() clamp in simplify_expression; return in count | usize | 256 | crates/disrobe-pass-dotnet/src/devirt/mba.rs |
disrobe-pass-dotnet | MAX_DOTNET_MBA_VARS | other | silent: return in intern_leaf; return in simplify_expression | usize | 6 | crates/disrobe-pass-dotnet/src/devirt/mba.rs |
disrobe-pass-dotnet | MAX_SAMPLES | other | silent: return in append_input_case; return in append_input_values | usize | 16 | crates/disrobe-pass-dotnet/src/devirt/oracle.rs |
disrobe-pass-dotnet | MAX_MODEL_STACK | other | error: untyped error | usize | 1_024 | crates/disrobe-pass-dotnet/src/devirt/oracle/model_ref.rs |
disrobe-pass-dotnet | MODEL_STEP_LIMIT | work | recorded: ModelRun::StepLimit | u64 | 4_000_000 | crates/disrobe-pass-dotnet/src/devirt/oracle/model_ref.rs |
disrobe-pass-dotnet | MAX_OPERAND_BYTES | size | error: Reject::new() | usize | 8 | crates/disrobe-pass-dotnet/src/devirt/profile.rs |
disrobe-pass-dotnet | MAX_ABSTRACT_STACK | other | error: Reject::new() | usize | 64 | crates/disrobe-pass-dotnet/src/devirt/state.rs |
disrobe-pass-dotnet | MAX_EXPR_DEPTH | recursion | error: Reject::new() | u8 | 32 | crates/disrobe-pass-dotnet/src/devirt/state.rs |
disrobe-pass-dotnet | MAX_STRUCTURE_BLOCKS | other | error: StructureError::new() | usize | 4_096 | crates/disrobe-pass-dotnet/src/devirt/structure.rs |
disrobe-pass-dotnet | MAX_STRUCTURE_DEPTH | recursion | error: StructureError::new() | usize | 128 | crates/disrobe-pass-dotnet/src/devirt/structure.rs |
disrobe-pass-dotnet | MAX_NESTING | recursion | silent: return in helper_body | usize | 8 | crates/disrobe-pass-dotnet/src/display_class_lowering.rs |
disrobe-pass-dotnet | MAX_FIELD_RVA_BYTES | size | silent: continue in build | u32 | 512 | crates/disrobe-pass-dotnet/src/field_rva.rs |
disrobe-pass-dotnet | MAX_ARRAY_FIELD_BYTES | size | silent: continue in array_field_data | usize | 1 << 20 | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_CALL_SITES | other | silent: break in recover_bitmono_strings | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_CIPHERTEXT_BYTES | size | silent: return in decrypt_site | usize | 1 << 16 | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_DECRYPTOR_INSTRUCTIONS | other | silent: continue in method_bodies | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_DERIVATIONS | other | silent: return in decrypt_site | usize | 32 | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_PBKDF2_ITERATIONS | work | silent: continue in locate_decryptor | u32 | 1_000_000 | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_CONSTANTS_BLOB_BYTES | size | recorded: flag size | usize | 16 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/confuserex_constants.rs |
disrobe-pass-dotnet | MAX_CONSTANTS_POOL_BYTES | size | silent: continue in recover_pool | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/confuserex_constants.rs |
disrobe-pass-dotnet | MAX_DECODE_ATTEMPTS | other | silent: return in recover_strings | usize | 1_000_000 | crates/disrobe-pass-dotnet/src/peel/confuserex_constants.rs |
disrobe-pass-dotnet | MAX_SEED_CANDIDATES | other | silent: break in collect_ldc_i4_immediates; break in recover_pool | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/confuserex_constants.rs |
disrobe-pass-dotnet | MAX_DECRYPTED_RESOURCE_BYTES | size | error: Error::Truncated (DR-DOTNET-0005) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/confuserex_resources.rs |
disrobe-pass-dotnet | MAX_ENCRYPTED_BLOB_BYTES | size | error: Error::Truncated (DR-DOTNET-0005) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/confuserex_resources.rs |
disrobe-pass-dotnet | MAX_SEED_CANDIDATES | other | silent: break in collect_ldc_i4_immediates; break in peel_confuserex_resources | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/confuserex_resources.rs |
disrobe-pass-dotnet | MAX_METHODS_SCANNED | other | silent: break in recover_seeds_by_emulation | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/confuserex_seed.rs |
disrobe-pass-dotnet | MAX_SEED_RUN | other | silent: return in seed_run | usize | 64 | crates/disrobe-pass-dotnet/src/peel/confuserex_seed.rs |
disrobe-pass-dotnet | KEY_PATH_STEP_CAP | work | silent: return in reaches_dispatcher_switch | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/deflatten/blocks.rs |
disrobe-pass-dotnet | MAX_BLOCKS | other | silent: return in build | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/deflatten/blocks.rs |
disrobe-pass-dotnet | FIELD_RVA_READ_CAP | other | silent: .min() clamp in build_field_env | usize | 1 << 16 | crates/disrobe-pass-dotnet/src/peel/deflatten/decrypt.rs |
disrobe-pass-dotnet | MAX_CALL_SITES | other | silent: return in scan_call_sites | usize | 8192 | crates/disrobe-pass-dotnet/src/peel/deflatten/decrypt.rs |
disrobe-pass-dotnet | STEP_LIMIT | work | error: ResolveError::StepLimit | u32 | 8192 | crates/disrobe-pass-dotnet/src/peel/deflatten/interp.rs |
disrobe-pass-dotnet | NATIVE_STEP_CAP | work | delegated: .run()? | u64 | 200_000 | crates/disrobe-pass-dotnet/src/peel/deflatten/predicate.rs |
disrobe-pass-dotnet | NATIVE_STUB_READ_CAP | other | silent: .min() clamp in classify | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/deflatten/predicate.rs |
disrobe-pass-dotnet | MAX_VISIT | other | silent: break in deflatten_with_oracle | usize | 8192 | crates/disrobe-pass-dotnet/src/peel/deflatten/rebuild.rs |
disrobe-pass-dotnet | MAX_ATTEMPTS_PER_IMAGE | other | recorded: RewriteOutcome::Refused | usize | 256 | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_EXPRESSION_DEPTH | recursion | recorded: RewriteOutcome::Refused | usize | 32 | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_EXPRESSION_NODES | count | recorded: RewriteOutcome::Refused | usize | 256 | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_EXPRESSION_VARS | other | recorded: RewriteOutcome::Refused | usize | 6 | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_INSTRUCTIONS_PER_IMAGE | other | recorded: RewriteOutcome::Refused | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_INSTRUCTIONS_PER_METHOD | other | recorded: RewriteOutcome::Refused | usize | 4_096 | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_METHODS_PER_IMAGE | other | recorded: RewriteOutcome::Refused | usize | 1_024 | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_STACK_VALUES | other | silent: return in lower_postfix; return in verify_straight_line | usize | 1_024 | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_INSTRS | other | error: DecodeError::Truncated | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/eazvm/disasm.rs |
disrobe-pass-dotnet | MAX_RESOURCE_BYTES | size | silent: return in locate_embedded_resource | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/ilprotector_bodies.rs |
disrobe-pass-dotnet | MAX_BLOCKS | other | error: DisasmError::TooManyBlocks | usize | 512 | crates/disrobe-pass-dotnet/src/peel/koivm/disasm.rs |
disrobe-pass-dotnet | MAX_INSTRS_PER_BLOCK | other | silent: for range in decode_block | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/koivm/disasm.rs |
disrobe-pass-dotnet | MAX_SECTION_BYTES | size | silent: .min() clamp in locate_encrypted_section | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/maxtocode_bodies.rs |
disrobe-pass-dotnet | MAX_EAZVM_ANALYSIS_NAME_CHARS | other | silent: .take() in bounded_eazvm_analysis_name | usize | 128 | crates/disrobe-pass-dotnet/src/peel/mod.rs |
disrobe-pass-dotnet | MAX_EAZVM_ANALYSIS_REFUSALS | other | silent: skipped in apply_eazvm_tier | usize | 32 | crates/disrobe-pass-dotnet/src/peel/mod.rs |
disrobe-pass-dotnet | MAX_DISASM_BYTES | size | silent: .min() clamp in surface_native_stub | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/native_surface.rs |
disrobe-pass-dotnet | MAX_SURFACED_INSNS | other | silent: .take() in surface_native_stub | usize | 64 | crates/disrobe-pass-dotnet/src/peel/native_surface.rs |
disrobe-pass-dotnet | MAX_ACCESSORS | other | silent: return in prove_constructor | usize | 65_000 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_ACCESSOR_CODE | other | silent: return in prove_accessor | u32 | 256 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_ACCESSOR_INSTRUCTIONS | other | silent: return in prove_accessor | usize | 32 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_CONSTRUCTOR_CODE | other | silent: return in prove_constructor | u32 | 16 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_CONSTRUCTOR_INSTRUCTIONS | other | silent: return in prove_constructor | usize | 2_048 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_FIELD_DATA | other | silent: return in prove_constructor | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_FIELD_ROWS | other | error: ScanFailure::TableLimit | u32 | 131_072 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_GETTER_CODE | other | silent: return in prove_getter | u32 | 4 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_GETTER_INSTRUCTIONS | other | silent: return in prove_getter | usize | 256 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_IMAGE_BYTES | size | error: ScanFailure::ImageLimit | usize | 256 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_MEMBER_REF_ROWS | other | error: ScanFailure::TableLimit | u32 | 131_072 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_METADATA_BLOB_BYTES | size | error: ScanFailure::ImageLimit | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_METADATA_BYTES | size | error: ScanFailure::ImageLimit | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_METHOD_CODE | other | error: ScanFailure::MethodBodies | u32 | 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_METHOD_PARSE_BYTES | size | silent: .min() clamp in read_bodies | usize | 1024 * 1024 + 64 * 1024 + 64 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_METHOD_ROWS | other | error: ScanFailure::TableLimit | u32 | 131_072 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_MODEL_NAME_BYTES | size | error: ScanFailure::TableLimit | usize | 4 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_MODEL_SIGNATURE_BYTES | size | error: ScanFailure::TableLimit | usize | 4 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_RECOVERED_BYTES | size | silent: return in prove_accessors | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_RECOVERED_NAME_BYTES | size | silent: ? on a checked operation in prove_accessors | usize | 4 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_STACK | other | silent: return in prove_accessor; return in prove_constructor; return in prove_getter | u16 | 64 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_STRING_BYTES | size | silent: return in prove_accessors | usize | 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_TOTAL_EXCEPTION_CLAUSES | other | error: ScanFailure::MethodBodies | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_TOTAL_INSTRUCTIONS | other | error: ScanFailure::MethodBodies | usize | 1_000_000 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_TOTAL_METHOD_CODE | other | error: ScanFailure::MethodBodies | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_TOTAL_PARSE_BYTES | size | error: ScanFailure::MethodBodies | usize | 72 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_TOTAL_TABLE_ROWS | other | error: ScanFailure::TableLimit | u64 | 1_000_000 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_TYPE_ROWS | other | error: ScanFailure::TableLimit | u32 | 65_536 | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_EMBEDDED_RESOURCES | other | error: .to_string() | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/protector_resources.rs |
disrobe-pass-dotnet | MAX_RESOURCE_BYTES | size | error: .to_string(); refused(); untyped format!; 1 more | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/protector_resources.rs |
disrobe-pass-dotnet | MAX_STRINGS | other | silent: break in read_unicode_records_varint; return in read_unicode_records_int32_strict; return in read_unicode_records_varint_strict | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/protector_resources.rs |
disrobe-pass-dotnet | MAX_REACTOR_ENTRY_METHODS | other | error: .to_string() | usize | 256 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_HEAP_BYTES | size | error: .to_string() | usize | 16 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_METADATA_BYTES | size | error: .to_string() | usize | 64 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_METADATA_STREAMS | other | error: .to_string() | usize | 64 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_METHOD_CODE_BYTES | size | error: untyped format! | u32 | 4096 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_METHOD_INSTRUCTIONS | other | error: untyped format! | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_METHOD_ROWS | other | error: .to_string() | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_METHOD_TOTAL_BYTES | size | error: untyped format! | usize | 16 * 1024 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_PE_SECTIONS | other | error: .to_string() | usize | 96 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_RELEVANT_METADATA_ROWS | other | error: .to_string() | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_SELECTED_HEAP_BYTES | size | error: .to_string() | usize | 32 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_STRING_HEAP_ENTRIES | count | error: .to_string() | usize | 262_144 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_REACTOR_TOTAL_METADATA_ROWS | other | error: .to_string() | u64 | 262_144 | crates/disrobe-pass-dotnet/src/peel/protector_resources/reactor.rs |
disrobe-pass-dotnet | MAX_PARTS | other | error: untyped format! | usize | 65_536 | crates/disrobe-pass-dotnet/src/peel/smartassembly_resources.rs |
disrobe-pass-dotnet | MAX_ROT_SHIFT | other | silent: no action in recover_spices | u16 | 64 | crates/disrobe-pass-dotnet/src/peel/spices_strings.rs |
disrobe-pass-dotnet | MAX_PROBE_ARGS | other | silent: for range in probe_decoder | i64 | 64 | crates/disrobe-pass-dotnet/src/peel/static_decrypt.rs |
disrobe-pass-dotnet | MAX_DECRYPTOR_INSTRUCTIONS | other | silent: continue in collect_from_type | usize | 4096 | crates/disrobe-pass-dotnet/src/peel/string_emu.rs |
disrobe-pass-dotnet | MAX_RECOVERED_STRINGS | other | silent: return in recover_emulated_strings | usize | 8192 | crates/disrobe-pass-dotnet/src/peel/string_emu.rs |
disrobe-pass-dotnet | MAX_R2R_METHOD_BODY_INPUT_BYTES | size | recorded: R2rMethodBodyRefusal::InputBudgetExhausted | usize | 1024 * 1024 | crates/disrobe-pass-dotnet/src/r2r.rs |
disrobe-pass-dotnet | MAX_R2R_METHOD_BODY_OUTPUT_BYTES | output | recorded: R2rMethodBodyRefusal::OutputBudgetExhausted | usize | 1024 * 1024 | crates/disrobe-pass-dotnet/src/r2r.rs |
disrobe-pass-dotnet | MAX_R2R_METHOD_BODY_TOTAL_INPUT_BYTES | size | recorded: R2rMethodBodyRefusal::InputBudgetExhausted | usize | 16 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/r2r.rs |
disrobe-pass-dotnet | MAX_R2R_METHOD_BODY_TOTAL_OUTPUT_BYTES | output | recorded: R2rMethodBodyRefusal::OutputBudgetExhausted | usize | 8 * 1024 * 1024 | crates/disrobe-pass-dotnet/src/r2r.rs |
disrobe-pass-dotnet | MAX_R2R_RUNTIME_FUNCTIONS | other | error: Error::InvalidR2rRuntimeFunctions (DR-DOTNET-0042); invalid_method_def() | usize | 1_048_576 | crates/disrobe-pass-dotnet/src/r2r.rs |
disrobe-pass-dotnet | MAX_R2R_SECTIONS | other | error: Error::TooManyR2rSections (DR-DOTNET-0040); invalid_method_def() | u32 | 1024 | crates/disrobe-pass-dotnet/src/r2r.rs |
disrobe-pass-dotnet | MAX_R2R_USER_STRING_ENTRIES | count | error: invalid_method_def() | usize | 1_048_576 | crates/disrobe-pass-dotnet/src/r2r.rs |
disrobe-pass-dotnet | MAX_SUPPORTED_R2R_MAJOR_VERSION | other | error: Error::TooManyR2rSections (DR-DOTNET-0040); Error::UnsupportedR2rVersion (DR-DOTNET-0016) | u16 | 27 | crates/disrobe-pass-dotnet/src/r2r.rs |
disrobe-pass-dotnet | MAX_SIGNATURE_NODES | count | error: Error::SignatureTooManyNodes (DR-DOTNET-0028) | usize | 4096 | crates/disrobe-pass-dotnet/src/signature.rs |
disrobe-pass-dotnet | MAX_SIG_DEPTH | recursion | error: Error::SignatureTooDeep (DR-DOTNET-0026) | usize | 256 | crates/disrobe-pass-dotnet/src/signature.rs |
disrobe-pass-dotnet | MAX_CONDITION_DEPTH | recursion | silent: return in compound_condition | usize | 64 | crates/disrobe-pass-dotnet/src/structure_emit.rs |
disrobe-pass-dotnet | MAX_FORWARDING_HOPS | work | silent: for range in forward_target | usize | 16 | crates/disrobe-pass-dotnet/src/structure_emit.rs |
disrobe-pass-dotnet | MAX_STRUCTURE_DEPTH | recursion | silent: return in emit_region | usize | 256 | crates/disrobe-pass-dotnet/src/structure_emit.rs |
disrobe-pass-dotnet | MAX_TYPE_ROUNDS | work | silent: for range in plan_stack_slots | usize | 4 | crates/disrobe-pass-dotnet/src/structure_emit/stack_slots.rs |
disrobe-pass-dotnet | MAX_ARRAY_LITERAL_ELEMENTS | work | error: value | usize | 64 | crates/disrobe-pass-dotnet/src/structurize.rs |
disrobe-pass-dotnet | MAX_COERCION_DEPTH | recursion | silent: return in coerce_bounded | usize | 32 | crates/disrobe-pass-dotnet/src/structurize.rs |
disrobe-pass-dotnet | MAX_EXPR_DEPTH | recursion | silent: return in expression_depth; fallback value in bounded_expression | usize | 256 | crates/disrobe-pass-dotnet/src/structurize.rs |
disrobe-pass-dotnet | INFERENCE_DEPTH_LIMIT | recursion | silent: return in infer_bounded; return in may_convert | usize | 32 | crates/disrobe-pass-dotnet/src/structurize/operand_kind.rs |
disrobe-pass-dotnet | MAX_TABLE_ROWS | other | error: Error::TableRowCountTooLarge (DR-DOTNET-0029) | u64 | 1_000_000 | crates/disrobe-pass-dotnet/src/tables.rs |
disrobe-pass-go | FLAT_32_ADDRESS_LIMIT | other | unused: no use in the crate | u64 | 1 << 32 | crates/disrobe-pass-go/src/binary.rs |
disrobe-pass-go | MD_WORD_FTAB_CAP | other | unused: no use in the crate | usize | 18 | crates/disrobe-pass-go/src/binary.rs |
disrobe-pass-go | MD_WORD_FUNCNAMETAB_CAP | other | unused: no use in the crate | usize | 3 | crates/disrobe-pass-go/src/binary.rs |
disrobe-pass-go | MD_WORD_PCLNTABLE_CAP | other | unused: no use in the crate | usize | 15 | crates/disrobe-pass-go/src/binary.rs |
disrobe-pass-go | MAX_LISTED_FUNCS | other | silent: .take() in push_defer_section; .take() in render_symbol_report; no action in push_defer_section; 1 more | usize | 4_096 | crates/disrobe-pass-go/src/chain_detector.rs |
disrobe-pass-go | MAX_CALL_SCAN_BYTES | size | recorded: flag truncated | usize | 1 << 20 | crates/disrobe-pass-go/src/defers.rs |
disrobe-pass-go | MAX_LISTED_CALL_SITES | other | recorded: flag truncated | usize | 1 << 18 | crates/disrobe-pass-go/src/defers.rs |
disrobe-pass-go | MAX_LISTED_DEFER_FUNCS | other | recorded: flag truncated | usize | 1 << 16 | crates/disrobe-pass-go/src/defers.rs |
disrobe-pass-go | MAX_LISTED_RUNTIME_HOOKS | other | recorded: flag truncated | usize | 1 << 8 | crates/disrobe-pass-go/src/defers.rs |
disrobe-pass-go | MAX_PCDATA_ENTRIES | count | silent: return in read_func_defer_view | u32 | 64 | crates/disrobe-pass-go/src/defers.rs |
disrobe-pass-go | MAX_RUNTIME_CALL_TARGET_NAMES | other | recorded: flag truncated | usize | 1 << 12 | crates/disrobe-pass-go/src/defers.rs |
disrobe-pass-go | MAX_TOTAL_CALL_SCAN_BYTES | size | recorded: flag truncated | usize | 64 << 20 | crates/disrobe-pass-go/src/defers.rs |
disrobe-pass-go | MAX_DECOMPRESSED_LEN | size | silent: .take() in inflate_raw; return in decompress_zdebug; fallback value in inflate_raw | u64 | 1 << 30 | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DWARF_FUNCS | other | silent: break in collect_unit; break in walk_dwarf; skipped in push_function | usize | 1 << 18 | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DWARF_NAMES_PER_FUNC | other | silent: break in collect_unit; skipped in collect_unit | usize | 1 << 10 | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DWARF_NAMES_TOTAL | other | silent: break in collect_unit | usize | MAX_DWARF_FUNCS * MAX_DWARF_NAMES_PER_FUNC | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DWARF_TYPE_NAMES | other | silent: break in walk_dwarf; skipped in collect_unit | usize | 1 << 16 | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_ZDEBUG_INITIAL_CAPACITY | other | allocation: with_capacity in decompress_zdebug | usize | 8 * 1024 * 1024 | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DIRECTIVES | other | silent: break in collect_directives | usize | 4096 | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_DIRECTIVE_TAIL | other | silent: .min() clamp in collect_directives | usize | 256 | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_EMBED_DATA_LEN | size | silent: return in parse_record | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_EMBED_NAME_LEN | size | silent: return in is_clean_embed_path; return in parse_record | u64 | 4096 | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_MAPS | other | recorded: flag maps_capped | usize | 256 | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_MAP_ENTRIES | count | silent: return in read_map | u64 | 1 << 16 | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_TOTAL_EMBED_BYTES | size | silent: .min() clamp in read_member_bytes | usize | 512 * 1024 * 1024 | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | LITERAL_NO_INTERPRETER_LIMIT | work | unclassified: stored in literal_recovery_limit with no read found | &str | "garble -literals string encryption is recovered by emulating each \ literal's decrypt thunk, and the thunk interpreter covers x86-64 code only. this build's \ architecture has no interpreter, so its encrypted literals are reported as present but stay \ encrypted | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | LITERAL_RECOVERY_LIMIT | work | unclassified: stored in literal_recovery_limit with no read found | &str | "garble -literals string encryption is not a one-time pad: each literal's key is derived by \ an init-time decrypt thunk from material stored in the binary, so the plaintext is recovered \ statically by emulating that thunk. a scoped x86-64 interpreter runs the thunk the go compiler \ emitted for each literal, reading the encrypted data/key/positions/fullData arrays from rodata \ and the external-key arguments from the call site, including proxy-dispatcher field loads \ through .data. it covers the five obfuscators (simple, swap, shuffle, split, seed), with the \ decrypt as a separate closure or inlined into the caller, and the legacy single-byte \ XOR/ADD/SUB, repeating-key XOR, and standalone data/key blob cases. the interpreter follows the \ seed obfuscator's decFunc closure chain and the proxy dispatcher's indirect calls. the key \ | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_LITERAL_SCAN_BYTES | work | silent: skipped in recover_strings; slice in recover_strings | usize | 4 * 1024 * 1024 | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_PLAIN_STRINGS | other | silent: return in scan_ascii_strings; skipped in scan_ascii_strings | usize | MAX_RECOVERED_STRINGS | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_RECOVERED_STRINGS | other | silent: .take() in recover_strings; .truncate() in recover_strings; return in scan_ascii_strings; 2 more | usize | 4096 | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_REPEATING_KEY | other | silent: for range in scan_repeating_xor | usize | 8 | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | STRING_SCAN_BUDGET | work | silent: break in recover_strings | Duration | Duration::from_secs(8) | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_BLOB | other | silent: .min() clamp in grow_clean_pair | usize | 256 | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_BRIDGE_GAP | other | silent: break in extract_string_window | usize | 1 | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_PERTURBED_BYTES | size | silent: return in grow_clean_pair | usize | 12 | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_PLACEHOLDER_RATIO_PCT | other | silent: return in plausible_plaintext | usize | 12 | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_SIMPLE_RECOVERIES | other | silent: return in recover_simple_literals | usize | 1024 | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_SIMPLE_SCAN_BYTES | size | silent: return in recover_simple_literals | usize | 4 * 1024 * 1024 | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_STRING_JUNK_BYTES | size | silent: break in grow_clean_pair | usize | 8 | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | WORK_BUDGET | work | silent: return in recover_simple_literals | u64 | 48_000_000 | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | GLOBAL_STEP_BUDGET | work | silent: break in run_block; return in call_into_text | u64 | 6_000_000 | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_CALLERS_PER_THUNK | other | silent: skipped in build_caller_index | usize | 4 | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_EMU_MEM_BYTES | size | silent: continue in write_mem; for range in zero_fill | usize | 8 * 1024 * 1024 | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_INLINE_STRING | other | silent: return in span_is_printable; no action in snapshot_consumer_args | usize | 4096 | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_NESTED_CALL_DEPTH | recursion | silent: return in call_into_text | u32 | 96 | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_STEPS | work | silent: while condition in run_block | usize | 200_000 | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_THUNK_BYTES | size | silent: .min() clamp in slice_for | usize | 64 << 10 | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | THUNK_SCAN_BUDGET | work | silent: break in recover_thunk_literals | Duration | Duration::from_secs(8) | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_BACKSEARCH_CANDIDATES | other | silent: return in via_pclntab_backsearch | usize | 4096 | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_BUILDINFO_DEPS | other | silent: skipped in build_info_from_parts | usize | 1 << 16 | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_BUILDINFO_SETTINGS | other | silent: skipped in build_info_from_parts | usize | 1 << 12 | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_MODULENAME_LEN | size | delegated: .or()?; passed to .kv | usize | 4096 | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_PLAUSIBLE_SLICE_LEN | size | silent: return in validated_slice | u64 | 1 << 22 | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_PCLNTAB_CANDIDATES | other | silent: while condition in collect_needles_in_section | usize | 16 | crates/disrobe-pass-go/src/pclntab.rs |
disrobe-pass-go | MAX_PLAUSIBLE_SIG_FUNCS | other | silent: return in validate_header_structure | u64 | 16 * 1024 * 1024 | crates/disrobe-pass-go/src/pclntab.rs |
disrobe-pass-go | MAX_FILETAB_ENTRY_LEN | size | silent: return in is_source_file; fallback value in read_filetab_name; skipped in collect_filetab_blob | usize | 4096 | crates/disrobe-pass-go/src/symbols.rs |
disrobe-pass-go | MAX_FUNC_PREALLOC | other | allocation: .reserve() in func_table_go116; .reserve() in func_table_go118_plus; .reserve() in func_table_go12 | usize | 1 << 16 | crates/disrobe-pass-go/src/symbols.rs |
disrobe-pass-go | MAX_GO_NAME_BYTES | size | recorded: record_package() | usize | 4096 | crates/disrobe-pass-go/src/symbols.rs |
disrobe-pass-go | MAX_PLAUSIBLE_FUNCS | other | silent: return in bounded_func_count | u64 | 16 * 1024 * 1024 | crates/disrobe-pass-go/src/symbols.rs |
disrobe-pass-go | MAX_PLAUSIBLE_START_LINE | other | delegated: passed to .kv | i32 | 1 << 26 | crates/disrobe-pass-go/src/symbols.rs |
disrobe-pass-go | DISAMBIG_CANDIDATE_BUDGET | work | silent: break in disambiguate_shape_args | usize | 1 << 22 | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | ITABLINKS_WALK_CAP | other | recorded: flag truncated | usize | 1 << 14 | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_FIELDS_PER_STRUCT | other | silent: return in read_struct_fields | u64 | 1 << 12 | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_IMETHODS_PER_INTERFACE | other | silent: return in read_interface_methods | u64 | 1 << 12 | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_METHODS_PER_TYPE | other | silent: return in read_type_methods | u16 | 1 << 12 | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_STRUCT_FIELD_TAG_LEN | size | silent: return in decode_name_component | u64 | 1 << 12 | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_TYPE_NAME_LEN | size | recorded: flag duplicate_names_dropped | usize | 1024 | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | TYPELINKS_WALK_CAP | other | recorded: flag truncated | usize | 1 << 14 | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-js-deob | MAX_SIBLING_MAP_BYTES | size | error: SiblingMapRefusal::TooLarge | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-js-deob/src/bundle/sourcemap.rs |
disrobe-pass-js-deob | MAX_MAP_BYTES | size | error: Error::SyntaxLimit (DR-JSDEOB-0005) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-js-deob/src/bundle/sourcemap_recover.rs |
disrobe-pass-js-deob | MAX_NAMES_PER_SOURCE | other | silent: skipped in collect_coverage_by_source | usize | 4096 | crates/disrobe-pass-js-deob/src/bundle/sourcemap_recover.rs |
disrobe-pass-js-deob | MAX_RENAMED_BINDINGS | other | silent: return in renamed_bindings | usize | 100_000 | crates/disrobe-pass-js-deob/src/bundle/sourcemap_recover.rs |
disrobe-pass-js-deob | MAX_SECTIONS | other | error: Error::SyntaxLimit (DR-JSDEOB-0005) | usize | 1 << 20 | crates/disrobe-pass-js-deob/src/bundle/sourcemap_recover.rs |
disrobe-pass-js-deob | MAX_SOURCES | other | error: CoreError::PassFailure (DR-CORE-0003); Error::OxcParse (DR-JSDEOB-0003); Error::SyntaxLimit (DR-JSDEOB-0005); 20 more | usize | 1 << 22 | crates/disrobe-pass-js-deob/src/bundle/sourcemap_recover.rs |
disrobe-pass-js-deob | MAX_RECURSIVE_DEPTH | recursion | silent: return in recursive_descend | usize | 6 | crates/disrobe-pass-js-deob/src/esoteric/atob_indirection.rs |
disrobe-pass-js-deob | MAX_OPERATOR_CHAIN | other | error: CoreError::PassFailure (DR-CORE-0003) | usize | 4096 | crates/disrobe-pass-js-deob/src/esoteric/jsfuck.rs |
disrobe-pass-js-deob | MAX_PEEL_LAYERS | other | silent: while condition in unpack | usize | 32 | crates/disrobe-pass-js-deob/src/esoteric/packer.rs |
disrobe-pass-js-deob | LOOP_ITERATION_LIMIT | work | delegated: passed to .set_loop_iteration_limit | u64 | 1_000_000 | crates/disrobe-pass-js-deob/src/esoteric/sandbox.rs |
disrobe-pass-js-deob | MAX_CAPTURE_SCRIPT_BYTES | size | silent: return in eval_to_source | usize | 8 * 1024 * 1024 | crates/disrobe-pass-js-deob/src/esoteric/sandbox.rs |
disrobe-pass-js-deob | MAX_SCRIPT_BYTES | size | error: ProbeRefusal::InputTooLarge | usize | 256 * 1024 | crates/disrobe-pass-js-deob/src/esoteric/sandbox.rs |
disrobe-pass-js-deob | RECURSION_LIMIT | recursion | delegated: passed to .set_recursion_limit | usize | 1_024 | crates/disrobe-pass-js-deob/src/esoteric/sandbox.rs |
disrobe-pass-js-deob | STACK_SIZE_LIMIT | size | delegated: passed to .set_stack_size_limit | usize | 16 * 1024 | crates/disrobe-pass-js-deob/src/esoteric/sandbox.rs |
disrobe-pass-js-deob | MAX_EXACT_MAGNITUDE | other | silent: return in arith_combine; return in int_pattern; return in lower_arith | u128 | 1u128 << 53 | crates/disrobe-pass-js-deob/src/jsconfuser/algebraic_opaque.rs |
disrobe-pass-js-deob | MAX_FIXPOINT_ROUNDS | work | silent: for range in fold_algebraic_opaque | usize | 32 | crates/disrobe-pass-js-deob/src/jsconfuser/algebraic_opaque.rs |
disrobe-pass-js-deob | MAX_LOWER_DEPTH | recursion | silent: return in lower_arith; return in lower_bits; return in lower_predicate; 1 more | usize | 128 | crates/disrobe-pass-js-deob/src/jsconfuser/algebraic_opaque.rs |
disrobe-pass-js-deob | MAX_DENSE_ARRAY_ELEMENTS | other | silent: return in assign_to | usize | 1 << 20 | crates/disrobe-pass-js-deob/src/jsconfuser/cff_vm/interp.rs |
disrobe-pass-js-deob | MAX_LZSTRING_DICT_ENTRIES | count | silent: return in lzstring_decompress_values | usize | 1 << 20 | crates/disrobe-pass-js-deob/src/jsconfuser/string_compression.rs |
disrobe-pass-js-deob | MAX_LZSTRING_INPUT_UNITS | other | silent: return in lzstring_decompress_base64; return in lzstring_decompress_uri; return in lzstring_decompress_utf16_raw; 3 more | usize | 1 << 20 | crates/disrobe-pass-js-deob/src/jsconfuser/string_compression.rs |
disrobe-pass-js-deob | MAX_LZSTRING_OUTPUT_UNITS | output | silent: return in lzstring_decompress_values | usize | 4 << 20 | crates/disrobe-pass-js-deob/src/jsconfuser/string_compression.rs |
disrobe-pass-js-deob | LOOP_LIMIT | other | delegated: passed to .set_loop_iteration_limit | u64 | 2_000_000 | crates/disrobe-pass-js-deob/src/jscrambler/strict_dispatch_tests.rs |
disrobe-pass-js-deob | RECURSION_LIMIT | recursion | delegated: passed to .set_recursion_limit | usize | 1_500 | crates/disrobe-pass-js-deob/src/jscrambler/strict_dispatch_tests.rs |
disrobe-pass-js-deob | STACK_LIMIT | other | delegated: passed to .set_stack_size_limit | usize | 50_000 | crates/disrobe-pass-js-deob/src/jscrambler/strict_dispatch_tests.rs |
disrobe-pass-js-deob | MAX_CALL_BYTES | size | silent: return in try_fold_at | usize | 64 * 1024 | crates/disrobe-pass-js-deob/src/jsobfu/fold_chars.rs |
disrobe-pass-js-deob | MAX_FOLD_PASSES | other | silent: for range in fold_char_constructors | usize | 8 | crates/disrobe-pass-js-deob/src/jsobfu/fold_chars.rs |
disrobe-pass-js-deob | MAX_IIFE_BYTES | size | silent: return in try_fold_iife | usize | 8 * 1024 | crates/disrobe-pass-js-deob/src/jsobfu/fold_chars.rs |
disrobe-pass-js-deob | MAX_RESULT_CHARS | other | silent: return in is_safe_literal_body | usize | 4096 | crates/disrobe-pass-js-deob/src/jsobfu/fold_chars.rs |
disrobe-pass-js-deob | MAX_RECOVER_PASSES | other | silent: for range in try_recover | usize | 6 | crates/disrobe-pass-js-deob/src/jsobfu/mod.rs |
disrobe-pass-js-deob | MAX_PRIOR_CONFIDENCE | other | error: Error::AuthorizationRequired (DR-JSDEOB-0010); Error::NoFamilyMatched (DR-JSDEOB-0001) | u8 | Confidence::LOW.0 | crates/disrobe-pass-js-deob/src/mangled_names/corpus_source.rs |
disrobe-pass-js-deob | MAX_PASS_CEILING | other | recorded: flag hit_pass_ceiling | u32 | 32 | crates/disrobe-pass-js-deob/src/obfuscator_io/dispatch.rs |
disrobe-pass-js-deob | MAX_ARRAY_BUFFER_BYTES | size | unclassified: stored in max_buffer_size() with no read found | u64 | 64 * 1_024 * 1_024 | crates/disrobe-pass-js-deob/src/sandbox_guard.rs |
disrobe-pass-js-deob | MAX_EXPRESSION_DEPTH | recursion | error: ProbeRefusal::UnsafeNesting | usize | 28_000 | crates/disrobe-pass-js-deob/src/sandbox_guard.rs |
disrobe-pass-js-deob | MAX_OPERATOR_CHAIN | other | error: Error::SyntaxLimit (DR-JSDEOB-0005); ProbeRefusal::UnsafeNesting | usize | 600 | crates/disrobe-pass-js-deob/src/sandbox_guard.rs |
disrobe-pass-js-deob | MAX_SYNTACTIC_NESTING_DEPTH | recursion | error: Error::SyntaxLimit (DR-JSDEOB-0005); ProbeRefusal::UnsafeNesting | usize | 600 | crates/disrobe-pass-js-deob/src/sandbox_guard.rs |
disrobe-pass-js-deob | MAX_TEMPLATE_SCAN_DEPTH | recursion | error: ProbeRefusal::UnsafeNesting | usize | 256 | crates/disrobe-pass-js-deob/src/string_array/mod.rs |
disrobe-pass-js-deob | MAX_ROTATIONS | other | silent: for range in simulate | u32 | 4096 | crates/disrobe-pass-js-deob/src/string_array/rotate.rs |
disrobe-pass-js-deob | DEFAULT_LOOP_ITERATION_LIMIT | work | delegated: passed to .set_loop_iteration_limit | u64 | 100_000 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | DEFAULT_RECURSION_LIMIT | recursion | delegated: passed to .set_recursion_limit | usize | 256 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | DEFAULT_STACK_SIZE_LIMIT | size | delegated: passed to .set_stack_size_limit | usize | 8 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_AGGREGATE_EXPRESSION_BYTES | size | error: ProbeRefusal::InputTooLarge | usize | 4 * 1024 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_BATCH_JSON_BYTES | size | error: ProbeRefusal::BoundExceeded | usize | 8 * 1024 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_BATCH_OUTPUT_UNITS | output | silent: while condition in usize_decimal_len | usize | 1024 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_CONCURRENT_PROBES | other | silent: while condition in acquire_probe_permit_from | usize | 1 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_DECODED_TOTAL_BYTES | size | error: ProbeRefusal::BoundExceeded | usize | 4 * 1024 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_DECODED_VALUE_BYTES | size | error: ProbeRefusal::BoundExceeded | usize | 64 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_ENVIRONMENT_CALLS | other | error: ProbeRefusal::BoundExceeded | u64 | 10_000_000 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_EXPRESSION_BYTES | size | error: ProbeRefusal::InputTooLarge | usize | 64 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_GENERATED_SCRIPT_BYTES | size | error: ProbeRefusal::InputTooLarge | usize | 4 * 1024 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_PROBE_EXPRESSIONS | other | error: ProbeRefusal::BoundExceeded | usize | 65_536 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_SCRIPT_BYTES | size | error: ProbeRefusal::InputTooLarge | usize | 256 * 1024 | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_MANGLED_SOURCE_BYTES | size | error: Error::SyntaxLimit (DR-JSDEOB-0005) | usize | 1 << 20 | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_MEMBER_CALL_LITERALS | work | silent: .take() in restore_terser_mangled_bounded; skipped in restore_terser_mangled_bounded | usize | 8 | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_NEARBY_STRINGS | other | silent: .take() in static_member_call_literals_on_reference; return in collect_string_literals | usize | 4 | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_STRING_SEARCH_DEPTH | recursion | silent: return in collect_string_literals | usize | 8 | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_SUFFIX_ATTEMPTS | other | silent: for range in allocate | u32 | 512 | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_PASSES | other | silent: for range in fold_binary | usize | 16 | crates/disrobe-pass-js-deob/src/unminify/arithmetic.rs |
disrobe-pass-js-deob | MAX_MBA_LOWER_DEPTH | recursion | silent: return in lower_expression_at; return in render_expression_at | usize | 256 | crates/disrobe-pass-js-deob/src/unminify/ast/mba_simplify.rs |
disrobe-pass-js-deob | MAX_PREDICATE_VARS | other | silent: return in classify_predicate | usize | 3 | crates/disrobe-pass-js-deob/src/unminify/ast/mba_simplify.rs |
disrobe-pass-js-deob | MAX_DEPENDENCY_SETTER_PAIRS | other | silent: return in recover; return in registration | usize | 4_096 | crates/disrobe-pass-js-deob/src/unminify/ast/system_register_param.rs |
disrobe-pass-js-deob | MAX_GENERATED_EDITS | other | recorded: RegistrationEditResult::Exhausted | usize | 65_536 | crates/disrobe-pass-js-deob/src/unminify/ast/system_register_param.rs |
disrobe-pass-js-deob | MAX_REGISTRATIONS | other | silent: return in recover | usize | 4_096 | crates/disrobe-pass-js-deob/src/unminify/ast/system_register_param.rs |
disrobe-pass-js-deob | MAX_CANDIDATES | other | recorded: Refusal::TooLarge | usize | 4096 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async.rs |
disrobe-pass-js-deob | MAX_DEPTH | recursion | error: UnsupportedShape | usize | 256 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/canon.rs |
disrobe-pass-js-deob | MAX_SIMPLIFY_ROUNDS | work | silent: for range in simplify | usize | 64 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/emit.rs |
disrobe-pass-js-deob | MAX_BLOCKS | other | error: Refusal::TooLarge | usize | 4096 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/machine.rs |
disrobe-pass-js-deob | MAX_REGIONS | other | error: Refusal::RegionShape | usize | 512 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/machine.rs |
disrobe-pass-js-deob | MAX_REGION_DEPTH | recursion | error: Refusal::TooDeep | usize | 64 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/machine.rs |
disrobe-pass-js-deob | MAX_WALK_DEPTH | recursion | error: Refusal::TooDeep | usize | 512 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/order.rs |
disrobe-pass-js-deob | MAX_RENDER_DEPTH | recursion | error: Refusal::TooDeep | usize | 256 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/render.rs |
disrobe-pass-js-deob | MAX_TREE_DEPTH | recursion | error: Refusal::TooDeep | usize | 128 | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/structure.rs |
disrobe-pass-js-deob | MAX_FIX_POINT_PASSES | other | silent: for range in unminify | usize | 8 | crates/disrobe-pass-js-deob/src/unminify/mod.rs |
disrobe-pass-js-deob | MAX_CHAIN | other | silent: break in collect_chain | usize | 1024 | crates/disrobe-pass-js-deob/src/unminify/string_split.rs |
disrobe-pass-js-deob | MAX_PASSES | other | silent: for range in fold_string_concat | usize | 32 | crates/disrobe-pass-js-deob/src/unminify/string_split.rs |
disrobe-pass-js-deob | MAX_OPERANDS | other | silent: while condition in new | usize | 5usize | crates/disrobe-pass-js-deob/src/v8/bytecode_opcodes.rs |
disrobe-pass-js-deob | MAX_DESERIALIZE_OBJECTS | other | error: Error::OxcParse (DR-JSDEOB-0003) | usize | 1usize << 20usize | crates/disrobe-pass-js-deob/src/v8/code_serializer.rs |
disrobe-pass-js-deob | MAX_FRAME_SIZE | size | silent: return in recover_bytecode_array_with_layout | i32 | 1i32 << 24i32 | crates/disrobe-pass-js-deob/src/v8/code_serializer.rs |
disrobe-pass-js-deob | MAX_RECURSION_DEPTH | recursion | error: Error::OxcParse (DR-JSDEOB-0003) | usize | 256usize | crates/disrobe-pass-js-deob/src/v8/code_serializer.rs |
disrobe-pass-js-deob | MAX_STRING_BODY | other | silent: return in decode_string_from_run | usize | 1usize << 20usize | crates/disrobe-pass-js-deob/src/v8/code_serializer.rs |
disrobe-pass-js-deob | MAX_RENDERED_ARGUMENTS | output | delegated: passed to push_format | i64 | 65_534 | crates/disrobe-pass-js-deob/src/v8/flat_bytecode_lift.rs |
disrobe-pass-js-deob | REGISTER_RANGE_SCAN_LIMIT | other | silent: no action in prepare_accumulator | i64 | 256 | crates/disrobe-pass-js-deob/src/v8/flat_bytecode_lift.rs |
disrobe-pass-js-deob | MAX_STRING_LEN | size | silent: continue in extract_framed_strings | u32 | 1u32 << 24u32 | crates/disrobe-pass-js-deob/src/v8/serialized_code.rs |
disrobe-pass-jvm | MAX_JADX_INPUT_FILE_NAME_BYTES | size | error: JadxRefusal::InvalidInputFileName | usize | 255 | crates/disrobe-pass-jvm/src/android_backend.rs |
disrobe-pass-jvm | MAX_JADX_INPUT_FILE_NAME_UTF16_UNITS | other | error: JadxRefusal::InvalidInputFileName | usize | 255 | crates/disrobe-pass-jvm/src/android_backend.rs |
disrobe-pass-jvm | MAX_JADX_OUTPUT_TREE_BYTES | output | error: JadxRefusal::OutputLimit | u64 | 128 * 1024 * 1024 | crates/disrobe-pass-jvm/src/android_backend.rs |
disrobe-pass-jvm | MAX_JADX_OUTPUT_TREE_ENTRIES | output | error: JadxRefusal::OutputLimit | usize | 262_144 | crates/disrobe-pass-jvm/src/android_backend.rs |
disrobe-pass-jvm | MAX_JADX_SOURCE_BYTES | size | error: JadxRefusal::OutputLimit | u64 | 16 * 1024 * 1024 | crates/disrobe-pass-jvm/src/android_backend.rs |
disrobe-pass-jvm | MAX_JADX_SOURCE_FILES | count | error: JadxRefusal::OutputLimit | usize | 65_536 | crates/disrobe-pass-jvm/src/android_backend.rs |
disrobe-pass-jvm | MAX_JADX_TOTAL_SOURCE_BYTES | size | error: JadxRefusal::OutputLimit | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-jvm/src/android_backend.rs |
disrobe-pass-jvm | V1_SIGNATURE_ENTRY_BYTES_CAP | size | error: Error::Zip (DR-JVM-0011) | u64 | 16 * 1024 * 1024 | crates/disrobe-pass-jvm/src/apk_sig.rs |
disrobe-pass-jvm | V1_SIGNATURE_FILE_COUNT_CAP | count | error: Error::Zip (DR-JVM-0011) | usize | 256 | crates/disrobe-pass-jvm/src/apk_sig.rs |
disrobe-pass-jvm | V1_SIGNATURE_PREALLOC_BYTES_CAP | size | allocation: with_capacity in read_v1_signature_file | u64 | 1024 * 1024 | crates/disrobe-pass-jvm/src/apk_sig.rs |
disrobe-pass-jvm | MAX_ANNOTATION_DEPTH | recursion | error: AnnotationError() | usize | 64 | crates/disrobe-pass-jvm/src/attributes.rs |
disrobe-pass-jvm | MAX_ANNOTATION_INPUT_BYTES | size | error: .to_string(); AnnotationError(); Error::Dex2JarLimit (DR-JVM-0094); 11 more | usize | 4 * 1024 * 1024 | crates/disrobe-pass-jvm/src/attributes.rs |
disrobe-pass-jvm | MAX_ANNOTATION_NODES | count | error: AnnotationError(); SWITCH; SignatureSyntaxError; 2 more | usize | 65_535 | crates/disrobe-pass-jvm/src/attributes.rs |
disrobe-pass-jvm | MAX_ANNOTATION_RENDER_BYTES | output | error: Error::BadBytecode (DR-JVM-0025) | usize | 4 * 1024 * 1024 | crates/disrobe-pass-jvm/src/attributes.rs |
disrobe-pass-jvm | MAX_ANNOTATION_TEXT_BYTES | size | error: AnnotationError() | usize | 4 * 1024 * 1024 | crates/disrobe-pass-jvm/src/attributes.rs |
disrobe-pass-jvm | MAX_AXML_ATTRIBUTES | other | error: Error::BadAxml (DR-JVM-0013) | usize | 65_536 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_AXML_ATTRIBUTES_PER_ELEMENT | other | error: Error::BadAxml (DR-JVM-0013) | usize | 4_096 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_AXML_ELEMENT_DEPTH | recursion | error: Error::BadAxml (DR-JVM-0013) | usize | 128 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_AXML_EVENTS | other | error: Error::BadAxml (DR-JVM-0013) | usize | 65_536 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_AXML_OWNED_TEXT_BYTES | size | error: Error::BadAxml (DR-JVM-0013) | usize | 16 * 1_048_576 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_AXML_RESOURCE_IDS | other | error: Error::BadAxml (DR-JVM-0013) | usize | 65_536 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_AXML_STRING_BYTES | size | error: Error::BadAxml (DR-JVM-0013) | usize | 1_048_576 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_AXML_STRING_COUNT | count | error: Error::BadAxml (DR-JVM-0013) | usize | 65_536 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_AXML_TEXT_BYTES | size | error: Error::BadAxml (DR-JVM-0013) | usize | 16 * 1_048_576 | crates/disrobe-pass-jvm/src/axml.rs |
disrobe-pass-jvm | MAX_BACKEND_CAPTURE | other | delegated: subprocess::run_captured()? | usize | 4 * 1024 * 1024 | crates/disrobe-pass-jvm/src/backends.rs |
disrobe-pass-jvm | JAVA_RANDOM_REJECTION_CAP | other | silent: for range in next_bounded_int | usize | 128 | crates/disrobe-pass-jvm/src/bytecode_eval.rs |
disrobe-pass-jvm | MAX_CALL_DEPTH | recursion | error: EvalError::CallDepthExceeded | u32 | 24 | crates/disrobe-pass-jvm/src/bytecode_eval.rs |
disrobe-pass-jvm | MAX_HEAP_OBJECTS | other | error: EvalError::HeapExhausted | usize | 16_384 | crates/disrobe-pass-jvm/src/bytecode_eval.rs |
disrobe-pass-jvm | MAX_STACK_DEPTH | recursion | error: EvalError::StackOverflow | usize | 8_192 | crates/disrobe-pass-jvm/src/bytecode_eval.rs |
disrobe-pass-jvm | MAX_STRING_LEN | size | error: EvalError::BadShape | usize | 65_536 | crates/disrobe-pass-jvm/src/bytecode_eval.rs |
disrobe-pass-jvm | STEP_LIMIT | work | error: EvalError::StepLimitExceeded | u64 | 6_000_000 | crates/disrobe-pass-jvm/src/bytecode_eval.rs |
disrobe-pass-jvm | MAX_MAJOR | other | error: Error::UnknownConstantTag (DR-JVM-0005); Error::UnsupportedClassVersion (DR-JVM-0004) | u16 | 69 | crates/disrobe-pass-jvm/src/classfile.rs |
disrobe-pass-jvm | MAX_DATAFLOW_VISITS_PER_INSTRUCTION | other | silent: return in local_constants_at_block_entries | usize | 16 | crates/disrobe-pass-jvm/src/const_fold.rs |
disrobe-pass-jvm | MAX_MASK_SEARCH_PAIRS | other | silent: return in recover_dispatch_mask | usize | 4096 | crates/disrobe-pass-jvm/src/dalvik_blackobf.rs |
disrobe-pass-jvm | MAX_DALVIK_BLOCKS | other | error: StructureError::TooManyBlocks | usize | 16_384 | crates/disrobe-pass-jvm/src/dalvik_cfg.rs |
disrobe-pass-jvm | MAX_FLOW_WORDS | other | silent: return in analyze | usize | 1 << 22 | crates/disrobe-pass-jvm/src/dalvik_cfg.rs |
disrobe-pass-jvm | MAX_DIAGNOSTICS | other | silent: no action in analyze | usize | 256 | crates/disrobe-pass-jvm/src/dalvik_core_library.rs |
disrobe-pass-jvm | MAX_MARKER_BYTES | size | silent: return in parse_marker | usize | 4096 | crates/disrobe-pass-jvm/src/dalvik_core_library.rs |
disrobe-pass-jvm | MAX_MARKER_IDENTIFIERS | other | recorded: flag marker_conflicts | usize | 16 | crates/disrobe-pass-jvm/src/dalvik_core_library.rs |
disrobe-pass-jvm | MAX_NESTED_CLASS_DEPTH | recursion | silent: for range in lexically_encloses; for range in translated_owner_path; no action in compose_rendered_class | usize | 64 | crates/disrobe-pass-jvm/src/dalvik_decompile.rs |
disrobe-pass-jvm | MAX_RENDER_BYTES | output | silent: return in render_region | usize | 4 * 1024 * 1024 | crates/disrobe-pass-jvm/src/dalvik_decompile.rs |
disrobe-pass-jvm | MAX_LAYERS | other | error: CROSSING_TRIES | usize | 512 | crates/disrobe-pass-jvm/src/dalvik_decompile/nested_blocks.rs |
disrobe-pass-jvm | MAX_NEST_DEPTH | recursion | error: TOO_DEEP | usize | 384 | crates/disrobe-pass-jvm/src/dalvik_decompile/nested_blocks.rs |
disrobe-pass-jvm | MAX_TRAMPOLINE_STEPS | work | silent: for range in fixup_path; for range in trampoline_end | usize | 16 | crates/disrobe-pass-jvm/src/dalvik_decompile/nested_blocks.rs |
disrobe-pass-jvm | MAX_REGION_DEPTH | recursion | error: TOO_LARGE | usize | 512 | crates/disrobe-pass-jvm/src/dalvik_decompile/region_check.rs |
disrobe-pass-jvm | MAX_REGION_NODES | count | error: TOO_LARGE | usize | 100_000 | crates/disrobe-pass-jvm/src/dalvik_decompile/region_check.rs |
disrobe-pass-jvm | MAX_SWITCH_VALUES | other | error: SWITCH | usize | 65_536 | crates/disrobe-pass-jvm/src/dalvik_decompile/region_check.rs |
disrobe-pass-jvm | MAX_TRAMPOLINE_STEPS | work | silent: for range in canonical | usize | 64 | crates/disrobe-pass-jvm/src/dalvik_decompile/region_check.rs |
disrobe-pass-jvm | MAX_DESUGAR_SCAN_INSNS | other | silent: return in exclusively_constructed; return in helper_references; return in scan_references | usize | 1_048_576 | crates/disrobe-pass-jvm/src/dalvik_desugar.rs |
disrobe-pass-jvm | MAX_INLINE_BODY_INSNS | other | silent: return in inlinable_helper_body | usize | 64 | crates/disrobe-pass-jvm/src/dalvik_desugar.rs |
disrobe-pass-jvm | MAX_REFERENCE_BODY_INSNS | other | silent: return in match_reference_body | usize | 64 | crates/disrobe-pass-jvm/src/dalvik_desugar.rs |
disrobe-pass-jvm | MAX_RESOLVE_ROUNDS | work | silent: break in unflatten_with_graph | usize | 65_536 | crates/disrobe-pass-jvm/src/dalvik_dexguard.rs |
disrobe-pass-jvm | MAX_ARRAY_LEN | size | error: SkipReason::OutputTooLarge; SkipReason::Unsound | usize | 1 << 20 | crates/disrobe-pass-jvm/src/dalvik_interp.rs |
disrobe-pass-jvm | MAX_BACKWARD_BRANCHES | other | error: SkipReason::BudgetExhausted | u32 | 500_000 | crates/disrobe-pass-jvm/src/dalvik_interp.rs |
disrobe-pass-jvm | MAX_HEAP_BYTES | size | error: SkipReason::OutputTooLarge | usize | 8 << 20 | crates/disrobe-pass-jvm/src/dalvik_interp.rs |
disrobe-pass-jvm | MAX_HEAP_OBJECTS | other | error: SkipReason::OutputTooLarge | usize | 65_536 | crates/disrobe-pass-jvm/src/dalvik_interp.rs |
disrobe-pass-jvm | MAX_RECURSION_DEPTH | recursion | error: SkipReason::BudgetExhausted | u32 | 12 | crates/disrobe-pass-jvm/src/dalvik_interp.rs |
disrobe-pass-jvm | STEP_BUDGET | work | error: SkipReason::BudgetExhausted | u64 | 2_000_000 | crates/disrobe-pass-jvm/src/dalvik_interp.rs |
disrobe-pass-jvm | TOTAL_STEP_BUDGET | work | error: SkipReason::BudgetExhausted | u64 | 16 * STEP_BUDGET | crates/disrobe-pass-jvm/src/dalvik_interp.rs |
disrobe-pass-jvm | MAX_ARRAY_DATA_ELEMENTS | other | silent: return in array_data_elements | usize | 16_384 | crates/disrobe-pass-jvm/src/dalvik_lift.rs |
disrobe-pass-jvm | MAX_INLINE_DEPTH | recursion | silent: return in inline_helper_body | u16 | 2 | crates/disrobe-pass-jvm/src/dalvik_lift.rs |
disrobe-pass-jvm | MAX_HANDLER_BLOCKS | other | silent: break in monitor_handler | usize | 4 | crates/disrobe-pass-jvm/src/dalvik_monitor.rs |
disrobe-pass-jvm | MAX_MONITOR_BODY_BLOCKS | other | silent: continue in releases_before_leaving; return in monitor_region | usize | 4_096 | crates/disrobe-pass-jvm/src/dalvik_monitor.rs |
disrobe-pass-jvm | MAX_TRAMPOLINE_HOPS | work | silent: for range in past_trampolines | usize | 4 | crates/disrobe-pass-jvm/src/dalvik_monitor.rs |
disrobe-pass-jvm | MAX_RECOVERABLE_PAYLOAD_LEN | size | recorded: note; record_construction(); record_reference_store() | usize | 64 * 1024 * 1024 | crates/disrobe-pass-jvm/src/dalvik_pack_stub_loader.rs |
disrobe-pass-jvm | MAX_HELPER_ARITY | other | recorded: flag applied | usize | 6 | crates/disrobe-pass-jvm/src/dalvik_r8_inline/detect.rs |
disrobe-pass-jvm | JAVA_RANDOM_REJECTION_CAP | other | silent: for range in next_bounded_int | usize | 128 | crates/disrobe-pass-jvm/src/dalvik_strdec.rs |
disrobe-pass-jvm | MAX_ARRAY_LEN | size | error: EvalError::BadShape | usize | 1 << 20 | crates/disrobe-pass-jvm/src/dalvik_strdec.rs |
disrobe-pass-jvm | MAX_HEAP_OBJECTS | other | error: EvalError::HeapExhausted | usize | 65_536 | crates/disrobe-pass-jvm/src/dalvik_strdec.rs |
disrobe-pass-jvm | STEP_LIMIT | work | error: EvalError::StepLimitExceeded | u64 | 2_000_000 | crates/disrobe-pass-jvm/src/dalvik_strdec.rs |
disrobe-pass-jvm | MAX_CANDIDATE_PARAMS | other | silent: return in signature_weight | usize | 2 | crates/disrobe-pass-jvm/src/dalvik_strdec_generic.rs |
disrobe-pass-jvm | MAX_BUCKET_TESTS | other | silent: for range in bucket_chain | usize | 256 | crates/disrobe-pass-jvm/src/dalvik_string_switch.rs |
disrobe-pass-jvm | MAX_TRAMPOLINE_HOPS | work | silent: for range in absorb_trampolines; for range in skip_trampolines | usize | 4 | crates/disrobe-pass-jvm/src/dalvik_string_switch.rs |
disrobe-pass-jvm | MAX_BRANCH_INSNS | other | recorded: record_bail_kind() | usize | 2048 | crates/disrobe-pass-jvm/src/dalvik_to_jvm.rs |
disrobe-pass-jvm | MAX_CODE_BYTES | size | recorded: record_bail_kind() | usize | 60_000 | crates/disrobe-pass-jvm/src/dalvik_to_jvm.rs |
disrobe-pass-jvm | MAX_METHOD_INSNS | other | recorded: record_bail_kind() | usize | 8192 | crates/disrobe-pass-jvm/src/dalvik_to_jvm.rs |
disrobe-pass-jvm | MAX_TRACKED_NARROW_CONSTANT_REGS | other | silent: return in must_narrow_constant_states | usize | 128 | crates/disrobe-pass-jvm/src/dalvik_to_jvm.rs |
disrobe-pass-jvm | MAX_REGION_BLOCKS | other | silent: for range in nearest_common_dominator; return in merge_ranges | usize | 4_096 | crates/disrobe-pass-jvm/src/dalvik_try_regions.rs |
disrobe-pass-jvm | MAX_ARRAY_JOIN_DEPTH | recursion | silent: return in join_ref | usize | 16 | crates/disrobe-pass-jvm/src/dalvik_typestate.rs |
disrobe-pass-jvm | MAX_FIXPOINT_ITERS | work | delegated: passed to debug::dbg_kv | usize | 50_000 | crates/disrobe-pass-jvm/src/dalvik_typestate.rs |
disrobe-pass-jvm | MAX_SUPERCLASS_DEPTH | recursion | silent: while condition in root_first_chain | usize | 256 | crates/disrobe-pass-jvm/src/dalvik_typestate.rs |
disrobe-pass-jvm | ARM_CONDITION_BLOCK_CAP | other | silent: return in arm_tree_value; return in arm_value; return in join_value_entry; 1 more | usize | 32 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | INT_USE_SCAN_LIMIT | other | silent: .take() in loaded_int_has_int_use | usize | 32 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_BOOL_EXPR_BYTES | size | silent: return in eval_bool_node_memo | usize | 64 * 1024 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_DUP_EXPR_NODES | count | error: Error::ArscTruncated (DR-JVM-0032); Error::BadBytecode (DR-JVM-0025); Error::BadKotlinMetadata (DR-JVM-0020); 9 more | usize | 1024 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_GENERIC_REPLACEMENTS | other | silent: return in replacement_nodes | usize | 4_096 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_GENERIC_REPLACEMENT_BYTES | size | silent: return in replacement_nodes | usize | 262_144 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_RENDER_BYTES | output | silent: return in append_inner_output; return in append_java_replacement; return in emit_nested_class_stubs; 2 more | usize | 4 * 1024 * 1024 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | RECORD_ARITY_PROBE_CAP | other | silent: while condition in infer_record_arity | usize | 64 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | REUSED_LOCAL_SPLIT_WORK_LIMIT | work | silent: return in claim_reused_local_split_work | usize | 1_000_000 | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_BLOCKS | other | error: StructureError::TooManyBlocks | usize | 16_384 | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_CONDITION_CHAIN | other | silent: return in latch_condition_chain; return in short_circuit_merge; return in structure_condition_chain; 1 more | usize | 64 | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_JOIN_CHAIN | other | silent: break in continuation_joins; for range in goto_chain_end; for range in handler_join_after; 1 more | usize | 8 | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_STRUCTURE_DEPTH | recursion | recorded: flag had_irreducible | usize | 256 | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_STRUCTURE_WORK | work | recorded: flag had_irreducible | usize | 200_000 | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_TAIL_BLOCKS | other | silent: return in duplicable_tail | usize | 8 | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_TAIL_INSTRUCTIONS | other | silent: return in duplicable_tail | usize | 64 | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_ARRAY_DIMENSIONS | other | silent: return in parse_one; return in type_descriptor_end | u8 | 255 | crates/disrobe-pass-jvm/src/descriptor.rs |
disrobe-pass-jvm | MAX_SYSTEM_ANNOTATION_DEPTH | recursion | error: SignatureSyntaxError; system_metadata_error() | usize | 64 | crates/disrobe-pass-jvm/src/dex.rs |
disrobe-pass-jvm | MAX_SYSTEM_ANNOTATION_VALUES | other | error: Error::BadBytecode (DR-JVM-0025) | usize | 1_048_576 | crates/disrobe-pass-jvm/src/dex.rs |
disrobe-pass-jvm | MAX_SYSTEM_METADATA_BYTES | size | error: Error::BadBytecode (DR-JVM-0025) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-jvm/src/dex.rs |
disrobe-pass-jvm | MAX_SYSTEM_METADATA_DIAGNOSTICS | other | recorded: flag suppressed_diagnostics | usize | 256 | crates/disrobe-pass-jvm/src/dex.rs |
disrobe-pass-jvm | MAX_SYSTEM_METADATA_NORMALIZATION_ROUNDS | work | silent: for range in normalize_system_metadata | usize | 8 | crates/disrobe-pass-jvm/src/dex.rs |
disrobe-pass-jvm | MAX_INNER_CLASS_DEPTH | recursion | error: untyped error | usize | 64 | crates/disrobe-pass-jvm/src/dex2jar.rs |
disrobe-pass-jvm | MAX_STORED_FRAME_SLOTS | other | recorded: FrameInferOutcome::BudgetExceeded; note | usize | 4 << 20 | crates/disrobe-pass-jvm/src/frame_infer.rs |
disrobe-pass-jvm | MAX_DEX_HIERARCHY_DECODED_BYTES | size | error: Error::BadBytecode (DR-JVM-0025) | usize | 16 * 1024 * 1024 | crates/disrobe-pass-jvm/src/hierarchy.rs |
disrobe-pass-jvm | MAX_DEX_HIERARCHY_EDGES | other | error: Error::BadBytecode (DR-JVM-0025) | usize | 65_536 | crates/disrobe-pass-jvm/src/hierarchy.rs |
disrobe-pass-jvm | MAX_DEX_HIERARCHY_NODES | count | error: Error::BadBytecode (DR-JVM-0025) | usize | 16_384 | crates/disrobe-pass-jvm/src/hierarchy.rs |
disrobe-pass-jvm | MAX_PREALLOC | other | allocation: with_capacity in read_zip_file | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-jvm/src/jar.rs |
disrobe-pass-jvm | ZIP_ENTRY_BYTES_CAP | size | error: Error::Zip (DR-JVM-0011) | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-jvm/src/jar.rs |
disrobe-pass-jvm | ZIP_ENTRY_COUNT_CAP | count | error: Error::Zip (DR-JVM-0011) | usize | 65_536 | crates/disrobe-pass-jvm/src/jar.rs |
disrobe-pass-jvm | ZIP_TOTAL_BYTES_CAP | size | error: Error::Zip (DR-JVM-0011) | u64 | 1024 * 1024 * 1024 | crates/disrobe-pass-jvm/src/jar.rs |
disrobe-pass-jvm | MAX_ARRAY_DIMS | other | silent: return in consume_field_type | usize | 255 | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_JNI_STRING_LEN | size | silent: return in is_jni_method_name; return in read_c_string | usize | 512 | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_NATIVE_INT_KEYS | other | silent: break in extract_static_int_keys | usize | 4096 | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_NATIVE_KEY_LIBS | other | silent: .take() in extract_static_int_keys | usize | 128 | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_NATIVE_KEY_LIB_BYTES | size | silent: continue in extract_static_int_keys | usize | 64 * 1024 * 1024 | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_STUB_BYTES | size | silent: .min() clamp in bytes_at_address | usize | 16 | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_HANDLER_COVERAGE | other | error: TOO_LARGE | usize | 4_000_000 | crates/disrobe-pass-jvm/src/jsr_inline.rs |
disrobe-pass-jvm | MAX_INLINE_DEPTH | recursion | error: TOO_DEEP | usize | 64 | crates/disrobe-pass-jvm/src/jsr_inline.rs |
disrobe-pass-jvm | MAX_OUTPUT | output | error: TOO_LARGE | usize | 1_000_000 | crates/disrobe-pass-jvm/src/jsr_inline.rs |
disrobe-pass-jvm | MAX_REMAP_WORK | work | error: TOO_LARGE | usize | 64_000_000 | crates/disrobe-pass-jvm/src/jsr_inline.rs |
disrobe-pass-jvm | MAX_OAT_DEX_BYTES | size | error: out_of_range() | usize | 256 * 1024 * 1024 | crates/disrobe-pass-jvm/src/oat.rs |
disrobe-pass-jvm | MAX_OAT_DEX_LOCATION_LEN | size | error: out_of_range() | usize | 4096 | crates/disrobe-pass-jvm/src/oat.rs |
disrobe-pass-jvm | MAX_HIERARCHY_DEPTH | recursion | silent: return in resolve_field_with_inheritance; return in resolve_method_with_inheritance | usize | 256 | crates/disrobe-pass-jvm/src/proguard.rs |
disrobe-pass-jvm | MAX_METHOD_INSNS | other | silent: return in unflatten_method | usize | 200_000 | crates/disrobe-pass-jvm/src/protectors/unflatten.rs |
disrobe-pass-jvm | MAX_DISPATCH_RESOLVE_STEPS | work | silent: break in simplify_flattened_cfg | usize | 65_536 | crates/disrobe-pass-jvm/src/sccp.rs |
disrobe-pass-jvm | MAX_SIGNATURE_BYTES | size | error: .to_string() | usize | 65_535 | crates/disrobe-pass-jvm/src/signature.rs |
disrobe-pass-jvm | MAX_SIGNATURE_DEPTH | recursion | error: .error() | u16 | 64 | crates/disrobe-pass-jvm/src/signature.rs |
disrobe-pass-jvm | MAX_SIGNATURE_ITEMS | count | error: .error(); .to_string() | usize | 1_024 | crates/disrobe-pass-jvm/src/signature.rs |
disrobe-pass-jvm | MAX_SIGNATURE_NODES | count | error: .error() | u32 | 4_096 | crates/disrobe-pass-jvm/src/signature.rs |
disrobe-pass-jvm | MAX_HEAP_OBJECTS | other | error: RecoveryError::HeapExhausted | usize | 8_192 | crates/disrobe-pass-jvm/src/string_recovery.rs |
disrobe-pass-jvm | MAX_STRING_LEN | size | error: RecoveryError::BadShape | usize | 65_536 | crates/disrobe-pass-jvm/src/string_recovery.rs |
disrobe-pass-jvm | STEP_LIMIT | work | error: RecoveryError::StepLimitExceeded | u64 | 4_000_000 | crates/disrobe-pass-jvm/src/string_recovery.rs |
disrobe-pass-jvm | STEP_LIMIT | work | error: EmulationError::StepLimitExceeded | u64 | 2_000_000 | crates/disrobe-pass-jvm/src/stub_emulator.rs |
disrobe-pass-lua | MAX_PROTO_DEPTH | recursion | error: Error::ProtoNestingTooDeep (DR-LUA-0025) | usize | 256 | crates/disrobe-pass-lua/src/cursor.rs |
disrobe-pass-lua | MAX_RESERVE_BYTES | size | error: Error::LimitExceeded (DR-LUA-0027) | usize | 16 << 20 | crates/disrobe-pass-lua/src/cursor.rs |
disrobe-pass-lua | MAX_LIFT_WORK | work | error: .to_owned(); CoreError::PassFailure (DR-CORE-0003); Error::BadConstantTag (DR-LUA-0011); 6 more | u64 | 1 << 24 | crates/disrobe-pass-lua/src/decompile/budget.rs |
disrobe-pass-lua | MAX_INLINED_CLOSURE_BYTES | size | recorded: warnings; flag fully_structured | usize | 8 << 20 | crates/disrobe-pass-lua/src/decompile/lift.rs |
disrobe-pass-lua | MAX_LIFT_DEPTH | recursion | recorded: flag fully_structured | usize | 200 | crates/disrobe-pass-lua/src/decompile/lift.rs |
disrobe-pass-lua | MAX_LIFT_DEPTH | recursion | recorded: warnings; flag fully_structured | usize | 200 | crates/disrobe-pass-lua/src/decompile/luajit_lift.rs |
disrobe-pass-lua | MAX_DIRECT_RENDER_NESTING | recursion | recorded: flag refused | usize | 256 | crates/disrobe-pass-lua/src/decompile/luau_lift.rs |
disrobe-pass-lua | MAX_LIFT_DEPTH | recursion | recorded: warnings; flag fully_structured | usize | 200 | crates/disrobe-pass-lua/src/decompile/luau_lift.rs |
disrobe-pass-lua | MAX_RENDERED_NUMBER_BYTES | output | silent: ? on a checked operation in template_rendered_bytes | usize | 330 | crates/disrobe-pass-lua/src/decompile/luau_lift.rs |
disrobe-pass-lua | MAX_RENDERED_STRUCTURE_BYTES | output | error: .to_owned(); Error::DecompileUnsupported (DR-LUA-0020) | usize | 16 * 1024 * 1024 | crates/disrobe-pass-lua/src/decompile/luau_lift.rs |
disrobe-pass-lua | MAX_BX | other | recorded: refuse() | u32 | (1 << 18) - 1 | crates/disrobe-pass-lua/src/decompile/luau_lift/translate.rs |
disrobe-pass-lua | MAX_C | other | recorded: refuse() | u32 | 511 | crates/disrobe-pass-lua/src/decompile/luau_lift/translate.rs |
disrobe-pass-lua | MAX_JUMP_CHAIN | other | silent: for range in rethread_loop_exits | usize | 64 | crates/disrobe-pass-lua/src/decompile/luau_lift/translate.rs |
disrobe-pass-lua | MAX_RK_INDEX | other | recorded: refuse() | u32 | 255 | crates/disrobe-pass-lua/src/decompile/luau_lift/translate.rs |
disrobe-pass-lua | MAX_STACK | other | recorded: refuse() | u32 | 250 | crates/disrobe-pass-lua/src/decompile/luau_lift/translate.rs |
disrobe-pass-lua | MAX_TEMPLATE_WORDS | other | recorded: refuse() | usize | 1 << 20 | crates/disrobe-pass-lua/src/decompile/luau_lift/translate.rs |
disrobe-pass-lua | MAX_TRANSLATE_DEPTH | recursion | recorded: refuse() | usize | 200 | crates/disrobe-pass-lua/src/decompile/luau_lift/translate.rs |
disrobe-pass-lua | MAX_STRUCTURE_VISITS_PER_NODE | other | silent: .min() clamp in for_nodes | usize | 2 | crates/disrobe-pass-lua/src/decompile/luau_structure.rs |
disrobe-pass-lua | MAX_STRUCTURE_WORK | work | silent: .min() clamp in for_nodes | usize | 1 << 16 | crates/disrobe-pass-lua/src/decompile/luau_structure.rs |
disrobe-pass-lua | MAX_RESERVED_NAME_SCAN | other | silent: return in names_referenced_by | usize | 1 << 20 | crates/disrobe-pass-lua/src/decompile/struct_lift.rs |
disrobe-pass-lua | MAX_STRUCT_DEPTH | recursion | silent: return in lift_structured_captured | usize | 200 | crates/disrobe-pass-lua/src/decompile/struct_lift.rs |
disrobe-pass-lua | MAX_STRUCT_NODES | count | silent: return in lift_structured_captured | usize | 1 << 20 | crates/disrobe-pass-lua/src/decompile/struct_lift.rs |
disrobe-pass-lua | READ_SEARCH_STATE_BUDGET | work | silent: return in dominates_its_reads; return in read_after_control_flow; return in read_on_another_path | usize | 1 << 16 | crates/disrobe-pass-lua/src/decompile/struct_lift.rs |
disrobe-pass-lua | MAX_SCOPE_DEPTH | recursion | silent: return in block_captures_in_closure; return in block_mentions_by; return in declare_in_block; 3 more | usize | 200 | crates/disrobe-pass-lua/src/decompile/struct_lift/declare.rs |
disrobe-pass-lua | MAX_CONDITION_CHAIN | other | silent: while condition in recover_short_circuit_chains | usize | 64 | crates/disrobe-pass-lua/src/decompile/struct_lift/structurer.rs |
disrobe-pass-lua | MAX_EXIT_SCAN | other | silent: .take() in retarget_exits_through_skip_jumps | usize | 4_096 | crates/disrobe-pass-lua/src/decompile/struct_lift/structurer.rs |
disrobe-pass-lua | MAX_BUILD_STEPS | work | silent: return in build | usize | 4_096 | crates/disrobe-pass-lua/src/decompile/struct_lift/value_region.rs |
disrobe-pass-lua | MAX_REGION_INSTRUCTIONS | other | silent: return in build; while condition in region_bounds | usize | 256 | crates/disrobe-pass-lua/src/decompile/struct_lift/value_region.rs |
disrobe-pass-lua | MAX_LOADER_DEPTH | recursion | silent: for range in peel | usize | 16 | crates/disrobe-pass-lua/src/obfuscator/hercules.rs |
disrobe-pass-lua | MAX_CAESAR_KEY | other | silent: return in caesar_decode | i64 | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/hercules_recover.rs |
disrobe-pass-lua | MAX_FOLDED_STRING_BYTES | size | silent: return in const_string | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/hercules_recover.rs |
disrobe-pass-lua | MAX_ROUNDS | work | silent: break in recover_source | usize | 1024 | crates/disrobe-pass-lua/src/obfuscator/hercules_recover.rs |
disrobe-pass-lua | MAX_ENCODED_BYTES | size | error: Error::DecompileUnsupported (DR-LUA-0020) | usize | 64 << 20 | crates/disrobe-pass-lua/src/obfuscator/hercules_vm.rs |
disrobe-pass-lua | MAX_PROTO_DEPTH | recursion | error: Error::DecompileUnsupported (DR-LUA-0020) | usize | 200 | crates/disrobe-pass-lua/src/obfuscator/hercules_vm.rs |
disrobe-pass-lua | IB_CONST_COUNT_CAP | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 16 | crates/disrobe-pass-lua/src/obfuscator/ironbrew2_real.rs |
disrobe-pass-lua | IB_FUNCTION_COUNT_CAP | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 16 | crates/disrobe-pass-lua/src/obfuscator/ironbrew2_real.rs |
disrobe-pass-lua | IB_INSTRUCTION_COUNT_CAP | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/ironbrew2_real.rs |
disrobe-pass-lua | IB_LINEINFO_COUNT_CAP | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/ironbrew2_real.rs |
disrobe-pass-lua | MAX_LOC_CONSTANTS | other | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1usize << 16 | crates/disrobe-pass-lua/src/obfuscator/luaobfuscator_com.rs |
disrobe-pass-lua | MAX_LOC_INSTRUCTIONS | other | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1usize << 20 | crates/disrobe-pass-lua/src/obfuscator/luaobfuscator_com.rs |
disrobe-pass-lua | MAX_LOC_PROTOS | other | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1usize << 16 | crates/disrobe-pass-lua/src/obfuscator/luaobfuscator_com.rs |
disrobe-pass-lua | MAX_LOC_STRING_BYTES | size | error: Error::LimitExceeded (DR-LUA-0027) | usize | 16usize << 20 | crates/disrobe-pass-lua/src/obfuscator/luaobfuscator_com.rs |
disrobe-pass-lua | MAX_PROTO_DEPTH | recursion | error: Error::ProtoNestingTooDeep (DR-LUA-0025) | usize | 200 | crates/disrobe-pass-lua/src/obfuscator/luaobfuscator_com.rs |
disrobe-pass-lua | LURAPH_SCAN_LIMIT | other | silent: .min() clamp in find_lua_assignment_value | usize | 8 << 20 | crates/disrobe-pass-lua/src/obfuscator/luraph.rs |
disrobe-pass-lua | MAX_BOOTSTRAP_TABLE_VALUES | other | silent: return in parse_numeric_table_len | usize | 4096 | crates/disrobe-pass-lua/src/obfuscator/luraph.rs |
disrobe-pass-lua | MAX_LURAPH_EXPR_LEN | size | silent: return in rewrite_hex_literals | usize | 4096 | crates/disrobe-pass-lua/src/obfuscator/luraph.rs |
disrobe-pass-lua | CONSTANT_ARRAY_BUDGET | work | error: Error::LiftBudgetExceeded (DR-LUA-0031); Error::LimitExceeded (DR-LUA-0027); Error::other(); 1 more | ConstantArrayBudget | ConstantArrayBudget { max_source_bytes: crate::obfuscator::prometheus_vm_ast::MAX_SOURCE_BYTES, max_entries: MAX_CONSTANT_ARRAY_ENTRIES, max_decoded_bytes: MAX_CONSTANT_ARRAY_DECODED_BYTES, } | crates/disrobe-pass-lua/src/obfuscator/prometheus.rs |
disrobe-pass-lua | MAX_CONSTANT_ARRAY_DECODED_BYTES | size | error: Error::LimitExceeded (DR-LUA-0027); limit_exceeded() | usize | 4 << 20 | crates/disrobe-pass-lua/src/obfuscator/prometheus.rs |
disrobe-pass-lua | MAX_CONSTANT_ARRAY_ENTRIES | count | error: Error::LiftBudgetExceeded (DR-LUA-0031); Error::LimitExceeded (DR-LUA-0027); Error::other() | usize | 1 << 14 | crates/disrobe-pass-lua/src/obfuscator/prometheus.rs |
disrobe-pass-lua | MAX_NESTED_VMIFY_PASSES | recursion | silent: while condition in apply_vmify_devirt | usize | 4 | crates/disrobe-pass-lua/src/obfuscator/prometheus.rs |
disrobe-pass-lua | VMIFY_DISPATCH_SCAN_LIMIT | other | silent: return in matches_vmify_container_shape | usize | 1 << 24 | crates/disrobe-pass-lua/src/obfuscator/prometheus.rs |
disrobe-pass-lua | MAX_BLOCK_STATEMENTS | other | error: Error::DecompileUnsupported (DR-LUA-0020) | usize | 1 << 18 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_ast.rs |
disrobe-pass-lua | MAX_LOCALS | other | error: Error::DecompileUnsupported (DR-LUA-0020) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_ast.rs |
disrobe-pass-lua | MAX_NEST_DEPTH | recursion | error: Error::DecompileUnsupported (DR-LUA-0020) | usize | 200 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_ast.rs |
disrobe-pass-lua | MAX_SOURCE_BYTES | size | error: Error::DecompileUnsupported (DR-LUA-0020); Error::LimitExceeded (DR-LUA-0027); limit_exceeded(); 1 more | usize | 8 << 20 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_ast.rs |
disrobe-pass-lua | MAX_TOKENS | other | error: Error::DecompileUnsupported (DR-LUA-0020) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_ast.rs |
disrobe-pass-lua | MAX_ANTITAMPER_EXPRESSION_DEPTH | recursion | silent: return in anti_tamper_value | usize | 32 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_ANTITAMPER_PROOF_STEPS | work | error: refuse() | usize | 1 << 16 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_ANTITAMPER_STATE_BINDINGS | other | error: refuse() | usize | 1 << 12 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_BOX_STATEMENT_USES | other | error: refuse() | usize | 1 << 12 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_BOX_STATE_BINDINGS | other | error: refuse() | usize | 1 << 18 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_CONSTANT_POOL_RESOLVERS | other | error: refuse() | usize | 8 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_DISPATCH_DEPTH | recursion | error: refuse() | u32 | 96 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_FUNCTIONS | other | error: refuse() | usize | 1 << 10 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_FUNCTION_BLOCKS | other | error: refuse() | usize | 1 << 14 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_LOOP_NESTING | recursion | silent: return in render_loop | usize | 32 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_REACHABILITY_STEPS | work | error: refuse() | usize | 1 << 18 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_RECOVERY_DEPTH | recursion | error: refuse() | usize | 6 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_REGION_TREE_STEPS | work | silent: ? on a checked operation in collect_region_nodes; ? on a checked operation in loop_exit_tails; ? on a checked operation in region_contains_node; 1 more | usize | 1 << 16 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_SCRATCH_CHAIN_DEPTH | recursion | silent: return in resolve_and_expr; return in resolve_number_via_last_write | u32 | 12 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_STATIC_NUMBER_DEPTH | recursion | silent: return in evaluate_at_depth | usize | 32 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_STATIC_NUMBER_FUEL | work | delegated: passed to .set | usize | 1 << 12 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | DISPATCH_SCAN_LIMIT | other | silent: return in analyze_dispatch | usize | 1 << 24 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vmlift.rs |
disrobe-pass-lua | MAX_FOLD_TOKENS | other | silent: return in fold_one_expression; return in try_fold_span | usize | 4096 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vmlift.rs |
disrobe-pass-lua | NUMERIC_EXPR_BUDGET | work | error: Error::DecompileUnsupported (DR-LUA-0020) | usize | 1 << 24 | crates/disrobe-pass-lua/src/obfuscator/prometheus_vmlift.rs |
disrobe-pass-lua | MAX_DECOMPRESSED | other | error: Error::Io (DR-LUA-0001); Error::LiftBudgetExceeded (DR-LUA-0031); Error::LimitExceeded (DR-LUA-0027); 1 more | usize | 64 * 1024 * 1024 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | MAX_PROTO_DEPTH | recursion | error: Error::ProtoNestingTooDeep (DR-LUA-0025) | usize | 200 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | MAX_SLUA_CODE_COUNT | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | MAX_SLUA_CONSTANT_COUNT | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | MAX_SLUA_LINE_COUNT | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | MAX_SLUA_LOCAL_COUNT | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | MAX_SLUA_PROTO_COUNT | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 16 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | MAX_SLUA_UPVALUE_COUNT | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 16 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | MAX_SLUA_UPVALUE_NAME_COUNT | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 16 | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | U32_FIELD_LIMIT | other | error: Error::LimitExceeded (DR-LUA-0027) | usize | u32::MAX as usize | crates/disrobe-pass-lua/src/obfuscator/slua.rs |
disrobe-pass-lua | BASE64_PAYLOAD_CHAR_CAP | other | silent: return in decode_base64_payload_run | usize | (LUA_STRING_PAYLOAD_CAP / 3) * 4 + 8 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | BOOTSTRAP_SCAN_LIMIT | other | silent: .min() clamp in find_lua_assignment_value; while condition in extract_named_lua_byte_buffer | usize | 8 << 20 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | EMBEDDED_PAYLOAD_SCAN_LIMIT | other | silent: .min() clamp in extract_lua_string_payload | usize | 8 << 20 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | LUA_STRING_PAYLOAD_CAP | other | error: Error::LimitExceeded (DR-LUA-0027) | usize | 16 << 20 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | LUA_TABLE_PAYLOAD_CAP | other | silent: return in decode_lua_byte_table | usize | 16 << 20 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | PB_STACK_LIMIT | other | error: Error::BootstrapEmulationFailed (DR-LUA-0026) | usize | 256 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | PB_STEP_LIMIT | work | error: Error::BootstrapEmulationFailed (DR-LUA-0026) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | VM_CODE_COUNT_CAP | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | VM_CONST_COUNT_CAP | count | error: Error::LimitExceeded (DR-LUA-0027) | usize | 1 << 20 | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | DISPATCH_BLOCK_LIMIT | other | silent: break in lift_dispatch | usize | 4096 | crates/disrobe-pass-lua/src/obfuscator/wearedevs.rs |
disrobe-pass-lua | DISPATCH_GUARD_LIMIT | other | silent: break in collect_threshold_cuts | usize | 256 | crates/disrobe-pass-lua/src/obfuscator/wearedevs.rs |
disrobe-pass-lua | DISPATCH_PARSE_DEPTH_LIMIT | recursion | silent: return in parse_dispatch_node | usize | 512 | crates/disrobe-pass-lua/src/obfuscator/wearedevs.rs |
disrobe-pass-lua | DISPATCH_SCAN_LIMIT | other | silent: .min() clamp in lift_dispatch | usize | 256 * 1024 | crates/disrobe-pass-lua/src/obfuscator/wearedevs.rs |
disrobe-pass-lua | INT_VARINT_LIMIT | other | error: Error::VarintOverflow (DR-LUA-0032) | u64 | i32::MAX as u64 | crates/disrobe-pass-lua/src/reader/lua55.rs |
disrobe-pass-lua | MAX_MATERIALIZED_STRING_BYTES | size | error: Error::LimitExceeded (DR-LUA-0027) | usize | 64 << 20 | crates/disrobe-pass-lua/src/reader/lua55.rs |
disrobe-pass-lua | MAX_ASSEMBLED_NODES | count | error: Error::LuauOpcodeMap (DR-LUA-0030) | usize | 1 << 16 | crates/disrobe-pass-lua/src/reader/luau.rs |
disrobe-pass-lua | MAX_BUILD_ID_BYTES | size | error: Error::LuauOpcodeMap (DR-LUA-0030) | usize | 128 | crates/disrobe-pass-lua/src/reader/luau.rs |
disrobe-pass-lua | MAX_OPCODE_MAP_BYTES | size | error: Error::LuauOpcodeMap (DR-LUA-0030) | u64 | 64 << 10 | crates/disrobe-pass-lua/src/reader/luau.rs |
disrobe-pass-lua | MAX_PROTO_DEPTH | recursion | error: Error::LuauOpcodeMap (DR-LUA-0030) | usize | 200 | crates/disrobe-pass-lua/src/reader/luau.rs |
disrobe-pass-lua | MAX_TEMPLATE_STORAGE_BYTES | size | error: Error::LuauTableTemplateStorageLimit (DR-LUA-0039) | usize | 16 << 20 | crates/disrobe-pass-lua/src/reader/luau.rs |
disrobe-pass-mobile | MAX_EMBEDDED_DEX_CARVES | other | silent: while condition in collect_plain_dex_carves; while condition in collect_xor_dex_carves | usize | 16 | crates/disrobe-pass-mobile/src/apk_recon.rs |
disrobe-pass-mobile | MAX_PROTECTOR_CARVE_SCAN | other | silent: skipped in analyze; skipped in extract_android_dex_children | u64 | 64 << 20 | crates/disrobe-pass-mobile/src/apk_recon.rs |
disrobe-pass-mobile | MAX_RESOLVED_RESOURCES | other | silent: break in summarise_arsc | usize | 4096 | crates/disrobe-pass-mobile/src/apk_recon.rs |
disrobe-pass-mobile | MAX_TEXT_ASSET | other | silent: skipped in analyze | u64 | 16 << 20 | crates/disrobe-pass-mobile/src/apk_recon.rs |
disrobe-pass-mobile | MAX_CERTS_PER_SIGNER | other | silent: break in parse_signer | usize | 256 | crates/disrobe-pass-mobile/src/apk_signing.rs |
disrobe-pass-mobile | MAX_DIGESTS_PER_SIGNER | other | silent: break in parse_signer | usize | 256 | crates/disrobe-pass-mobile/src/apk_signing.rs |
disrobe-pass-mobile | MAX_PAIRS | other | silent: break in parse_id_value_pairs | usize | 4096 | crates/disrobe-pass-mobile/src/apk_signing.rs |
disrobe-pass-mobile | MAX_SIGNERS | other | silent: break in parse_scheme | usize | 4096 | crates/disrobe-pass-mobile/src/apk_signing.rs |
disrobe-pass-mobile | MAX_POOL_STRINGS | other | error: Error::ArscTruncated (DR-MOB-0029) | u32 | 1 << 22 | crates/disrobe-pass-mobile/src/arsc.rs |
disrobe-pass-mobile | MAX_TYPE_ENTRIES | count | error: Error::ArscTruncated (DR-MOB-0029) | u32 | 1 << 20 | crates/disrobe-pass-mobile/src/arsc.rs |
disrobe-pass-mobile | MAX_DEPTH | recursion | error: Error::AxmlTruncated (DR-MOB-0026) | usize | 512 | crates/disrobe-pass-mobile/src/axml.rs |
disrobe-pass-mobile | TRAVERSAL_INSN_BUDGET | work | silent: break in traverse | usize | 1 << 22 | crates/disrobe-pass-mobile/src/flutter/arm64_traversal.rs |
disrobe-pass-mobile | MAX_BOOLEAN_RETURN_INSTRUCTIONS | other | silent: return in recover_boolean_return | usize | 64 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_BOXED_DOUBLE_SETUP_INSTRUCTIONS | other | silent: ? on a checked operation in skip | usize | 8 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_BOXED_DOUBLE_TRACE_INSTRUCTIONS | other | silent: ? on a checked operation in skip | usize | 256 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_CONSUMED_TEXT_BYTES | size | silent: skipped in consumed_text | usize | 1 << 16 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_FLOAT_RETURN_SPILL_DISTANCE | other | silent: ? on a checked operation in skip | usize | 3 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_FRAME_SLOTS | other | silent: return in record_frame | usize | 128 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_MERGE_PREDECESSORS | other | silent: return in entry_state | usize | 64 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_STACK_ARGUMENTS | other | silent: return in record_stack; return in stack_arguments | usize | 32 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_TRACKED_CALLS | other | silent: break in track_call_sites | usize | 1 << 14 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_TRACKED_EFFECTS | other | silent: return in define; skipped in bookkeeping; skipped in step | usize | 1 << 16 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_VALUE_DEPTH | recursion | silent: return in render_value | usize | 6 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_VALUE_NODES | count | silent: ? on a checked operation in node_budget | usize | 48 | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | CLUSTER_TAG_SCAN_LIMIT | other | silent: .min() clamp in scan_cid_tags | usize | 1 << 16 | crates/disrobe-pass-mobile/src/flutter/cluster.rs |
disrobe-pass-mobile | MAX_CODE_TABLE_ENTRIES | count | error: Error::DartCodeTableUnavailable (DR-MOB-0048) | usize | 1 << 22 | crates/disrobe-pass-mobile/src/flutter/code_table.rs |
disrobe-pass-mobile | HARD_CLUSTER_LIMIT | other | error: DartPoolUnresolvedReason::ClusterBodyUnmodelled; DartPoolUnresolvedReason::DeclaredNameMissing; DartPoolUnresolvedReason::ImmediateMissing; 18 more | usize | 4096 | crates/disrobe-pass-mobile/src/flutter/dart_graph.rs |
disrobe-pass-mobile | HARD_OBJECT_LIMIT | other | error: DartPoolUnresolvedReason::ObjectOutOfRange; DartPoolUnresolvedReason::TypeArgumentsMalformed; DartPoolUnresolvedReason::TypeFlagsMissing; 2 more | usize | 2_000_000 | crates/disrobe-pass-mobile/src/flutter/dart_graph.rs |
disrobe-pass-mobile | HARD_REFERENCE_LIMIT | other | error: DartPoolUnresolvedReason::Cyclic; DartPoolUnresolvedReason::DeclaredNameMissing; DartPoolUnresolvedReason::ObjectOutOfRange; 7 more | usize | 16_000_000 | crates/disrobe-pass-mobile/src/flutter/dart_graph.rs |
disrobe-pass-mobile | HARD_STRING_CODE_UNIT_LIMIT | other | error: Error::DartGraphConfiguredLimitExceeded (DR-MOB-0044); Error::DartGraphLimitExceeded (DR-MOB-0035) | usize | 16 * 1024 * 1024 | crates/disrobe-pass-mobile/src/flutter/dart_graph.rs |
disrobe-pass-mobile | HARD_TOTAL_STRING_BYTE_LIMIT | size | error: Error::DartGraphConfiguredLimitExceeded (DR-MOB-0044); Error::DartGraphLimitExceeded (DR-MOB-0035) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-mobile/src/flutter/dart_graph.rs |
disrobe-pass-mobile | HARD_VARIABLE_LENGTH_LIMIT | size | error: Error::DartGraphConfiguredLimitExceeded (DR-MOB-0044); Error::DartGraphInvalidClusterValue (DR-MOB-0037); Error::DartGraphLimitExceeded (DR-MOB-0035) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-mobile/src/flutter/dart_graph.rs |
disrobe-pass-mobile | MAX_POOL_SLOTS | other | silent: skipped in fill_object_pools | usize | 1 << 21 | crates/disrobe-pass-mobile/src/flutter/dart_graph.rs |
disrobe-pass-mobile | FEATURE_STRING_CAP | other | error: Error::DartGraphInvalidHeader (DR-MOB-0047) | usize | 4096 | crates/disrobe-pass-mobile/src/flutter/dart_graph_recovery.rs |
disrobe-pass-mobile | MAX_FUNCTION_INSNS | other | silent: while condition in disassemble_function; while condition in disassemble_range | usize | 1 << 16 | crates/disrobe-pass-mobile/src/flutter/disasm.rs |
disrobe-pass-mobile | MEMBER_TABLE_CAP | other | silent: return in member_table_from_count; return in parse | usize | 1 << 20 | crates/disrobe-pass-mobile/src/flutter/kernel.rs |
disrobe-pass-mobile | MAX_POOL_LITERALS | work | silent: break in resolve_pool_literals; while condition in resolve_pool_literals | usize | 1 << 16 | crates/disrobe-pass-mobile/src/flutter/object_pool.rs |
disrobe-pass-mobile | MAX_RUN_PROBE | other | silent: while condition in pool_run_length | usize | 64 | crates/disrobe-pass-mobile/src/flutter/object_pool.rs |
disrobe-pass-mobile | POOL_DECODE_BUDGET | work | silent: .min() clamp in recover_object_pool_references | usize | 1 << 24 | crates/disrobe-pass-mobile/src/flutter/object_pool.rs |
disrobe-pass-mobile | MAX_LIST_ELEMENTS | other | error: DartPoolUnresolvedReason::TypeArgumentsMalformed | usize | 8 | crates/disrobe-pass-mobile/src/flutter/pool_table.rs |
disrobe-pass-mobile | MAX_LITERAL_CHARS | work | error: DartPoolUnresolvedReason::TextTooLong | usize | 120 | crates/disrobe-pass-mobile/src/flutter/pool_table.rs |
disrobe-pass-mobile | MAX_LITERAL_DEPTH | recursion | error: DartPoolUnresolvedReason::DepthExceeded | usize | 4 | crates/disrobe-pass-mobile/src/flutter/pool_table.rs |
disrobe-pass-mobile | MAX_LITERAL_NODES | work | error: DartPoolUnresolvedReason::NodeBudgetExhausted | usize | 64 | crates/disrobe-pass-mobile/src/flutter/pool_table.rs |
disrobe-pass-mobile | MAX_DART_IDENTIFIER_BYTES | size | recorded: flag current_overlong | usize | 1 << 14 | crates/disrobe-pass-mobile/src/flutter/snapshot.rs |
disrobe-pass-mobile | MAX_DART_IDENTIFIER_COUNT | count | silent: break in extract_dart_identifiers; skipped in flush_identifier | usize | 1 << 16 | crates/disrobe-pass-mobile/src/flutter/snapshot.rs |
disrobe-pass-mobile | MAX_FUNCTION_BOUNDARIES | other | silent: while condition in scan_function_boundaries | usize | 1 << 20 | crates/disrobe-pass-mobile/src/flutter/snapshot.rs |
disrobe-pass-mobile | MAX_STRING_CHARS | other | silent: continue in scan_one_byte_strings | usize | 1 << 16 | crates/disrobe-pass-mobile/src/flutter/string_pool.rs |
disrobe-pass-mobile | MAX_ALLOCATOR_WORDS | other | silent: for range in allocate_object_helper_inputs | usize | 64 | crates/disrobe-pass-mobile/src/flutter/stub_abi.rs |
disrobe-pass-mobile | MAX_REGISTER_SAVES | other | silent: return in stub_frame_entry | usize | 32 | crates/disrobe-pass-mobile/src/flutter/stub_abi.rs |
disrobe-pass-mobile | MAX_STUB_ARGUMENT_STEPS | work | silent: for range in runtime_call_stub | usize | 16 | crates/disrobe-pass-mobile/src/flutter/stub_abi.rs |
disrobe-pass-mobile | MAX_TAG_WORDS | other | silent: return in allocation_stub_for_class | usize | 4 | crates/disrobe-pass-mobile/src/flutter/stub_abi.rs |
disrobe-pass-mobile | MAX_DECIMAL_BYTES | size | silent: fallback value in bigint_literal | usize | 4096 | crates/disrobe-pass-mobile/src/hermes/bigint.rs |
disrobe-pass-mobile | MAX_DECODED_INSTRUCTIONS | other | silent: while condition in decode_instructions | usize | 1 << 20 | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_INLINE_CLOSURE_BYTES | size | silent: no action in closure_expr | usize | 1 << 16 | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_INLINE_CLOSURE_DEPTH | recursion | silent: return in inlined_closure_bodies | usize | 8 | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_REG_EXPR_BYTES | size | silent: no action in set_reg | usize | 4096 | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_RENDERED_CALL_ARGS | output | silent: .min() clamp in unrecovered_arg_list; return in call_window_registers | u64 | 256 | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_RENDER_BYTES | output | silent: break in render_block_stmts; break in render_structured | usize | 1 << 20 | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_SWITCH_CASES | other | silent: return in switch_table_entries | u64 | 4096 | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_DECODED_LITERALS | work | silent: return in decode_literals; while condition in decode_literals | usize | 1 << 20 | crates/disrobe-pass-mobile/src/hermes/literals.rs |
disrobe-pass-mobile | MAX_REGEX_DEPTH | recursion | recorded: flag fully_modeled | usize | 512 | crates/disrobe-pass-mobile/src/hermes/regex.rs |
disrobe-pass-mobile | MAX_REGEX_INSNS | other | silent: while condition in decode_body; while condition in render_range_inner | usize | 1 << 16 | crates/disrobe-pass-mobile/src/hermes/regex.rs |
disrobe-pass-mobile | MAX_LOOP_EXTENSION_ROUNDS | work | silent: for range in extend_loop_body | usize | 64 | crates/disrobe-pass-mobile/src/hermes/structure.rs |
disrobe-pass-mobile | MAX_LOWERED_LOOPS | work | error: StructureDecline::BlockBudgetExceeded | usize | 4096 | crates/disrobe-pass-mobile/src/hermes/structure.rs |
disrobe-pass-mobile | MAX_REGION_DEPTH | recursion | error: StructureDecline::DepthExceeded | usize | 64 | crates/disrobe-pass-mobile/src/hermes/structure.rs |
disrobe-pass-mobile | MAX_STRUCTURE_BLOCKS | other | error: StructureDecline::BlockBudgetExceeded | usize | 4096 | crates/disrobe-pass-mobile/src/hermes/structure.rs |
disrobe-pass-mobile | MAX_STRUCTURE_STATEMENTS | other | error: StructureDecline::StatementBudgetExceeded | usize | 1 << 16 | crates/disrobe-pass-mobile/src/hermes/structure.rs |
disrobe-pass-mobile | MACHO_FAT_ARCH_COUNT_CAP | count | error: Error::MachOFatTooManyArches (DR-MOB-0031) | usize | 4096 | crates/disrobe-pass-mobile/src/ios.rs |
disrobe-pass-mobile | ZIP_ENTRY_COUNT_CAP | count | error: Error::Zip (DR-MOB-0002) | usize | 65_536 | crates/disrobe-pass-mobile/src/lib.rs |
disrobe-pass-mobile | ZIP_ENTRY_PREALLOC_CAP | other | unused: no use in the crate | usize | 64 << 20 | crates/disrobe-pass-mobile/src/lib.rs |
disrobe-pass-mobile | ZIP_ENTRY_READ_CAP | other | error: Error::Zip (DR-MOB-0002) | usize | 512 << 20 | crates/disrobe-pass-mobile/src/lib.rs |
disrobe-pass-mobile | MAX_DECODED_XML | other | silent: break in decode_archive | usize | 4096 | crates/disrobe-pass-mobile/src/res_decode.rs |
disrobe-pass-mobile | MAX_VALUES_ENTRIES | count | silent: break in reconstruct_values | usize | 16384 | crates/disrobe-pass-mobile/src/res_decode.rs |
disrobe-pass-native | MAX_HARVEST_INSNS | other | silent: break in harvested_hash_constants | usize | 200_000 | crates/disrobe-pass-native/src/api_hash.rs |
disrobe-pass-native | MAX_CHAIN_DEPTH | recursion | silent: while condition in build_chain | usize | 12 | crates/disrobe-pass-native/src/authenticode.rs |
disrobe-pass-native | MAX_BLOCKS | other | silent: return in build_cfg; return in collect_leaders | usize | 256 | crates/disrobe-pass-native/src/basic_blocks.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | other | silent: return in build_block; return in collect_leaders | usize | 1024 | crates/disrobe-pass-native/src/basic_blocks.rs |
disrobe-pass-native | MAX_AUTO_PSEUDO_FUNCTIONS | other | silent: return in native_pseudo_report | usize | 256 | crates/disrobe-pass-native/src/chain_detector.rs |
disrobe-pass-native | MAX_AUTO_PSEUDO_IMAGE_BYTES | size | silent: return in native_pseudo_report | usize | 1024 * 1024 | crates/disrobe-pass-native/src/chain_detector.rs |
disrobe-pass-native | MAX_AUTO_PSEUDO_REPORT_BYTES | size | silent: no action in build_image_children | usize | 8 * 1024 * 1024 | crates/disrobe-pass-native/src/chain_detector.rs |
disrobe-pass-native | MAX_X86_INSTRUCTION_BYTES | size | silent: slice in is_import_thunk | usize | 15 | crates/disrobe-pass-native/src/code_symbol.rs |
disrobe-pass-native | MAX_ITANIUM_ACTION_STEPS | work | error: untyped error | usize | 65_536 | crates/disrobe-pass-native/src/cxx_recovery.rs |
disrobe-pass-native | MAX_ITANIUM_LSDA_ENTRIES | count | error: Error::Dwarf (DR-NATIVE-0006); untyped format! | usize | 65_536 | crates/disrobe-pass-native/src/cxx_recovery.rs |
disrobe-pass-native | MAX_WINDOWS_SEH_SCOPE_ENTRIES | count | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 65_536 | crates/disrobe-pass-native/src/cxx_recovery.rs |
disrobe-pass-native | MAX_AGGREGATE_BYTES | size | error: PdbProvenanceError::AggregateLimit | usize | 64 * 1024 * 1024 | crates/disrobe-pass-native/src/debug_info/pdb_provenance.rs |
disrobe-pass-native | MAX_IPI_RECORDS | count | error: PdbProvenanceError::IpiRecordLimit | usize | 1_000_000 | crates/disrobe-pass-native/src/debug_info/pdb_provenance.rs |
disrobe-pass-native | MAX_MODULES | other | error: PdbProvenanceError::ModuleLimit | usize | 65_536 | crates/disrobe-pass-native/src/debug_info/pdb_provenance.rs |
disrobe-pass-native | MAX_MODULE_SYMBOLS | other | error: PdbProvenanceError::ModuleSymbolLimit | usize | 1_000_000 | crates/disrobe-pass-native/src/debug_info/pdb_provenance.rs |
disrobe-pass-native | MAX_RESOLVED_STRING_BYTES | size | error: PdbProvenanceError::ResolvedStringLimit | usize | 1024 * 1024 | crates/disrobe-pass-native/src/debug_info/pdb_provenance.rs |
disrobe-pass-native | MAX_SUBSTRING_DEPTH | recursion | error: PdbProvenanceError::SubstringDepth | usize | 64 | crates/disrobe-pass-native/src/debug_info/pdb_provenance.rs |
disrobe-pass-native | MAX_SUBSTRING_REFERENCES | other | error: PdbProvenanceError::SubstringReferenceLimit; PdbProvenanceError::SubstringTraversalLimit | usize | 16_384 | crates/disrobe-pass-native/src/debug_info/pdb_provenance.rs |
disrobe-pass-native | MAX_DEPTH | recursion | silent: return in process_value; return in read_object; return in read_prop_list | usize | 512 | crates/disrobe-pass-native/src/delphi/dfm.rs |
disrobe-pass-native | MAX_OBJECTS | other | silent: return in read_object | usize | 200_000 | crates/disrobe-pass-native/src/delphi/dfm.rs |
disrobe-pass-native | MAX_OUTPUT_BYTES | output | recorded: flag capped | usize | 16 * 1024 * 1024 | crates/disrobe-pass-native/src/delphi/dfm.rs |
disrobe-pass-native | BYTE_SCAN_LIMIT | size | silent: slice in identify; slice in scan_window | usize | 8 * 1024 * 1024 | crates/disrobe-pass-native/src/delphi/image.rs |
disrobe-pass-native | MAX_SHORTSTRING_LEN | size | silent: return in is_plausible_symbol_of_length; return in read_shortstring | usize | 255 | crates/disrobe-pass-native/src/delphi/image.rs |
disrobe-pass-native | MAX_STUB_BYTES | size | silent: slice in entry_stub_addresses | usize | 256 | crates/disrobe-pass-native/src/delphi/init_table.rs |
disrobe-pass-native | MAX_STUB_INSTRUCTIONS | other | silent: while condition in entry_stub_addresses | usize | 48 | crates/disrobe-pass-native/src/delphi/init_table.rs |
disrobe-pass-native | MAX_UNITS | other | silent: return in parse_at | i32 | 8192 | crates/disrobe-pass-native/src/delphi/init_table.rs |
disrobe-pass-native | MAX_ENTRIES | count | silent: .min() clamp in entry_count | u32 | 8192 | crates/disrobe-pass-native/src/delphi/resource.rs |
disrobe-pass-native | MAX_NAME_CHARS | other | silent: .min() clamp in read_res_name | usize | 512 | crates/disrobe-pass-native/src/delphi/resource.rs |
disrobe-pass-native | MAX_RESOURCES | other | silent: return in walk_langs; return in walk_names; return in walk_types | usize | 8192 | crates/disrobe-pass-native/src/delphi/resource.rs |
disrobe-pass-native | MAX_SCAN_POSITIONS | other | silent: break in scan | usize | 16_000_000 | crates/disrobe-pass-native/src/delphi/strings.rs |
disrobe-pass-native | MAX_STRINGS | other | silent: break in scan | usize | 65_536 | crates/disrobe-pass-native/src/delphi/strings.rs |
disrobe-pass-native | MAX_STRING_UNITS | other | silent: return in read_candidate | u32 | 1 << 20 | crates/disrobe-pass-native/src/delphi/strings.rs |
disrobe-pass-native | MAX_DYNAMIC_METHODS | other | silent: return in parse_dynamic_table | u16 | 4096 | crates/disrobe-pass-native/src/delphi/tables.rs |
disrobe-pass-native | MAX_FIELDS_PER_CLASS | other | silent: return in parse_field_table | u16 | 4096 | crates/disrobe-pass-native/src/delphi/tables.rs |
disrobe-pass-native | MAX_FIELD_CLASSES | other | silent: return in field_class_candidates | u16 | 8192 | crates/disrobe-pass-native/src/delphi/tables.rs |
disrobe-pass-native | MAX_INTERFACES | other | silent: return in parse_interface_table | i32 | 1024 | crates/disrobe-pass-native/src/delphi/tables.rs |
disrobe-pass-native | MAX_ENUM_MEMBERS | count | silent: return in fill_enumeration | i64 | 4096 | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_FIELD_VISIBILITY | other | silent: return in parse_record_fields | u8 | 3 | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_MANAGED_FIELDS | other | silent: return in fill_record | i32 | 4096 | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_RECORD_FIELDS | other | silent: return in parse_record_fields | i32 | 4096 | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_RECORD_OPERATORS | other | unclassified: stored in record_fields with no read found | u8 | 64 | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_RECORD_SIZE | size | silent: return in fill_record | i32 | 1 << 20 | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_PATH_TAIL | other | silent: slice in scan_toolchain_paths | usize | 16 | crates/disrobe-pass-native/src/delphi/version.rs |
disrobe-pass-native | MAX_CLASSES | other | recorded: flag scan_truncated | usize | 8192 | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_INSTANCE_SIZE | size | silent: return in validate_class | u32 | 0x0100_0000 | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_METHODS_PER_CLASS | other | silent: .min() clamp in parse_method_table | u16 | 8192 | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_PARENT_DEPTH | recursion | silent: break in accumulate | usize | 64 | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_PROPS_PER_CLASS | work | silent: .min() clamp in parse_typeinfo | u16 | 8192 | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_SCAN_POSITIONS | other | recorded: flag scan_truncated | usize | 8_000_000 | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_TYPE_RECORDS | count | silent: .take() in describe_types | usize | 16384 | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_DECODE_INSNS | other | silent: while condition in decode_all | usize | 4096 | crates/disrobe-pass-native/src/deobf/abi.rs |
disrobe-pass-native | MAX_DECODE_INSNS | other | silent: while condition in decode_all | usize | 8192 | crates/disrobe-pass-native/src/deobf/bcf_dse.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | other | silent: while condition in decode_all | usize | 4096 | crates/disrobe-pass-native/src/deobf/branchfold.rs |
disrobe-pass-native | MAX_BLOCKS | other | silent: return in carve_blocks | usize | 8192 | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_DISPATCH_TREE_STEPS | work | silent: break in compare_chain_blocks; return in model_compare_tree; while condition in enqueue_jump_table_targets; 1 more | usize | 4096 | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_INSNS | other | silent: return in build_program; return in recursive_decode | usize | 200_000 | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_REGION_DEPTH | recursion | silent: return in walk | u32 | 128 | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_REGION_STEPS | work | silent: return in walk | u32 | 4096 | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_RESOLVE_DEPTH | recursion | silent: return in resolve_loc | u32 | 4 | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | other | silent: while condition in decode_all | usize | 4096 | crates/disrobe-pass-native/src/deobf/copyprop.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | other | silent: while condition in decode_all | usize | 4096 | crates/disrobe-pass-native/src/deobf/deadflags.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | other | silent: while condition in decode_all | usize | 4096 | crates/disrobe-pass-native/src/deobf/jumptable.rs |
disrobe-pass-native | MAX_TABLE_ENTRIES | count | silent: .min() clamp in read_pic_table; .min() clamp in read_table; while condition in read_pic_table; 1 more | u64 | 4096 | crates/disrobe-pass-native/src/deobf/jumptable.rs |
disrobe-pass-native | MAX_EXPR_NODES | count | recorded: flag capped | usize | 4096 | crates/disrobe-pass-native/src/deobf/mba_lift.rs |
disrobe-pass-native | MAX_LIFT_INSNS | other | silent: return in lift_arith_value; return in lift_operand_pair | usize | 8192 | crates/disrobe-pass-native/src/deobf/mba_lift.rs |
disrobe-pass-native | MAX_CONSTRAINTS | other | recorded: WallReason::ConstraintBudgetExceeded | usize | 64 | crates/disrobe-pass-native/src/deobf/pathsense.rs |
disrobe-pass-native | MAX_DECODE_INSNS | other | silent: while condition in decode_all | usize | 8192 | crates/disrobe-pass-native/src/deobf/pathsense.rs |
disrobe-pass-native | MAX_FEASIBILITY_EVALS | other | recorded: WallReason::NonExhaustibleDomain | u128 | 1 << 24 | crates/disrobe-pass-native/src/deobf/pathsense.rs |
disrobe-pass-native | MAX_FEASIBILITY_VARS | other | recorded: WallReason::VariableBudgetExceeded | u32 | 3 | crates/disrobe-pass-native/src/deobf/pathsense.rs |
disrobe-pass-native | MAX_PATH_BLOCKS | other | silent: return in walk | usize | 256 | crates/disrobe-pass-native/src/deobf/pathsense.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | other | silent: return in build_block; return in collect_leaders | usize | 256 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_DECODE_INSNS | other | silent: while condition in decode_all | usize | 4096 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_JOINS | other | silent: return in summarize_region | usize | 64 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_LOOPS | work | silent: for range in unroll_natural_loops | usize | 1 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_OUTPUT_REGISTERS | output | silent: return in finalize_summary | usize | 32 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_OUTPUT_STACK_CELLS | output | silent: return in finalize_summary | usize | 32 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_REGION_BLOCKS | other | silent: return in build_region; return in collect_leaders | usize | 64 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_REGION_INSNS | other | silent: return in build_region | usize | 2048 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_UNROLL | other | silent: break in rs_emit_range; continue in forward_join_lowering_candidates; continue in prove_one; 34 more | usize | 8 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_UNROLLED_BLOCKS | other | silent: return in unroll_one | usize | 512 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | VERIFY_ARITY_CAP | other | silent: return in densify | u32 | 12 | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_DIRECT_CALL_SWEEP_OFFSETS | other | silent: .min() clamp in add_linear_call_evidence; .min() clamp in sweep_direct_call_target_evidence; break in add_linear_call_evidence; 1 more | usize | 32 * 1024 * 1024 | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_DISCOVERY_FUNCTIONS | other | delegated: passed to unwind::visit_frame_ranges | usize | 1 << 18 | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_INTERIOR_PROLOGUE_PROVENANCE | other | silent: skipped in traverse_function | usize | MAX_DISCOVERY_FUNCTIONS | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_JUMP_TABLE_ENTRIES | count | silent: while condition in resolve_jump_table | usize | 1 << 12 | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_NORETURN_DECODED_INSTRUCTIONS | other | recorded: NoreturnCandidates::Exhausted; NoreturnFunctionOutcome::Exhausted | usize | 262_144 | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_NORETURN_ITERATIONS | work | silent: for range in noreturn_closure | usize | 64 | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_REL32_BACKWARD_DISTANCE | other | silent: return in direct_call_target | u64 | 1_u64 << 31 | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_REL32_FORWARD_DISTANCE | other | silent: return in direct_call_target | u64 | (1_u64 << 31) - 1 | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_BOUNDARY_PADDING_BYTES | size | silent: return in is_alignment_boundary | u64 | 64 | crates/disrobe-pass-native/src/disasm_ir.rs |
disrobe-pass-native | MAX_DECODE_TEXT_BYTES | size | error: .to_owned(); AuthenticodeVerdict::MalformedSignature; CompactUnwindError::Address; 21 more | usize | 32 * 1024 * 1024 | crates/disrobe-pass-native/src/disasm_ir.rs |
disrobe-pass-native | MAX_PAYLOAD_INSTRUCTIONS | other | error: .to_owned(); AuthenticodeVerdict::MalformedSignature; CompactUnwindError::Address; 21 more | usize | 4_000_000 | crates/disrobe-pass-native/src/disasm_ir.rs |
disrobe-pass-native | MAX_AARCH64_PLT_ENTRIES | count | silent: for range in collect_elf_plt_entries | usize | 1 << 16 | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_EXECUTABLE_RANGES | other | silent: break in new; return in new_pe64 | usize | 1 << 12 | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_PE_GUARD_CF_FUNCTIONS | other | silent: .min() clamp in decode_pe_arm64_guard_cf_functions | usize | 1 << 17 | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_PE_TLS_CALLBACKS | other | silent: for range in decode_pe_arm64_tls_callbacks | usize | 1 << 12 | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_POINTER_SLOTS | other | silent: break in collect_data_pointers; return in collect_initializer_tables | usize | 1 << 21 | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_SEEDS | other | silent: break in aarch64_boundary_prologue_seeds; break in aarch64_gap_boundary_prologue_seeds; return in aarch64_boundary_prologue_seeds; 3 more | usize | 1 << 17 | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_UNWIND_ENTRIES | count | error: CompactUnwindError::Index; CompactUnwindError::Limit | usize | 1 << 17 | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_RENDERED_TYPE_NAME_BYTES | output | error: Error::Dwarf (DR-NATIVE-0006) | usize | 64 * 1024 | crates/disrobe-pass-native/src/dwarf_sourcemap.rs |
disrobe-pass-native | MAX_RENDERED_TYPE_WORK_BYTES | work | error: Error::Dwarf (DR-NATIVE-0006) | usize | 16 * 1024 * 1024 | crates/disrobe-pass-native/src/dwarf_sourcemap.rs |
disrobe-pass-native | MAX_DYNAMIC_ENTRIES | count | silent: while condition in read_dynamic_entries | usize | 16 * 1024 | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_ELF_PROGRAM_HEADERS | other | silent: return in is_well_formed_elf_executable; return in validate_section_table | usize | 1_000_000 | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_GNU_HASH_BUCKETS | other | silent: return in gnu_hash_symbol_count | usize | 1 << 20 | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_NEEDED | other | silent: .min() clamp in read_pointer_array; continue in analyze | usize | 4096 | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_RELOCATIONS | other | silent: return in read_rel; return in read_rela | usize | 512 * 1024 | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_STRING_BYTES | size | silent: .min() clamp in read_interpreter; .min() clamp in resolve_dynstr | usize | 64 * 1024 | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_SYMBOLS | other | silent: .min() clamp in bounded_symbol_scan; .min() clamp in read_dynamic_symbols; return in gnu_hash_symbol_count; 2 more | usize | 256 * 1024 | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 4096 | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_BUFFERS_PER_CANDIDATE | other | silent: .take() in emulate_string_decoders_inner | usize | 24 | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_CANDIDATES | other | silent: .take() in emulate_string_decoders_inner | usize | 64 | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_DECODE_SPAN | other | silent: .min() clamp in emulate_string_decoders_inner | u64 | 64 * 1024 | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_HARVEST_PER_RUN | other | silent: break in merge_harvests; return in harvest_ascii; return in harvest_utf16; 3 more | usize | 512 | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_STRING_LEN | size | silent: return in insert_static_run; return in push_candidate; return in push_wide_candidate | usize | 4096 | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | PER_CANDIDATE_STEP_CAP | work | silent: break in run | u64 | 200_000 | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_ENTROPY_BITS | other | silent: .clamp() clamp in normalized_entropy | f64 | 8.0 | crates/disrobe-pass-native/src/entropy_viz.rs |
disrobe-pass-native | OVERLAY_SCAN_CAP | other | recorded: .record() | usize | 64 * 1024 | crates/disrobe-pass-native/src/fileid.rs |
disrobe-pass-native | LIBRARY_NAME_CAP | other | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 1024 | crates/disrobe-pass-native/src/flirt.rs |
disrobe-pass-native | MAX_DECOMPRESSED_BODY | other | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-native/src/flirt.rs |
disrobe-pass-native | MAX_PATTERN_LEN | size | error: Error::SignatureDb (DR-NATIVE-0019) | u8 | 64 | crates/disrobe-pass-native/src/flirt.rs |
disrobe-pass-native | MAX_TREE_DEPTH | recursion | error: Error::SignatureDb (DR-NATIVE-0019) | u32 | 256 | crates/disrobe-pass-native/src/flirt.rs |
disrobe-pass-native | SCAN_LIMIT | other | silent: slice in bytes_find | usize | 4 * 1024 * 1024 | crates/disrobe-pass-native/src/identify.rs |
disrobe-pass-native | NATIVE_MATCH_DEFAULT_LIMIT | other | unused: no use in the crate | usize | DEFAULT_LISTING_LIMIT | crates/disrobe-pass-native/src/native_match.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 16_384 | crates/disrobe-pass-native/src/packers/aspack_phase2.rs |
disrobe-pass-native | MAX_ASPACK_IMPORTS_PER_MODULE | other | recorded: flag overflowed | usize | 256 | crates/disrobe-pass-native/src/packers/aspack_phase2.rs |
disrobe-pass-native | MAX_ASPACK_IMPORT_DESCRIPTORS | other | silent: break in find_aspack_runtime_import_directory; return in find_aspack_runtime_import_directory; return in reconstruct_aspack_import_descriptors | usize | 64 | crates/disrobe-pass-native/src/packers/aspack_phase2.rs |
disrobe-pass-native | MAX_ASPACK_MODULE_NAME_LEN | size | silent: continue in collect_aspack_import_layouts; for range in read_guest_cstr; return in reconstruct_aspack_import_descriptors | usize | 260 | crates/disrobe-pass-native/src/packers/aspack_phase2.rs |
disrobe-pass-native | MAX_ASPACK_THUNK_CANDIDATES | other | silent: return in find_unique_thunk_tables | usize | 1 << 20 | crates/disrobe-pass-native/src/packers/aspack_phase2.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 65_536 | crates/disrobe-pass-native/src/packers/emulated_unpack.rs |
disrobe-pass-native | MAX_DECOMPRESSED_BYTES | size | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/kkrunchy_cca.rs |
disrobe-pass-native | OUTPUT_CAP | output | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/kkrunchy_k7_cm.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 16_384 | crates/disrobe-pass-native/src/packers/kkrunchy_phase2.rs |
disrobe-pass-native | MAX_DECODED_SIZE | size | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/kkrunchy_unpack.rs |
disrobe-pass-native | MAX_RECOVERED_BYTES | size | error: donut_module_error(); loader_error() | usize | 64 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/loader_generators.rs |
disrobe-pass-native | MAX_MEW_LEADING_CHUNKS | other | unclassified: stored in max_entries with no read found | usize | 64 | crates/disrobe-pass-native/src/packers/mew_unpack.rs |
disrobe-pass-native | MAX_DECOMPRESSED_BYTES | size | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/mpress_lzma.rs |
disrobe-pass-native | MAX_POS_BITS | other | silent: fallback value in decode_bit | usize | 4 | crates/disrobe-pass-native/src/packers/mpress_lzma.rs |
disrobe-pass-native | MAX_POS_STATES | other | silent: fallback value in decode_bit | usize | 1 << MAX_POS_BITS | crates/disrobe-pass-native/src/packers/mpress_lzma.rs |
disrobe-pass-native | MAX_IMAGE_BYTES | size | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/mpress_unpack.rs |
disrobe-pass-native | MAX_DECOMPRESSED_BYTES | size | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/nspack_unpack.rs |
disrobe-pass-native | MAX_IMPORTED_MODULES | other | silent: break in locate_import_record; while condition in locate_import_descriptors | usize | 96 | crates/disrobe-pass-native/src/packers/nspack_unpack.rs |
disrobe-pass-native | MAX_IMPORTS_PER_MODULE | other | silent: break in locate_import_record | usize | 4096 | crates/disrobe-pass-native/src/packers/nspack_unpack.rs |
disrobe-pass-native | MAX_MODULE_NAME_BYTES | size | silent: slice in module_name_is_plausible | usize | 96 | crates/disrobe-pass-native/src/packers/nspack_unpack.rs |
disrobe-pass-native | MAX_DEPTH | recursion | error: Error::LoaderRecovery (DR-NATIVE-0026); untyped format! | usize | 8 | crates/disrobe-pass-native/src/packers/pe_resource.rs |
disrobe-pass-native | MAX_DIRECTORIES | other | error: Error::LoaderRecovery (DR-NATIVE-0026); untyped format! | usize | 4096 | crates/disrobe-pass-native/src/packers/pe_resource.rs |
disrobe-pass-native | MAX_ENTRIES_PER_DIRECTORY | count | error: Error::LoaderRecovery (DR-NATIVE-0026); untyped format! | usize | 4096 | crates/disrobe-pass-native/src/packers/pe_resource.rs |
disrobe-pass-native | MAX_GAP_SEARCH_BYTES | size | silent: return in forced_leaf_placements | u32 | 1 << 22 | crates/disrobe-pass-native/src/packers/pe_resource.rs |
disrobe-pass-native | MAX_LEAVES | other | error: Error::LoaderRecovery (DR-NATIVE-0026); untyped format! | usize | 16384 | crates/disrobe-pass-native/src/packers/pe_resource.rs |
disrobe-pass-native | MAX_RECOVERED_IMAGE_BYTES | size | error: Error::LoaderRecovery (DR-NATIVE-0026); untyped format! | usize | 512 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/pe_resource.rs |
disrobe-pass-native | MAX_RESOURCE_DEPTH | recursion | silent: return in walk_resource_dir | u32 | 8 | crates/disrobe-pass-native/src/packers/pe_unbind.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 65_536 | crates/disrobe-pass-native/src/packers/pecompact_phase2.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 16_384 | crates/disrobe-pass-native/src/packers/petite_phase2.rs |
disrobe-pass-native | EMULATED_IMAGE_EXPANSION_LIMIT | other | recorded: flag int3_gauntlet_cleared | u64 | 4096 | crates/disrobe-pass-native/src/packers/section_recovery.rs |
disrobe-pass-native | MAX_BLOCKS | other | silent: return in decode_elf_extents_with_budget; return in walk_block_chain | usize | 1 << 16 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_BRUTE_FORCE_OFFSETS | other | silent: .min() clamp in decode_image_with_budget; .min() clamp in decode_multiblock_with_budget; .min() clamp in locate_structural | usize | 1 << 16 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_DECOMPRESSED | other | error: .clone(); .to_owned(); AddressError::RvaNotMapped; 69 more | usize | 256 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_DECOMPRESSION_ATTEMPTS | other | error: .clone(); .to_owned(); AddressError::RvaNotMapped; 69 more | usize | 4096 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_L_INFO_SCAN | other | silent: .min() clamp in elf_first_block_offset | usize | 64 * 1024 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_RESYNC_OFFSETS | other | silent: while condition in decode_elf_extents_with_budget | usize | 1 << 16 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_STRUCTURAL_CHECKSUM_BYTES | size | silent: return in reserve | usize | 64 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_TAIL_SCAN | other | error: Error::UpxDecode (DR-NATIVE-0022) | usize | 4096 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_TOTAL_DECOMPRESSED_OUTPUT | output | error: .clone(); .to_owned(); AddressError::RvaNotMapped; 69 more | usize | MAX_DECOMPRESSED * 2 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_VERIFY_CANDIDATES | other | silent: break in locate_structural | usize | 4096 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_VERIFY_EXPANSION | other | error: Error::UpxDecode (DR-NATIVE-0022) | u64 | 64 | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_CARVED_PROTECTED_BYTES | size | recorded: flag blob_truncated | usize | 64 * 1024 * 1024 | crates/disrobe-pass-native/src/packers/vmprotect_carve.rs |
disrobe-pass-native | MAX_CARVED_PROTECTED_SECTIONS | other | silent: .take() in carve_themida; .take() in carve_vmprotect | usize | 64 | crates/disrobe-pass-native/src/packers/vmprotect_carve.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 131_072 | crates/disrobe-pass-native/src/packers/yodas_crypter.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 65_536 | crates/disrobe-pass-native/src/packers/yodas_emulated_unpack.rs |
disrobe-pass-native | EMU_LAZY_PAGE_BUDGET | work | error: Error::GoblinParse (DR-NATIVE-0005) | u32 | 65_536 | crates/disrobe-pass-native/src/packers/yodas_protector_phase2.rs |
disrobe-pass-native | ADDRESS_SPACE_CAP | other | silent: return in flatten_address_space | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-native/src/pass.rs |
disrobe-pass-native | DEOBF_SECTION_CAP | other | silent: .min() clamp in executable_sections | usize | 4 * 1024 * 1024 | crates/disrobe-pass-native/src/pass.rs |
disrobe-pass-native | MAX_TYPE_RECORDS | count | error: Error::Pdb (DR-NATIVE-0007) | usize | 4_000_000 | crates/disrobe-pass-native/src/pdb_cxx/catalog.rs |
disrobe-pass-native | MAX_FIELDLIST_CHAIN | other | silent: for range in collect_fieldlist | usize | 256 | crates/disrobe-pass-native/src/pdb_cxx/emit.rs |
disrobe-pass-native | MAX_MODULES | other | silent: continue in recover_module_procedures | usize | 65_536 | crates/disrobe-pass-native/src/pdb_cxx/procedures.rs |
disrobe-pass-native | MAX_PARAMETERS | other | error: FunctionRejectReason::Malformed | usize | 4_096 | crates/disrobe-pass-native/src/pdb_cxx/procedures.rs |
disrobe-pass-native | MAX_PROCEDURES | other | silent: continue in recover_module_procedures | usize | 262_144 | crates/disrobe-pass-native/src/pdb_cxx/procedures.rs |
disrobe-pass-native | MAX_SYMBOLS_PER_MODULE | other | recorded: flag modules_truncated_at_symbol_bound | usize | 4_000_000 | crates/disrobe-pass-native/src/pdb_cxx/procedures.rs |
disrobe-pass-native | MAX_RECURSION_BUDGET | recursion | silent: return in resolve_spelling_bounded | u32 | 24 | crates/disrobe-pass-native/src/pdb_cxx/spelling.rs |
disrobe-pass-native | MAX_UNWRAP_DEPTH | recursion | silent: for range in resolve_spelling_bounded | u32 | 64 | crates/disrobe-pass-native/src/pdb_cxx/spelling.rs |
disrobe-pass-native | MAX_MACHO_IMPORT_NAME_BYTES | size | silent: return in resolve_macho_stub_imports | usize | 16 * 1024 * 1024 | crates/disrobe-pass-native/src/plt_resolve.rs |
disrobe-pass-native | MAX_MACHO_IMPORT_STUBS | other | silent: return in resolve_macho_stub_imports | usize | 65_536 | crates/disrobe-pass-native/src/plt_resolve.rs |
disrobe-pass-native | MAX_MACHO_SCANNED_NAME_BYTES | size | silent: return in resolve_macho_stub_imports; slice in resolve_macho_stub_imports | usize | 16 * 1024 * 1024 | crates/disrobe-pass-native/src/plt_resolve.rs |
disrobe-pass-native | MAX_MACHO_SYMBOL_NAME_BYTES | size | silent: slice in resolve_macho_stub_imports | usize | 4 * 1024 | crates/disrobe-pass-native/src/plt_resolve.rs |
disrobe-pass-native | AARCH64_STACK_FP_ALIAS_LIMIT | other | error: Error::LlvmIr (DR-NATIVE-0018) | usize | 64 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | ACYCLIC_JOIN_BLOCK_CAP | other | silent: return in acyclic_join_lowering_plan; return in join_plan_preserves_blocks | usize | 256 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | FORWARD_JOIN_PLAN_CAP | other | silent: return in forward_join_lowering_candidates | usize | 32 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | LOOP_EXIT_TAIL_ABSORPTION_BUDGET | work | silent: for range in absorb_private_exit_tails | usize | 64 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_LOCAL_NORETURN_BYTES | size | silent: return in local_noreturn_leaf_is_proven; return in outlined_noreturn_exit | usize | 1024 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_LOCAL_NORETURN_CALLEES | other | silent: continue in object_transfer_facts; skipped in object_transfer_facts | usize | 16 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_LOCAL_NORETURN_RELOCATIONS | other | silent: .take() in read; return in read | usize | 4096 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_OUTLINED_EXIT_SLOTS | other | silent: return in outlined_noreturn_exit | usize | 8 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_PROGRAM_FUNCTION_BYTES | size | delegated: passed to debug::dbg_line | usize | 64 * 1024 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | PURE_TAIL_CLONE_BUDGET | work | silent: for range in emit_cloned_pure_tail | usize | 8 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | RUST_RESUME_LABEL_CAP | other | silent: return in rs_forward_exit_labels; return in rs_resume_paths | usize | 32 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | RUST_RESUME_NODE_CAP | other | silent: return in rs_forward_exit_labels; return in rs_resume_paths | usize | 4096 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | TAIL_JOIN_WALK_BUDGET | work | silent: return in joins_every_non_tail_path | usize | 4096 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | TAIL_SPLIT_BLOCK_CAP | other | silent: return in closed_loop_body; return in render_cfg_blocks_via_cns; return in split_tail_regions | usize | 256 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | TAIL_SUBTREE_CAP | other | silent: return in private_tail_subtree | usize | 32 | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_FRAME_BYTES | size | error: reject_at() | i64 | 1 << 20 | crates/disrobe-pass-native/src/pseudo_c/aarch64.rs |
disrobe-pass-native | MAX_INSTRUCTIONS | other | error: reject() | usize | 4096 | crates/disrobe-pass-native/src/pseudo_c/aarch64.rs |
disrobe-pass-native | MAX_SWITCH_CASES | other | silent: return in readable_switch_table; return in recover_aarch64_switch | usize | 4096 | crates/disrobe-pass-native/src/pseudo_c/aarch64.rs |
disrobe-pass-native | MAX_SWITCH_SLICE_INSTRUCTIONS | other | silent: for range in matching_switch_guard; for range in single_block_definition; for range in single_block_pc_relative_definition; 1 more | usize | 16 | crates/disrobe-pass-native/src/pseudo_c/aarch64.rs |
disrobe-pass-native | MAX_SWITCH_TABLE_BYTES | size | silent: return in readable_switch_table | usize | MAX_SWITCH_CASES * 8 | crates/disrobe-pass-native/src/pseudo_c/aarch64.rs |
disrobe-pass-native | REGISTER_ARGUMENT_LIMIT | other | silent: for range in prove_arguments | usize | 8 | crates/disrobe-pass-native/src/pseudo_c/aarch64_callsite.rs |
disrobe-pass-native | MAX_FIXPOINT_STEPS | work | error: reject() | usize | 1 << 20 | crates/disrobe-pass-native/src/pseudo_c/aarch64_frame.rs |
disrobe-pass-native | MAX_CALLEE_BYTES | size | silent: return in clobbers | usize | 1 << 16 | crates/disrobe-pass-native/src/pseudo_c/call_clobber.rs |
disrobe-pass-native | MAX_CALLEE_FUNCTIONS | other | silent: return in clobbers | usize | 64 | crates/disrobe-pass-native/src/pseudo_c/call_clobber.rs |
disrobe-pass-native | MAX_AFFINE_SHIFT | other | silent: fallback value in remainder_register | u8 | 126 | crates/disrobe-pass-native/src/pseudo_c/idiom.rs |
disrobe-pass-native | MAX_DIVIDEND_BITS | other | silent: return in disjoint_or; return in divisor_reproduces_witness; return in quotient_ceiling; 2 more | u32 | 64 | crates/disrobe-pass-native/src/pseudo_c/idiom.rs |
disrobe-pass-native | MAX_BLOCKS | other | silent: return in specialize | usize | 256 | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_EXPR_NODES | count | silent: return in push_value | usize | 128 | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_FOLDS | other | silent: for range in specialize | usize | 16 | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_PROOFS | other | silent: ? on a checked operation in prove_one | usize | 64 | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_READ_STEPS | work | error: Error::LlvmIr (DR-NATIVE-0018) | usize | 16384 | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_STATEMENTS | other | silent: return in specialize | usize | 2048 | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_VALUES | other | silent: return in definitions | usize | 4 | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | PATH_BUDGET | work | error: untyped error | usize | 1 << 16 | crates/disrobe-pass-native/src/pseudo_c/return_channel.rs |
disrobe-pass-native | MAX_INLINED_DEFINITIONS | other | silent: for range in inline_single_use_definitions | usize | 128 | crates/disrobe-pass-native/src/pseudo_c/spill.rs |
disrobe-pass-native | MAX_LOOP_WEIGHT_DEPTH | recursion | delegated: passed to debug::dbg_line | u32 | 8 | crates/disrobe-pass-native/src/pseudo_c/spill.rs |
disrobe-pass-native | MAX_RECORDED_DECISIONS | other | silent: return in record | usize | 128 | crates/disrobe-pass-native/src/pseudo_c/spill.rs |
disrobe-pass-native | MAX_AUDITABLE_COMPRESSED_BYTES | size | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 4 * 1024 * 1024 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | MAX_AUDITABLE_DECOMPRESSED_BYTES | size | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 16 * 1024 * 1024 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | MAX_AUDITABLE_JSON_CONTAINER_ENTRIES | count | error: untyped format! | usize | 65_536 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | MAX_AUDITABLE_JSON_DEPTH | recursion | error: untyped format! | usize | 32 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | MAX_AUDITABLE_JSON_ESCAPED_STRING_BYTES | size | error: Error::SignatureDb (DR-NATIVE-0019) | usize | 64 * 1024 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | MAX_AUDITABLE_JSON_STRING_BYTES | size | error: untyped format! | usize | 9 * 1024 * 1024 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | MAX_AUDITABLE_JSON_WORK_ITEMS | work | error: untyped format! | usize | 1_048_576 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | MAX_AUDITABLE_PACKAGES | other | error: untyped format! | usize | 16_384 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | MAX_AUDITABLE_PACKAGE_TEXT_BYTES | size | error: untyped format! | usize | 8 * 1024 * 1024 | crates/disrobe-pass-native/src/rust_recovery.rs |
disrobe-pass-native | SCAN_LIMIT | other | silent: slice in analyze; slice in dotnet_bundle_finding; slice in pkr_ce1a_finding; 1 more | usize | 16 * 1024 * 1024 | crates/disrobe-pass-native/src/sig_engine.rs |
disrobe-pass-native | VERSION_TAIL_CAP | other | silent: slice in dotted_after; slice in literal_tail | usize | 64 | crates/disrobe-pass-native/src/sig_engine.rs |
disrobe-pass-native | ADRP_PAIR_SCAN_LIMIT | other | silent: for range in paired_low_bits | usize | 16 | crates/disrobe-pass-native/src/similarity.rs |
disrobe-pass-native | WIDE_MOVE_CHAIN_LIMIT | other | silent: while condition in fold_wide_move | usize | 3 | crates/disrobe-pass-native/src/similarity.rs |
disrobe-pass-native | WINDOW_INSTRUCTION_LIMIT | other | silent: while condition in window_start | usize | 64 | crates/disrobe-pass-native/src/similarity/opaque.rs |
disrobe-pass-native | MAX_GROUP_SPAN | other | silent: no action in reassemble_group | i64 | 1024 | crates/disrobe-pass-native/src/stack_string.rs |
disrobe-pass-native | MAX_SCAN_INSNS | other | silent: break in harvest_stack_stores | usize | 200_000 | crates/disrobe-pass-native/src/stack_string.rs |
disrobe-pass-native | MAX_RIP_REFS | other | silent: break in scan_rip_relative_refs | usize | 200_000 | crates/disrobe-pass-native/src/stream_disasm.rs |
disrobe-pass-native | MAX_MAP_BYTES | size | error: Error::GoblinParse (DR-NATIVE-0005); Error::SignatureDb (DR-NATIVE-0019); untyped format! | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-native/src/stub_emu/mem.rs |
disrobe-pass-native | MAX_MAP_PAGES | other | error: Error::GoblinParse (DR-NATIVE-0005) | u64 | MAX_MAP_BYTES / (PAGE_SIZE as u64) | crates/disrobe-pass-native/src/stub_emu/mem.rs |
disrobe-pass-native | MAX_WRITE_LOG_ENTRIES | count | recorded: flag write_log_truncated | usize | 1 << 19 | crates/disrobe-pass-native/src/stub_emu/mem.rs |
disrobe-pass-native | MAX_CHAIN_PAGES | other | silent: ? on a checked operation in apply_chains | usize | 65_536 | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_CHAIN_STEPS | work | silent: ? on a checked operation in apply_chains | usize | 65_536 | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_FIXUP_BYTES | size | silent: return in apply | usize | 1 << 20 | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_SECTIONS | other | silent: return in loaded_section_ranges; return in validate_loaded_sections | usize | 4096 | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_SEGMENTS | other | silent: return in apply_chains; return in apply | usize | 256 | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | STEP_CAP | work | error: EvalError::StepCapExceeded | u64 | 5_000_000 | crates/disrobe-pass-native/src/vm_devirt/eval.rs |
disrobe-pass-native | MAX_GUARDIAN_BYTECODE_BYTES | size | silent: .min() clamp in devirtualize_guardian_rs | usize | 1 << 20 | crates/disrobe-pass-native/src/vm_devirt/guardian.rs |
disrobe-pass-native | MAX_BYTECODE_INSNS | size | error: LiftError::TooLarge | usize | 1 << 20 | crates/disrobe-pass-native/src/vm_devirt/mod.rs |
disrobe-pass-native | MAX_HANDLERS | other | silent: return in read_pointer_table; return in recover_via_codescan; return in recover_via_exports; 1 more | usize | 4096 | crates/disrobe-pass-native/src/vm_devirt/mod.rs |
disrobe-pass-native | MAX_VM_REGS | other | error: EvalError::RegisterOutOfRange; EvalError::TooManyArgs | usize | 256 | crates/disrobe-pass-native/src/vm_devirt/mod.rs |
disrobe-pass-native | MAX_VM_STACK | other | error: EvalError::StackOverflow | usize | 4096 | crates/disrobe-pass-native/src/vm_devirt/mod.rs |
disrobe-pass-nativelang | MAX_BODY_CARVE_BYTES | size | recorded: BodySkip::CodeBudgetExhausted; skipped | u64 | 8 * 1024 * 1024 | crates/disrobe-pass-nativelang/src/bodies.rs |
disrobe-pass-nativelang | MAX_BODY_CODE_BYTES | size | recorded: skipped | u64 | 64 * 1024 | crates/disrobe-pass-nativelang/src/bodies.rs |
disrobe-pass-nativelang | MAX_BODY_FUNCTIONS | other | recorded: BodySkip::FunctionBudgetExhausted | usize | MAX_LISTED_FUNCTIONS | crates/disrobe-pass-nativelang/src/bodies.rs |
disrobe-pass-nativelang | MAX_EMITTED_NAME_CHARS | output | silent: .take() in emitted_identifier | usize | 120 | crates/disrobe-pass-nativelang/src/bodies.rs |
disrobe-pass-nativelang | MAX_GATE_TOKENS | other | recorded: flag truncated | usize | 1 << 20 | crates/disrobe-pass-nativelang/src/bodies.rs |
disrobe-pass-nativelang | MAX_RETAINED_SOURCE_BYTES | size | recorded: BodyStatus::RecoveredElided | u64 | 4 * 1024 * 1024 | crates/disrobe-pass-nativelang/src/bodies.rs |
disrobe-pass-nativelang | MAX_DEPTH | recursion | silent: fallback value in enter | usize | 256 | crates/disrobe-pass-nativelang/src/d_mangle.rs |
disrobe-pass-nativelang | MAX_OUTPUT | output | recorded: flag output_exhausted | usize | 1 << 16 | crates/disrobe-pass-nativelang/src/d_mangle.rs |
disrobe-pass-nativelang | MAX_STEPS | work | error: DDemangleError::StepBudget | usize | 200_000 | crates/disrobe-pass-nativelang/src/d_mangle.rs |
disrobe-pass-nativelang | MAX_NIM_DEPTH | recursion | silent: return in read_nim_type; return in split_itanium_params | usize | 256 | crates/disrobe-pass-nativelang/src/demangle.rs |
disrobe-pass-nativelang | MAX_NIM_GENERATED_SYMBOL_BYTES | size | silent: return in demangle_nim_generated_itanium | usize | 4_096 | crates/disrobe-pass-nativelang/src/demangle.rs |
disrobe-pass-nativelang | MAX_NIM_GENERATED_UID_DIGITS | other | silent: return in decode_nim_itanium_identifier | usize | 20 | crates/disrobe-pass-nativelang/src/demangle.rs |
disrobe-pass-nativelang | MAX_INSTRUCTIONS_PER_FUNCTION | other | recorded: flag truncated | usize | 8192 | crates/disrobe-pass-nativelang/src/disasm.rs |
disrobe-pass-nativelang | MAX_LISTED_FUNCTIONS | other | recorded: BodySkip::FunctionBudgetExhausted | usize | 4096 | crates/disrobe-pass-nativelang/src/disasm.rs |
disrobe-pass-nativelang | INITIAL_INFLATE_CAP | other | allocation: with_capacity in inflate_up_to | usize | 64 * 1024 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_ARRAY_DIMENSIONS | other | silent: while condition in array_dimensions | usize | 1 << 8 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_AGGREGATES | other | silent: break in walk_dwarf; skipped in collect_aggregates; skipped in push_aggregate | usize | 1 << 16 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_AGGREGATE_DEPTH | recursion | silent: skipped in collect_aggregates | usize | 1 << 8 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_AGGREGATE_ITEMS | count | silent: return in collect_aggregates; return in take_aggregate_item | usize | 1 << 16 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_DIE_VISITS | other | silent: break in walk_dwarf; return in collect_aggregates; return in visit_die | usize | 1 << 22 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_FUNCS | other | silent: break in walk_dwarf; return in collect_unit; skipped in push_function | usize | 1 << 18 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_FUNCTION_PARAMS | other | silent: return in collect_unit; return in take_function_param | usize | 1 << 16 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_REFERENCE_DEPTH | recursion | silent: continue in resolve_attr_queue; skipped in resolve_attr_queue | usize | 8 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_REFERENCE_VISITS | other | silent: return in enqueue_references; while condition in resolve_attr_queue | usize | 16 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_STRING_BYTES | size | recorded: flag string_limit_hit | usize | 1 << 26 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_STRING_LEN | size | recorded: flag string_limit_hit | usize | 1 << 14 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_TYPE_DEPTH | recursion | silent: return in resolve_type_name | u8 | 8 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_LINE_ROWS | other | silent: break in assign_line_ranges; break in fill_line_ranges | u64 | 1 << 24 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_TOTAL_DEBUG_BYTES | size | error: untyped format! | u64 | 2 << 30 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_UNCOMPRESSED | other | error: untyped format! | u64 | 1 << 30 | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_REPORTED_TYPES | other | silent: .take() in recover_types | usize | 1 << 16 | crates/disrobe-pass-nativelang/src/dwarf_types.rs |
disrobe-pass-nativelang | MAX_EH_FRAME_BYTES | size | silent: return in recover_eh_frame_functions | usize | 64 * 1024 * 1024 | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_EH_FRAME_FDES | other | silent: while condition in recover_eh_frame_functions | usize | 1 << 20 | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_FUNCTION_BYTES | size | recorded: skipped | u64 | 256 * 1024 | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_RECOVERED_FUNCTIONS | other | silent: break in recover_functions | usize | 1 << 18 | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_TRAVERSAL_TEXT | other | silent: return in run_traversal | usize | 16 * 1024 * 1024 | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_STRING_COUNT | count | silent: return in push_capped | usize | 1 << 20 | crates/disrobe-pass-nativelang/src/image.rs |
disrobe-pass-nativelang | MAX_STRING_SCAN_BYTES | size | recorded: flag truncated | usize | 64 * 1024 * 1024 | crates/disrobe-pass-nativelang/src/image.rs |
disrobe-pass-nativelang | MAX_TABLE_FUNCTION_STARTS | other | silent: .take() in parse; .take() in pe_unwind_table_starts; break in macho_function_starts | usize | 1 << 20 | crates/disrobe-pass-nativelang/src/image.rs |
disrobe-pass-nativelang | MAX_NIR_FUNCTIONS | other | silent: .take() in lift_native_nir | usize | 4096 | crates/disrobe-pass-nativelang/src/nir.rs |
disrobe-pass-nativelang | MAX_NIR_SYMBOLS | other | silent: .take() in lift_native_nir | usize | 8192 | crates/disrobe-pass-nativelang/src/nir.rs |
disrobe-pass-nativelang | MAX_D_RTTI_CANDIDATES | other | recorded: flag truncated | usize | 1 << 20 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_NAME_BYTES | size | recorded: flag truncated | usize | 16 * 1024 * 1024 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_NAME_LEN | size | silent: return in accept_d_rtti_name; return in demangle_d_struct_type; return in mapped_d_slice | usize | 64 * 1024 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_SCAN_BYTES | size | recorded: flag truncated | usize | 64 * 1024 * 1024 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_SECTIONS | other | recorded: TraversalRun::Incomplete; skipped; flag sections_truncated | usize | 96 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_SEGMENTS | other | silent: return in accept_d_rtti_name | usize | 64 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_SLICE_LEN | size | silent: return in mapped_d_slice | usize | 64 * 1024 * 1024 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_SYMBOLS | other | recorded: flag any; flag truncated | usize | 16 * 1024 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_VECTOR_LEN | size | silent: return in d_class_info_at; return in d_class_info_name_at | usize | 1 << 20 | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nuitka | MAX_CONTAINER_LEN | size | silent: return in walk_sequence; return in walk_value | u64 | 1 << 24 | crates/disrobe-pass-nuitka/src/blob_scan.rs |
disrobe-pass-nuitka | MAX_DEPTH | recursion | silent: return in walk_value | usize | 64 | crates/disrobe-pass-nuitka/src/blob_scan.rs |
disrobe-pass-nuitka | MAX_LEAF_BYTES | size | silent: .min() clamp in scan_constants_blob; ? on a checked operation in read_zero_terminated_bytes; break in scan_constants_blob; 1 more | usize | 1 << 20 | crates/disrobe-pass-nuitka/src/blob_scan.rs |
disrobe-pass-nuitka | MAX_LEAVES | other | silent: return in push_int; return in push_str | usize | 200_000 | crates/disrobe-pass-nuitka/src/blob_scan.rs |
disrobe-pass-nuitka | MAX_LIFT_DEPTH | recursion | silent: return in eval_atom; return in eval_value; return in lift_block | usize | 256 | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_PREPROCESSOR_NESTING | recursion | silent: return in parse_primary | usize | 256usize | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_TOP_LEVEL_ARGUMENTS | other | silent: return in split_top_args | usize | 4_096 | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_TOP_LEVEL_ARGUMENT_BYTES | size | silent: return in split_top_args | usize | 1_048_576 | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_VALUE_DIAMOND_DEPTH | recursion | silent: return in arm_value | usize | 64 | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_FIELD_LEN | size | silent: continue in decode_record | usize | 256 | crates/disrobe-pass-nuitka/src/buildinfo.rs |
disrobe-pass-nuitka | MAX_RECORD_LEN | size | silent: .min() clamp in scan_build_info | usize | 4096 | crates/disrobe-pass-nuitka/src/buildinfo.rs |
disrobe-pass-nuitka | MAX_MODULES | other | error: Error::ConstTooManyStreams (DR-NUITKA-0016) | usize | 1 << 20 | crates/disrobe-pass-nuitka/src/bytecode_table.rs |
disrobe-pass-nuitka | MAX_C_CALL_ARGUMENT_BYTES | size | silent: return in split_top_level_args_with_mask | usize | 1_048_576 | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_C_DIRECT_STATEMENT_BYTES | size | silent: return in direct_statement_suffix | usize | 1_048_576 | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_C_FUNCTION_PARAMETERS | other | error: Error::CSourceComplexityExceeded (DR-NUITKA-0027) | usize | 4_096 | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_C_MODULE_RECORDS | count | error: Error::CSourceComplexityExceeded (DR-NUITKA-0027) | usize | 65_536 | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_FACTORY_TOP_LEVEL_STATEMENTS | other | silent: return in factory_top_level_statements | usize | 4_096 | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_TEMPORARY_CONST_ASSIGNMENTS | other | error: Error::CSourceComplexityExceeded (DR-NUITKA-0027) | usize | 65_536 | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_TEMPORARY_CONST_SCOPES | other | error: Error::CSourceComplexityExceeded (DR-NUITKA-0027) | usize | 65_536 | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_TEMPORARY_CONST_SCOPE_SEGMENTS | other | error: Error::CSourceComplexityExceeded (DR-NUITKA-0027) | usize | 131_072 | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MANIFEST_ENTRY_EXTRACT_CAP | other | silent: fallback value in render_manifest_light | usize | 64 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/chain_detector.rs |
disrobe-pass-nuitka | MAX_ONEFILE_MAIN_DECOMPILE_BYTES | size | silent: skipped in extract_children | usize | 1024 * 1024 | crates/disrobe-pass-nuitka/src/chain_detector.rs |
disrobe-pass-nuitka | MAX_CHUNK_BYTES | size | silent: return in plausible_table_header; return in try_chunk_with_layout | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_CHUNK_COUNT | count | silent: return in big_int; return in plausible_table_header; return in sequence; 2 more | u64 | 200_000 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_DEPTH | recursion | silent: return in value | usize | 200 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_NAME_LEN | size | silent: return in plausible_table_header; return in try_chunk_with_layout; slice in plausible_table_header; 1 more | usize | 200 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_PREVIOUS_CLONE_WEIGHT | other | silent: return in value_body | usize | 128 * 1024 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_STORED_LAST_WEIGHT | other | silent: fallback value in value | usize | 4096 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_TABLE_HEADER_HINTS | other | silent: while condition in table_header_hints | usize | 64 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_VALUE_BYTES | size | silent: return in bounded_len | usize | 64 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_WIDE_SCAN_BYTES | size | recorded: ConstantsUnparsedReason::WideScanSkipped | usize | 256 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_CONSTANT_MANIFEST_BYTES | size | error: Error::ArtifactTooLarge (DR-NUITKA-0026); Error::InputTooLarge (DR-NUITKA-0032) | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/const_manifest.rs |
disrobe-pass-nuitka | MAX_CONSTANT_MANIFEST_ENTRIES | count | error: Error::ConstManifestTooManyEntries (DR-NUITKA-0030); untyped format! | usize | 4_096 | crates/disrobe-pass-nuitka/src/const_manifest.rs |
disrobe-pass-nuitka | MAX_CONSTANT_MANIFEST_MEMBERS | count | error: Error::ConstManifestTooManyEntries (DR-NUITKA-0030); untyped format! | usize | MAX_CONSTANT_MANIFEST_ENTRIES + 1usize | crates/disrobe-pass-nuitka/src/const_manifest.rs |
disrobe-pass-nuitka | MAX_BUILD_CONST_BYTES | size | error: Error::ArtifactTooLarge (DR-NUITKA-0026); Error::BuildConstantsTooLarge (DR-NUITKA-0029); Error::InputTooLarge (DR-NUITKA-0032) | u64 | 1024 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/constants.rs |
disrobe-pass-nuitka | MAX_BUILD_CONST_FILES | count | error: Error::TooManyConstFiles (DR-NUITKA-0028); Error::TooManyConstantInputs (DR-NUITKA-0033) | usize | 4_096 | crates/disrobe-pass-nuitka/src/constants.rs |
disrobe-pass-nuitka | MAX_CONSTANT_LABEL_BYTES | size | error: Error::InputTooLarge (DR-NUITKA-0032) | usize | 4_096 | crates/disrobe-pass-nuitka/src/constants.rs |
disrobe-pass-nuitka | MAX_CONST_FILE_BYTES | size | error: Error::ArtifactTooLarge (DR-NUITKA-0026); Error::InputTooLarge (DR-NUITKA-0032) | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/constants.rs |
disrobe-pass-nuitka | MAX_STREAMS_PER_FILE | other | error: Error::ConstTooManyStreams (DR-NUITKA-0016) | usize | 1_000_000 | crates/disrobe-pass-nuitka/src/constants.rs |
disrobe-pass-nuitka | MAX_BOUNDED_READ_PREALLOC_BYTES | size | allocation: with_capacity in read_file_bounded | usize | 1024 * 1024 | crates/disrobe-pass-nuitka/src/decompile.rs |
disrobe-pass-nuitka | MAX_BUILD_DIRECTORY_ENTRIES | count | error: Error::TooManyDirectoryEntries (DR-NUITKA-0031) | usize | 65_536 | crates/disrobe-pass-nuitka/src/decompile.rs |
disrobe-pass-nuitka | MAX_SIBLING_BINARY_BYTES | size | silent: .take() in read_file_bounded; return in read_file_bounded | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/decompile.rs |
disrobe-pass-nuitka | MAX_PYTHON_ABI_MINOR | other | silent: for range in find_python_runtime_name; for range in find_python_version_marker | u8 | 20 | crates/disrobe-pass-nuitka/src/detect.rs |
disrobe-pass-nuitka | MAX_FROZEN_MODULES | other | silent: while condition in recover_frozen_bytecode | usize | 1 << 16 | crates/disrobe-pass-nuitka/src/frozen.rs |
disrobe-pass-nuitka | MAX_MARSHAL_BYTES | size | silent: slice in load_code | usize | 32 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/frozen.rs |
disrobe-pass-nuitka | MAX_BINARY_INPUT_BYTES | size | error: Error::ArtifactTooLarge (DR-NUITKA-0026); Error::InputTooLarge (DR-NUITKA-0032) | u64 | 1024 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/limits.rs |
disrobe-pass-nuitka | MAX_C_SOURCE_BYTES | size | error: Error::CSourceTooLarge (DR-NUITKA-0023) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/limits.rs |
disrobe-pass-nuitka | MAX_C_SOURCE_LINES | other | error: Error::CSourceComplexityExceeded (DR-NUITKA-0027) | usize | 1_000_000 | crates/disrobe-pass-nuitka/src/limits.rs |
disrobe-pass-nuitka | MAX_ENTRIES | count | silent: break in map_names | usize | 100_000 | crates/disrobe-pass-nuitka/src/name_map.rs |
disrobe-pass-nuitka | MAX_NAMES | other | silent: .take() in map_names | usize | 50_000 | crates/disrobe-pass-nuitka/src/name_map.rs |
disrobe-pass-nuitka | MAX_NAME_LEN | size | silent: continue in map_names; return in map_names; slice in read_c_string | usize | 200 | crates/disrobe-pass-nuitka/src/name_map.rs |
disrobe-pass-nuitka | MAX_NAME_MAP_TEXT_BYTES | size | silent: for range in map_names | usize | 96 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/name_map.rs |
disrobe-pass-nuitka | MAX_API_CALLS | other | silent: break in collect_api_calls | usize | 64 | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | MAX_ENUMERATION_INSNS | other | recorded: flag exhausted | usize | 4_000_000 | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | MAX_FUNCTIONS | other | silent: .min() clamp in parse_pdata; break in locate_impls; skipped in collect_ctor_sites | usize | 20_000 | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | MAX_IMPL_INSNS | other | silent: while condition in decode_function | usize | 20_000 | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | MAX_TEXT_BYTES | size | silent: .min() clamp in parse_pe | usize | 64 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | MAX_DECOMPRESSED_ABS | other | error: Error::Zstd (DR-NUITKA-0005); untyped format! | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/onefile.rs |
disrobe-pass-nuitka | MAX_DECOMPRESSION_RATIO | other | error: Error::Zstd (DR-NUITKA-0005); untyped format! | u64 | 1024 | crates/disrobe-pass-nuitka/src/onefile.rs |
disrobe-pass-nuitka | MAX_ENTRY_COUNT | count | error: Error::EntryTruncated (DR-NUITKA-0006) | usize | 1 << 20 | crates/disrobe-pass-nuitka/src/onefile.rs |
disrobe-pass-nuitka | MAX_ENTRY_SIZE | size | error: Error::EntryTruncated (DR-NUITKA-0006) | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/onefile.rs |
disrobe-pass-nuitka | MAX_EXTRACTED_DATA_BYTES | size | error: Error::InputTooLarge (DR-NUITKA-0032) | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-nuitka/src/onefile.rs |
disrobe-pass-nuitka | MAX_FILENAME_BYTES | size | error: Error::EntryTruncated (DR-NUITKA-0006) | usize | 4096 | crates/disrobe-pass-nuitka/src/onefile.rs |
disrobe-pass-nuitka | GLOBAL_CANDIDATE_LOG_CAP | other | silent: skipped in locate_onefile_payload | u32 | 16 | crates/disrobe-pass-nuitka/src/onefile_locator.rs |
disrobe-pass-nuitka | MAX_ANNOTATION_EXPRESSION_BYTES | size | silent: return in is_safe_annotation_expression | usize | 8_192usize | crates/disrobe-pass-nuitka/src/surface.rs |
disrobe-pass-nuitka | MAX_ANNOTATION_NESTING | recursion | silent: return in enter_nesting | usize | 64usize | crates/disrobe-pass-nuitka/src/surface.rs |
disrobe-pass-nuitka | MAX_STATIC_PICKLE_DEPTH | recursion | silent: return in contains_nonfinite_float; return in is_static_pickle_hashable; return in is_static_pickle_value; 1 more | usize | 256 | crates/disrobe-pass-nuitka/src/surface.rs |
disrobe-pass-php | MAX_PARSE_DEPTH | recursion | silent: return in parse_destructure_targets | u32 | 128 | crates/disrobe-pass-php/src/decode_loop.rs |
disrobe-pass-php | MAX_STATEMENTS | other | silent: return in parse_block_body; return in parse_destructure_targets; return in parse_program | usize | 4096 | crates/disrobe-pass-php/src/decode_loop.rs |
disrobe-pass-php | MAX_PREALLOC | other | allocation: with_capacity in fold_rope; with_capacity in parse_literals; with_capacity in parse_one; 5 more | usize | 1 << 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | MAX_UNRECOVERED_RECORDS | count | silent: break in emit_body; skipped in limit; skipped in record_opaque_literals; 2 more | usize | 4096 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | REASON_ROPE_BUDGET | work | error: Error::ContainerBadFraming (DR-PHP-0100); Error::OpcacheLayout (DR-PHP-0125); untyped error | &str | "the rope exceeds the bounded php 8 rope folding budget" | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CALL_ARGUMENT_CAP | other | recorded: .refuse() | usize | 1 << 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CALL_RENDER_CAP | output | recorded: .refuse() | usize | 1 << 20 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CATCH_CLAUSE_CAP | other | silent: return in catch_region_end; return in lift_catch_arms | usize | 256 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CATCH_TYPE_CAP | other | silent: return in catch_clause | usize | 256 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CHILD_CAP | other | error: Error::OpArrayFieldOversize (DR-PHP-0093) | u32 | 1 << 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CLOSURE_USE_CAP | other | silent: return in fold_closure | usize | 256 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CONDITION_RENDER_CAP | output | silent: return in fold_test_graph | usize | 1 << 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_FOR_STEP_CAP | work | silent: return in for_step_start | usize | 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_IF_TEST_CHAIN_CAP | other | silent: while condition in if_test_chain | usize | 256 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LIST_ELEMENT_CAP | other | silent: return in list_entries | usize | 1 << 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LIST_RENDER_CAP | output | silent: return in fold_list_assign; return in list_entries; return in push_list_text | usize | 1 << 20 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LITERAL_CAP | work | error: Error::OpArrayFieldOversize (DR-PHP-0093) | u32 | 4_000_000 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LOOP_EXIT_FREE_CAP | other | silent: return in exit_frees_match | u32 | SANE_LIFT_DEPTH | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LOOP_RELIFT_WORK_CAP | work | silent: ? on a checked operation in loop_relift_charge | usize | 1 << 20 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_NAME_CAP | other | error: Error::OpArrayFieldOversize (DR-PHP-0093) | u32 | 1 << 20 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_OP_CAP | other | error: Error::OpArrayFieldOversize (DR-PHP-0093) | u32 | 4_000_000 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_ROPE_WORK_CAP | work | recorded: .refuse() | usize | 1 << 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_SWITCH_ARM_CAP | other | error: Error::OpArrayFieldOversize (DR-PHP-0093) | usize | 1 << 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_SWITCH_LABEL_WORK_CAP | work | error: Error::OpArrayFieldOversize (DR-PHP-0093) | usize | 1 << 20 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_SWITCH_STATE_WORK_CAP | work | silent: return in structure_linear_match; return in structure_switch_dispatch | usize | 1 << 20 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_TRY_CATCH_CAP | other | error: Error::OpArrayFieldOversize (DR-PHP-0093) | u32 | 1 << 16 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_VAR_CAP | other | error: Error::OpArrayFieldOversize (DR-PHP-0093) | u32 | 1 << 20 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | USE_SCAN_BUDGET | work | silent: break in read_after_jump; return in free_unconsumed; return in structure_switch_dispatch | usize | 256 | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | MAX_LABEL_ATTRIBUTIONS_PER_ITEM | other | error: Error::Deflatten (DR-PHP-0110) | usize | 64 | crates/disrobe-pass-php/src/deflatten.rs |
disrobe-pass-php | MAX_LINEARIZE_DEPTH | recursion | silent: return in try_emit_braced | usize | 256 | crates/disrobe-pass-php/src/deflatten.rs |
disrobe-pass-php | MAX_LINEARIZE_STEPS | work | error: Error::Deflatten (DR-PHP-0110) | usize | 1 << 20 | crates/disrobe-pass-php/src/deflatten.rs |
disrobe-pass-php | MIN_LABEL_ATTRIBUTION_BUDGET | work | error: Error::Deflatten (DR-PHP-0110) | usize | 4096 | crates/disrobe-pass-php/src/deflatten.rs |
disrobe-pass-php | CONTAINER_INFLATE_OUTPUT_CAP | output | error: Error::ContainerInflateBomb (DR-PHP-0102) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-php/src/encoder/container.rs |
disrobe-pass-php | ZEND_OPTIMIZER_OBF_KEY_CAP | other | silent: return in read_zend_optimizer_key | usize | 4096 | crates/disrobe-pass-php/src/encoder/container.rs |
disrobe-pass-php | ZEND_OBFUSCATION_KEY_CAP | other | silent: return in recover_zend_optimizer_obfuscation_key | usize | 4096 | crates/disrobe-pass-php/src/key_extractor.rs |
disrobe-pass-php | EXPR_INFLATE_CAP | other | error: Error::StrReplaceExpansion (DR-PHP-0036) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | EXPR_INITIAL_CAP | other | allocation: with_capacity in inflate_bounded | usize | 64 * 1024 | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | MAX_OPAQUE_STATEMENT | other | silent: skipped in parse_statements | usize | 1 << 20 | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | MAX_PARSE_DEPTH | recursion | silent: return in parse_expr; return in parse_var_ref | usize | 256 | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | STR_REPEAT_OUTPUT_CAP | output | silent: return in str_repeat | usize | 256 * 1024 * 1024 | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | STR_REPLACE_OUTPUT_CAP | output | error: Error::StrReplaceExpansion (DR-PHP-0036) | usize | EXPR_INFLATE_CAP | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | MAX_ARGS | other | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 16 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_CLASS_NAMES | other | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 12 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_COPIED_BYTES | size | error: Error::OpcacheOversize (DR-PHP-0124) | usize | 1 << 28 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_DEPTH | recursion | error: Error::OpcacheNestTooDeep (DR-PHP-0126) | u32 | 64 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_DYNAMIC_DEFS | other | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 16 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_HASH_ELEMENTS | other | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 20 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_LITERALS | work | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 20 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_OPS | work | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 20 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_OP_ARRAYS | other | error: Error::OpcacheOversize (DR-PHP-0124) | usize | 1 << 16 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_TEMPORARIES | other | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 20 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_TRY_CATCH | other | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 16 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_TYPE_LIST | other | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 8 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_VALUE_NODES | count | error: Error::OpcacheOversize (DR-PHP-0124) | usize | 1 << 22 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | MAX_VARS | other | error: Error::OpcacheOversize (DR-PHP-0124) | u32 | 1 << 16 | crates/disrobe-pass-php/src/opcache.rs |
disrobe-pass-php | EVAL_CHAIN_INFLATE_OUTPUT_CAP | output | error: Error::GzInflateBomb (DR-PHP-0035); Error::StrReplaceExpansion (DR-PHP-0036) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-php/src/peel.rs |
disrobe-pass-php | EVAL_PROBE_MIN_BUDGET | work | silent: ? on a checked operation in next_eval_call_arg | usize | 64 * 1024 | crates/disrobe-pass-php/src/peel.rs |
disrobe-pass-php | INFLATE_INITIAL_CAP | other | allocation: with_capacity in inflate_bounded | usize | 64 * 1024 | crates/disrobe-pass-php/src/peel.rs |
disrobe-pass-php | RESOLVE_DEPTH_CAP | recursion | silent: return in classify_inner_at_depth; return in resolve_arg | u32 | 32 | crates/disrobe-pass-php/src/peel.rs |
disrobe-pass-php | STR_REPLACE_OUTPUT_CAP | output | error: Error::StrReplaceExpansion (DR-PHP-0036) | usize | EVAL_CHAIN_INFLATE_OUTPUT_CAP | crates/disrobe-pass-php/src/peel.rs |
disrobe-pass-php | PHAR_ALIAS_CAP | other | error: Error::PharAliasOversize (DR-PHP-0024) | u32 | 1 << 14 | crates/disrobe-pass-php/src/phar.rs |
disrobe-pass-php | PHAR_DECOMPRESS_CAP | other | error: Error::PharArchiveQuotaExceeded (DR-PHP-0037); Error::PharDeclaredSizeImplausible (DR-PHP-0029) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-php/src/phar.rs |
disrobe-pass-php | PHAR_DECOMPRESS_INITIAL_CAP | other | allocation: with_capacity in try_bounded | usize | 64 * 1024 | crates/disrobe-pass-php/src/phar.rs |
disrobe-pass-php | PHAR_ENTRY_NAME_CAP | other | error: Error::PharManifestTruncated (DR-PHP-0022) | u32 | 1 << 12 | crates/disrobe-pass-php/src/phar.rs |
disrobe-pass-php | PHAR_MANIFEST_ENTRY_CAP | other | error: Error::PharManifestTooLarge (DR-PHP-0023) | u32 | 1 << 20 | crates/disrobe-pass-php/src/phar.rs |
disrobe-pass-php | PHAR_META_CAP | other | error: Error::PharManifestTruncated (DR-PHP-0022) | u32 | 1 << 22 | crates/disrobe-pass-php/src/phar.rs |
disrobe-pass-php | PHAR_PAYLOAD_CAP | other | error: Error::PharEntryPayloadTruncated (DR-PHP-0025) | u32 | 1 << 30 | crates/disrobe-pass-php/src/phar.rs |
disrobe-pass-php | MAX_RESTRUCTURE_DEPTH | recursion | silent: return in emit_units; return in structure_region; fallback value in emit_unit | usize | 256 | crates/disrobe-pass-php/src/restructure.rs |
disrobe-pass-php | MAX_TOKEN_COUNT | count | error: Error::TokenCountExceeded (DR-PHP-0012) | usize | 1_000_000 | crates/disrobe-pass-php/src/token.rs |
disrobe-pass-pickle | MAX_RENDER_DEPTH | recursion | silent: return in inline_unused_refs; return in render | u32 | 2_048 | crates/disrobe-pass-pickle/src/decompile.rs |
disrobe-pass-pickle | LONG_BODY_BUDGET | work | error: Error::LongBudget (DR-PICKLE-0024) | usize | 1 << 18 | crates/disrobe-pass-pickle/src/disasm.rs |
disrobe-pass-pickle | MAX_LONG_BODY | other | error: Error::LongTooLong (DR-PICKLE-0023) | usize | 4_096 | crates/disrobe-pass-pickle/src/disasm.rs |
disrobe-pass-pickle | MAX_STACKED_STREAMS | other | silent: break in disassemble_streams; no action in analyze_streams; no action in run | usize | 4_096 | crates/disrobe-pass-pickle/src/disasm.rs |
disrobe-pass-pickle | OPCODE_BUDGET | work | error: Error::OpcodeBudget (DR-PICKLE-0012) | usize | 5_000_000 | crates/disrobe-pass-pickle/src/disasm.rs |
disrobe-pass-pickle | ANCHOR_OPCODE_BUDGET | work | silent: .min() clamp in scan_for_embedded_with_work | usize | 1 << 16 | crates/disrobe-pass-pickle/src/ml.rs |
disrobe-pass-pickle | MAX_ZIP_COMMENT | other | recorded: notes | usize | 0xFFFF | crates/disrobe-pass-pickle/src/polyglot.rs |
disrobe-pass-pickle | MAX_CYCLE_TARGETS | other | recorded: flag reexecutable | usize | 4_096 | crates/disrobe-pass-pickle/src/reconstruct.rs |
disrobe-pass-pickle | MAX_NESTED_PICKLE_BYTES | recursion | silent: return in analyze_nested_pickle | usize | 1_048_576 | crates/disrobe-pass-pickle/src/safety.rs |
disrobe-pass-pickle | MAX_NESTED_PICKLE_DEPTH | recursion | silent: return in analyze_nested_pickle | usize | 3 | crates/disrobe-pass-pickle/src/safety.rs |
disrobe-pass-pickle | MAX_SCAN_DEPTH | recursion | silent: return in scan_nested_pickles; return in scan_value | usize | 2_048 | crates/disrobe-pass-pickle/src/safety.rs |
disrobe-pass-pickle | MAX_VALUE_DEPTH | recursion | error: Error::ValueDepth (DR-PICKLE-0018) | u32 | 1_000 | crates/disrobe-pass-pickle/src/vm.rs |
disrobe-pass-pickle | NODE_BUDGET | work | error: Error::NodeBudget (DR-PICKLE-0017) | u64 | 8_000_000 | crates/disrobe-pass-pickle/src/vm.rs |
disrobe-pass-pickle | RECURSION_LIMIT | recursion | error: Error::RecursionLimit (DR-PICKLE-0011) | usize | 2_000 | crates/disrobe-pass-pickle/src/vm.rs |
disrobe-pass-py-decompile | MAX_SLOT_INDEX | other | error: DecompileError::Emit | u32 | 1 << 16 | crates/disrobe-pass-py-decompile/src/alt_lift/mpy.rs |
disrobe-pass-py-decompile | MAX_PATTERN_NEST_DEPTH | recursion | silent: return in classify_mapping_pattern; return in classify_sequence_pattern | usize | 256 | crates/disrobe-pass-py-decompile/src/ast/builder/branches.rs |
disrobe-pass-py-decompile | MAX_IMPORT_LEVEL | other | silent: continue in build_linear_stmts_sim_seed; fallback value in bounded_import_level | u32 | 32 | crates/disrobe-pass-py-decompile/src/ast/builder/exprs.rs |
disrobe-pass-py-decompile | MAX_LAMBDA_BRANCH_DEPTH | recursion | silent: return in returned_expr | usize | 64 | crates/disrobe-pass-py-decompile/src/ast/builder/function_meta.rs |
disrobe-pass-py-decompile | LOOP_HEADER_PREFIX_LIMIT | other | error: DecompileError::AstDesync; DecompileError::BlockOutOfRange; DecompileError::MalformedExceptionTable | usize | 4 | crates/disrobe-pass-py-decompile/src/ast/builder/loops.rs |
disrobe-pass-py-decompile | CODEOBJ_DEPTH_LIMIT | recursion | error: DecompileError::StructuringDepthExceeded | usize | 200 | crates/disrobe-pass-py-decompile/src/ast/builder/mod.rs |
disrobe-pass-py-decompile | EXIT_PROBE_STEP_BUDGET | work | error: DecompileError::StructuringBudgetExceeded; exit_probe_budget_error() | usize | 1 << 22 | crates/disrobe-pass-py-decompile/src/ast/builder/mod.rs |
disrobe-pass-py-decompile | MAX_SYNTH_OPERANDS | other | silent: .min() clamp in pop_n; for range in build_linear_stmts_sim_seed | usize | 1 << 16 | crates/disrobe-pass-py-decompile/src/ast/builder/mod.rs |
disrobe-pass-py-decompile | STRUCTURE_DEPTH_LIMIT | recursion | error: DecompileError::StructuringDepthExceeded | usize | 600 | crates/disrobe-pass-py-decompile/src/ast/builder/mod.rs |
disrobe-pass-py-decompile | STRUCTURE_REENTRY_LIMIT | other | silent: return in enter_active_region | usize | 4 | crates/disrobe-pass-py-decompile/src/ast/builder/mod.rs |
disrobe-pass-py-decompile | MAX_EMIT_DEPTH | recursion | delegated: passed to drop | usize | 256 | crates/disrobe-pass-py-decompile/src/codegen/expr.rs |
disrobe-pass-py-decompile | MAX_SCANNED_LITERAL_BYTES | work | silent: .min() clamp in collect_byte_tokens | usize | 1 << 20 | crates/disrobe-pass-py-decompile/src/emit/marker_guard.rs |
disrobe-pass-py-decompile | MAX_SCANNED_STRINGS | other | silent: return in collect_code; return in collect_object | usize | 1 << 16 | crates/disrobe-pass-py-decompile/src/emit/marker_guard.rs |
disrobe-pass-py-decompile | MAX_SCAN_DEPTH | recursion | silent: return in collect_code; return in collect_object | usize | 64 | crates/disrobe-pass-py-decompile/src/emit/marker_guard.rs |
disrobe-pass-py-decompile | MAX_FRAME_NEST_DEPTH | recursion | silent: no action in attach_into | usize | 256 | crates/disrobe-pass-py-decompile/src/frame_tree/builder.rs |
disrobe-pass-py-decompile | MAX_PROBE_CAPTURE | other | delegated: capture_command()? | usize | 1024 * 1024 | crates/disrobe-pass-py-decompile/src/recompile.rs |
disrobe-pass-py-decompile | MAX_CANDIDATES | other | silent: .take() in accept_reordering_core | usize | 48 | crates/disrobe-pass-py-decompile/src/selfcheck/opcontent.rs |
disrobe-pass-py-decompile | MAX_DEPTH | recursion | silent: return in lower_seq; return in lower_try | u32 | 96 | crates/disrobe-pass-py-decompile/src/selfcheck/relower.rs |
disrobe-pass-py-decompile | MAX_HOIST_CANDIDATES | other | silent: .take() in repair_else_tail | usize | 64 | crates/disrobe-pass-py-decompile/src/selfcheck/repair.rs |
disrobe-pass-py-deob | MAX_FSTRING_OUTPUT | output | error: EvalError::Overflow | usize | 1 << 20 | crates/disrobe-pass-py-deob/src/ast_eval/eval.rs |
disrobe-pass-py-deob | MAX_REPEAT_ITEMS | count | error: EvalError::Overflow | usize | 8192 | crates/disrobe-pass-py-deob/src/ast_eval/eval.rs |
disrobe-pass-py-deob | MAX_SPLIT | other | error: EvalError::IndexOutOfRange; EvalError::Overflow; EvalError::TypeMismatch; 1 more | i128 | 65_536 | crates/disrobe-pass-py-deob/src/ast_eval/methods.rs |
disrobe-pass-py-deob | MAX_OUTPUT | output | error: EvalError::Overflow | usize | 1 << 20 | crates/disrobe-pass-py-deob/src/ast_eval/pyformat.rs |
disrobe-pass-py-deob | MAX_WIDTH | other | error: EvalError::Overflow | usize | 4096 | crates/disrobe-pass-py-deob/src/ast_eval/pyformat.rs |
disrobe-pass-py-deob | MAX_KEY_CANDIDATES | other | silent: .truncate() in dedup_and_rank | usize | 64 | crates/disrobe-pass-py-deob/src/cipher.rs |
disrobe-pass-py-deob | MAX_REPEATING_KEYLEN | size | silent: for range in best_keylengths | usize | 40 | crates/disrobe-pass-py-deob/src/cipher.rs |
disrobe-pass-py-deob | MAX_FOLDED_LEN | size | silent: return in fold_binop | usize | 1 << 20 | crates/disrobe-pass-py-deob/src/constant_fold.rs |
disrobe-pass-py-deob | MAX_PASSES | other | silent: for range in fold | usize | 16 | crates/disrobe-pass-py-deob/src/constant_fold.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | recursion | silent: return in collect_code_objects | usize | 32 | crates/disrobe-pass-py-deob/src/hyperion_v2v3.rs |
disrobe-pass-py-deob | MAX_XOR_KEY_LEN | size | error: Error::XorKey (DR-PYDEOB-0011) | usize | 4 * 1024 | crates/disrobe-pass-py-deob/src/hyperion_v2v3.rs |
disrobe-pass-py-deob | MAX_CHAIN_DEPTH | recursion | silent: for range in peel_to_marshal_blob | usize | 16 | crates/disrobe-pass-py-deob/src/marshal.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | recursion | silent: return in collect_nested_blobs; no action in decompile_code | usize | 64 | crates/disrobe-pass-py-deob/src/marshal.rs |
disrobe-pass-py-deob | MAX_CODEPOINT | other | silent: return in apply_shift; return in stage1_codepoints | u32 | 0x0010_FFFF | crates/disrobe-pass-py-deob/src/obfuscators/de4py_family.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | recursion | silent: return in walk | usize | 32 | crates/disrobe-pass-py-deob/src/obfuscators/obfuxtreme.rs |
disrobe-pass-py-deob | MAX_LIFT_DEPTH | recursion | error: LiftError | usize | 64 | crates/disrobe-pass-py-deob/src/obfuscators/patchwork/abyss/lift.rs |
disrobe-pass-py-deob | MAX_STORE_TARGET_NESTING | recursion | error: LiftError | usize | 64 | crates/disrobe-pass-py-deob/src/obfuscators/patchwork/abyss/lift.rs |
disrobe-pass-py-deob | MAX_REINSERT_DEPTH | recursion | error: Error::Marshal (DR-PYDEOB-0010) | usize | 64 | crates/disrobe-pass-py-deob/src/obfuscators/patchwork/reinsert.rs |
disrobe-pass-py-deob | MAX_LOADER_BYTECODE | size | silent: return in looks_like_loader | usize | 256 | crates/disrobe-pass-py-deob/src/obfuscators/pyc_zipper.rs |
disrobe-pass-py-deob | MAX_CODE_DEPTH | recursion | recorded: flag depth_limited | usize | 64 | crates/disrobe-pass-py-deob/src/obfuscators/pyc_zipper/reverse.rs |
disrobe-pass-py-deob | MAX_STORE_DISTANCE | other | silent: .take() in store_target | usize | 64 | crates/disrobe-pass-py-deob/src/obfuscators/pyc_zipper/reverse.rs |
disrobe-pass-py-deob | MAX_GENERATED_SOURCE_BYTES | size | error: Error::AstCleanup (DR-PYDEOB-0009) | usize | 8 << 20 | crates/disrobe-pass-py-deob/src/obfuscators/pyobfus.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | recursion | silent: return in collect_code_objects | usize | 32 | crates/disrobe-pass-py-deob/src/obfuscators/pyobfus.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | recursion | silent: return in collect_code_objects | usize | 32 | crates/disrobe-pass-py-deob/src/obfuscators/pypacker.rs |
disrobe-pass-py-deob | MAX_DEPTH | recursion | error: Error::DepthLimit (DR-PYDEOB-0003) | usize | 32 | crates/disrobe-pass-py-deob/src/peel.rs |
disrobe-pass-py-deob | MAX_TOKEN_CHARS | other | silent: return in recover | usize | 8 * 1024 * 1024 | crates/disrobe-pass-py-deob/src/shuffled_base64.rs |
disrobe-pass-py-deob | MAX_OUTER_PASSES | other | silent: for range in cleanup_source | usize | 8 | crates/disrobe-pass-py-deob/src/source_cleanup.rs |
disrobe-pass-py-deob | MAX_CANONICAL_NAMES | other | silent: continue in canonicalize_homoglyph_names | usize | 100_000 | crates/disrobe-pass-py-deob/src/unrename.rs |
disrobe-pass-py-disasm | HEAD_SCAN_LIMIT | other | error: AltRuntimeError::NotDetected (DR-PYALT-0004) | usize | 32 * 1024 | crates/disrobe-pass-py-disasm/src/alt_runtimes/brython.rs |
disrobe-pass-py-disasm | MAX_NESTING | recursion | error: AltRuntimeError::BadEncoding (DR-PYALT-0006) | u8 | 48 | crates/disrobe-pass-py-disasm/src/alt_runtimes/micropython.rs |
disrobe-pass-py-disasm | MAX_OBJ_NESTING | recursion | error: AltRuntimeError::BadEncoding (DR-PYALT-0006) | u8 | 64 | crates/disrobe-pass-py-disasm/src/alt_runtimes/micropython.rs |
disrobe-pass-py-disasm | MAX_TABLE_ITEMS | count | error: AltRuntimeError::BadEncoding (DR-PYALT-0006) | usize | 65_536 | crates/disrobe-pass-py-disasm/src/alt_runtimes/micropython.rs |
disrobe-pass-py-disasm | MAX_TABLE_PREALLOC | other | allocation: with_capacity in decode_arg_names; with_capacity in parse_bytecode; with_capacity in parse; 1 more | usize | 4096 | crates/disrobe-pass-py-disasm/src/alt_runtimes/micropython.rs |
disrobe-pass-py-disasm | MAX_VARINT_BYTES | size | error: AltRuntimeError::BadEncoding (DR-PYALT-0006) | usize | 10 | crates/disrobe-pass-py-disasm/src/alt_runtimes/micropython.rs |
disrobe-pass-py-disasm | MAX_NATIVE_VERSION | other | error: AltRuntimeError::NotDetected (DR-PYALT-0004); AltRuntimeError::UnsupportedVersion (DR-PYALT-0003) | u8 | 6 | crates/disrobe-pass-py-disasm/src/alt_runtimes/micropython_native.rs |
disrobe-pass-py-disasm | MAX_OBJ_NESTING | recursion | error: AltRuntimeError::BadEncoding (DR-PYALT-0006) | u8 | 64 | crates/disrobe-pass-py-disasm/src/alt_runtimes/micropython_native.rs |
disrobe-pass-py-disasm | MAX_ALT_RUNTIME_INPUT_BYTES | size | error: AltRuntimeError::InputTooLarge (DR-PYALT-0007) | usize | 16 * 1024 * 1024 | crates/disrobe-pass-py-disasm/src/alt_runtimes/mod.rs |
disrobe-pass-py-disasm | MAX_CODE_UNITS | other | silent: break in disassemble_code_tree | usize | 4096 | crates/disrobe-pass-py-disasm/src/alt_runtimes/pypy.rs |
disrobe-pass-py-disasm | MAX_NESTED_CODE_OBJECTS | recursion | error: CoreError::PassFailure (DR-CORE-0003) | usize | 20_000 | crates/disrobe-pass-py-disasm/src/chain_detector.rs |
disrobe-pass-py-disasm | MAX_RENDER_DEPTH | recursion | silent: return in repr_object | usize | 64 | crates/disrobe-pass-py-disasm/src/const_repr.rs |
disrobe-pass-py-disasm | MAX_REPR_LONG_DIGITS | other | silent: return in repr_bigint | usize | 512 | crates/disrobe-pass-py-disasm/src/const_repr.rs |
disrobe-pass-py-disasm | MAX_SET_SIMULATION | other | silent: return in cpython_set_order | usize | 1 << 20 | crates/disrobe-pass-py-disasm/src/const_repr.rs |
disrobe-pass-py-disasm | MAX_EXTENDED_ARG_PREFIXES | other | recorded: flag argrepr | u32 | 3 | crates/disrobe-pass-py-disasm/src/lib.rs |
disrobe-pass-pyarmor | MAX_NAME_LEN | size | silent: return in resolve_name | usize | 128 | crates/disrobe-pass-pyarmor/src/bcc/dispatch.rs |
disrobe-pass-pyarmor | MAX_RECORDS | count | silent: while condition in parse_records | usize | 65_536 | crates/disrobe-pass-pyarmor/src/bcc/dispatch.rs |
disrobe-pass-pyarmor | MAX_SECTIONS | other | silent: .min() clamp in enumerate_elf_sections | usize | 4096 | crates/disrobe-pass-pyarmor/src/bcc/dispatch.rs |
disrobe-pass-pyarmor | EXECUTION_BUDGET | work | silent: return in run | usize | 200_000 | crates/disrobe-pass-pyarmor/src/bcc/dispatch_recover.rs |
disrobe-pass-pyarmor | MAX_BODY_BYTES | size | recorded: notes | usize | 256 * 1024 | crates/disrobe-pass-pyarmor/src/bcc/dispatch_recover.rs |
disrobe-pass-pyarmor | MAX_BODY_BYTES | size | recorded: notes | usize | 256 * 1024 | crates/disrobe-pass-pyarmor/src/bcc/recover.rs |
disrobe-pass-pyarmor | MAX_TREE_DEPTH | recursion | silent: no action in build_node; no action in walk_artifacts | usize | 64 | crates/disrobe-pass-pyarmor/src/bcc/residual.rs |
disrobe-pass-pyarmor | MAX_TREE_NODES | count | silent: break in build_node; break in walk_artifacts | usize | 65_536 | crates/disrobe-pass-pyarmor/src/bcc/residual.rs |
disrobe-pass-pyarmor | MAX_STEPS | work | silent: return in recover_idealized | usize | 4096 | crates/disrobe-pass-pyarmor/src/bcc/stmt_structure.rs |
disrobe-pass-pyarmor | MAX_PACKAGE_DEPTH | recursion | silent: break in derive_module_path | usize | 64 | crates/disrobe-pass-pyarmor/src/bcc/stub.rs |
disrobe-pass-pyarmor | MAX_CALL_TARGETS_SCANNED | other | silent: .take() in resolve_sibling_calls | usize | 1024 | crates/disrobe-pass-pyarmor/src/bcc_lift.rs |
disrobe-pass-pyarmor | MAX_DISASM_LINES | other | silent: break in render_unmodeled | usize | 4096 | crates/disrobe-pass-pyarmor/src/bcc_lift.rs |
disrobe-pass-pyarmor | MAX_FUNCTIONS | other | silent: while condition in discover_functions | usize | 4096 | crates/disrobe-pass-pyarmor/src/bcc_lift.rs |
disrobe-pass-pyarmor | MAX_RESOLVED_CALLS | other | silent: break in resolve_sibling_calls | usize | 256 | crates/disrobe-pass-pyarmor/src/bcc_lift.rs |
disrobe-pass-pyarmor | MAX_DYNAMIC_CAPTURE | other | error: Error::DynamicHookTimedOut (DR-PYARM-0018); Error::KeyExtraction (DR-PYARM-0009) | usize | 4 * 1024 * 1024 | crates/disrobe-pass-pyarmor/src/dynamic_hook.rs |
disrobe-pass-pyarmor | MAX_CODE_OBJECT_DEPTH | recursion | recorded: flag depth_limit_truncations | u32 | 512 | crates/disrobe-pass-pyarmor/src/inner_cipher.rs |
disrobe-pass-pyarmor | MAX_READ | other | silent: .min() clamp in extract_runtime_key | usize | 16 * 1024 * 1024 | crates/disrobe-pass-pyarmor/src/key.rs |
disrobe-pass-pyarmor | MAX_CAPTURE_FILE_BYTES | size | error: ErrorKind::InvalidData | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-pyarmor/src/lib.rs |
disrobe-pass-pyarmor | MAX_JSON_FILE_BYTES | size | error: ErrorKind::InvalidData | u64 | 16 * 1024 * 1024 | crates/disrobe-pass-pyarmor/src/lib.rs |
disrobe-pass-pyarmor | MAX_RUNTIME_DIR_ENTRIES | count | error: ErrorKind::InvalidData | usize | 4096 | crates/disrobe-pass-pyarmor/src/lib.rs |
disrobe-pass-pyarmor | MAX_RUNTIME_FILE_BYTES | size | error: ErrorKind::InvalidData | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-pyarmor/src/lib.rs |
disrobe-pass-pyarmor | MAX_IMPORT_SCAN_BYTES | size | silent: slice in scan_import_symbols; slice in scan_printable_strings | usize | 8 * 1024 * 1024 | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_IMPORT_SYMBOLS | other | silent: return in scan_import_symbols | usize | 4096 | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_STRING_BYTES | size | silent: .min() clamp in push_printable_string | usize | 4096 | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_STRING_CONSTANTS | other | silent: return in scan_printable_strings | usize | 2048 | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_STRING_SCAN_BYTES | size | silent: slice in scan_printable_strings | usize | MAX_IMPORT_SCAN_BYTES | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_BCC_SEGMENTS | other | silent: while condition in peel_bcc | usize | 4096 | crates/disrobe-pass-pyarmor/src/v8v9.rs |
disrobe-pass-pyfreeze | MAX_WALK_DEPTH | recursion | error: Error::BriefcaseWalkBounded (DR-PYFRZ-0024) | usize | 64 | crates/disrobe-pass-pyfreeze/src/briefcase/layout.rs |
disrobe-pass-pyfreeze | MAX_WALK_ENTRIES | count | error: Error::BriefcaseWalkBounded (DR-PYFRZ-0024) | usize | 200_000 | crates/disrobe-pass-pyfreeze/src/briefcase/layout.rs |
disrobe-pass-pyfreeze | MAX_ENTRY_BYTES | size | silent: continue in carve_zip_members | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/chain_detector.rs |
disrobe-pass-pyfreeze | MAX_ZIP_ENTRIES | count | silent: .min() clamp in carve_zip_members | usize | 65_536 | crates/disrobe-pass-pyfreeze/src/chain_detector.rs |
disrobe-pass-pyfreeze | MAX_JSON_MANIFEST_BYTES | size | error: Error::JsonManifestTooLarge (DR-PYFRZ-0027) | usize | 16 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/common/mod.rs |
disrobe-pass-pyfreeze | MAX_PREALLOC | other | allocation: with_capacity in read_to_vec_bounded; with_capacity in read_to_vec_limited | usize | 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/common/read_bounded.rs |
disrobe-pass-pyfreeze | MAX_COMMENT | other | silent: for range in locate | usize | 0xFFFF | crates/disrobe-pass-pyfreeze/src/common/zip_tail.rs |
disrobe-pass-pyfreeze | SEARCH_BUDGET | work | silent: for range in locate | usize | MAX_COMMENT + EOCD_FIXED_LEN + 4 | crates/disrobe-pass-pyfreeze/src/common/zip_tail.rs |
disrobe-pass-pyfreeze | MAX_TREE_DEPTH | recursion | error: Error::QuotaExceeded (DR-PYFRZ-0018) | usize | 32 | crates/disrobe-pass-pyfreeze/src/cxfreeze/lib_tree.rs |
disrobe-pass-pyfreeze | MAX_TREE_ENTRIES | count | error: Error::QuotaExceeded (DR-PYFRZ-0018) | usize | 200_000 | crates/disrobe-pass-pyfreeze/src/cxfreeze/lib_tree.rs |
disrobe-pass-pyfreeze | MAX_FILESYSTEM_BYTECODE_ATTEMPTS | size | recorded: flag filesystem_bytecode_capped | usize | 512 | crates/disrobe-pass-pyfreeze/src/cxfreeze/mod.rs |
disrobe-pass-pyfreeze | MAX_FREEZE_DIR_ENTRIES | count | silent: .take() in find_python_runtime; break in sibling_native_extensions | usize | 4096 | crates/disrobe-pass-pyfreeze/src/lib.rs |
disrobe-pass-pyfreeze | MAX_FREEZE_INPUT_BYTES | size | error: ErrorKind::InvalidData | u64 | 1024 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/lib.rs |
disrobe-pass-pyfreeze | MAX_LIBRARY_ZIP_BYTES | size | error: ErrorKind::InvalidData | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/lib.rs |
disrobe-pass-pyfreeze | MAX_RECOVERY_FILE_BYTES | size | error: ErrorKind::InvalidData | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/lib.rs |
disrobe-pass-pyfreeze | MAX_PEX_ENTRY | other | delegated: read_bounded::read_to_vec_limited()? | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/pex/mod.rs |
disrobe-pass-pyfreeze | MAX_PYTHONSCRIPT_BYTES | size | error: Error::PeParse (DR-PYFRZ-0013) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/py2exe/pe.rs |
disrobe-pass-pyfreeze | MAX_BLOB_SECTIONS | other | silent: return in parse_blob_index | usize | 4096 | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_BLOB_SLICE | other | silent: .min() clamp in extract_resources_blob | usize | 256 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_NAME_LEN | size | silent: while condition in scan_name_start | usize | 4096 | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_RESOURCE_ENTRIES | count | silent: break in heuristic_walk; return in extract_modules_structured; return in parse_structured_region | usize | 1_000_000 | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_STRUCTURED_VERSION | other | silent: for range in extract_resources_blob; no action in find_packed_magic | u8 | 3 | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_DISASM_BYTES | size | silent: slice in surface_native | usize | 1 << 20 | crates/disrobe-pass-pyfreeze/src/recover.rs |
disrobe-pass-pyfreeze | SAMPLE_INSTRUCTION_CAP | other | silent: .take() in surface_native | usize | 32 | crates/disrobe-pass-pyfreeze/src/recover.rs |
disrobe-pass-pyfreeze | MAX_MANIFEST_BYTES | size | delegated: read_bounded::read_to_vec_limited()? | u64 | 16 * 1024 * 1024 | crates/disrobe-pass-pyfreeze/src/shiv/mod.rs |
disrobe-pass-pyinstaller | MAX_ZIP_COMMENT | other | silent: return in find_eocd | usize | u16::MAX as usize | crates/disrobe-pass-pyinstaller/src/base_library.rs |
disrobe-pass-pyinstaller | MAX_ZIP_ENTRIES | count | silent: while condition in walk_central_directory | usize | 1 << 20 | crates/disrobe-pass-pyinstaller/src/base_library.rs |
disrobe-pass-pyinstaller | MAX_NATIVE_SURFACE_BYTES | size | silent: skipped in extract_children | usize | 96 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/chain_detector.rs |
disrobe-pass-pyinstaller | MAX_AGGREGATE_INFLATE | other | error: ErrorKind::InvalidData | u64 | 8 * 1024 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/extract.rs |
disrobe-pass-pyinstaller | MAX_INFLATE_ABS | other | error: ErrorKind::InvalidData | u64 | 4 * 1024 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/extract.rs |
disrobe-pass-pyinstaller | MAX_INFLATE_RATIO | other | error: ErrorKind::InvalidData | u64 | 1024 | crates/disrobe-pass-pyinstaller/src/extract.rs |
disrobe-pass-pyinstaller | MAX_INPUT_FILE_BYTES | size | error: Error::InputFileTooLarge (DR-PYINST-0013) | u64 | 1024 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/extract.rs |
disrobe-pass-pyinstaller | MAX_KEY_MODULE_INFLATE | other | error: ErrorKind::InvalidData | u64 | 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/extract.rs |
disrobe-pass-pyinstaller | MAX_DEEP_ANALYZE_BYTES | size | silent: skipped in surface_native_entry | usize | 16 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/native_surface.rs |
disrobe-pass-pyinstaller | MAX_CANDIDATE_BYTES | size | recorded: flag exhausted | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/pyc_zipper.rs |
disrobe-pass-pyinstaller | MAX_CANDIDATE_CONSTS | other | recorded: flag exhausted | usize | 4096 | crates/disrobe-pass-pyinstaller/src/pyc_zipper.rs |
disrobe-pass-pyinstaller | MAX_CODE_WALK_DEPTH | recursion | silent: return in collect_byte_consts | usize | 64 | crates/disrobe-pass-pyinstaller/src/pyc_zipper.rs |
disrobe-pass-pyinstaller | MAX_DECOMPRESS_ATTEMPTS | other | silent: break in unzip_pyc_with_limits; return in take | usize | 1024 | crates/disrobe-pass-pyinstaller/src/pyc_zipper.rs |
disrobe-pass-pyinstaller | MAX_RECOVERED_BYTES | size | silent: .take() in read_capped; return in read_capped | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/pyc_zipper.rs |
disrobe-pass-pyinstaller | MAX_AGGREGATE_INFLATE | other | error: ErrorKind::InvalidData | u64 | 8 * 1024 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/pyz.rs |
disrobe-pass-pyinstaller | MAX_INFLATE_ABS | other | error: ErrorKind::InvalidData | u64 | 4 * 1024 * 1024 * 1024 | crates/disrobe-pass-pyinstaller/src/pyz.rs |
disrobe-pass-pyinstaller | MAX_INFLATE_RATIO | other | error: ErrorKind::InvalidData | u64 | 1024 | crates/disrobe-pass-pyinstaller/src/pyz.rs |
disrobe-pass-pyinstaller | MAX_PYZ_TOC_ENTRIES | count | error: Error::TocWalk (DR-PYINST-0004) | usize | 1 << 20 | crates/disrobe-pass-pyinstaller/src/pyz.rs |
disrobe-pass-ruby | POOL_PREALLOC_CAP | other | allocation: with_capacity in read_record | usize | 4096 | crates/disrobe-pass-ruby/src/mruby/irep.rs |
disrobe-pass-ruby | MAX_KEYWORD_PARAMS | other | allocation: with_capacity in keyword_prologue | usize | 31 | crates/disrobe-pass-ruby/src/mruby/lift.rs |
disrobe-pass-ruby | MAX_LIFT_DEPTH | recursion | recorded: flag coverage_complete | u32 | 64 | crates/disrobe-pass-ruby/src/mruby/lift.rs |
disrobe-pass-ruby | MAX_LIFT_OUTPUT_PREALLOC | output | allocation: with_capacity in lift_tree | usize | 1 << 20 | crates/disrobe-pass-ruby/src/mruby/lift.rs |
disrobe-pass-ruby | MAX_REGS | other | silent: skipped in set_pending; skipped in set | usize | 4096 | crates/disrobe-pass-ruby/src/mruby/lift.rs |
disrobe-pass-ruby | OCRA_DECOMPRESS_CAP | other | error: Error::other(); RubyError::OcraLzmaDecode (DR-RUBY-0064) | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-ruby/src/wrappers.rs |
disrobe-pass-ruby | MAX_EXPR_LEN | size | silent: fallback value in push | usize | 8192 | crates/disrobe-pass-ruby/src/yarv/decompile.rs |
disrobe-pass-ruby | MAX_NEST_DEPTH | recursion | silent: return in emit_send; return in massign_targets; return in render_iseq_statements; 1 more | u32 | 64 | crates/disrobe-pass-ruby/src/yarv/decompile.rs |
disrobe-pass-ruby | MAX_OPERAND_COUNT | count | recorded: flag assigns; flag escaped | usize | MAX_STACK | crates/disrobe-pass-ruby/src/yarv/decompile.rs |
disrobe-pass-ruby | MAX_STACK | other | recorded: flag assigns; flag escaped | usize | 8192 | crates/disrobe-pass-ruby/src/yarv/decompile.rs |
disrobe-pass-ruby | IBF_ARRAY_LEN_CAP | size | silent: .min() clamp in decode_object; for range in parse_ci_entries | usize | 1_048_576 | crates/disrobe-pass-ruby/src/yarv/ibf.rs |
disrobe-pass-ruby | IBF_OBJECT_LIST_ENTRY_CAP | other | silent: .min() clamp in parse_image | u32 | 1_048_576 | crates/disrobe-pass-ruby/src/yarv/ibf.rs |
disrobe-pass-ruby | IBF_STRING_LEN_CAP | size | silent: break in decode_iseq_body; skipped in decode_object | usize | 16 * 1024 * 1024 | crates/disrobe-pass-ruby/src/yarv/ibf.rs |
disrobe-pass-scriptlang | MAX_SWF_BYTES | size | silent: return in inflate_cws | usize | 1usize << 26 | crates/disrobe-pass-scriptlang/src/lang/haxe.rs |
disrobe-pass-scriptlang | MAX_ADAPTIVE_BYTES | size | error: Error::StarkitMetakit (DR-SCRIPT-0404) | usize | 5usize | crates/disrobe-pass-scriptlang/src/lang/metakit.rs |
disrobe-pass-scriptlang | MAX_COLUMNS | other | error: Error::StarkitMetakit (DR-SCRIPT-0404); untyped format! | usize | 64usize | crates/disrobe-pass-scriptlang/src/lang/metakit.rs |
disrobe-pass-scriptlang | MAX_DESCRIPTION_BYTES | size | error: Error::StarkitMetakit (DR-SCRIPT-0404); untyped format! | usize | 1usize << 16 | crates/disrobe-pass-scriptlang/src/lang/metakit.rs |
disrobe-pass-scriptlang | MAX_MEMBERS | count | error: Error::StarkitMetakit (DR-SCRIPT-0404); untyped format! | usize | 65_536usize | crates/disrobe-pass-scriptlang/src/lang/metakit.rs |
disrobe-pass-scriptlang | MAX_PATH_BYTES | size | error: Error::StarkitMetakit (DR-SCRIPT-0404); untyped format! | usize | 4096usize | crates/disrobe-pass-scriptlang/src/lang/metakit.rs |
disrobe-pass-scriptlang | MAX_TOTAL_PATH_BYTES | size | error: Error::StarkitMetakit (DR-SCRIPT-0404); untyped format! | usize | 64usize << 20 | crates/disrobe-pass-scriptlang/src/lang/metakit.rs |
disrobe-pass-scriptlang | MAX_VIEW_DEPTH | recursion | error: Error::StarkitMetakit (DR-SCRIPT-0404); untyped format! | usize | 8usize | crates/disrobe-pass-scriptlang/src/lang/metakit.rs |
disrobe-pass-scriptlang | MAX_VIEW_ROWS | other | error: Error::StarkitMetakit (DR-SCRIPT-0404); untyped format! | i64 | 1i64 << 20 | crates/disrobe-pass-scriptlang/src/lang/metakit.rs |
disrobe-pass-scriptlang | MAX_RDS_BYTES | size | silent: .take() in read_bounded; return in maybe_gunzip_rds_with_limit; return in read_bounded | usize | 1usize << 29 | crates/disrobe-pass-scriptlang/src/lang/mod.rs |
disrobe-pass-scriptlang | MAX_BYTECODE_TEXT_BYTES | size | error: Error::PerlBytecodeTruncated (DR-SCRIPT-0211); Error::PerlBytecodeValueTooLarge (DR-SCRIPT-0214) | usize | 1usize << 20 | crates/disrobe-pass-scriptlang/src/lang/perl_bytecode.rs |
disrobe-pass-scriptlang | MAX_OPS | work | silent: while condition in read_bytecode | usize | 2_000_000usize | crates/disrobe-pass-scriptlang/src/lang/perl_bytecode.rs |
disrobe-pass-scriptlang | MAX_MULTICONCAT_SEGMENTS | other | silent: .take() in parse_multiconcat | usize | 256 | crates/disrobe-pass-scriptlang/src/lang/perl_decompile.rs |
disrobe-pass-scriptlang | COMPLEX_VECTOR_CAP | other | silent: .min() clamp in walk_item_body | usize | 1024usize | crates/disrobe-pass-scriptlang/src/lang/r_rds.rs |
disrobe-pass-scriptlang | MAX_DEPTH | recursion | error: Error::RdsDepthExceeded (DR-SCRIPT-0303) | usize | 256usize | crates/disrobe-pass-scriptlang/src/lang/r_rds.rs |
disrobe-pass-scriptlang | MAX_NODES | count | error: Error::RdsNodeLimitExceeded (DR-SCRIPT-0306) | usize | 65_536usize | crates/disrobe-pass-scriptlang/src/lang/r_rds.rs |
disrobe-pass-scriptlang | MAX_RVALUE_VECTOR_ENTRIES | count | error: Error::RdsValueTooLarge (DR-SCRIPT-0307) | usize | 4096usize | crates/disrobe-pass-scriptlang/src/lang/r_rds.rs |
disrobe-pass-scriptlang | MAX_STRING_BYTES | size | error: Error::RdsValueTooLarge (DR-SCRIPT-0307) | usize | 64 * 1024 | crates/disrobe-pass-scriptlang/src/lang/r_rds.rs |
disrobe-pass-scriptlang | RAW_VECTOR_CAP | other | recorded: flag truncated | usize | 4096usize | crates/disrobe-pass-scriptlang/src/lang/r_rds.rs |
disrobe-pass-scriptlang | ENTRY_PREALLOC_CAP | other | allocation: with_capacity in member_bytes; with_capacity in read_zip_entry_to_limit | u64 | 1024 * 1024 | crates/disrobe-pass-scriptlang/src/lang/tcl.rs |
disrobe-pass-scriptlang | MAX_ENTRIES | count | silent: for range in extract_zip_with_limits; while condition in scan_metakit_files | usize | 65_536usize | crates/disrobe-pass-scriptlang/src/lang/tcl.rs |
disrobe-pass-scriptlang | MAX_ENTRY_BYTES | size | error: Error::StarkitMetakit (DR-SCRIPT-0404); Error::StarkitZip (DR-SCRIPT-0401) | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-scriptlang/src/lang/tcl.rs |
disrobe-pass-scriptlang | MAX_METAKIT_NAME_LEN | size | silent: return in read_metakit_token; skipped in scan_metakit_files | usize | 255usize | crates/disrobe-pass-scriptlang/src/lang/tcl.rs |
disrobe-pass-scriptlang | MAX_TOTAL_ENTRY_BYTES | size | error: Error::StarkitZip (DR-SCRIPT-0401) | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-scriptlang/src/lang/tcl.rs |
disrobe-pass-scriptlang | MAX_BASE64_CHUNK_BYTES | size | silent: for range in base64_decode | usize | 1usize << 22 | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-scriptlang | MAX_BASE64_INPUT_BYTES | size | silent: return in base64_decode; skipped in base64_blobs | usize | (MAX_INFLATE_BYTES / 3usize) * 4usize + 4usize | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-scriptlang | MAX_INFLATE_BYTES | size | silent: break in rebuild_replace; return in base64_decode; return in read_inflate_text; 1 more | usize | 1usize << 26 | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-scriptlang | MAX_INFLATE_READ_BYTES | size | silent: .take() in read_inflate_text | u64 | (1u64 << 26) + 1u64 | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-scriptlang | MAX_LAYERS | other | silent: while condition in recover | usize | 16usize | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-shell | MAX_ARITH_DEPTH | recursion | silent: return in parse_expression; return in parse_unary | usize | 256 | crates/disrobe-pass-shell/src/bash/arith.rs |
disrobe-pass-shell | MAX_ARRAY_ELEMENTS | other | silent: return in parse_array_assignment | usize | 4096 | crates/disrobe-pass-shell/src/bash/bash_eval.rs |
disrobe-pass-shell | MAX_FOR_INDICES | other | silent: return in parse_for_lookup_loop | usize | 4096 | crates/disrobe-pass-shell/src/bash/bash_eval.rs |
disrobe-pass-shell | MAX_PRINTF_BYTES | size | silent: return in try_string_split_indirection | usize | 65536 | crates/disrobe-pass-shell/src/bash/bash_eval.rs |
disrobe-pass-shell | MAX_TAG_LEN | size | silent: return in parse_md5_cut_chunk | usize | 1024 | crates/disrobe-pass-shell/src/bash/bash_eval.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | other | silent: return in try_compress_payload | usize | 2 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/bashfuscator.rs |
disrobe-pass-shell | MAX_DECOMPRESS_BYTES | size | silent: return in try_compress_payload | usize | 8 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/bashfuscator.rs |
disrobe-pass-shell | MAX_PEEL_ROUNDS | work | silent: for range in reverse_bashfuscator; no action in reverse_bashfuscator | usize | 12 | crates/disrobe-pass-shell/src/bash/bashfuscator.rs |
disrobe-pass-shell | MAX_DEPTH | recursion | silent: return in eval_wrapped_command; no action in wall | usize | 64 | crates/disrobe-pass-shell/src/bash/decode.rs |
disrobe-pass-shell | MAX_INFLATE | other | recorded: .note() | u64 | 8 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/decode.rs |
disrobe-pass-shell | MAX_OUTPUT | output | silent: break in decode_pipeline; break in evaluate | usize | 16 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/decode.rs |
disrobe-pass-shell | MAX_REPEAT | other | silent: no action in expand_tr_set | usize | 1 << 20 | crates/disrobe-pass-shell/src/bash/decode.rs |
disrobe-pass-shell | MAX_GZIP_OUTPUT | output | silent: .take() in peel_non_eval_layers; .truncate() in peel_non_eval_layers; fallback value in peel_non_eval_layers | u64 | 8 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/indirect.rs |
disrobe-pass-shell | MAX_PEELED_OUTPUT | output | silent: break in peel_indirection_with_policy | usize | 16 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/indirect.rs |
disrobe-pass-shell | MAX_PEEL_ROUNDS | work | silent: break in peel_indirection_with_policy | usize | 32 | crates/disrobe-pass-shell/src/bash/indirect.rs |
disrobe-pass-shell | MAX_LEXER_INPUT_BYTES | size | recorded: BashTokenKind::Truncated; flag truncation | usize | 8 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/lexer.rs |
disrobe-pass-shell | MAX_SUBSTITUTION_DEPTH | recursion | recorded: flag nesting_truncated | usize | 256usize | crates/disrobe-pass-shell/src/bash/lexer.rs |
disrobe-pass-shell | MAX_TOKEN_COUNT | count | silent: while condition in tokenize_bash | usize | 65_536usize | crates/disrobe-pass-shell/src/bash/lexer.rs |
disrobe-pass-shell | MAX_TOKEN_SOURCE_BYTES | size | recorded: flag source_limit_exceeded | usize | MAX_TOKEN_TEXT_BYTES / 3usize | crates/disrobe-pass-shell/src/bash/lexer.rs |
disrobe-pass-shell | MAX_TOKEN_TEXT_BYTES | size | recorded: flag source_limit_exceeded | usize | 65_536usize | crates/disrobe-pass-shell/src/bash/lexer.rs |
disrobe-pass-shell | MAX_TOTAL_TOKEN_TEXT_BYTES | size | recorded: flag budget | usize | 8 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/lexer.rs |
disrobe-pass-shell | MAX_RECOVERED_OUTPUT | output | silent: break in reverse_node_bash_obfuscate | usize | 32 * 1024 * 1024 | crates/disrobe-pass-shell/src/bash/node_bash_obfuscate.rs |
disrobe-pass-shell | MAX_TABLE_ENTRIES | count | silent: while condition in parse_chunk_table | usize | 200_000 | crates/disrobe-pass-shell/src/bash/node_bash_obfuscate.rs |
disrobe-pass-shell | MAX_GLOB_ANCHORED_PATTERN_LEN | size | silent: return in substitute; return in trim_prefix; return in trim_suffix | usize | 256 | crates/disrobe-pass-shell/src/bash/param_expand.rs |
disrobe-pass-shell | MAX_GLOB_ANCHORED_TEXT_LEN | size | silent: return in substitute; return in trim_prefix; return in trim_suffix | usize | 4096 | crates/disrobe-pass-shell/src/bash/param_expand.rs |
disrobe-pass-shell | MAX_GLOB_SCAN_PATTERN_LEN | size | silent: return in substitute | usize | 64 | crates/disrobe-pass-shell/src/bash/param_expand.rs |
disrobe-pass-shell | MAX_GLOB_SCAN_TEXT_LEN | size | silent: return in substitute | usize | 512 | crates/disrobe-pass-shell/src/bash/param_expand.rs |
disrobe-pass-shell | MAX_ARITH_DEPTH | recursion | silent: return in parse_expr; return in parse_unary | usize | 256 | crates/disrobe-pass-shell/src/batch/arith.rs |
disrobe-pass-shell | MAX_CIPHERTEXT | other | silent: continue in recover_stages | usize | 1 << 20 | crates/disrobe-pass-shell/src/batch/chain.rs |
disrobe-pass-shell | MAX_EXPANSION_ROUNDS | work | silent: for range in expand_repeated | usize | 16 | crates/disrobe-pass-shell/src/batch/engine.rs |
disrobe-pass-shell | MAX_LINES | other | silent: break in deobfuscate_batch | usize | 50_000 | crates/disrobe-pass-shell/src/batch/engine.rs |
disrobe-pass-shell | MAX_TOTAL_OUTPUT | output | silent: break in deobfuscate_batch | usize | 64 * 1024 * 1024 | crates/disrobe-pass-shell/src/batch/engine.rs |
disrobe-pass-shell | MAX_EXPANSION_OUTPUT | output | silent: break in expand_sigil; return in reserve_expansion_bytes | usize | 16 * 1024 * 1024 | crates/disrobe-pass-shell/src/batch/expand.rs |
disrobe-pass-shell | MAX_FOR_ITERATIONS | work | silent: return in numeric_sequence | usize | 4096 | crates/disrobe-pass-shell/src/batch/forloop.rs |
disrobe-pass-shell | MAX_REVERSE_ADDED_BYTES | size | silent: return in reserve_expansion_bytes | usize | expand::MAX_EXPANSION_OUTPUT | crates/disrobe-pass-shell/src/batch/mod.rs |
disrobe-pass-shell | MAX_DECODE_LEN | size | silent: continue in extract_base64_blobs; return in decode_base64_flexible | usize | 1 << 20 | crates/disrobe-pass-shell/src/batch/payload.rs |
disrobe-pass-shell | MAX_POWERSHELL_LAYER_ROUNDS | work | silent: for range in reverse_powershell_layers | usize | 16 | crates/disrobe-pass-shell/src/chain_detector.rs |
disrobe-pass-shell | MAX_SCRIPT_SCAN_BYTES | size | silent: slice in detect | usize | 16 * 1024 * 1024 | crates/disrobe-pass-shell/src/detect.rs |
disrobe-pass-shell | MAX_ACTION_DEPTH | recursion | silent: return in handle_action | usize | 64 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_ARRAY_ELEMENTS | other | silent: break in parse_array | usize | 1 << 20 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_DICT_ENTRIES | count | silent: break in parse_dictionary_or_stream | usize | 1 << 16 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_DOCUMENT_BYTES | size | silent: slice in analyze | usize | 256 * 1024 * 1024 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_FILTER_CHAIN | other | silent: break in decode_stream | usize | 8 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_FINDINGS | other | silent: break in collect_name_tree; break in scan_hex_obfuscated_names; return in add_embedded; 2 more | usize | 8192 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_FINDING_TEXT | other | silent: .truncate() in extract_javascript; while condition in cutoff; no action in cutoff | usize | 1024 * 1024 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_LZW_CODES | other | silent: skipped in lzw_decode | usize | 4096 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_NAME_BYTES | size | silent: break in parse_name; break in scan_hex_obfuscated_names | usize | 4096 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_NAME_TREE_NODES | count | silent: break in collect_name_tree | usize | 1 << 16 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_OBJECTS | other | silent: break in brute_force; return in insert_object | usize | 1 << 20 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_OBJECT_DEPTH | recursion | silent: return in parse_object | usize | 96 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_OBJSTM_OBJECTS | other | silent: .min() clamp in expand_object_streams | usize | 1 << 20 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_PREDICTOR_COLUMNS | other | silent: .clamp() clamp in apply_predictor | usize | 250_000 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_RESOLVE_STEPS | work | silent: return in resolve | usize | 256 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_STREAM_OUTPUT | output | recorded: flag capped | usize | 64 * 1024 * 1024 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_STRING_BYTES | size | silent: break in parse_hex_string; break in parse_literal_string | usize | 32 * 1024 * 1024 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_STRING_CONCAT | other | silent: break in extract_javascript | usize | 8 * 1024 * 1024 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_TOTAL_OUTPUT | output | recorded: flag capped | usize | 512 * 1024 * 1024 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_WALK_NODES | count | silent: break in global_sweep; break in walk_acroform; break in walk_pages; 3 more | usize | 1 << 18 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_XREF_CHAIN | other | silent: break in parse_xref_chain | usize | 1024 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_XREF_ENTRIES | count | silent: .min() clamp in parse_xref_stream; for range in parse_xref_table | usize | 1 << 21 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_XREF_FIELD_WIDTH | other | silent: return in parse_xref_stream | usize | 8 | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | STATIC_EVAL_DEPTH_CAP | recursion | silent: break in peel_indirection_with_policy; continue in unwrap; return in eval_wrapped_command; 2 more | usize | 2 | crates/disrobe-pass-shell/src/policy.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | other | silent: return in decode_frombase64_payload | usize | 2 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/chameleon.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | other | error: Error::InputTooLarge (DR-NUITKA-0032) | usize | 2 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/invoke_obfuscation.rs |
disrobe-pass-shell | MAX_DECOMPRESSED | other | silent: .take() in reverse_compress; .truncate() in reverse_compress; fallback value in reverse_compress | u64 | 16 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/invoke_obfuscation.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | other | silent: return in reverse_then_b64_decode | usize | 2 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/invoke_stealth.rs |
disrobe-pass-shell | MAX_LEXER_INPUT_BYTES | size | recorded: .note(); BashTokenKind::Truncated; TokenKind::Truncated; 31 more | usize | 8 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/lexer.rs |
disrobe-pass-shell | MAX_TOKEN_COUNT | count | silent: while condition in tokenize | usize | 65_536usize | crates/disrobe-pass-shell/src/powershell/lexer.rs |
disrobe-pass-shell | MAX_TOKEN_SOURCE_BYTES | size | recorded: flag source_limit_exceeded | usize | MAX_TOKEN_TEXT_BYTES / 3usize | crates/disrobe-pass-shell/src/powershell/lexer.rs |
disrobe-pass-shell | MAX_TOKEN_TEXT_BYTES | size | recorded: flag source_limit_exceeded | usize | 65_536usize | crates/disrobe-pass-shell/src/powershell/lexer.rs |
disrobe-pass-shell | MAX_TOTAL_TOKEN_TEXT_BYTES | size | recorded: flag budget | usize | 8 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/lexer.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | other | error: Error::InputTooLarge (DR-NUITKA-0032) | usize | 2 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/powerhell.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | other | error: Error::InputTooLarge (DR-NUITKA-0032) | usize | 2 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/psobf.rs |
disrobe-pass-shell | MAX_DECOMPRESSED | other | silent: .take() in reverse_psobf; .truncate() in reverse_psobf; fallback value in reverse_psobf | u64 | 16 * 1024 * 1024 | crates/disrobe-pass-shell/src/powershell/psobf.rs |
disrobe-pass-shell | MAX_CFB_STREAM_BYTES | size | error: Error::VbaPcode | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-shell/src/vba/extract.rs |
disrobe-pass-shell | MAX_CFB_STREAM_RESERVE | other | allocation: with_capacity in read_stream | usize | 4 * 1024 * 1024 | crates/disrobe-pass-shell/src/vba/extract.rs |
disrobe-pass-shell | MAX_ENTRY_BYTES | size | error: Error::VbaPcode | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-shell/src/vba/extract.rs |
disrobe-pass-shell | MAX_ENTRY_RESERVE | other | allocation: with_capacity in read_zip_entry_bounded | usize | 4 * 1024 * 1024 | crates/disrobe-pass-shell/src/vba/extract.rs |
disrobe-pass-shell | MAX_MODULE_REFS | other | error: Error::VbaPcode | usize | 512 | crates/disrobe-pass-shell/src/vba/extract.rs |
disrobe-pass-shell | MAX_TOTAL_MODULE_STREAM_BYTES | size | error: Error::VbaPcode | u64 | 256 * 1024 * 1024 | crates/disrobe-pass-shell/src/vba/extract.rs |
disrobe-pass-shell | PROJECT_INFORMATION_RECORD_LIMIT | other | silent: for range in project_codepage | usize | 32 | crates/disrobe-pass-shell/src/vba/extract.rs |
disrobe-pass-shell | MAX_CALL_ARGS | other | silent: .min() clamp in pop_n | usize | 256 | crates/disrobe-pass-shell/src/vba/pcode_lift.rs |
disrobe-pass-shell | MAX_CFB_ENTRIES | count | silent: .take() in locate_vba_storages | usize | 8192 | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_CFB_STREAM_BYTES | size | error: Error::VbaPcode | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_CFB_STREAM_RESERVE | other | allocation: with_capacity in read_stream | usize | 4 * 1024 * 1024 | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_FUNC_ARG_CHAIN | other | silent: while condition in disasm_func | usize | 4096 | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_OVBA_DECOMPRESSED_BYTES | size | error: Error::VbaPcode | usize | 64 * 1024 * 1024 | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_TYPE_DESCRIPTOR_DEPTH | recursion | silent: return in named_type_from_descriptor | usize | 8 | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_ARRAY_VALUES | other | silent: return in read_array_constant | usize | 1 << 20 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_EXTERN_NAMES | other | silent: continue in build | usize | 1 << 16 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_RECORDS | count | silent: while condition in iter_biff12; while condition in iter_biff8 | usize | 1 << 20 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_RECORD_BODY | other | silent: .min() clamp in iter_biff12; .min() clamp in iter_biff8; fallback value in iter_biff8 | usize | 4 * 1024 * 1024 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_RGCE | other | silent: return in parse_fmla_biff12; return in parse_formula_biff8; return in parse_lbl; 1 more | usize | 512 * 1024 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_SHEETS | other | silent: break in enumerate_sheets | usize | 4096 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_STACK_DEPTH | recursion | recorded: flag aborted | usize | 4096 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_STRING_CHARS | other | silent: .min() clamp in decode_chars; return in read_utf16_units | usize | 1 << 20 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_TOKENS | other | recorded: flag aborted | usize | 1 << 18 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_WORKBOOK_BYTES | work | silent: .take() in read_cfb_stream; return in read_cfb_stream | u64 | 128 * 1024 * 1024 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_XTI | other | silent: .min() clamp in parse_externsheet | usize | 1 << 16 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_ZIP_ENTRIES | count | silent: return in open_biff12 | usize | 8192 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_ZIP_ENTRY_BYTES | size | silent: .take() in read_zip_entry; return in read_zip_entry | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-sourcedefender | MAX_ARMORED_INPUT_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | usize | 96 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/codec.rs |
disrobe-pass-sourcedefender | MAX_ARMORED_OUTPUT_BYTES | output | error: Error::InputLimit (DR-SDEF-0011) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/codec.rs |
disrobe-pass-sourcedefender | MAX_HEX_INPUT_BYTES | size | error: CoreError::PassFailure (DR-CORE-0003); Error::InputLimit (DR-SDEF-0011); Error::Msgpack (DR-SDEF-0008); 1 more | usize | 96 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/codec.rs |
disrobe-pass-sourcedefender | MAX_SOURCEDEFENDER_INFLATE | other | error: Error::Base85 (DR-SDEF-0004) | usize | 256 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/codec.rs |
disrobe-pass-sourcedefender | MAX_MSGPACK_BINARY_BYTES | size | error: Error::Msgpack (DR-SDEF-0008) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/envelope.rs |
disrobe-pass-sourcedefender | MAX_MSGPACK_CONTAINER_ITEMS | count | error: Error::Msgpack (DR-SDEF-0008) | usize | 4096 | crates/disrobe-pass-sourcedefender/src/envelope.rs |
disrobe-pass-sourcedefender | MAX_MSGPACK_DEPTH | recursion | error: Error::Msgpack (DR-SDEF-0008) | usize | 64 | crates/disrobe-pass-sourcedefender/src/envelope.rs |
disrobe-pass-sourcedefender | MAX_MSGPACK_ENVELOPE_BYTES | size | error: Error::Msgpack (DR-SDEF-0008) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/envelope.rs |
disrobe-pass-sourcedefender | MAX_MSGPACK_STRING_BYTES | size | error: Error::Msgpack (DR-SDEF-0008) | usize | 32 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/envelope.rs |
disrobe-pass-sourcedefender | MAX_PYE_ARMORED_CIPHERTEXT_CHARS | other | error: Error::Base85 (DR-SDEF-0004); Error::InputLimit (DR-SDEF-0011) | usize | 96 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/envelope.rs |
disrobe-pass-sourcedefender | MAX_PYE_FRAME_LINES | other | error: Error::Base85 (DR-SDEF-0004) | usize | 32_768 | crates/disrobe-pass-sourcedefender/src/envelope.rs |
disrobe-pass-sourcedefender | MAX_PYE_FRAME_TEXT_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | usize | MAX_PYE_ARMORED_CIPHERTEXT_CHARS + 64 * 1024 | crates/disrobe-pass-sourcedefender/src/envelope.rs |
disrobe-pass-sourcedefender | MAX_GCM_AAD_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | u64 | (1u64 << 61) - 1 | crates/disrobe-pass-sourcedefender/src/gcm_tag.rs |
disrobe-pass-sourcedefender | MAX_GCM_CIPHERTEXT_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | u64 | (1u64 << 36) - 32 | crates/disrobe-pass-sourcedefender/src/gcm_tag.rs |
disrobe-pass-sourcedefender | MAX_INLINED_BLOCKS | other | error: Error::InputLimit (DR-SDEF-0011) | usize | 4096 | crates/disrobe-pass-sourcedefender/src/inlined.rs |
disrobe-pass-sourcedefender | MAX_INLINED_SOURCE_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | usize | MAX_ARMORED_INPUT_BYTES | crates/disrobe-pass-sourcedefender/src/inlined.rs |
disrobe-pass-sourcedefender | MAX_FILENAME_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | usize | 4096 | crates/disrobe-pass-sourcedefender/src/kdf.rs |
disrobe-pass-sourcedefender | MAX_CONTAINER_INPUT_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | usize | MAX_HEX_INPUT_BYTES + 64 * 1024 | crates/disrobe-pass-sourcedefender/src/layered.rs |
disrobe-pass-sourcedefender | MAX_MODERN_BODY_LINES | other | error: Error::InputLimit (DR-SDEF-0011) | usize | 32_768 | crates/disrobe-pass-sourcedefender/src/layered.rs |
disrobe-pass-sourcedefender | MAX_MODERN_GCM_BODY_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | usize | MAX_HEX_INPUT_BYTES / 2 | crates/disrobe-pass-sourcedefender/src/modern_gcm.rs |
disrobe-pass-sourcedefender | MAX_CODE_OBJECT_SUMMARIES | other | error: Error::InputLimit (DR-SDEF-0011) | usize | 4096 | crates/disrobe-pass-sourcedefender/src/source_recover.rs |
disrobe-pass-sourcedefender | MAX_MARSHAL_PAYLOAD_BYTES | size | error: Error::InputLimit (DR-SDEF-0011) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-sourcedefender/src/source_recover.rs |
disrobe-pass-sourcedefender | MAX_MARSHAL_TRAVERSAL_OBJECTS | other | error: Error::InputLimit (DR-SDEF-0011) | usize | 131_072 | crates/disrobe-pass-sourcedefender/src/source_recover.rs |
disrobe-pass-sourcedefender | MAX_NESTED_CODE_DEPTH | recursion | error: Error::NestingLimit (DR-SDEF-0012) | usize | 32 | crates/disrobe-pass-sourcedefender/src/source_recover.rs |
disrobe-pass-swift-objc | MAX_CHAIN_CHILDREN | other | error: CoreError::PassFailure (DR-CORE-0003) | usize | 256 | crates/disrobe-pass-swift-objc/src/chain_detector.rs |
disrobe-pass-swift-objc | CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT | other | error: Error::Demangle (DR-IOS-0011) | u32 | 0x1005 | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_BLOB_LEN | size | silent: break in parse | u32 | 64 * 1024 * 1024 | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_IDENTIFIER_LEN | size | silent: ? on a checked operation in read_cstr_bounded | usize | 1024 | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_SLOT_COUNT | count | silent: .min() clamp in parse | usize | 1024 | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_VERIFIED_PAGES | other | silent: .min() clamp in verify_page_hashes | u32 | 65_536 | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_DEPTH | recursion | recorded: flag depth_limit_hits | usize | 1024 | crates/disrobe-pass-swift-objc/src/demangle.rs |
disrobe-pass-swift-objc | MAX_NODES | count | silent: ? on a checked operation in spend | usize | 1 << 18 | crates/disrobe-pass-swift-objc/src/demangle.rs |
disrobe-pass-swift-objc | MAX_REPEAT_COUNT | count | silent: return in demangle_repeated_standard_substitution; return in demangle_substitution_chain; return in demangle_substitution | u32 | 2048 | crates/disrobe-pass-swift-objc/src/demangle.rs |
disrobe-pass-swift-objc | MAX_SYMBOL_LEN | size | error: Error::Demangle (DR-IOS-0011) | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/demangle.rs |
disrobe-pass-swift-objc | MAX_IMAGES | other | error: Error::BadDyldCache (DR-IOS-0016) | usize | 1 << 20 | crates/disrobe-pass-swift-objc/src/dyld_cache.rs |
disrobe-pass-swift-objc | MAX_IMAGE_OUTPUT_BYTES | output | error: Error::BadDyldCache (DR-IOS-0016) | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-swift-objc/src/dyld_cache.rs |
disrobe-pass-swift-objc | MAX_LOCAL_SYMBOL_ENTRIES | count | error: Error::BadDyldCache (DR-IOS-0016) | usize | 1 << 20 | crates/disrobe-pass-swift-objc/src/dyld_cache.rs |
disrobe-pass-swift-objc | MAX_MAPPINGS | other | error: Error::BadDyldCache (DR-IOS-0016) | usize | 4096 | crates/disrobe-pass-swift-objc/src/dyld_cache.rs |
disrobe-pass-swift-objc | MAX_RECORDED_AUTH_POINTERS | other | silent: skipped in unapply_segment_slide | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/dyld_cache.rs |
disrobe-pass-swift-objc | MAX_TOTAL_OUTPUT_BYTES | output | error: Error::BadDyldCache (DR-IOS-0016) | u64 | 1024 * 1024 * 1024 | crates/disrobe-pass-swift-objc/src/dyld_cache.rs |
disrobe-pass-swift-objc | MAX_INDIRECT_SYMBOLS | other | error: Error::BadDyldCache (DR-IOS-0016) | usize | 8_000_000 | crates/disrobe-pass-swift-objc/src/dyld_cache/linkedit.rs |
disrobe-pass-swift-objc | MAX_LINKEDIT_BYTES | size | error: Error::BadDyldCache (DR-IOS-0016) | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-swift-objc/src/dyld_cache/linkedit.rs |
disrobe-pass-swift-objc | MAX_LINKEDIT_SYMBOLS | other | error: Error::BadDyldCache (DR-IOS-0016) | usize | 4_000_000 | crates/disrobe-pass-swift-objc/src/dyld_cache/linkedit.rs |
disrobe-pass-swift-objc | MAX_PAGE_EXTRAS | other | error: Error::BadDyldCache (DR-IOS-0016) | usize | 1 << 20 | crates/disrobe-pass-swift-objc/src/dyld_cache/slide.rs |
disrobe-pass-swift-objc | MAX_SLIDE_PAGES | other | error: Error::BadDyldCache (DR-IOS-0016) | usize | 1 << 22 | crates/disrobe-pass-swift-objc/src/dyld_cache/slide.rs |
disrobe-pass-swift-objc | MAX_V1_ENTRY_BYTES | size | error: Error::BadDyldCache (DR-IOS-0016) | usize | 4096 | crates/disrobe-pass-swift-objc/src/dyld_cache/slide.rs |
disrobe-pass-swift-objc | MAX_FAMILY_BYTES | size | error: Error::BadDyldCache (DR-IOS-0016) | u64 | 12 * 1024 * 1024 * 1024 | crates/disrobe-pass-swift-objc/src/dyld_cache/subcache.rs |
disrobe-pass-swift-objc | MAX_SUB_CACHES | other | error: Error::BadDyldCache (DR-IOS-0016) | usize | 128 | crates/disrobe-pass-swift-objc/src/dyld_cache/subcache.rs |
disrobe-pass-swift-objc | MAX_ENTRY_BYTES | size | error: Error::Ipa (DR-IOS-0002) | u64 | 512 * 1024 * 1024 | crates/disrobe-pass-swift-objc/src/ipa.rs |
disrobe-pass-swift-objc | MAX_PREALLOC | other | allocation: with_capacity in read_zip_entry_limited | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-swift-objc/src/ipa.rs |
disrobe-pass-swift-objc | MAX_ZIP_ENTRY_COUNT | count | error: Error::Ipa (DR-IOS-0002) | usize | 65_536 | crates/disrobe-pass-swift-objc/src/ipa.rs |
disrobe-pass-swift-objc | FAT_ARCH_COUNT_CAP | count | error: Error::BadFatHeader (DR-IOS-0006) | usize | 4096 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_DYLIBS | other | silent: skipped in parse_slice | usize | 4096 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_EXPORT_DEPTH | recursion | silent: return in walk_export_node | usize | 128 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_EXPORT_NAME | other | silent: ? on a checked operation in cstr_in; continue in walk_export_node | usize | 4096 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_EXPORT_NODES | count | silent: return in walk_export_node | usize | 1 << 20 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_FUNCTION_STARTS | other | silent: while condition in function_starts | usize | 1 << 22 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_INDIRECT_SYMBOLS | other | silent: .min() clamp in import_thunks | usize | 1 << 22 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_RPATHS | other | silent: skipped in parse_slice | usize | 1024 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_SYMBOLS | other | silent: .min() clamp in function_symbols; .min() clamp in symbol_names | usize | 1 << 22 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_SYMBOL_LEN | size | silent: ? on a checked operation in read_cstr_bounded | usize | 4096 | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_FUNCTION_BYTES | size | silent: .min() clamp in end_boundary; return in carve | u64 | 256 * 1024 | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_INSTRUCTIONS_PER_FUNCTION | other | recorded: flag truncated | usize | 8192 | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_LINES_PER_FUNCTION | other | silent: .take() in lines_for | usize | 4096 | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_LISTED_FUNCTIONS | other | silent: .take() in lift_native_nir; break in build_function_bodies | usize | 4096 | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_NIR_SYMBOLS | other | silent: .take() in lift_native_nir | usize | 8192 | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_REPORTED_TYPES | other | silent: .take() in recover_native_bodies | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_SELECTOR_HINT_WORK | work | silent: continue in index_selectors | u64 | 4_000_000 | crates/disrobe-pass-swift-objc/src/objc.rs |
disrobe-pass-swift-objc | MAX_BIND_OPS | work | silent: while condition in interpret_bind | usize | 1 << 20 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CALL_SITES | other | silent: break in annotate_instructions | usize | 1 << 14 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CFG_DEPTH | recursion | silent: return in reaching_def_from; return in reaching_slot | usize | 16 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CFG_STEPS | work | silent: return in build | usize | 1 << 13 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CHAINED_IMPORTS | other | silent: .min() clamp in parse_chained_imports | usize | 1 << 20 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CHAINED_PAGES | other | silent: .min() clamp in walk_chained_pages; for range in walk_chained_pages | usize | 1 << 22 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CHAINED_SEGMENTS | other | silent: .min() clamp in chained_segment_infos | usize | 1 << 12 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CSTR | other | silent: ? on a checked operation in chained_symbol_at; ? on a checked operation in cstr_at_offset | usize | 4096 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_MOVE_HOPS | work | silent: for range in trace_pointer_slot | usize | 8 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_SLOTS | other | silent: .min() clamp in build_classref_map; .min() clamp in build_selref_map; .min() clamp in interpret_bind | usize | 1 << 20 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_STUB_ENTRIES | count | silent: while condition in build_arm64_stub_map; while condition in build_x86_stub_map | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_TOTAL_BINDS | other | silent: break in interpret_bind; for range in walk_chain; while condition in interpret_bind | usize | 1 << 20 | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CATEGORIES | other | silent: .take() in recover_categories | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_CLASSES | other | silent: .take() in recover_interfaces | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_CSTR | other | silent: ? on a checked operation in cstr_at_offset | usize | 4096 | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_LIST_COUNT | count | silent: return in read_entsize_list_header | usize | 1 << 18 | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_PROTOCOLS | other | silent: .take() in recover_protocols | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_PROTOCOL_REFS | other | silent: return in parse_protocol_refs | usize | 1 << 12 | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_EMBEDDED_IMAGES | other | error: CoreError::PassFailure (DR-CORE-0003) | usize | 256 | crates/disrobe-pass-swift-objc/src/pass.rs |
disrobe-pass-swift-objc | MAX_REPORTED_INSTALL_NAMES | other | silent: .take() in dyld_cache_report | usize | 4096 | crates/disrobe-pass-swift-objc/src/pass.rs |
disrobe-pass-swift-objc | MAX_ZIP_ENTRY | other | delegated: ipa::read_zip_entry_limited()? | u64 | 64 * 1024 * 1024 | crates/disrobe-pass-swift-objc/src/pass.rs |
disrobe-pass-swift-objc | MAX_CSTR | other | silent: ? on a checked operation in cstr_at_offset; ? on a checked operation in mangled_name_at_offset | usize | 4096 | crates/disrobe-pass-swift-objc/src/swift_reflect.rs |
disrobe-pass-swift-objc | MAX_DESCRIPTORS | other | silent: while condition in parse_field_descriptors | usize | 1 << 18 | crates/disrobe-pass-swift-objc/src/swift_reflect.rs |
disrobe-pass-swift-objc | MAX_FIELDS_PER_TYPE | other | silent: .min() clamp in read_field_list; break in parse_field_descriptors | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/swift_reflect.rs |
disrobe-pass-swift-objc | MAX_NAME_LEN | size | silent: ? on a checked operation in cstr_at_offset | usize | 4096 | crates/disrobe-pass-swift-objc/src/swift_symbolic.rs |
disrobe-pass-swift-objc | MAX_PARENT_WALK | other | silent: break in synthesize_nominal_mangling | usize | 16 | crates/disrobe-pass-swift-objc/src/swift_symbolic.rs |
disrobe-pass-swift-objc | MAX_NAME_LEN | size | silent: ? on a checked operation in cstr_at_offset | usize | 4096 | crates/disrobe-pass-swift-objc/src/swift_typedump.rs |
disrobe-pass-swift-objc | MAX_PARENT_WALK | other | silent: break in walk_parent_names | usize | 16 | crates/disrobe-pass-swift-objc/src/swift_typedump.rs |
disrobe-pass-swift-objc | MAX_PROTOCOL_REQUIREMENTS | other | silent: .min() clamp in read_protocol_requirements | usize | 1 << 14 | crates/disrobe-pass-swift-objc/src/swift_typedump.rs |
disrobe-pass-swift-objc | MAX_TYPE_RECORDS | count | error: Error::BadDyldCache (DR-IOS-0016) | usize | 1 << 16 | crates/disrobe-pass-swift-objc/src/swift_typedump.rs |
disrobe-pass-swift-objc | MAX_ARRAY_LEN | size | error: Error::BadBitstream (DR-IOS-0014) | u64 | 1 << 26 | crates/disrobe-pass-swift-objc/src/swiftmodule.rs |
disrobe-pass-swift-objc | MAX_DEPTH | recursion | error: Error::BadBitstream (DR-IOS-0014) | usize | 64 | crates/disrobe-pass-swift-objc/src/swiftmodule.rs |
disrobe-pass-swift-objc | MAX_VBR_PIECES | other | error: Error::BadBitstream (DR-IOS-0014) | u32 | 16 | crates/disrobe-pass-swift-objc/src/swiftmodule.rs |
disrobe-pass-swift-objc | MAX_TOOLCHAIN_HINTS | other | silent: .take() in report | usize | 16 | crates/disrobe-pass-swift-objc/src/toolchain.rs |
disrobe-pass-wasm-deob | MAX_BOUNDARY_LINKS | other | error: BoundaryLinksError::TooManyLinks; BoundaryNamePropagationError::WorkLimitExceeded; Error::Parse (DR-WASMDEOB-0001) | usize | 2_048 | crates/disrobe-pass-wasm-deob/src/boundary_links.rs |
disrobe-pass-wasm-deob | MAX_BOUNDARY_LINKS_JSON_BYTES | size | error: BoundaryLinksError::InputTooLarge | usize | 1_048_576 | crates/disrobe-pass-wasm-deob/src/boundary_links.rs |
disrobe-pass-wasm-deob | MAX_BOUNDARY_LINK_STRING_BYTES | size | error: BoundaryLinksError::InvalidLanguage; BoundaryLinksError::StringTooLong; BoundaryNamePropagationError::NameTooLong | usize | 4_096 | crates/disrobe-pass-wasm-deob/src/boundary_links.rs |
disrobe-pass-wasm-deob | MAX_BOUNDARY_NAME_PROPAGATION_WORK | work | error: BoundaryNamePropagationError::WorkLimitExceeded | usize | MAX_BOUNDARY_NAME_SEEDS * MAX_BOUNDARY_LINKS * 4 | crates/disrobe-pass-wasm-deob/src/boundary_name_propagation.rs |
disrobe-pass-wasm-deob | MAX_BOUNDARY_NAME_SEEDS | other | error: BoundaryNamePropagationError::TooManyNames; BoundaryNamePropagationError::WorkLimitExceeded | usize | 256 | crates/disrobe-pass-wasm-deob/src/boundary_name_propagation.rs |
disrobe-pass-wasm-deob | MAX_BODY_OPS | work | silent: break in fingerprint_body | usize | 2_000_000 | crates/disrobe-pass-wasm-deob/src/fingerprint.rs |
disrobe-pass-wasm-deob | MAX_ORIGIN_DEPTH | recursion | error: TypeRecoveryRefusal::AddressDepth | u32 | 1024 | crates/disrobe-pass-wasm-deob/src/lib.rs |
disrobe-pass-wasm-deob | MAX_RENDER_INDENT | output | silent: .min() clamp in pad; .min() clamp in render_operators | usize | 64 | crates/disrobe-pass-wasm-deob/src/lib.rs |
disrobe-pass-wasm-deob | MAX_TYPESCRIPT_EXPORT_NAME_BYTES | size | error: AtomicMemoryRefusal::ExportNameBytes | usize | 16 * 1024 * 1024 | crates/disrobe-pass-wasm-deob/src/lift.rs |
disrobe-pass-wasm-deob | MAX_TYPESCRIPT_MODULE_EXPORTS | other | error: AtomicMemoryRefusal::ExportCount | usize | 65_536 | crates/disrobe-pass-wasm-deob/src/lift.rs |
disrobe-pass-wasm-deob | MAX_TYPESCRIPT_MODULE_FUNCTIONS | other | error: AtomicMemoryRefusal::FunctionCount | usize | 4096 | crates/disrobe-pass-wasm-deob/src/lift.rs |
disrobe-pass-wasm-deob | DATA_ESCAPE_PREALLOC_CAP | other | allocation: with_capacity in encode_data_bytes | usize | 1 << 20 | crates/disrobe-pass-wasm-deob/src/lift_module_faithful.rs |
disrobe-pass-wasm-deob | MAX_SYNTHETIC_STRUCT_FIELDS | other | silent: .clamp() clamp in record_struct_field_count; .min() clamp in record_struct_new_field_types; return in record_struct_field_index | u32 | 4096 | crates/disrobe-pass-wasm-deob/src/lift_wat.rs |
disrobe-pass-wasm-deob | MAX_TREE_NODES | count | silent: return in lower_inner | usize | 64 | crates/disrobe-pass-wasm-deob/src/obfuscators/mba.rs |
disrobe-pass-wasm-deob | MAX_GENERATED_NAMES | other | error: Error::Parse (DR-WASMDEOB-0001) | usize | 65_536 | crates/disrobe-pass-wasm-deob/src/obfuscators/name_obfuscator/name_section.rs |
disrobe-pass-wasm-deob | MAX_MODULE_BYTES | size | error: Error::ModuleInputLimit (DR-WASMDEOB-0005) | usize | 64 * 1024 * 1024 | crates/disrobe-pass-wasm-deob/src/obfuscators/name_obfuscator/name_section.rs |
disrobe-pass-wasm-deob | MAX_SECTION_HEADER_BYTES | size | error: Error::Parse (DR-WASMDEOB-0001) | usize | 5 | crates/disrobe-pass-wasm-deob/src/obfuscators/name_obfuscator/name_section.rs |
disrobe-pass-wasm-deob | MAX_ITERATIONS | work | silent: break in unflatten; for range in unflatten_to_fixed_point | usize | 64 | crates/disrobe-pass-wasm-deob/src/obfuscators/tigress/unflatten.rs |
disrobe-pass-wasm-deob | FUEL_BUDGET | work | delegated: .set_fuel()? | u64 | 100_000_000 | crates/disrobe-pass-wasm-deob/src/obfuscators/wasmixer/sandbox_unwrap.rs |
disrobe-pass-wasm-deob | TABLE_ELEMENT_LIMIT | other | delegated: .call()?; .get_memory()?; .instantiate()?; 1 more | usize | 1 << 16 | crates/disrobe-pass-wasm-deob/src/obfuscators/wasmixer/sandbox_unwrap.rs |
disrobe-pass-wasm-deob | MAX_EXPR_NODES | count | silent: return in parse_value | usize | 96 | crates/disrobe-pass-wasm-deob/src/recover.rs |
disrobe-pass-wasm-deob | MAX_FOLD_INSTRUCTIONS | other | recorded: flag intra_function_folding_skipped | usize | 1 << 21 | crates/disrobe-pass-wasm-deob/src/recover.rs |
disrobe-pass-wasm-deob | NESTED_SEQ_LIMIT | recursion | recorded: flag truncated | usize | 4096 | crates/disrobe-pass-wasm-deob/src/recover/cff.rs |
disrobe-pass-wasm-deob | MAX_GUARD_LEN | size | silent: return in match_diamond | usize | 64 | crates/disrobe-pass-wasm-deob/src/recover/opaque.rs |
disrobe-pass-wasm-deob | MAX_CALL_DEPTH | recursion | silent: return in invoke | u32 | 8 | crates/disrobe-pass-wasm-deob/src/recover/pure_eval.rs |
disrobe-pass-wasm-deob | MAX_MODULE_STEPS | work | recorded: flag guard_folding_budget_exhausted | u64 | 50_000_000 | crates/disrobe-pass-wasm-deob/src/recover/pure_eval.rs |
disrobe-pass-wasm-deob | MAX_STEPS | work | silent: return in eval_guard; return in run_seq | u64 | 2_000_000 | crates/disrobe-pass-wasm-deob/src/recover/pure_eval.rs |
disrobe-pass-wasm-deob | MAX_VALUE_STACK | other | silent: return in run_seq | usize | 4_096 | crates/disrobe-pass-wasm-deob/src/recover/pure_eval.rs |
disrobe-pass-wasm-deob | MULTI_EXIT_LIMIT | other | unclassified: match pattern in render | usize | 16 | crates/disrobe-pass-wasm-deob/src/recover/reloop.rs |
disrobe-pass-wasm-deob | NODE_LIMIT | other | silent: .take() in collect_branch_transitions; return in accesses_cell_outside_root; return in accesses_cell; 8 more | usize | 512 | crates/disrobe-pass-wasm-deob/src/recover/reloop.rs |
disrobe-pass-wasm-deob | STATE_EXPRESSION_LIMIT | other | silent: ? on a checked operation in expression_suffix; ? on a checked operation in state_write_expression; return in eval_value; 5 more | usize | 64 | crates/disrobe-pass-wasm-deob/src/recover/reloop.rs |
disrobe-pass-wasm-deob | TRANSITION_INSTRUCTION_LIMIT | other | silent: return in classify_select_conditional; return in condition_has_isolated_value_stack; return in structured_work_is_bounded | usize | 512 | crates/disrobe-pass-wasm-deob/src/recover/reloop.rs |
disrobe-pass-wasm-deob | MAX_BOUNDARY_RESOURCES | other | error: Error::Parse (DR-WASMDEOB-0001) | usize | MAX_BOUNDARY_LINKS | crates/disrobe-pass-wasm-deob/src/signature.rs |
disrobe-pass-wasm-deob | MAX_FUNCTION_LOCALS | other | delegated: passed to iter::repeat_n | usize | 100_000 | crates/disrobe-pass-wasm-deob/src/signature.rs |
disrobe-pass-webview | COMPRESSED_SAMPLE_CAP | other | silent: .min() clamp in looks_compressed | usize | 4096 | crates/disrobe-pass-webview/src/decompress.rs |
disrobe-pass-webview | MAX_EVIDENCE_MARKERS | other | silent: .truncate() in classify_all; .truncate() in marker_evidence | usize | 8 | crates/disrobe-pass-webview/src/detect.rs |
disrobe-pass-webview | MAX_ENTRY_PATH_BYTES | size | silent: return in bounded_join; while condition in bounded_join; slice in bounded_join | usize | 4096 | crates/disrobe-pass-webview/src/electron.rs |
disrobe-pass-webview | MAX_EXTENSION_LEN | size | silent: continue in scan; no action in best_window | usize | 16 | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_HASH_HAMMING | other | silent: fallback value in hash_window | usize | 1 | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_PATH_LEN | size | silent: return in validate | usize | 4096 | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_RECORD_BLOB | other | unclassified: pattern binding in validate | usize | 256 * 1024 * 1024 | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_SCAN_RECORDS | count | silent: return in collect_runs; skipped in collect_runs | usize | 2_000_000 | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_UNREADABLE_GAP | other | silent: break in collect_runs | usize | 2 | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_FAT_SLICES | other | silent: .take() in build_slices | usize | 64 | crates/disrobe-pass-webview/src/resolve.rs |
disrobe-pass-webview | MAX_OVERLAP_WALK | other | silent: slice in containing | usize | 64 | crates/disrobe-pass-webview/src/resolve.rs |
disrobe-pass-webview | MAX_SPANS | other | silent: break in build | usize | 4096 | crates/disrobe-pass-webview/src/resolve.rs |
disrobe-playground | MAX_CIRCULAR_FILES_SCANNED | count | silent: break in scan_circularity | usize | 16_384 | crates/disrobe-playground/src/circular.rs |
disrobe-playground | MAX_CIRCULAR_FILE_BYTES | size | silent: .take() in read_text_bounded; return in read_text_bounded | u64 | 1024 * 1024 | crates/disrobe-playground/src/circular.rs |
disrobe-playground | MAX_DISCOVERED_PACKED_PAIRS | other | silent: break in discover_packed_pairs | usize | 4096 | crates/disrobe-playground/src/manifest.rs |
disrobe-playground | MAX_DISCOVERED_RECOMPILE_PYC | other | silent: break in discover_recompile_pyc | usize | 4096 | crates/disrobe-playground/src/manifest.rs |
disrobe-playground | MAX_MANIFEST_FILES | count | silent: break in build | usize | 4096 | crates/disrobe-playground/src/manifest.rs |
disrobe-playground | MAX_MANIFEST_TOML_BYTES | size | silent: .take() in read_text_bounded; return in read_text_bounded | u64 | 1024 * 1024 | crates/disrobe-playground/src/manifest.rs |
disrobe-playground | MAX_NATIVE_MATCH_INPUT_BYTES | size | error: NativeMatchUploadError::InputTooLarge (DR-PLAYGROUND-0100) | usize | 64 * 1024 * 1024 | crates/disrobe-playground/src/native_match.rs |
disrobe-playground | MAX_SOURCE_BYTES | size | delegated: lift_module_source_with_limit()? | usize | 64 * 1024 * 1024 | crates/disrobe-playground/src/wasm.rs |
disrobe-plugin-host | DEFAULT_FUEL_BUDGET | work | delegated: .set_fuel()? | u64 | 50_000_000 | crates/disrobe-plugin-host/src/lib.rs |
disrobe-plugin-host | MAX_FUEL_BUDGET | work | delegated: .set_fuel()? | u64 | 1_000_000_000 | crates/disrobe-plugin-host/src/lib.rs |
disrobe-plugin-host | MAX_MEMORY_CAP_BYTES | size | error: SandboxError::Memory | usize | 256 * 1024 * 1024 | crates/disrobe-plugin-host/src/lib.rs |
disrobe-plugin-host | MAX_WALL_DEADLINE | other | error: SandboxError::Timeout | Duration | Duration::from_secs(30) | crates/disrobe-plugin-host/src/lib.rs |
disrobe-plugin-host | MAX_WASM_MODULE_BYTES | size | error: SandboxError::ModuleTooLarge | usize | DEFAULT_MEMORY_CAP_BYTES | crates/disrobe-plugin-host/src/lib.rs |
disrobe-plugin-loader | MAX_SIGNATURE_BYTES | size | error: LoaderError::SignatureTooLarge | usize | 16 * 1024 | crates/disrobe-plugin-loader/src/lib.rs |
disrobe-plugin-loader | MAX_SIGNED_COMPONENT_BYTES | size | error: LoaderError::ComponentTooLarge | usize | 16 * 1024 * 1024 | crates/disrobe-plugin-loader/src/lib.rs |
disrobe-plugin-loader | MAX_CAPABILITIES | other | error: ManifestError::TooManyCapabilities | usize | 128 | crates/disrobe-plugin-loader/src/manifest.rs |
disrobe-plugin-loader | MAX_CAPABILITY_BYTES | size | error: ManifestError::CapabilityTooLarge | usize | 256 | crates/disrobe-plugin-loader/src/manifest.rs |
disrobe-plugin-loader | MAX_MANIFEST_NAME_BYTES | size | error: ManifestError::NameTooLarge | usize | 128 | crates/disrobe-plugin-loader/src/manifest.rs |
disrobe-plugin-loader | MAX_MANIFEST_TOML_BYTES | size | error: ManifestError::ManifestTooLarge | usize | 64 * 1024 | crates/disrobe-plugin-loader/src/manifest.rs |
disrobe-plugin-loader | MAX_MANIFEST_VERSION_BYTES | size | error: ManifestError::VersionTooLarge | usize | 64 | crates/disrobe-plugin-loader/src/manifest.rs |
disrobe-prowl | MAX_CONFIG_BYTES | size | error: KeyError::ConfigTooLarge | u64 | 1 << 20 | crates/disrobe-prowl/src/keys.rs |
disrobe-py-marshal | BYTE_BUDGET | work | error: Error::ByteBudget (DR-MARSHAL-0018) | u64 | 1024 * 1024 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | BYTE_BUDGET | work | error: Error::ByteBudget (DR-MARSHAL-0018) | u64 | 512 * 1024 * 1024 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_COLLECTION_ITEMS | count | error: Error::LengthOverflow (DR-MARSHAL-0011) | usize | 1 << 20 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_DEPTH | recursion | error: Error::DepthLimit (DR-MARSHAL-0009) | usize | 256 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_DICT_ENTRIES | count | error: Error::LengthOverflow (DR-MARSHAL-0011) | usize | 1 << 20 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_INTERNED_STRINGS | other | error: Error::LengthOverflow (DR-MARSHAL-0011) | usize | 1 << 13 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_INTERNED_STRINGS | other | error: Error::LengthOverflow (DR-MARSHAL-0011) | usize | 1 << 20 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_LEN | size | error: Error::LengthOverflow (DR-MARSHAL-0011) | u32 | 1 << 28 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_LONG_DIGITS | other | error: Error::LongDigitOverflow (DR-MARSHAL-0010) | u32 | 1 << 24 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_OBJECT_PREALLOC | other | allocation: with_capacity in read_n_objects | usize | 1024 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_REFS | other | error: Error::LengthOverflow (DR-MARSHAL-0011) | usize | 1 << 20 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_TRACE_ENTRIES | count | recorded: flag entries_omitted | usize | 1 << 12 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | MAX_TRACE_ENTRIES | count | recorded: flag entries_omitted | usize | 1 << 20 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-py-marshal | NODE_BUDGET | work | error: Error::NodeBudget (DR-MARSHAL-0014) | u64 | 8_000_000 | crates/disrobe-py-marshal/src/reader.rs |
disrobe-pyarmor-cextract | MAX_CAPTURED_CODE_OBJECTS | other | error: CextractError::CaptureLimit | usize | 65_536 | crates/disrobe-pyarmor-cextract/src/capture.rs |
disrobe-pyarmor-cextract | MAX_CAPTURED_PYC_BYTES | size | error: CextractError::CaptureLimit | usize | 256 * 1024 * 1024 | crates/disrobe-pyarmor-cextract/src/capture.rs |
disrobe-pyarmor-cextract | MAX_PROLOGUE_SCAN | other | error: CextractError::HotpatchFailed | usize | 32 | crates/disrobe-pyarmor-cextract/src/hotpatch/x86_disasm.rs |
disrobe-pyarmor-cextract | MAX_MARSHAL_BODY_BYTES | size | error: CextractError::PycTooLarge | usize | 16 * 1024 * 1024 | crates/disrobe-pyarmor-cextract/src/marshal_writer.rs |
disrobe-pyarmor-pytrace | MAX_CAPTURED | other | silent: skipped in _trace_callback | usize | 262_144 | crates/disrobe-pyarmor-pytrace/src/lib.rs |
disrobe-pyarmor-pytrace | MAX_DRAIN_OUTPUTS | output | error: untyped format! | usize | 65_536 | crates/disrobe-pyarmor-pytrace/src/lib.rs |
disrobe-pyarmor-pytrace | MAX_DRAIN_OUTPUT_BYTES | output | error: DrainLimitError::OutputBytes | usize | 256 * 1024 * 1024 | crates/disrobe-pyarmor-pytrace/src/lib.rs |
disrobe-pyarmor-pytrace | MAX_MARSHALLED_CODE_BYTES | size | error: DrainLimitError::MarshalledCodeObject | usize | 16 * 1024 * 1024 | crates/disrobe-pyarmor-pytrace/src/lib.rs |
disrobe-python | MAX_CONTAINER_INPUT_BYTES | size | error: untyped format! | usize | 256 * 1024 * 1024 | crates/disrobe-python/src/container.rs |
disrobe-python | MAX_PY_JSON_DEPTH | recursion | error: untyped format! | usize | 256 | crates/disrobe-python/src/convert.rs |
disrobe-python | MAX_PY_JSON_ITEMS | count | error: untyped format! | usize | 1_000_000 | crates/disrobe-python/src/convert.rs |
disrobe-query | MAX_JVM_HIERARCHY_DESCRIPTOR_BYTES | size | recorded: JvmHierarchyDiagnostic::DescriptorBytesLimit; JvmHierarchyDiagnostic::MissingDefinitionDiagnosticLimit; JvmHierarchyDiagnostic::TargetDescriptorBytesLimit; 2 more | usize | 1_048_576 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_HIERARCHY_EDGES | other | recorded: JvmHierarchyDiagnostic::EdgeLimit; diagnostics | usize | 65_536 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_HIERARCHY_NODES | count | recorded: JvmHierarchyDiagnostic::NodeLimit; diagnostics | usize | 16_384 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_IMPLEMENTOR_MATCHES | other | recorded: JvmHierarchyDiagnostic::MatchLimit; diagnostics | usize | 16_384 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_MALFORMED_DESCRIPTOR_BYTES | size | recorded: JvmHierarchyDiagnostic::MalformedDescriptorDiagnosticLimit; flag truncated | usize | 1_048_576 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_MALFORMED_DESCRIPTOR_DIAGNOSTICS | other | recorded: JvmHierarchyDiagnostic::MalformedDescriptorDiagnosticLimit; flag truncated | usize | 16_384 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_MISSING_DEFINITION_DIAGNOSTICS | other | recorded: JvmHierarchyDiagnostic::MissingDefinitionDiagnosticLimit; flag missing_diagnostics_truncated | usize | 16_384 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_PROOF_BYTES | size | recorded: JvmHierarchyDiagnostic::ProofBytesLimit; diagnostics | usize | 1_048_576 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_PROOF_DEPTH | recursion | recorded: JvmHierarchyDiagnostic::ProofDepthLimit; diagnostics | usize | 256 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_JVM_PROOF_ELEMENTS | other | recorded: JvmHierarchyDiagnostic::ProofElementsLimit; diagnostics | usize | 65_536 | crates/disrobe-query/src/jvm.rs |
disrobe-query | MAX_QUERY_ARGUMENT_BYTES | size | error: ParseError::ArgumentTooLong | usize | 4 * 1024 | crates/disrobe-query/src/parse.rs |
disrobe-query | MAX_QUERY_BYTES | size | error: ParseError::TooLong | usize | 8 * 1024 | crates/disrobe-query/src/parse.rs |
disrobe-semdiff | MAX_LINEAGE_VARIANTS | other | silent: slice in variant_lineage | usize | 32 | crates/disrobe-semdiff/src/lineage.rs |
disrobe-semdiff | MAX_FUNCTIONS_PER_MODULE | other | recorded: Indeterminate::FunctionCountCapExceeded; refused_report() | usize | 50_000 | crates/disrobe-semdiff/src/structural.rs |
disrobe-semdiff | MAX_PROPAGATION_ROUNDS | work | recorded: flag exhausted_by_cap | u32 | 8 | crates/disrobe-semdiff/src/structural.rs |
disrobe-semdiff | MAX_ADDRESS_PEEL_STEPS | work | silent: while condition in address_form | u32 | 32 | crates/disrobe-semdiff/src/summary.rs |
disrobe-semdiff | MAX_SUMMARY_BLOCKS | other | error: SummaryDecline::BlockCountExceeded | usize | 128 | crates/disrobe-semdiff/src/summary.rs |
disrobe-semdiff | MAX_SUMMARY_DEPTH | recursion | recorded: SummaryDecline::DepthBudgetExhausted | u32 | 128 | crates/disrobe-semdiff/src/summary.rs |
disrobe-semdiff | MAX_SUMMARY_INSTRUCTIONS | other | error: SummaryDecline::InstructionCountExceeded | usize | 4096 | crates/disrobe-semdiff/src/summary.rs |
disrobe-semdiff | MAX_SUMMARY_MEMORY_CELLS | other | recorded: SummaryDecline::MemoryCellBudgetExhausted | usize | 256 | crates/disrobe-semdiff/src/summary.rs |
disrobe-semdiff | MAX_SUMMARY_NODES | count | recorded: SummaryDecline::NodeBudgetExhausted | usize | 4096 | crates/disrobe-semdiff/src/summary.rs |
disrobe-semdiff | MAX_SUMMARY_OUTPUTS | output | recorded: SummaryDecline::OutputBudgetExhausted | usize | 64 | crates/disrobe-semdiff/src/summary.rs |
disrobe-similarity | REFINEMENT_ROUND_CAP | work | silent: for range in refine | usize | 16 | crates/disrobe-similarity/src/fingerprint.rs |
disrobe-similarity | PROPAGATION_ROUND_CAP | work | silent: for range in propagate | usize | 64 | crates/disrobe-similarity/src/matcher/propagation.rs |
disrobe-similarity | DEFAULT_LISTING_LIMIT | other | unused: no use in the crate | usize | 25 | crates/disrobe-similarity/src/presentation.rs |
disrobe-sleigh | MAX_DECODE_CONSTRUCTOR_ATTEMPTS | other | recorded: DecodeOutcome::ResourceLimit; flag exceeded | usize | 65_536 | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | MAX_EVALUATION_DEPTH | recursion | error: SleighError::Parse | usize | 128 | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | MAX_FIXED_BITS_MEMO_ENTRIES | count | silent: skipped in table_bits | usize | 65_536 | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | MAX_PATTERN_CLAUSES | other | recorded: flag unavailable | usize | 4_096 | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | MAX_TABLE_CLAUSE_MEMO_CLAUSES | other | silent: return in remember_table_clauses | usize | 4_194_304 | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | MAX_TABLE_CLAUSE_MEMO_ENTRIES | count | silent: return in remember_table_clauses | usize | 65_536 | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | MAX_TABLE_CONSTRUCTORS | other | error: SleighError::Parse | usize | 4_096 | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | UNSUPPORTED_ENCODING_CAPTURE_LIMIT | other | silent: .min() clamp in unsupported_length | usize | 24 | crates/disrobe-sleigh/src/lifter/riscv.rs |
disrobe-sleigh | MAX_CONDITION_DEPTH | recursion | silent: return in parse_unary | usize | 64 | crates/disrobe-sleigh/src/preprocessor.rs |
disrobe-sleigh | MAX_ITEM_DEPTH | recursion | silent: return in parse_with | usize | 64 | crates/disrobe-sleigh/src/syntax.rs |
disrobe-sleigh | MAX_PATTERN_NESTING | recursion | silent: return in pattern_nesting_exceeds | usize | 64 | crates/disrobe-sleigh/src/syntax.rs |
disrobe-sleigh | MAX_SOURCE_BYTES | size | error: SleighError::Parse | usize | 4 * 1024 * 1024 | crates/disrobe-sleigh/src/syntax.rs |
disrobe-sleigh | MAX_TOKEN_COUNT | count | error: SleighError::Parse | usize | 500_000 | crates/disrobe-sleigh/src/syntax.rs |
disrobe-taint | CALL_EDGE_TARGET_CAP | other | recorded: CallEdgeEvidence::CandidateSetLimit; flag over_cap | usize | 4_096 | crates/disrobe-taint/src/callgraph.rs |
disrobe-taint | MAX_INTERNED | other | recorded: flag truncated | u16 | 63 | crates/disrobe-taint/src/config.rs |
disrobe-taint | MAX_OUT_ARGUMENTS_PER_SOURCE | other | silent: skipped in insert_out_argument | usize | 32 | crates/disrobe-taint/src/config.rs |
disrobe-taint | MAX_PATH_STEPS | work | silent: .truncate() in append_step; no action in append_step | usize | 128 | crates/disrobe-taint/src/engine.rs |
disrobe-taint | MAX_RECORDED_UNRESOLVED_CALLS | other | silent: skipped in collect_unresolved_calls | usize | 4096 | crates/disrobe-taint/src/engine.rs |
disrobe-testkit | MAX_SOURCE_BYTES | size | error: AuthoredSourceError::TooLarge | u64 | 8 * 1024 * 1024 | crates/disrobe-testkit/src/authored_source.rs |
disrobe-testkit | MAX_OPTIONAL_LIST_BYTES | size | error: PrerequisiteError::OptionalListTooLarge | u64 | 256 * 1024 | crates/disrobe-testkit/src/prerequisite.rs |
disrobe-testkit | MAX_RECORD_NAME | other | silent: .take() in record_name | usize | 160 | crates/disrobe-testkit/src/prerequisite.rs |
disrobe-testkit | MAX_CORPUS_ENTRY_BYTES | size | error: StressError::CorpusEntryTooLarge | usize | MAX_WIRE_CASE_BYTES / 4 | crates/disrobe-testkit/src/wire.rs |
disrobe-testkit | MAX_ENTRY_NAME_BYTES | size | error: ErrorKind::InvalidData; StressError::Inconsistent | usize | 4096 | crates/disrobe-testkit/src/wire.rs |
disrobe-testkit | MAX_WIRE_CASE_BYTES | size | error: ErrorKind::InvalidData; StressError::CorpusEntryTooLarge; StressError::MutatedCaseTooLarge | usize | 8 * 1024 * 1024 | crates/disrobe-testkit/src/wire.rs |
disrobe-tool-process | MAX_GROUP_MEMBERS | count | silent: return in macos_group_contains_only_zombies | usize | 1024 | crates/disrobe-tool-process/src/unix.rs |
disrobe-tool-process | MAX_COMMAND_LINE_UNITS | other | error: LaunchError::InvalidInput | usize | 32_767 | crates/disrobe-tool-process/src/windows.rs |
disrobe-tool-process | MAX_ENVIRONMENT_BLOCK_UNITS | other | error: LaunchError::InvalidInput | usize | 1_048_576 | crates/disrobe-tool-process/src/windows.rs |
disrobe-tool-process | MAX_ENVIRONMENT_INPUT_ENTRIES | count | error: LaunchError::InvalidInput | usize | 1_048_576 | crates/disrobe-tool-process/src/windows.rs |
disrobe-tool-process | MAX_ENVIRONMENT_STRING_UNITS | other | error: LaunchError::InvalidInput | usize | 32_767 | crates/disrobe-tool-process/src/windows.rs |
disrobe-tool-process | MAX_NORMAL_PROGRAM_PATH_UNITS | other | silent: return in child_visible_path | usize | 259 | crates/disrobe-tool-process/src/windows.rs |
disrobe-tool-process | MAX_RETAINED_ENVIRONMENT_BYTES | size | error: LaunchError::InvalidInput | usize | 32 * 1024 * 1024 | crates/disrobe-tool-process/src/windows.rs |
disrobe-typerec | MAX_COPY_DEPTH | recursion | silent: return in reg_slot_source | u8 | 8 | crates/disrobe-typerec/src/callsite.rs |
disrobe-typerec | MAX_THUNK_INSNS | other | silent: .take() in follow_thunk; slice in follow_thunk | usize | 8 | crates/disrobe-typerec/src/callsite.rs |
disrobe-typerec | MIN_SOLVE_BUDGET | work | silent: break in solve | usize | 4096 | crates/disrobe-typerec/src/constraint.rs |
disrobe-typerec | MAX_DECODE_INSNS | other | silent: while condition in decode_all | usize | 1 << 16 | crates/disrobe-typerec/src/decode.rs |
disrobe-typerec | MAX_DIE_VISITS | other | silent: break in collect_unit; break in walk_functions | usize | 1 << 20 | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_FIELDS | other | silent: return in flatten_members | usize | 1 << 12 | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_PARAMS | other | silent: skipped in collect_unit | usize | 64 | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_TYPE_DEPTH | recursion | silent: return in flatten_members; return in name_through_origin; return in resolve_int_type; 2 more | u8 | 16 | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_UNITS | other | silent: break in walk_functions | usize | 1 << 12 | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_VARS_PER_FUNCTION | other | recorded: .record_unlocated(); UnlocatedReason::VariableBudgetExhausted | usize | 1 << 12 | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_EXPRESSION_OPERATIONS | other | silent: return in classify_expression | usize | 64 | crates/disrobe-typerec/src/dwarf_location.rs |
disrobe-typerec | MAX_LOCATION_LIST_ENTRIES | count | silent: while condition in frame_slots; while condition in resolve_frame_base; skipped in push_slots; 1 more | usize | 512 | crates/disrobe-typerec/src/dwarf_location.rs |
disrobe-typerec | MAX_PROLOGUE_INSTRUCTIONS | other | silent: while condition in frame_pointer_delta_from_prologue | usize | 32 | crates/disrobe-typerec/src/dwarf_location.rs |
disrobe-typerec | MAX_DESCRIPTORS | other | silent: break in collect_pe_delay; break in collect_pe_imports | usize | 1 << 14 | crates/disrobe-typerec/src/import_map.rs |
disrobe-typerec | MAX_ENTRIES | count | silent: break in collect_pe_delay; break in collect_pe_imports; break in collect_pe_thunks; 3 more | usize | 1 << 21 | crates/disrobe-typerec/src/import_map.rs |
disrobe-typerec | MAX_THUNKS | other | silent: break in collect_pe_delay; break in collect_pe_thunks | u64 | 1 << 20 | crates/disrobe-typerec/src/import_map.rs |
disrobe-typerec | MAX_HEAP_BLOCKS | other | silent: return in heap_registers | usize | 1 << 12 | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_HEAP_ROUNDS | work | silent: .min() clamp in heap_registers | usize | 1 << 3 | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_HEAP_SLOTS | other | silent: skipped in heap_transfer | usize | 1 << 6 | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_REGION_CELLS | other | recorded: flag capped | usize | 1 << 8 | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_STACK_SLOTS | other | silent: return in group_offsets | usize | 1 << 12 | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_ALLOCATOR_SITES | other | silent: return in record_allocator_site | usize | 1 << 12 | crates/disrobe-typerec/src/region.rs |
disrobe-typerec | MAX_ALLOCATOR_SYMBOLS | other | silent: .take() in absorb_allocator_definitions | usize | 1 << 20 | crates/disrobe-typerec/src/region.rs |
disrobe-typerec | MAX_RELOC_TARGETS | other | silent: return in record_reloc_target | usize | 1 << 16 | crates/disrobe-typerec/src/region.rs |
disrobe-typerec | MAX_SECTIONS | other | silent: .take() in absorb_allocator_thunks; .take() in absorb_relocations; .take() in absorb_sections | usize | 1 << 12 | crates/disrobe-typerec/src/region.rs |
disrobe-typerec | MAX_THUNK_SCAN | other | silent: return in absorb_allocator_thunks; slice in absorb_allocator_thunks | usize | 1 << 24 | crates/disrobe-typerec/src/region.rs |
disrobe-validator | MAX_CORPUS_DEPTH | recursion | silent: return in collect | usize | 64 | crates/disrobe-validator/src/corpus.rs |
disrobe-validator | MAX_CORPUS_ENTRIES | count | silent: return in collect | usize | 65_536 | crates/disrobe-validator/src/corpus.rs |
disrobe-validator | MAX_HASH_DEPTH | recursion | error: untyped format! | usize | 64 | crates/disrobe-validator/src/runner.rs |
disrobe-validator | MAX_HASH_FILES | count | error: untyped format! | usize | 65_536 | crates/disrobe-validator/src/runner.rs |
disrobe-validator | MAX_HASH_FILE_BYTES | size | error: untyped format! | u64 | 64 * 1024 * 1024 | crates/disrobe-validator/src/runner.rs |
disrobe-validator | MAX_SAMPLE_BYTES | size | error: untyped format! | u64 | 256 * 1024 * 1024 | crates/disrobe-validator/src/runner.rs |
disrobe-vulnmatch | MAX_RESOLVED_INDIRECT_CALLEES_PER_SITE | other | recorded: flag traversal_complete | usize | 16 | crates/disrobe-vulnmatch/src/adapters.rs |
disrobe-vulnmatch | MAX_CONSTRAINT_BYTES | size | error: ConstraintError::TooLong | usize | 8 * 1024 | crates/disrobe-vulnmatch/src/constraint.rs |
disrobe-vulnmatch | MAX_CONSTRAINT_NODES | count | error: ConstraintError::TooManyPredicates; VersionScheme::Python | usize | 256 | crates/disrobe-vulnmatch/src/constraint.rs |
disrobe-vulnmatch | MAX_PACKAGE_MATCH_INPUTS | other | recorded: PackageMatchIssue::LimitExceeded; flag complete | usize | 16_384 | crates/disrobe-vulnmatch/src/matcher.rs |
disrobe-vulnmatch | MAX_PACKAGE_MATCH_OUTPUT_BYTES | output | recorded: PackageMatchIssue::LimitExceeded; flag complete | usize | 32 * 1024 * 1024 | crates/disrobe-vulnmatch/src/matcher.rs |
disrobe-vulnmatch | MAX_PACKAGE_MATCH_RESULTS | other | recorded: PackageMatchIssue::LimitExceeded; flag complete | usize | 16_384 | crates/disrobe-vulnmatch/src/matcher.rs |
disrobe-vulnmatch | MAX_PACKAGE_MATCH_TEXT_BYTES | size | recorded: PackageMatchIssue::LimitExceeded; flag complete | usize | 8 * 1024 | crates/disrobe-vulnmatch/src/matcher.rs |
disrobe-vulnmatch | MAX_PACKAGE_MATCH_WORK | work | recorded: PackageMatchIssue::LimitExceeded; flag complete | usize | 1_048_576 | crates/disrobe-vulnmatch/src/matcher.rs |
disrobe-vulnmatch | MAX_AFFECTED | other | error: OfflineMatchError::OsvCountLimit | usize | 4_096 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_EVALUATION_WORK | work | error: EvaluationError::WorkLimit | usize | 2_000_000 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_EVENTS | other | error: OfflineMatchError::OsvCountLimit | usize | 512 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_EXPLICIT_VERSIONS | other | error: OfflineMatchError::OsvCountLimit | usize | 8_192 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_FIELD_BYTES | size | error: OfflineMatchError::InvalidOsReleaseValue; OfflineMatchError::MalformedStatus | usize | 64 * 1024 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_FINDINGS | other | recorded: OfflineMatchIssueKind::WorkLimitReached; flag complete | usize | 10_000 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_ISSUES | other | recorded: flag complete | usize | 10_000 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_LINE_BYTES | size | error: OfflineMatchError::LineTooLong | usize | 64 * 1024 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_OSV_BYTES | size | error: OfflineMatchError::AllocationFailed; OfflineMatchError::FileTooLarge | u64 | 16 * 1024 * 1024 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_OS_RELEASE_BYTES | size | error: OfflineMatchError::AllocationFailed; OfflineMatchError::FileTooLarge | u64 | 64 * 1024 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_PACKAGES | other | error: OfflineMatchError::TooManyPackages | usize | 100_000 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_PACKAGE_FIELD_BYTES | size | error: OfflineMatchError::InvalidOsvField | usize | 4 * 1024 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_RANGES | other | error: OfflineMatchError::OsvCountLimit | usize | 128 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_STANZA_BYTES | size | error: OfflineMatchError::StanzaTooLarge | usize | 1024 * 1024 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_STATUS_BYTES | size | error: OfflineMatchError::FileTooLarge | u64 | 256 * 1024 * 1024 | crates/disrobe-vulnmatch/src/offline.rs |
disrobe-vulnmatch | MAX_PACKAGE_URL_INPUT_BYTES | size | error: PackageUrlError::TooLong | usize | 16_384 | crates/disrobe-vulnmatch/src/package_url.rs |
disrobe-vulnmatch | MAX_PACKAGE_URL_OUTPUT_BYTES | output | error: PackageUrlError::OutputTooLong | usize | 56 * 1024 | crates/disrobe-vulnmatch/src/package_url.rs |
disrobe-vulnmatch | MAX_VERSION_BYTES | size | error: VersionError::TooLong | usize | 4 * 1024 | crates/disrobe-vulnmatch/src/version.rs |
disrobe-vulnmatch | MAX_VERSION_PARTS | other | error: VersionScheme::Alpine; VersionScheme::Python; VersionScheme::Semver | usize | 256 | crates/disrobe-vulnmatch/src/version.rs |
disrobe-wasm | MAX_ENTROPY_BLOCKS | other | silent: while condition in entropy | usize | 4096 | crates/disrobe-wasm/src/entry.rs |
disrobe-wasm | MAX_DECODED_BYTES | size | error: untyped format!; untyped error | u64 | 128 * 1024 * 1024 | crates/disrobe-wasm/src/entry/apk.rs |
disrobe-wasm | MAX_ENTRIES | count | error: .to_string() | usize | 4096 | crates/disrobe-wasm/src/entry/apk.rs |
disrobe-wasm | MAX_ENTRY_BYTES | size | error: untyped format! | u64 | 32 * 1024 * 1024 | crates/disrobe-wasm/src/entry/apk.rs |
disrobe-wasm | MAX_MANIFEST_BYTES | size | error: .to_string() | u64 | 2 * 1024 * 1024 | crates/disrobe-wasm/src/entry/apk.rs |
disrobe-wasm | MAX_INSTRUCTIONS | other | error: .to_owned() | usize | 65_536 | crates/disrobe-wasm/src/entry/dotnet.rs |
disrobe-wasm | MAX_METHOD_INSTRUCTIONS | other | error: .to_owned() | usize | 16_384 | crates/disrobe-wasm/src/entry/dotnet.rs |
disrobe-wasm | MAX_IMAGE_NAMES | other | error: .to_string() | usize | 16 * 1024 * 1024 | crates/disrobe-wasm/src/entry/go.rs |
disrobe-wasm | MAX_INPUT | other | error: .to_string() | usize | 16 * 1024 * 1024 | crates/disrobe-wasm/src/entry/go.rs |
disrobe-wasm | MAX_RECORDS | count | error: .to_string() | usize | 131_072 | crates/disrobe-wasm/src/entry/go.rs |
disrobe-wasm | MAX_SYMBOLS | other | error: .to_string() | u64 | 65_536 | crates/disrobe-wasm/src/entry/go.rs |
disrobe-wasm | MAX_TYPES | other | error: .to_string() | u64 | 16_384 | crates/disrobe-wasm/src/entry/go.rs |
disrobe-wasm | MAX_CONSTANT_POOL_SLOTS | other | error: .to_owned() | usize | 16_384 | crates/disrobe-wasm/src/entry/jvm.rs |
disrobe-wasm | MAX_FIELDS | other | error: .to_owned() | usize | 4096 | crates/disrobe-wasm/src/entry/jvm.rs |
disrobe-wasm | MAX_INSTRUCTIONS | other | error: .to_owned() | usize | 65_536 | crates/disrobe-wasm/src/entry/jvm.rs |
disrobe-wasm | MAX_METHODS | other | error: .to_owned() | usize | 1024 | crates/disrobe-wasm/src/entry/jvm.rs |
disrobe-wasm | MAX_METHOD_EDGES | other | error: .to_owned() | usize | 2048 | crates/disrobe-wasm/src/entry/jvm.rs |
disrobe-wasm | MAX_METHOD_INSTRUCTIONS | other | error: .to_owned() | usize | 16_384 | crates/disrobe-wasm/src/entry/jvm.rs |
disrobe-wasm | MAX_ENTRIES | count | error: .to_string() | usize | 4096 | crates/disrobe-wasm/src/entry/phar.rs |
disrobe-wasm | MAX_MEMBER_BYTES | size | error: .to_string() | usize | 32 * 1024 * 1024 | crates/disrobe-wasm/src/entry/phar.rs |
disrobe-wasm | MAX_NAME_BYTES | size | error: .to_string() | usize | 1024 * 1024 | crates/disrobe-wasm/src/entry/phar.rs |
disrobe-wasm | MAX_METADATA_BYTES | size | error: .to_string() | usize | 8 * 1024 * 1024 | crates/disrobe-wasm/src/entry/pyarmor.rs |
disrobe-wasm | MAX_RUNTIME_BYTES | size | error: .to_string() | usize | 16 * 1024 * 1024 | crates/disrobe-wasm/src/entry/pyarmor.rs |
disrobe-wasm | MAX_WRAPPER_BYTES | size | error: .to_string() | usize | 1024 * 1024 | crates/disrobe-wasm/src/entry/pyarmor.rs |
disrobe-wasm | MAX_GUEST_ALLOC | other | silent: return in disrobe_alloc; return in disrobe_free | usize | 1 << 30 | crates/disrobe-wasm/src/lib.rs |
disrobe-wasm | MAX_INPUT_BYTES | size | error: .to_string(); untyped error | usize | 64 * 1024 * 1024 | crates/disrobe-wasm/src/lib.rs |
disrobe-wasm | MAX_RESULT_PAYLOAD | other | silent: return in disrobe_result_free; return in pack_prefixed_result | usize | 64 * 1024 * 1024 | crates/disrobe-wasm/src/lib.rs |
Silent stops
1026 bounds stop a loop, clamp a value or skip work with no typed error and no record when input exceeds them. Each is a defect: a parser recovers or refuses with a label, and malformed input is a typed error.
| Crate | Constant | Use | File |
|---|---|---|---|
disrobe-binfmt | SCAN_HIT_CAP | while condition in scan_magics | crates/disrobe-binfmt/src/carve.rs |
disrobe-binfmt | STREAM_DECODE_CAP | .take() in decode_validate; return in bzip2_exact_extent; return in gzip_exact_extent; 1 more | crates/disrobe-binfmt/src/carve.rs |
disrobe-binfmt | MAX_OMAP_ENTRIES | break in omap_leaf_mappings; for range in walk_fs_tree_leaf | crates/disrobe-binfmt/src/containers/apfs.rs |
disrobe-binfmt | MAX_CRAMFS_DEPTH | break in walk_cramfs | crates/disrobe-binfmt/src/containers/cramfs.rs |
disrobe-binfmt | MAX_CRAMFS_FILES | break in walk_cramfs | crates/disrobe-binfmt/src/containers/cramfs.rs |
disrobe-binfmt | MAX_DOC_LEN | .min() clamp in read_c_string; .take() in find_doc_starting_with | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_FILETABLE_ENTRIES | for range in recover_source_files | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_MODULE_NAME_LEN | return in module_name_from_init; no action in locate_module_init | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_NAME_LEN | .min() clamp in read_c_string; return in is_valid_identifier; skipped in scan_source_strings | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_SOURCE_FILES | skipped in push_unique | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_STRUCTURAL_RECORDS | return in recover_structural | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_STRUCTURAL_SCAN_ATTEMPTS | return in recover_structural | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_TABLE_ENTRIES | while condition in walk_method_table | crates/disrobe-binfmt/src/containers/cython.rs |
disrobe-binfmt | MAX_STUB_BYTES | return in render_cython_stub | crates/disrobe-binfmt/src/containers/cython_stub.rs |
disrobe-binfmt | MAX_MAGIC_CANDIDATES | .take() in magic_offsets | crates/disrobe-binfmt/src/containers/deno_compile.rs |
disrobe-binfmt | MAX_CHUNKS | return in parse_mish_chunks | crates/disrobe-binfmt/src/containers/dmg.rs |
disrobe-binfmt | MAX_PLAUSIBLE_MAJOR_VERSION | return in header_is_plausible | crates/disrobe-binfmt/src/containers/dotnet_bundle.rs |
disrobe-binfmt | PE_SECTION_LIMIT | return in pe_has_enigma_sections | crates/disrobe-binfmt/src/containers/enigma.rs |
disrobe-binfmt | MAX_CANDIDATE_OFFSETS | .truncate() in candidate_offsets; break in scan_magic_offsets | crates/disrobe-binfmt/src/containers/eszip.rs |
disrobe-binfmt | MAX_DIR_RECURSION | return in walk_dir | crates/disrobe-binfmt/src/containers/fat.rs |
disrobe-binfmt | MAX_PART_OUTPUT | .take() in decompress_xz | crates/disrobe-binfmt/src/containers/flatpak.rs |
disrobe-binfmt | MAX_FILES | return in walk_leaf_records | crates/disrobe-binfmt/src/containers/hfsplus.rs |
disrobe-binfmt | MAX_INNO_HEADER_STRING | return in read_inno_string; return in skip_inno_string | crates/disrobe-binfmt/src/containers/innosetup.rs |
disrobe-binfmt | MAX_FILE_GROUPS | while condition in read_file_groups | crates/disrobe-binfmt/src/containers/installshield.rs |
disrobe-binfmt | MAX_FILES | continue in walk_jffs2 | crates/disrobe-binfmt/src/containers/jffs2.rs |
disrobe-binfmt | MAX_MODULE_NAME_BYTES | return in read_minidump_string | crates/disrobe-binfmt/src/containers/minidump/mod.rs |
disrobe-binfmt | MAX_DEPTH | break in walk_minixfs | crates/disrobe-binfmt/src/containers/minixfs.rs |
disrobe-binfmt | MAX_FILES | break in walk_minixfs | crates/disrobe-binfmt/src/containers/minixfs.rs |
disrobe-binfmt | MAX_STREAM_BYTES | .take() in read_msi_extractable | crates/disrobe-binfmt/src/containers/msi.rs |
disrobe-binfmt | MAX_DEPTH | break in walk_ntfs | crates/disrobe-binfmt/src/containers/ntfs.rs |
disrobe-binfmt | MAX_FILES | break in walk_ntfs | crates/disrobe-binfmt/src/containers/ntfs.rs |
disrobe-binfmt | MAX_FILEZ_CONTENT | .take() in inflate_raw_deflate | crates/disrobe-binfmt/src/containers/ostree.rs |
disrobe-binfmt | MAX_OSTREE_DIR_ENTRIES | .take() in collect_refs_recursive; .take() in count_objects; .take() in reconstruct_delta_dirs | crates/disrobe-binfmt/src/containers/ostree.rs |
disrobe-binfmt | PM1_TREE_WALK_LIMIT | for range in read_byte_decode_index | crates/disrobe-binfmt/src/containers/pmarc.rs |
disrobe-binfmt | MAX_LENGTH | for range in make_decode_table; while condition in decode_number | crates/disrobe-binfmt/src/containers/rar_unpack3.rs |
disrobe-binfmt | MAX_LENGTH | for range in make_decode_table; while condition in decode_number | crates/disrobe-binfmt/src/containers/rar_unpack5.rs |
disrobe-binfmt | MAX_ROMFS_DEPTH | continue in walk_romfs | crates/disrobe-binfmt/src/containers/romfs.rs |
disrobe-binfmt | MAX_ROMFS_FILES | return in walk_romfs | crates/disrobe-binfmt/src/containers/romfs.rs |
disrobe-binfmt | MAX_METADATA_BLOCK | return in read_metadata_block_at; while condition in read_metadata_at | crates/disrobe-binfmt/src/containers/squashfs.rs |
disrobe-binfmt | MAX_PATH_DEPTH | break in walk_squashfs | crates/disrobe-binfmt/src/containers/squashfs.rs |
disrobe-binfmt | MAX_WALK_FILES | break in walk_squashfs | crates/disrobe-binfmt/src/containers/squashfs.rs |
disrobe-binfmt | MAX_SECTION_NAME | return in section_name | crates/disrobe-binfmt/src/coverage/elf.rs |
disrobe-binfmt | MAX_DT_STRSZ | return in parse_elf_dynamic | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_DYNAMIC_ENTRIES | return in parse_elf_dynamic | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_DYNAMIC_STRING_OUTPUT | return in resolve_bounded_string | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_NEEDED | return in push_needed_offset | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_PROGRAM_HEADERS | return in parse_elf_dynamic | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_STRING_LEN | .min() clamp in read_cstr | crates/disrobe-binfmt/src/elf_dynamic.rs |
disrobe-binfmt | MAX_DISK_NESTING_DEPTH | return in recurse_into_filesystem | crates/disrobe-binfmt/src/extract.rs |
disrobe-binfmt | MAX_NOTES_PER_SEGMENT | for range in find_build_ids | crates/disrobe-binfmt/src/rewrite/elf.rs |
disrobe-binfmt | MAX_DIRECTORY_SLOTS | .min() clamp in plan | crates/disrobe-binfmt/src/rewrite/pe.rs |
disrobe-capabilities | MAX_FILE_STRING_FEATURES | .take() in push_file_strings_with_limits | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | MAX_FILE_STRING_FEATURE_BYTES | continue in push_file_strings_with_limits | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | MAX_FILE_STRING_SCAN_BYTES | .min() clamp in push_file_strings_with_limits | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | MAX_NUMBER_FEATURES_PER_INSN | skipped in instruction_features | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | PE_HEADER_SCAN_CAP | .min() clamp in embedded_pe_offset | crates/disrobe-capabilities/src/extract.rs |
disrobe-capabilities | MAX_IMPORT_ENTRIES | break in from_elf; break in from_pe | crates/disrobe-capabilities/src/imports.rs |
disrobe-capabilities | MAX_STUB_SPAN | .min() clamp in name_at_thunk | crates/disrobe-capabilities/src/imports.rs |
disrobe-cfg | RETURN_TAIL_NODE_CAP | return in private_return_tail | crates/disrobe-cfg/src/lib.rs |
disrobe-cfg | MAX_RECONVERGENCE_CLONES | .min() clamp in tight_for_reconvergence | crates/disrobe-cfg/src/reconverge.rs |
disrobe-cli | RESOURCE_PREVIEW_LIMIT | .min() clamp in render_resources | crates/disrobe-cli/src/cli/apk.rs |
disrobe-cli | MAX_EVIDENCE_SHOWN | .take() in push_anti_analysis_evidence_lines; .take() in render_text; no action in push_anti_analysis_evidence_lines; 1 more | crates/disrobe-cli/src/cli/behavior.rs |
disrobe-cli | MAX_SIDECAR_REDACTION_BYTES | return in sidecar_shape | crates/disrobe-cli/src/cli/chain_v1.rs |
disrobe-cli | MAX_REPORTS_GRADED | break in find_reports | crates/disrobe-cli/src/cli/context.rs |
disrobe-cli | MAX_REPORT_SEARCH_DEPTH | for range in find_reports | crates/disrobe-cli/src/cli/context.rs |
disrobe-cli | MAX_INSTALL_LOG_ENTRIES | no action in trim_install_log; slice in trim_install_log | crates/disrobe-cli/src/cli/install/mod.rs |
disrobe-cli | DELPHI_LIST_LIMIT | .take() in render_delphi_classes; .take() in render_delphi_forms; .take() in render_delphi_types; 3 more | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | LOWEST_COVERED_CAP | .truncate() in lowest_covered | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | SYMBOL_PREVIEW_LIMIT | .min() clamp in render_cxx_class_rows; .min() clamp in render_import_rows; .min() clamp in render_symbol_rows | crates/disrobe-cli/src/cli/native.rs |
disrobe-cli | LITERAL_PREVIEW_LIMIT | .take() in preview; return in preview | crates/disrobe-cli/src/cli/native_match.rs |
disrobe-cli | MAX_BEHAVIOR_EVIDENCE | .take() in render_behavior_row; no action in render_behavior_row | crates/disrobe-cli/src/cli/report_html.rs |
disrobe-cli | MAX_IOC_ROWS | .take() in render_indicators; no action in render_indicators | crates/disrobe-cli/src/cli/report_html.rs |
disrobe-core | ANTI_ANALYSIS_SCAN_CAP | slice in scan_with_chain | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | MAX_EXEMPLARS_PER_KIND | .take() in cap_evidence; no action in cap_evidence | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | MAX_MACHO_LOAD_CMDS | .min() clamp in macho_code_layout | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | MAX_PARSED_SECTIONS | .min() clamp in elf_code_layout; .min() clamp in macho_segment_sections; .min() clamp in pe_code_layout | crates/disrobe-core/src/anti_analysis.rs |
disrobe-core | MAX_CACHE_ENTRY_BYTES | .take() in read_entry_file; return in read_entry_file | crates/disrobe-core/src/cache.rs |
disrobe-core | JOSE_HEADER_DECODE_CAP | return in decode_base64url; return in decode_jose_header | crates/disrobe-core/src/codec/crypto_wall.rs |
disrobe-core | MAX_SCAN | slice in classify | crates/disrobe-core/src/codec/crypto_wall.rs |
disrobe-core | MAX_STATIC_PASSPHRASES | break in static_passphrase_candidates; while condition in push_label_passphrases | crates/disrobe-core/src/codec/crypto_wall.rs |
disrobe-core | MAX_ENTITY_NAME | fallback value in html_entity_decode_with_scan | crates/disrobe-core/src/codec/web_escape.rs |
disrobe-core | MS_CAP | return in pretty_duration | crates/disrobe-core/src/provenance.rs |
disrobe-core | MAX_HISTORY_BLOBS | break in report_git | crates/disrobe-core/src/recon/git_history.rs |
disrobe-core | MAX_HISTORY_BLOB_BYTES | continue in report_git | crates/disrobe-core/src/recon/git_history.rs |
disrobe-core | MAX_HISTORY_COMMITS | break in report_git | crates/disrobe-core/src/recon/git_history.rs |
disrobe-core | MAX_BLOB_DECODE | continue in decode_and_recurse; continue in decode_codecs_and_recurse | crates/disrobe-core/src/recon/ioc.rs |
disrobe-core | MAX_CODEC_TOKEN | continue in decode_codecs_and_recurse | crates/disrobe-core/src/recon/ioc.rs |
disrobe-core | MAX_INDICATORS | break in extract_with_work; break in scan_text_layer; return in collect_domains; 7 more | crates/disrobe-core/src/recon/ioc.rs |
disrobe-core | MAX_BASE64_DECODED_TOTAL | break in base64_decode_findings; continue in base64_decode_findings | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_BASE64_DEPTH | return in base64_decode_findings | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_BASE64_RUNS | break in base64_decode_findings | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_CODEC_DECODED_TOTAL | break in codec_cascade_findings; return in codec_peel_token | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_CODEC_DEPTH | return in codec_cascade_findings | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_CODEC_RUN | return in codec_output_advances; return in codec_peel_token | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_CONTAINER_DEPTH | skipped in scan_blob | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_FILE_BYTES | .take() in read_scan_file; return in read_scan_file | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_TREE_FILES | break in walk_with_limit | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_WIDE_RUNS | break in merge_runs; return in push_narrow_run; return in push_wide_run; 2 more | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_ZIP_ENTRIES | .min() clamp in scan_zip_bytes; break in scan_tar_bytes | crates/disrobe-core/src/recon/mod.rs |
disrobe-core | MAX_RUNS | break in merge_runs; return in push_narrow_run; return in push_wide_run; 2 more | crates/disrobe-core/src/recon/string_emu.rs |
disrobe-core | MAX_RUN_BYTES | continue in unit_runs_wide; no action in collect_narrow_runs; slice in text_runs | crates/disrobe-core/src/recon/string_emu.rs |
disrobe-core | MAX_DECODE_RECURSE_LEN | continue in recover_base64; continue in recover_codec | crates/disrobe-core/src/strings.rs |
disrobe-core | MAX_PE_SECTIONS | return in pe_header_is_valid | crates/disrobe-core/src/structural.rs |
disrobe-core | ZIP_SEARCH_BUDGET | while condition in find_eocd | crates/disrobe-core/src/structural.rs |
disrobe-core | MAX_STRINGS | break in select_strings | crates/disrobe-core/src/yara_gen.rs |
disrobe-core | HEX_WORK_BUDGET | return in hex_matches_at | crates/disrobe-core/src/yara_match/atoms.rs |
disrobe-irsummary | MAX_FIXPOINT_ROUNDS | for range in optimize_graph | crates/disrobe-irsummary/src/optimize.rs |
disrobe-irsummary | MAX_BLOCKS | return in build_region; return in collect_leaders | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_BLOCK_INSNS | return in build_block; return in collect_leaders | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_INSNS | return in summarize_function | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_JOINS | return in summarize_region | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_OUTPUTS | return in finalize | crates/disrobe-irsummary/src/symexec.rs |
disrobe-irsummary | MAX_STACK_DEPTH | return in push | crates/disrobe-irsummary/src/symexec.rs |
disrobe-lift-x86 | MAX_X86_BLOCK_BYTES | .min() clamp in decode_block; .min() clamp in invalid_bitness_block; fallback value in with_limits | crates/disrobe-lift-x86/src/lib.rs |
disrobe-lift-x86 | MAX_X86_INSTRUCTIONS | while condition in decode_block; fallback value in with_limits | crates/disrobe-lift-x86/src/lib.rs |
disrobe-llm-metadata | MAX_PII_ENTRIES | .min() clamp in scan | crates/disrobe-llm-metadata/src/pii.rs |
disrobe-llm-metadata | MAX_SCAN_BYTES | .min() clamp in scan | crates/disrobe-llm-metadata/src/pii.rs |
disrobe-llm-metadata | MAX_DECLARED_TYPE_BYTES | return in parse_declared_type | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-llm-metadata | MAX_FUNCTIONS | skipped in add_function | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-llm-metadata | MAX_OBSERVATIONS_PER_VAR_U32 | skipped in observe | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-llm-metadata | MAX_VARIABLES_PER_FN | skipped in add_local; skipped in add_parameter | crates/disrobe-llm-metadata/src/usage_inference.rs |
disrobe-mba | BFS_TABLE_BUDGET | return in minimal_bitwise_for_table | crates/disrobe-mba/src/bitwise_synth.rs |
disrobe-mba | MAX_BITWISE_SYNTH_VARS | return in synthesize_bitwise_masked; no action in simplify_l0_l5 | crates/disrobe-mba/src/bitwise_synth.rs |
disrobe-mba | MAX_BOOLEAN_ATOMS | return in boolean_minimization_candidate; return in collect_boolean_atoms; return in collect_predicate_atoms; 2 more | crates/disrobe-mba/src/boolean.rs |
disrobe-mba | MAX_BOOLEAN_PRIMES | return in minimize_sop | crates/disrobe-mba/src/boolean.rs |
disrobe-mba | MAX_CFF_BLOCKS | return in devirtualize_cheap; return in devirtualize_table_dispatch; return in devirtualize_traced | crates/disrobe-mba/src/cff/detect.rs |
disrobe-mba | MAX_REGION_NODES | return in run | crates/disrobe-mba/src/cff/detect.rs |
disrobe-mba | CHEAP_LOOP_CAP | for range in cheap_initial; for range in cheap_resolve_block; return in cheap_initial; 1 more | crates/disrobe-mba/src/cff/mod.rs |
disrobe-mba | BANK_CAP | skipped in offer | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | GEN_BUDGET | return in expand_layer; return in grow; return in offer | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_ATOMS | return in push_atom | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_CANDIDATE_NODES | .min() clamp in synthesize | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_CONSTS | .truncate() in build_consts | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_ROUNDS | for range in grow | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_VARS | return in synthesize | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | VERIFY_BUDGET | no action in offer | crates/disrobe-mba/src/enum_synth.rs |
disrobe-mba | MAX_CERTIFICATE_DEGREE | return in composition_is_identity; return in polynomial_is_zero_function | crates/disrobe-mba/src/finite_diff.rs |
disrobe-mba | MULTIVAR_EVAL_BUDGET | return in multivar_induces_zero | crates/disrobe-mba/src/finite_diff.rs |
disrobe-mba | MAX_TABLE_ENTRIES | .min() clamp in solver_resolve; return in solver_resolve; return in try_resolve_vsa | crates/disrobe-mba/src/jumptable/mod.rs |
disrobe-mba | MAX_BASIS_VARS | return in synthesize_linear_basis | crates/disrobe-mba/src/linear_mba.rs |
disrobe-mba | MAX_SOLVER_VARS | return in solve_linear_mba; return in verify_equivalent; no action in simplify_l0_l5 | crates/disrobe-mba/src/linear_solver.rs |
disrobe-mba | MAX_SUBSET_COMBOS | return in subset_combinations | crates/disrobe-mba/src/linear_solver.rs |
disrobe-mba | MAX_SUBSET_SEARCH_VARS | skipped in solve_linear_mba | crates/disrobe-mba/src/linear_solver.rs |
disrobe-mba | MAX_ATOM_DEGREE | return in to_falling_factorial; return in to_power_basis | crates/disrobe-mba/src/poly_mba.rs |
disrobe-mba | MAX_POLY_ATOMS | return in intern_atom | crates/disrobe-mba/src/poly_mba.rs |
disrobe-mba | MAX_POLY_MBA_VARS | return in polynomial_solver_work; return in solve_polynomial_mba; no action in simplify_l0_l5 | crates/disrobe-mba/src/poly_mba.rs |
disrobe-mba | MAX_POLY_MONOMIALS | return in multiply_poly; return in substitute_axis | crates/disrobe-mba/src/poly_mba.rs |
disrobe-mba | MAX_CERTIFICATE_ATOMS | return in congruent_to_constant; return in induces_zero_over_free_atoms | crates/disrobe-mba/src/poly_oracle.rs |
disrobe-mba | MAX_MONOMIALS | return in multiply | crates/disrobe-mba/src/poly_oracle.rs |
disrobe-mba | MAX_MONOMIAL_DEGREE | return in multiply_monomials | crates/disrobe-mba/src/poly_oracle.rs |
disrobe-mba | MAX_REWRITE_PASSES | for range in canonicalize | crates/disrobe-mba/src/rewrite.rs |
disrobe-mba | MAX_BASIS_VARS | no action in simplify_l0_l5 | crates/disrobe-mba/src/simplify.rs |
disrobe-mba | MAX_LINEAR_VARS | skipped in simplify_l0_l5 | crates/disrobe-mba/src/simplify.rs |
disrobe-mba | MAX_TEMPLATE_VARS | skipped in simplify_l0_l5 | crates/disrobe-mba/src/simplify.rs |
disrobe-mba | EVAL_NODE_BUDGET | return in eval_term | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_ENUM_ASSIGNMENTS | return in enumeration_domain | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_ENUM_STEPS | .min() clamp in enumerate_conjunction | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_ENUM_VARS | return in enumeration_domain | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_ENUM_VAR_BITS | return in enumeration_domain | crates/disrobe-mba/src/symexec/solver_cert.rs |
disrobe-mba | MAX_COUNTEREXAMPLE_SLOTS | return in expand_counterexample | crates/disrobe-mba/src/verify.rs |
disrobe-mcp | MAX_AMBIGUOUS_CANDIDATES | .take() in call_outcome_out | crates/disrobe-mcp/src/navigation.rs |
disrobe-nir | MAX_INDENT_DEPTH | .min() clamp in write_indent | crates/disrobe-nir/src/emit.rs |
disrobe-nir | MAX_SHORT_CIRCUIT_CLONE_BYTES | ? on a checked operation in charge_condition_clone | crates/disrobe-nir/src/hir.rs |
disrobe-nir | MAX_SHORT_CIRCUIT_TESTS | return in resolve_condition_edge; return in short_circuit_candidate | crates/disrobe-nir/src/hir.rs |
disrobe-nir-lift | MAX_BIG_DECIMAL_BYTES | return in big_to_decimal | crates/disrobe-nir-lift/src/beam.rs |
disrobe-nir-lift | MAX_REPORTED_GAPS | .take() in block_gaps | crates/disrobe-nir-lift/src/pcode/arch.rs |
disrobe-nir-lift | MAX_FOLD_DEPTH | return in resolve | crates/disrobe-nir-lift/src/pcode/flags.rs |
disrobe-nir-lift | MAX_REACHING_ANALYSIS_ELEMENTS | return in compute_entries; return in eliminate_dead_values | crates/disrobe-nir-lift/src/pcode/flags.rs |
disrobe-pass-as3 | MULTINAME_RENDER_BUDGET | return in render_multiname_bounded | crates/disrobe-pass-as3/src/abc.rs |
disrobe-pass-as3 | MAX_DUP_EXPR_NODES | return in scope_node_count_capped; return in walk; fallback value in dup_clone | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_MERGE_DEFINITIONS | continue in merge_tracked_values | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_NEGATION_DEPTH | return in negate_without_introducing_not | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_OR_GUARD_TESTS | return in or_guard_shared_target | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_TERNARY_FOLDS | for range in resolve_ternary | crates/disrobe-pass-as3/src/lifter.rs |
disrobe-pass-as3 | MAX_ARCHNAME_BYTES | slice in is_byteloader_stream | crates/disrobe-pass-as3/src/other_langs.rs |
disrobe-pass-as3 | MAX_BYTELOADER_LINE_BYTES | slice in skip_line | crates/disrobe-pass-as3/src/other_langs.rs |
disrobe-pass-as3 | MAX_RUNTIME_SYMBOL_SCAN_BYTES | slice in detect_with_symbol_scan_limit | crates/disrobe-pass-as3/src/other_langs.rs |
disrobe-pass-as3 | MAX_SHEBANG_LINE_BYTES | slice in skip_line | crates/disrobe-pass-as3/src/other_langs.rs |
disrobe-pass-beam | MAX_JOIN_INSTRUCTIONS | return in build | crates/disrobe-pass-beam/src/body_lift/join.rs |
disrobe-pass-beam | MAX_JOIN_PASSES | for range in post_dominators | crates/disrobe-pass-beam/src/body_lift/join.rs |
disrobe-pass-beam | MAX_INTEGER_PROOF_DEPTH | return in yields_integer | crates/disrobe-pass-beam/src/body_lift/mod.rs |
disrobe-pass-beam | MAX_LABEL_VISITS | return in enter_label | crates/disrobe-pass-beam/src/body_lift/mod.rs |
disrobe-pass-beam | MAX_ARMS | return in collect; return in descend; return in split_receive_arms | crates/disrobe-pass-beam/src/body_lift/receive_clauses.rs |
disrobe-pass-beam | MAX_CONJUNCTS | return in split_receive_arms | crates/disrobe-pass-beam/src/body_lift/receive_clauses.rs |
disrobe-pass-beam | MAX_TERM_DEPTH | return in cannot_raise; return in is_guard_safe; return in is_literal; 1 more | crates/disrobe-pass-beam/src/body_lift/receive_clauses.rs |
disrobe-pass-beam | MAX_TREE_DEPTH | return in collect | crates/disrobe-pass-beam/src/body_lift/receive_clauses.rs |
disrobe-pass-beam | MAX_TYPE_ENTRIES | return in decode_table | crates/disrobe-pass-beam/src/body_lift/types.rs |
disrobe-pass-beam | MAX_SCAN_DEPTH | return in enforced_keys_in; return in find_enforced_keys; return in find_struct_list; 1 more | crates/disrobe-pass-beam/src/elixir.rs |
disrobe-pass-beam | MAX_RENDER_DEPTH | fallback value in enter | crates/disrobe-pass-beam/src/elixir_quoted.rs |
disrobe-pass-beam | MAX_RENDER_DEPTH | fallback value in enter | crates/disrobe-pass-beam/src/erlang_abstract.rs |
disrobe-pass-dotnet | EAGER_CCTOR_SCAN_CAP | while condition in detect | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_NAME_LEN | return in read_metadata_name | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_PROFILE_MAJOR | continue in declared_profile | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_READY_TO_RUN_SECTIONS | return in read_ready_to_run_header | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_RECOVERED_NAMES | break in recover_names_at_threshold; while condition in recover_names_at_threshold | crates/disrobe-pass-dotnet/src/aot.rs |
disrobe-pass-dotnet | MAX_CIL_EXPRESSION_DEPTH | return in append_output_expression; return in binary; return in expression_contains_stack_input | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_CIL_EXPRESSION_NODES | return in binary | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_CIL_HANDLER_INSTRUCTIONS | return in summarize_cil_handler | crates/disrobe-pass-dotnet/src/devirt/cil_handler.rs |
disrobe-pass-dotnet | MAX_DOTNET_MBA_NODES | .min() clamp in simplify_expression; return in count | crates/disrobe-pass-dotnet/src/devirt/mba.rs |
disrobe-pass-dotnet | MAX_DOTNET_MBA_VARS | return in intern_leaf; return in simplify_expression | crates/disrobe-pass-dotnet/src/devirt/mba.rs |
disrobe-pass-dotnet | MAX_SAMPLES | return in append_input_case; return in append_input_values | crates/disrobe-pass-dotnet/src/devirt/oracle.rs |
disrobe-pass-dotnet | MAX_NESTING | return in helper_body | crates/disrobe-pass-dotnet/src/display_class_lowering.rs |
disrobe-pass-dotnet | MAX_FIELD_RVA_BYTES | continue in build | crates/disrobe-pass-dotnet/src/field_rva.rs |
disrobe-pass-dotnet | MAX_ARRAY_FIELD_BYTES | continue in array_field_data | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_CALL_SITES | break in recover_bitmono_strings | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_CIPHERTEXT_BYTES | return in decrypt_site | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_DECRYPTOR_INSTRUCTIONS | continue in method_bodies | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_DERIVATIONS | return in decrypt_site | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_PBKDF2_ITERATIONS | continue in locate_decryptor | crates/disrobe-pass-dotnet/src/peel/bitmono_strings.rs |
disrobe-pass-dotnet | MAX_CONSTANTS_POOL_BYTES | continue in recover_pool | crates/disrobe-pass-dotnet/src/peel/confuserex_constants.rs |
disrobe-pass-dotnet | MAX_DECODE_ATTEMPTS | return in recover_strings | crates/disrobe-pass-dotnet/src/peel/confuserex_constants.rs |
disrobe-pass-dotnet | MAX_SEED_CANDIDATES | break in collect_ldc_i4_immediates; break in recover_pool | crates/disrobe-pass-dotnet/src/peel/confuserex_constants.rs |
disrobe-pass-dotnet | MAX_SEED_CANDIDATES | break in collect_ldc_i4_immediates; break in peel_confuserex_resources | crates/disrobe-pass-dotnet/src/peel/confuserex_resources.rs |
disrobe-pass-dotnet | MAX_METHODS_SCANNED | break in recover_seeds_by_emulation | crates/disrobe-pass-dotnet/src/peel/confuserex_seed.rs |
disrobe-pass-dotnet | MAX_SEED_RUN | return in seed_run | crates/disrobe-pass-dotnet/src/peel/confuserex_seed.rs |
disrobe-pass-dotnet | KEY_PATH_STEP_CAP | return in reaches_dispatcher_switch | crates/disrobe-pass-dotnet/src/peel/deflatten/blocks.rs |
disrobe-pass-dotnet | MAX_BLOCKS | return in build | crates/disrobe-pass-dotnet/src/peel/deflatten/blocks.rs |
disrobe-pass-dotnet | FIELD_RVA_READ_CAP | .min() clamp in build_field_env | crates/disrobe-pass-dotnet/src/peel/deflatten/decrypt.rs |
disrobe-pass-dotnet | MAX_CALL_SITES | return in scan_call_sites | crates/disrobe-pass-dotnet/src/peel/deflatten/decrypt.rs |
disrobe-pass-dotnet | NATIVE_STUB_READ_CAP | .min() clamp in classify | crates/disrobe-pass-dotnet/src/peel/deflatten/predicate.rs |
disrobe-pass-dotnet | MAX_VISIT | break in deflatten_with_oracle | crates/disrobe-pass-dotnet/src/peel/deflatten/rebuild.rs |
disrobe-pass-dotnet | MAX_STACK_VALUES | return in lower_postfix; return in verify_straight_line | crates/disrobe-pass-dotnet/src/peel/eazvm/cil_mba.rs |
disrobe-pass-dotnet | MAX_RESOURCE_BYTES | return in locate_embedded_resource | crates/disrobe-pass-dotnet/src/peel/ilprotector_bodies.rs |
disrobe-pass-dotnet | MAX_INSTRS_PER_BLOCK | for range in decode_block | crates/disrobe-pass-dotnet/src/peel/koivm/disasm.rs |
disrobe-pass-dotnet | MAX_SECTION_BYTES | .min() clamp in locate_encrypted_section | crates/disrobe-pass-dotnet/src/peel/maxtocode_bodies.rs |
disrobe-pass-dotnet | MAX_EAZVM_ANALYSIS_NAME_CHARS | .take() in bounded_eazvm_analysis_name | crates/disrobe-pass-dotnet/src/peel/mod.rs |
disrobe-pass-dotnet | MAX_EAZVM_ANALYSIS_REFUSALS | skipped in apply_eazvm_tier | crates/disrobe-pass-dotnet/src/peel/mod.rs |
disrobe-pass-dotnet | MAX_DISASM_BYTES | .min() clamp in surface_native_stub | crates/disrobe-pass-dotnet/src/peel/native_surface.rs |
disrobe-pass-dotnet | MAX_SURFACED_INSNS | .take() in surface_native_stub | crates/disrobe-pass-dotnet/src/peel/native_surface.rs |
disrobe-pass-dotnet | MAX_ACCESSORS | return in prove_constructor | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_ACCESSOR_CODE | return in prove_accessor | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_ACCESSOR_INSTRUCTIONS | return in prove_accessor | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_CONSTRUCTOR_CODE | return in prove_constructor | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_CONSTRUCTOR_INSTRUCTIONS | return in prove_constructor | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_FIELD_DATA | return in prove_constructor | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_GETTER_CODE | return in prove_getter | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_GETTER_INSTRUCTIONS | return in prove_getter | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_METHOD_PARSE_BYTES | .min() clamp in read_bodies | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_RECOVERED_BYTES | return in prove_accessors | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_RECOVERED_NAME_BYTES | ? on a checked operation in prove_accessors | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_STACK | return in prove_accessor; return in prove_constructor; return in prove_getter | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_STRING_BYTES | return in prove_accessors | crates/disrobe-pass-dotnet/src/peel/obfuscar_strings.rs |
disrobe-pass-dotnet | MAX_STRINGS | break in read_unicode_records_varint; return in read_unicode_records_int32_strict; return in read_unicode_records_varint_strict | crates/disrobe-pass-dotnet/src/peel/protector_resources.rs |
disrobe-pass-dotnet | MAX_ROT_SHIFT | no action in recover_spices | crates/disrobe-pass-dotnet/src/peel/spices_strings.rs |
disrobe-pass-dotnet | MAX_PROBE_ARGS | for range in probe_decoder | crates/disrobe-pass-dotnet/src/peel/static_decrypt.rs |
disrobe-pass-dotnet | MAX_DECRYPTOR_INSTRUCTIONS | continue in collect_from_type | crates/disrobe-pass-dotnet/src/peel/string_emu.rs |
disrobe-pass-dotnet | MAX_RECOVERED_STRINGS | return in recover_emulated_strings | crates/disrobe-pass-dotnet/src/peel/string_emu.rs |
disrobe-pass-dotnet | MAX_CONDITION_DEPTH | return in compound_condition | crates/disrobe-pass-dotnet/src/structure_emit.rs |
disrobe-pass-dotnet | MAX_FORWARDING_HOPS | for range in forward_target | crates/disrobe-pass-dotnet/src/structure_emit.rs |
disrobe-pass-dotnet | MAX_STRUCTURE_DEPTH | return in emit_region | crates/disrobe-pass-dotnet/src/structure_emit.rs |
disrobe-pass-dotnet | MAX_TYPE_ROUNDS | for range in plan_stack_slots | crates/disrobe-pass-dotnet/src/structure_emit/stack_slots.rs |
disrobe-pass-dotnet | MAX_COERCION_DEPTH | return in coerce_bounded | crates/disrobe-pass-dotnet/src/structurize.rs |
disrobe-pass-dotnet | MAX_EXPR_DEPTH | return in expression_depth; fallback value in bounded_expression | crates/disrobe-pass-dotnet/src/structurize.rs |
disrobe-pass-dotnet | INFERENCE_DEPTH_LIMIT | return in infer_bounded; return in may_convert | crates/disrobe-pass-dotnet/src/structurize/operand_kind.rs |
disrobe-pass-go | MAX_LISTED_FUNCS | .take() in push_defer_section; .take() in render_symbol_report; no action in push_defer_section; 1 more | crates/disrobe-pass-go/src/chain_detector.rs |
disrobe-pass-go | MAX_PCDATA_ENTRIES | return in read_func_defer_view | crates/disrobe-pass-go/src/defers.rs |
disrobe-pass-go | MAX_DECOMPRESSED_LEN | .take() in inflate_raw; return in decompress_zdebug; fallback value in inflate_raw | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DWARF_FUNCS | break in collect_unit; break in walk_dwarf; skipped in push_function | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DWARF_NAMES_PER_FUNC | break in collect_unit; skipped in collect_unit | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DWARF_NAMES_TOTAL | break in collect_unit | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DWARF_TYPE_NAMES | break in walk_dwarf; skipped in collect_unit | crates/disrobe-pass-go/src/dwarf.rs |
disrobe-pass-go | MAX_DIRECTIVES | break in collect_directives | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_DIRECTIVE_TAIL | .min() clamp in collect_directives | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_EMBED_DATA_LEN | return in parse_record | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_EMBED_NAME_LEN | return in is_clean_embed_path; return in parse_record | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_MAP_ENTRIES | return in read_map | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_TOTAL_EMBED_BYTES | .min() clamp in read_member_bytes | crates/disrobe-pass-go/src/embed_fs.rs |
disrobe-pass-go | MAX_LITERAL_SCAN_BYTES | skipped in recover_strings; slice in recover_strings | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_PLAIN_STRINGS | return in scan_ascii_strings; skipped in scan_ascii_strings | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_RECOVERED_STRINGS | .take() in recover_strings; .truncate() in recover_strings; return in scan_ascii_strings; 2 more | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_REPEATING_KEY | for range in scan_repeating_xor | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | STRING_SCAN_BUDGET | break in recover_strings | crates/disrobe-pass-go/src/garble.rs |
disrobe-pass-go | MAX_BLOB | .min() clamp in grow_clean_pair | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_BRIDGE_GAP | break in extract_string_window | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_PERTURBED_BYTES | return in grow_clean_pair | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_PLACEHOLDER_RATIO_PCT | return in plausible_plaintext | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_SIMPLE_RECOVERIES | return in recover_simple_literals | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_SIMPLE_SCAN_BYTES | return in recover_simple_literals | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | MAX_STRING_JUNK_BYTES | break in grow_clean_pair | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | WORK_BUDGET | return in recover_simple_literals | crates/disrobe-pass-go/src/garble_literals.rs |
disrobe-pass-go | GLOBAL_STEP_BUDGET | break in run_block; return in call_into_text | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_CALLERS_PER_THUNK | skipped in build_caller_index | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_EMU_MEM_BYTES | continue in write_mem; for range in zero_fill | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_INLINE_STRING | return in span_is_printable; no action in snapshot_consumer_args | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_NESTED_CALL_DEPTH | return in call_into_text | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_STEPS | while condition in run_block | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_THUNK_BYTES | .min() clamp in slice_for | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | THUNK_SCAN_BUDGET | break in recover_thunk_literals | crates/disrobe-pass-go/src/garble_thunk.rs |
disrobe-pass-go | MAX_BACKSEARCH_CANDIDATES | return in via_pclntab_backsearch | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_BUILDINFO_DEPS | skipped in build_info_from_parts | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_BUILDINFO_SETTINGS | skipped in build_info_from_parts | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_PLAUSIBLE_SLICE_LEN | return in validated_slice | crates/disrobe-pass-go/src/moduledata.rs |
disrobe-pass-go | MAX_PCLNTAB_CANDIDATES | while condition in collect_needles_in_section | crates/disrobe-pass-go/src/pclntab.rs |
disrobe-pass-go | MAX_PLAUSIBLE_SIG_FUNCS | return in validate_header_structure | crates/disrobe-pass-go/src/pclntab.rs |
disrobe-pass-go | MAX_FILETAB_ENTRY_LEN | return in is_source_file; fallback value in read_filetab_name; skipped in collect_filetab_blob | crates/disrobe-pass-go/src/symbols.rs |
disrobe-pass-go | MAX_PLAUSIBLE_FUNCS | return in bounded_func_count | crates/disrobe-pass-go/src/symbols.rs |
disrobe-pass-go | DISAMBIG_CANDIDATE_BUDGET | break in disambiguate_shape_args | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_FIELDS_PER_STRUCT | return in read_struct_fields | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_IMETHODS_PER_INTERFACE | return in read_interface_methods | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_METHODS_PER_TYPE | return in read_type_methods | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-go | MAX_STRUCT_FIELD_TAG_LEN | return in decode_name_component | crates/disrobe-pass-go/src/types.rs |
disrobe-pass-js-deob | MAX_NAMES_PER_SOURCE | skipped in collect_coverage_by_source | crates/disrobe-pass-js-deob/src/bundle/sourcemap_recover.rs |
disrobe-pass-js-deob | MAX_RENAMED_BINDINGS | return in renamed_bindings | crates/disrobe-pass-js-deob/src/bundle/sourcemap_recover.rs |
disrobe-pass-js-deob | MAX_RECURSIVE_DEPTH | return in recursive_descend | crates/disrobe-pass-js-deob/src/esoteric/atob_indirection.rs |
disrobe-pass-js-deob | MAX_PEEL_LAYERS | while condition in unpack | crates/disrobe-pass-js-deob/src/esoteric/packer.rs |
disrobe-pass-js-deob | MAX_CAPTURE_SCRIPT_BYTES | return in eval_to_source | crates/disrobe-pass-js-deob/src/esoteric/sandbox.rs |
disrobe-pass-js-deob | MAX_EXACT_MAGNITUDE | return in arith_combine; return in int_pattern; return in lower_arith | crates/disrobe-pass-js-deob/src/jsconfuser/algebraic_opaque.rs |
disrobe-pass-js-deob | MAX_FIXPOINT_ROUNDS | for range in fold_algebraic_opaque | crates/disrobe-pass-js-deob/src/jsconfuser/algebraic_opaque.rs |
disrobe-pass-js-deob | MAX_LOWER_DEPTH | return in lower_arith; return in lower_bits; return in lower_predicate; 1 more | crates/disrobe-pass-js-deob/src/jsconfuser/algebraic_opaque.rs |
disrobe-pass-js-deob | MAX_DENSE_ARRAY_ELEMENTS | return in assign_to | crates/disrobe-pass-js-deob/src/jsconfuser/cff_vm/interp.rs |
disrobe-pass-js-deob | MAX_LZSTRING_DICT_ENTRIES | return in lzstring_decompress_values | crates/disrobe-pass-js-deob/src/jsconfuser/string_compression.rs |
disrobe-pass-js-deob | MAX_LZSTRING_INPUT_UNITS | return in lzstring_decompress_base64; return in lzstring_decompress_uri; return in lzstring_decompress_utf16_raw; 3 more | crates/disrobe-pass-js-deob/src/jsconfuser/string_compression.rs |
disrobe-pass-js-deob | MAX_LZSTRING_OUTPUT_UNITS | return in lzstring_decompress_values | crates/disrobe-pass-js-deob/src/jsconfuser/string_compression.rs |
disrobe-pass-js-deob | MAX_CALL_BYTES | return in try_fold_at | crates/disrobe-pass-js-deob/src/jsobfu/fold_chars.rs |
disrobe-pass-js-deob | MAX_FOLD_PASSES | for range in fold_char_constructors | crates/disrobe-pass-js-deob/src/jsobfu/fold_chars.rs |
disrobe-pass-js-deob | MAX_IIFE_BYTES | return in try_fold_iife | crates/disrobe-pass-js-deob/src/jsobfu/fold_chars.rs |
disrobe-pass-js-deob | MAX_RESULT_CHARS | return in is_safe_literal_body | crates/disrobe-pass-js-deob/src/jsobfu/fold_chars.rs |
disrobe-pass-js-deob | MAX_RECOVER_PASSES | for range in try_recover | crates/disrobe-pass-js-deob/src/jsobfu/mod.rs |
disrobe-pass-js-deob | MAX_ROTATIONS | for range in simulate | crates/disrobe-pass-js-deob/src/string_array/rotate.rs |
disrobe-pass-js-deob | MAX_BATCH_OUTPUT_UNITS | while condition in usize_decimal_len | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_CONCURRENT_PROBES | while condition in acquire_probe_permit_from | crates/disrobe-pass-js-deob/src/string_array/sandbox.rs |
disrobe-pass-js-deob | MAX_MEMBER_CALL_LITERALS | .take() in restore_terser_mangled_bounded; skipped in restore_terser_mangled_bounded | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_NEARBY_STRINGS | .take() in static_member_call_literals_on_reference; return in collect_string_literals | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_STRING_SEARCH_DEPTH | return in collect_string_literals | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_SUFFIX_ATTEMPTS | for range in allocate | crates/disrobe-pass-js-deob/src/typescript/terser_restore.rs |
disrobe-pass-js-deob | MAX_PASSES | for range in fold_binary | crates/disrobe-pass-js-deob/src/unminify/arithmetic.rs |
disrobe-pass-js-deob | MAX_MBA_LOWER_DEPTH | return in lower_expression_at; return in render_expression_at | crates/disrobe-pass-js-deob/src/unminify/ast/mba_simplify.rs |
disrobe-pass-js-deob | MAX_PREDICATE_VARS | return in classify_predicate | crates/disrobe-pass-js-deob/src/unminify/ast/mba_simplify.rs |
disrobe-pass-js-deob | MAX_DEPENDENCY_SETTER_PAIRS | return in recover; return in registration | crates/disrobe-pass-js-deob/src/unminify/ast/system_register_param.rs |
disrobe-pass-js-deob | MAX_REGISTRATIONS | return in recover | crates/disrobe-pass-js-deob/src/unminify/ast/system_register_param.rs |
disrobe-pass-js-deob | MAX_SIMPLIFY_ROUNDS | for range in simplify | crates/disrobe-pass-js-deob/src/unminify/ast/ts_async/emit.rs |
disrobe-pass-js-deob | MAX_FIX_POINT_PASSES | for range in unminify | crates/disrobe-pass-js-deob/src/unminify/mod.rs |
disrobe-pass-js-deob | MAX_CHAIN | break in collect_chain | crates/disrobe-pass-js-deob/src/unminify/string_split.rs |
disrobe-pass-js-deob | MAX_PASSES | for range in fold_string_concat | crates/disrobe-pass-js-deob/src/unminify/string_split.rs |
disrobe-pass-js-deob | MAX_OPERANDS | while condition in new | crates/disrobe-pass-js-deob/src/v8/bytecode_opcodes.rs |
disrobe-pass-js-deob | MAX_FRAME_SIZE | return in recover_bytecode_array_with_layout | crates/disrobe-pass-js-deob/src/v8/code_serializer.rs |
disrobe-pass-js-deob | MAX_STRING_BODY | return in decode_string_from_run | crates/disrobe-pass-js-deob/src/v8/code_serializer.rs |
disrobe-pass-js-deob | REGISTER_RANGE_SCAN_LIMIT | no action in prepare_accumulator | crates/disrobe-pass-js-deob/src/v8/flat_bytecode_lift.rs |
disrobe-pass-js-deob | MAX_STRING_LEN | continue in extract_framed_strings | crates/disrobe-pass-js-deob/src/v8/serialized_code.rs |
disrobe-pass-jvm | JAVA_RANDOM_REJECTION_CAP | for range in next_bounded_int | crates/disrobe-pass-jvm/src/bytecode_eval.rs |
disrobe-pass-jvm | MAX_DATAFLOW_VISITS_PER_INSTRUCTION | return in local_constants_at_block_entries | crates/disrobe-pass-jvm/src/const_fold.rs |
disrobe-pass-jvm | MAX_MASK_SEARCH_PAIRS | return in recover_dispatch_mask | crates/disrobe-pass-jvm/src/dalvik_blackobf.rs |
disrobe-pass-jvm | MAX_FLOW_WORDS | return in analyze | crates/disrobe-pass-jvm/src/dalvik_cfg.rs |
disrobe-pass-jvm | MAX_DIAGNOSTICS | no action in analyze | crates/disrobe-pass-jvm/src/dalvik_core_library.rs |
disrobe-pass-jvm | MAX_MARKER_BYTES | return in parse_marker | crates/disrobe-pass-jvm/src/dalvik_core_library.rs |
disrobe-pass-jvm | MAX_NESTED_CLASS_DEPTH | for range in lexically_encloses; for range in translated_owner_path; no action in compose_rendered_class | crates/disrobe-pass-jvm/src/dalvik_decompile.rs |
disrobe-pass-jvm | MAX_RENDER_BYTES | return in render_region | crates/disrobe-pass-jvm/src/dalvik_decompile.rs |
disrobe-pass-jvm | MAX_TRAMPOLINE_STEPS | for range in fixup_path; for range in trampoline_end | crates/disrobe-pass-jvm/src/dalvik_decompile/nested_blocks.rs |
disrobe-pass-jvm | MAX_TRAMPOLINE_STEPS | for range in canonical | crates/disrobe-pass-jvm/src/dalvik_decompile/region_check.rs |
disrobe-pass-jvm | MAX_DESUGAR_SCAN_INSNS | return in exclusively_constructed; return in helper_references; return in scan_references | crates/disrobe-pass-jvm/src/dalvik_desugar.rs |
disrobe-pass-jvm | MAX_INLINE_BODY_INSNS | return in inlinable_helper_body | crates/disrobe-pass-jvm/src/dalvik_desugar.rs |
disrobe-pass-jvm | MAX_REFERENCE_BODY_INSNS | return in match_reference_body | crates/disrobe-pass-jvm/src/dalvik_desugar.rs |
disrobe-pass-jvm | MAX_RESOLVE_ROUNDS | break in unflatten_with_graph | crates/disrobe-pass-jvm/src/dalvik_dexguard.rs |
disrobe-pass-jvm | MAX_ARRAY_DATA_ELEMENTS | return in array_data_elements | crates/disrobe-pass-jvm/src/dalvik_lift.rs |
disrobe-pass-jvm | MAX_INLINE_DEPTH | return in inline_helper_body | crates/disrobe-pass-jvm/src/dalvik_lift.rs |
disrobe-pass-jvm | MAX_HANDLER_BLOCKS | break in monitor_handler | crates/disrobe-pass-jvm/src/dalvik_monitor.rs |
disrobe-pass-jvm | MAX_MONITOR_BODY_BLOCKS | continue in releases_before_leaving; return in monitor_region | crates/disrobe-pass-jvm/src/dalvik_monitor.rs |
disrobe-pass-jvm | MAX_TRAMPOLINE_HOPS | for range in past_trampolines | crates/disrobe-pass-jvm/src/dalvik_monitor.rs |
disrobe-pass-jvm | JAVA_RANDOM_REJECTION_CAP | for range in next_bounded_int | crates/disrobe-pass-jvm/src/dalvik_strdec.rs |
disrobe-pass-jvm | MAX_CANDIDATE_PARAMS | return in signature_weight | crates/disrobe-pass-jvm/src/dalvik_strdec_generic.rs |
disrobe-pass-jvm | MAX_BUCKET_TESTS | for range in bucket_chain | crates/disrobe-pass-jvm/src/dalvik_string_switch.rs |
disrobe-pass-jvm | MAX_TRAMPOLINE_HOPS | for range in absorb_trampolines; for range in skip_trampolines | crates/disrobe-pass-jvm/src/dalvik_string_switch.rs |
disrobe-pass-jvm | MAX_TRACKED_NARROW_CONSTANT_REGS | return in must_narrow_constant_states | crates/disrobe-pass-jvm/src/dalvik_to_jvm.rs |
disrobe-pass-jvm | MAX_REGION_BLOCKS | for range in nearest_common_dominator; return in merge_ranges | crates/disrobe-pass-jvm/src/dalvik_try_regions.rs |
disrobe-pass-jvm | MAX_ARRAY_JOIN_DEPTH | return in join_ref | crates/disrobe-pass-jvm/src/dalvik_typestate.rs |
disrobe-pass-jvm | MAX_SUPERCLASS_DEPTH | while condition in root_first_chain | crates/disrobe-pass-jvm/src/dalvik_typestate.rs |
disrobe-pass-jvm | ARM_CONDITION_BLOCK_CAP | return in arm_tree_value; return in arm_value; return in join_value_entry; 1 more | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | INT_USE_SCAN_LIMIT | .take() in loaded_int_has_int_use | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_BOOL_EXPR_BYTES | return in eval_bool_node_memo | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_GENERIC_REPLACEMENTS | return in replacement_nodes | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_GENERIC_REPLACEMENT_BYTES | return in replacement_nodes | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_RENDER_BYTES | return in append_inner_output; return in append_java_replacement; return in emit_nested_class_stubs; 2 more | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | RECORD_ARITY_PROBE_CAP | while condition in infer_record_arity | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | REUSED_LOCAL_SPLIT_WORK_LIMIT | return in claim_reused_local_split_work | crates/disrobe-pass-jvm/src/decompile.rs |
disrobe-pass-jvm | MAX_CONDITION_CHAIN | return in latch_condition_chain; return in short_circuit_merge; return in structure_condition_chain; 1 more | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_JOIN_CHAIN | break in continuation_joins; for range in goto_chain_end; for range in handler_join_after; 1 more | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_TAIL_BLOCKS | return in duplicable_tail | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_TAIL_INSTRUCTIONS | return in duplicable_tail | crates/disrobe-pass-jvm/src/decompile_struct.rs |
disrobe-pass-jvm | MAX_ARRAY_DIMENSIONS | return in parse_one; return in type_descriptor_end | crates/disrobe-pass-jvm/src/descriptor.rs |
disrobe-pass-jvm | MAX_SYSTEM_METADATA_NORMALIZATION_ROUNDS | for range in normalize_system_metadata | crates/disrobe-pass-jvm/src/dex.rs |
disrobe-pass-jvm | MAX_ARRAY_DIMS | return in consume_field_type | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_JNI_STRING_LEN | return in is_jni_method_name; return in read_c_string | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_NATIVE_INT_KEYS | break in extract_static_int_keys | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_NATIVE_KEY_LIBS | .take() in extract_static_int_keys | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_NATIVE_KEY_LIB_BYTES | continue in extract_static_int_keys | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_STUB_BYTES | .min() clamp in bytes_at_address | crates/disrobe-pass-jvm/src/jni.rs |
disrobe-pass-jvm | MAX_HIERARCHY_DEPTH | return in resolve_field_with_inheritance; return in resolve_method_with_inheritance | crates/disrobe-pass-jvm/src/proguard.rs |
disrobe-pass-jvm | MAX_METHOD_INSNS | return in unflatten_method | crates/disrobe-pass-jvm/src/protectors/unflatten.rs |
disrobe-pass-jvm | MAX_DISPATCH_RESOLVE_STEPS | break in simplify_flattened_cfg | crates/disrobe-pass-jvm/src/sccp.rs |
disrobe-pass-lua | MAX_RENDERED_NUMBER_BYTES | ? on a checked operation in template_rendered_bytes | crates/disrobe-pass-lua/src/decompile/luau_lift.rs |
disrobe-pass-lua | MAX_JUMP_CHAIN | for range in rethread_loop_exits | crates/disrobe-pass-lua/src/decompile/luau_lift/translate.rs |
disrobe-pass-lua | MAX_STRUCTURE_VISITS_PER_NODE | .min() clamp in for_nodes | crates/disrobe-pass-lua/src/decompile/luau_structure.rs |
disrobe-pass-lua | MAX_STRUCTURE_WORK | .min() clamp in for_nodes | crates/disrobe-pass-lua/src/decompile/luau_structure.rs |
disrobe-pass-lua | MAX_RESERVED_NAME_SCAN | return in names_referenced_by | crates/disrobe-pass-lua/src/decompile/struct_lift.rs |
disrobe-pass-lua | MAX_STRUCT_DEPTH | return in lift_structured_captured | crates/disrobe-pass-lua/src/decompile/struct_lift.rs |
disrobe-pass-lua | MAX_STRUCT_NODES | return in lift_structured_captured | crates/disrobe-pass-lua/src/decompile/struct_lift.rs |
disrobe-pass-lua | READ_SEARCH_STATE_BUDGET | return in dominates_its_reads; return in read_after_control_flow; return in read_on_another_path | crates/disrobe-pass-lua/src/decompile/struct_lift.rs |
disrobe-pass-lua | MAX_SCOPE_DEPTH | return in block_captures_in_closure; return in block_mentions_by; return in declare_in_block; 3 more | crates/disrobe-pass-lua/src/decompile/struct_lift/declare.rs |
disrobe-pass-lua | MAX_CONDITION_CHAIN | while condition in recover_short_circuit_chains | crates/disrobe-pass-lua/src/decompile/struct_lift/structurer.rs |
disrobe-pass-lua | MAX_EXIT_SCAN | .take() in retarget_exits_through_skip_jumps | crates/disrobe-pass-lua/src/decompile/struct_lift/structurer.rs |
disrobe-pass-lua | MAX_BUILD_STEPS | return in build | crates/disrobe-pass-lua/src/decompile/struct_lift/value_region.rs |
disrobe-pass-lua | MAX_REGION_INSTRUCTIONS | return in build; while condition in region_bounds | crates/disrobe-pass-lua/src/decompile/struct_lift/value_region.rs |
disrobe-pass-lua | MAX_LOADER_DEPTH | for range in peel | crates/disrobe-pass-lua/src/obfuscator/hercules.rs |
disrobe-pass-lua | MAX_CAESAR_KEY | return in caesar_decode | crates/disrobe-pass-lua/src/obfuscator/hercules_recover.rs |
disrobe-pass-lua | MAX_FOLDED_STRING_BYTES | return in const_string | crates/disrobe-pass-lua/src/obfuscator/hercules_recover.rs |
disrobe-pass-lua | MAX_ROUNDS | break in recover_source | crates/disrobe-pass-lua/src/obfuscator/hercules_recover.rs |
disrobe-pass-lua | LURAPH_SCAN_LIMIT | .min() clamp in find_lua_assignment_value | crates/disrobe-pass-lua/src/obfuscator/luraph.rs |
disrobe-pass-lua | MAX_BOOTSTRAP_TABLE_VALUES | return in parse_numeric_table_len | crates/disrobe-pass-lua/src/obfuscator/luraph.rs |
disrobe-pass-lua | MAX_LURAPH_EXPR_LEN | return in rewrite_hex_literals | crates/disrobe-pass-lua/src/obfuscator/luraph.rs |
disrobe-pass-lua | MAX_NESTED_VMIFY_PASSES | while condition in apply_vmify_devirt | crates/disrobe-pass-lua/src/obfuscator/prometheus.rs |
disrobe-pass-lua | VMIFY_DISPATCH_SCAN_LIMIT | return in matches_vmify_container_shape | crates/disrobe-pass-lua/src/obfuscator/prometheus.rs |
disrobe-pass-lua | MAX_ANTITAMPER_EXPRESSION_DEPTH | return in anti_tamper_value | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_LOOP_NESTING | return in render_loop | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_REGION_TREE_STEPS | ? on a checked operation in collect_region_nodes; ? on a checked operation in loop_exit_tails; ? on a checked operation in region_contains_node; 1 more | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_SCRATCH_CHAIN_DEPTH | return in resolve_and_expr; return in resolve_number_via_last_write | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | MAX_STATIC_NUMBER_DEPTH | return in evaluate_at_depth | crates/disrobe-pass-lua/src/obfuscator/prometheus_vm_cfg.rs |
disrobe-pass-lua | DISPATCH_SCAN_LIMIT | return in analyze_dispatch | crates/disrobe-pass-lua/src/obfuscator/prometheus_vmlift.rs |
disrobe-pass-lua | MAX_FOLD_TOKENS | return in fold_one_expression; return in try_fold_span | crates/disrobe-pass-lua/src/obfuscator/prometheus_vmlift.rs |
disrobe-pass-lua | BASE64_PAYLOAD_CHAR_CAP | return in decode_base64_payload_run | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | BOOTSTRAP_SCAN_LIMIT | .min() clamp in find_lua_assignment_value; while condition in extract_named_lua_byte_buffer | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | EMBEDDED_PAYLOAD_SCAN_LIMIT | .min() clamp in extract_lua_string_payload | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | LUA_TABLE_PAYLOAD_CAP | return in decode_lua_byte_table | crates/disrobe-pass-lua/src/obfuscator/vm_devirt.rs |
disrobe-pass-lua | DISPATCH_BLOCK_LIMIT | break in lift_dispatch | crates/disrobe-pass-lua/src/obfuscator/wearedevs.rs |
disrobe-pass-lua | DISPATCH_GUARD_LIMIT | break in collect_threshold_cuts | crates/disrobe-pass-lua/src/obfuscator/wearedevs.rs |
disrobe-pass-lua | DISPATCH_PARSE_DEPTH_LIMIT | return in parse_dispatch_node | crates/disrobe-pass-lua/src/obfuscator/wearedevs.rs |
disrobe-pass-lua | DISPATCH_SCAN_LIMIT | .min() clamp in lift_dispatch | crates/disrobe-pass-lua/src/obfuscator/wearedevs.rs |
disrobe-pass-mobile | MAX_EMBEDDED_DEX_CARVES | while condition in collect_plain_dex_carves; while condition in collect_xor_dex_carves | crates/disrobe-pass-mobile/src/apk_recon.rs |
disrobe-pass-mobile | MAX_PROTECTOR_CARVE_SCAN | skipped in analyze; skipped in extract_android_dex_children | crates/disrobe-pass-mobile/src/apk_recon.rs |
disrobe-pass-mobile | MAX_RESOLVED_RESOURCES | break in summarise_arsc | crates/disrobe-pass-mobile/src/apk_recon.rs |
disrobe-pass-mobile | MAX_TEXT_ASSET | skipped in analyze | crates/disrobe-pass-mobile/src/apk_recon.rs |
disrobe-pass-mobile | MAX_CERTS_PER_SIGNER | break in parse_signer | crates/disrobe-pass-mobile/src/apk_signing.rs |
disrobe-pass-mobile | MAX_DIGESTS_PER_SIGNER | break in parse_signer | crates/disrobe-pass-mobile/src/apk_signing.rs |
disrobe-pass-mobile | MAX_PAIRS | break in parse_id_value_pairs | crates/disrobe-pass-mobile/src/apk_signing.rs |
disrobe-pass-mobile | MAX_SIGNERS | break in parse_scheme | crates/disrobe-pass-mobile/src/apk_signing.rs |
disrobe-pass-mobile | TRAVERSAL_INSN_BUDGET | break in traverse | crates/disrobe-pass-mobile/src/flutter/arm64_traversal.rs |
disrobe-pass-mobile | MAX_BOOLEAN_RETURN_INSTRUCTIONS | return in recover_boolean_return | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_BOXED_DOUBLE_SETUP_INSTRUCTIONS | ? on a checked operation in skip | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_BOXED_DOUBLE_TRACE_INSTRUCTIONS | ? on a checked operation in skip | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_CONSUMED_TEXT_BYTES | skipped in consumed_text | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_FLOAT_RETURN_SPILL_DISTANCE | ? on a checked operation in skip | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_FRAME_SLOTS | return in record_frame | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_MERGE_PREDECESSORS | return in entry_state | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_STACK_ARGUMENTS | return in record_stack; return in stack_arguments | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_TRACKED_CALLS | break in track_call_sites | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_TRACKED_EFFECTS | return in define; skipped in bookkeeping; skipped in step | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_VALUE_DEPTH | return in render_value | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | MAX_VALUE_NODES | ? on a checked operation in node_budget | crates/disrobe-pass-mobile/src/flutter/call_args.rs |
disrobe-pass-mobile | CLUSTER_TAG_SCAN_LIMIT | .min() clamp in scan_cid_tags | crates/disrobe-pass-mobile/src/flutter/cluster.rs |
disrobe-pass-mobile | MAX_POOL_SLOTS | skipped in fill_object_pools | crates/disrobe-pass-mobile/src/flutter/dart_graph.rs |
disrobe-pass-mobile | MAX_FUNCTION_INSNS | while condition in disassemble_function; while condition in disassemble_range | crates/disrobe-pass-mobile/src/flutter/disasm.rs |
disrobe-pass-mobile | MEMBER_TABLE_CAP | return in member_table_from_count; return in parse | crates/disrobe-pass-mobile/src/flutter/kernel.rs |
disrobe-pass-mobile | MAX_POOL_LITERALS | break in resolve_pool_literals; while condition in resolve_pool_literals | crates/disrobe-pass-mobile/src/flutter/object_pool.rs |
disrobe-pass-mobile | MAX_RUN_PROBE | while condition in pool_run_length | crates/disrobe-pass-mobile/src/flutter/object_pool.rs |
disrobe-pass-mobile | POOL_DECODE_BUDGET | .min() clamp in recover_object_pool_references | crates/disrobe-pass-mobile/src/flutter/object_pool.rs |
disrobe-pass-mobile | MAX_DART_IDENTIFIER_COUNT | break in extract_dart_identifiers; skipped in flush_identifier | crates/disrobe-pass-mobile/src/flutter/snapshot.rs |
disrobe-pass-mobile | MAX_FUNCTION_BOUNDARIES | while condition in scan_function_boundaries | crates/disrobe-pass-mobile/src/flutter/snapshot.rs |
disrobe-pass-mobile | MAX_STRING_CHARS | continue in scan_one_byte_strings | crates/disrobe-pass-mobile/src/flutter/string_pool.rs |
disrobe-pass-mobile | MAX_ALLOCATOR_WORDS | for range in allocate_object_helper_inputs | crates/disrobe-pass-mobile/src/flutter/stub_abi.rs |
disrobe-pass-mobile | MAX_REGISTER_SAVES | return in stub_frame_entry | crates/disrobe-pass-mobile/src/flutter/stub_abi.rs |
disrobe-pass-mobile | MAX_STUB_ARGUMENT_STEPS | for range in runtime_call_stub | crates/disrobe-pass-mobile/src/flutter/stub_abi.rs |
disrobe-pass-mobile | MAX_TAG_WORDS | return in allocation_stub_for_class | crates/disrobe-pass-mobile/src/flutter/stub_abi.rs |
disrobe-pass-mobile | MAX_DECIMAL_BYTES | fallback value in bigint_literal | crates/disrobe-pass-mobile/src/hermes/bigint.rs |
disrobe-pass-mobile | MAX_DECODED_INSTRUCTIONS | while condition in decode_instructions | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_INLINE_CLOSURE_BYTES | no action in closure_expr | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_INLINE_CLOSURE_DEPTH | return in inlined_closure_bodies | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_REG_EXPR_BYTES | no action in set_reg | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_RENDERED_CALL_ARGS | .min() clamp in unrecovered_arg_list; return in call_window_registers | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_RENDER_BYTES | break in render_block_stmts; break in render_structured | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_SWITCH_CASES | return in switch_table_entries | crates/disrobe-pass-mobile/src/hermes/decompile.rs |
disrobe-pass-mobile | MAX_DECODED_LITERALS | return in decode_literals; while condition in decode_literals | crates/disrobe-pass-mobile/src/hermes/literals.rs |
disrobe-pass-mobile | MAX_REGEX_INSNS | while condition in decode_body; while condition in render_range_inner | crates/disrobe-pass-mobile/src/hermes/regex.rs |
disrobe-pass-mobile | MAX_LOOP_EXTENSION_ROUNDS | for range in extend_loop_body | crates/disrobe-pass-mobile/src/hermes/structure.rs |
disrobe-pass-mobile | MAX_DECODED_XML | break in decode_archive | crates/disrobe-pass-mobile/src/res_decode.rs |
disrobe-pass-mobile | MAX_VALUES_ENTRIES | break in reconstruct_values | crates/disrobe-pass-mobile/src/res_decode.rs |
disrobe-pass-native | MAX_HARVEST_INSNS | break in harvested_hash_constants | crates/disrobe-pass-native/src/api_hash.rs |
disrobe-pass-native | MAX_CHAIN_DEPTH | while condition in build_chain | crates/disrobe-pass-native/src/authenticode.rs |
disrobe-pass-native | MAX_BLOCKS | return in build_cfg; return in collect_leaders | crates/disrobe-pass-native/src/basic_blocks.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | return in build_block; return in collect_leaders | crates/disrobe-pass-native/src/basic_blocks.rs |
disrobe-pass-native | MAX_AUTO_PSEUDO_FUNCTIONS | return in native_pseudo_report | crates/disrobe-pass-native/src/chain_detector.rs |
disrobe-pass-native | MAX_AUTO_PSEUDO_IMAGE_BYTES | return in native_pseudo_report | crates/disrobe-pass-native/src/chain_detector.rs |
disrobe-pass-native | MAX_AUTO_PSEUDO_REPORT_BYTES | no action in build_image_children | crates/disrobe-pass-native/src/chain_detector.rs |
disrobe-pass-native | MAX_X86_INSTRUCTION_BYTES | slice in is_import_thunk | crates/disrobe-pass-native/src/code_symbol.rs |
disrobe-pass-native | MAX_DEPTH | return in process_value; return in read_object; return in read_prop_list | crates/disrobe-pass-native/src/delphi/dfm.rs |
disrobe-pass-native | MAX_OBJECTS | return in read_object | crates/disrobe-pass-native/src/delphi/dfm.rs |
disrobe-pass-native | BYTE_SCAN_LIMIT | slice in identify; slice in scan_window | crates/disrobe-pass-native/src/delphi/image.rs |
disrobe-pass-native | MAX_SHORTSTRING_LEN | return in is_plausible_symbol_of_length; return in read_shortstring | crates/disrobe-pass-native/src/delphi/image.rs |
disrobe-pass-native | MAX_STUB_BYTES | slice in entry_stub_addresses | crates/disrobe-pass-native/src/delphi/init_table.rs |
disrobe-pass-native | MAX_STUB_INSTRUCTIONS | while condition in entry_stub_addresses | crates/disrobe-pass-native/src/delphi/init_table.rs |
disrobe-pass-native | MAX_UNITS | return in parse_at | crates/disrobe-pass-native/src/delphi/init_table.rs |
disrobe-pass-native | MAX_ENTRIES | .min() clamp in entry_count | crates/disrobe-pass-native/src/delphi/resource.rs |
disrobe-pass-native | MAX_NAME_CHARS | .min() clamp in read_res_name | crates/disrobe-pass-native/src/delphi/resource.rs |
disrobe-pass-native | MAX_RESOURCES | return in walk_langs; return in walk_names; return in walk_types | crates/disrobe-pass-native/src/delphi/resource.rs |
disrobe-pass-native | MAX_SCAN_POSITIONS | break in scan | crates/disrobe-pass-native/src/delphi/strings.rs |
disrobe-pass-native | MAX_STRINGS | break in scan | crates/disrobe-pass-native/src/delphi/strings.rs |
disrobe-pass-native | MAX_STRING_UNITS | return in read_candidate | crates/disrobe-pass-native/src/delphi/strings.rs |
disrobe-pass-native | MAX_DYNAMIC_METHODS | return in parse_dynamic_table | crates/disrobe-pass-native/src/delphi/tables.rs |
disrobe-pass-native | MAX_FIELDS_PER_CLASS | return in parse_field_table | crates/disrobe-pass-native/src/delphi/tables.rs |
disrobe-pass-native | MAX_FIELD_CLASSES | return in field_class_candidates | crates/disrobe-pass-native/src/delphi/tables.rs |
disrobe-pass-native | MAX_INTERFACES | return in parse_interface_table | crates/disrobe-pass-native/src/delphi/tables.rs |
disrobe-pass-native | MAX_ENUM_MEMBERS | return in fill_enumeration | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_FIELD_VISIBILITY | return in parse_record_fields | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_MANAGED_FIELDS | return in fill_record | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_RECORD_FIELDS | return in parse_record_fields | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_RECORD_SIZE | return in fill_record | crates/disrobe-pass-native/src/delphi/typeinfo.rs |
disrobe-pass-native | MAX_PATH_TAIL | slice in scan_toolchain_paths | crates/disrobe-pass-native/src/delphi/version.rs |
disrobe-pass-native | MAX_INSTANCE_SIZE | return in validate_class | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_METHODS_PER_CLASS | .min() clamp in parse_method_table | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_PARENT_DEPTH | break in accumulate | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_PROPS_PER_CLASS | .min() clamp in parse_typeinfo | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_TYPE_RECORDS | .take() in describe_types | crates/disrobe-pass-native/src/delphi/vmt.rs |
disrobe-pass-native | MAX_DECODE_INSNS | while condition in decode_all | crates/disrobe-pass-native/src/deobf/abi.rs |
disrobe-pass-native | MAX_DECODE_INSNS | while condition in decode_all | crates/disrobe-pass-native/src/deobf/bcf_dse.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | while condition in decode_all | crates/disrobe-pass-native/src/deobf/branchfold.rs |
disrobe-pass-native | MAX_BLOCKS | return in carve_blocks | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_DISPATCH_TREE_STEPS | break in compare_chain_blocks; return in model_compare_tree; while condition in enqueue_jump_table_targets; 1 more | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_INSNS | return in build_program; return in recursive_decode | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_REGION_DEPTH | return in walk | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_REGION_STEPS | return in walk | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_RESOLVE_DEPTH | return in resolve_loc | crates/disrobe-pass-native/src/deobf/cff.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | while condition in decode_all | crates/disrobe-pass-native/src/deobf/copyprop.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | while condition in decode_all | crates/disrobe-pass-native/src/deobf/deadflags.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | while condition in decode_all | crates/disrobe-pass-native/src/deobf/jumptable.rs |
disrobe-pass-native | MAX_TABLE_ENTRIES | .min() clamp in read_pic_table; .min() clamp in read_table; while condition in read_pic_table; 1 more | crates/disrobe-pass-native/src/deobf/jumptable.rs |
disrobe-pass-native | MAX_LIFT_INSNS | return in lift_arith_value; return in lift_operand_pair | crates/disrobe-pass-native/src/deobf/mba_lift.rs |
disrobe-pass-native | MAX_DECODE_INSNS | while condition in decode_all | crates/disrobe-pass-native/src/deobf/pathsense.rs |
disrobe-pass-native | MAX_PATH_BLOCKS | return in walk | crates/disrobe-pass-native/src/deobf/pathsense.rs |
disrobe-pass-native | MAX_BLOCK_INSNS | return in build_block; return in collect_leaders | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_DECODE_INSNS | while condition in decode_all | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_JOINS | return in summarize_region | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_LOOPS | for range in unroll_natural_loops | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_OUTPUT_REGISTERS | return in finalize_summary | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_OUTPUT_STACK_CELLS | return in finalize_summary | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_REGION_BLOCKS | return in build_region; return in collect_leaders | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_REGION_INSNS | return in build_region | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_UNROLL | break in rs_emit_range; continue in forward_join_lowering_candidates; continue in prove_one; 34 more | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_UNROLLED_BLOCKS | return in unroll_one | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | VERIFY_ARITY_CAP | return in densify | crates/disrobe-pass-native/src/deobf/summary.rs |
disrobe-pass-native | MAX_DIRECT_CALL_SWEEP_OFFSETS | .min() clamp in add_linear_call_evidence; .min() clamp in sweep_direct_call_target_evidence; break in add_linear_call_evidence; 1 more | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_INTERIOR_PROLOGUE_PROVENANCE | skipped in traverse_function | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_JUMP_TABLE_ENTRIES | while condition in resolve_jump_table | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_NORETURN_ITERATIONS | for range in noreturn_closure | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_REL32_BACKWARD_DISTANCE | return in direct_call_target | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_REL32_FORWARD_DISTANCE | return in direct_call_target | crates/disrobe-pass-native/src/desync.rs |
disrobe-pass-native | MAX_BOUNDARY_PADDING_BYTES | return in is_alignment_boundary | crates/disrobe-pass-native/src/disasm_ir.rs |
disrobe-pass-native | MAX_AARCH64_PLT_ENTRIES | for range in collect_elf_plt_entries | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_EXECUTABLE_RANGES | break in new; return in new_pe64 | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_PE_GUARD_CF_FUNCTIONS | .min() clamp in decode_pe_arm64_guard_cf_functions | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_PE_TLS_CALLBACKS | for range in decode_pe_arm64_tls_callbacks | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_POINTER_SLOTS | break in collect_data_pointers; return in collect_initializer_tables | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_SEEDS | break in aarch64_boundary_prologue_seeds; break in aarch64_gap_boundary_prologue_seeds; return in aarch64_boundary_prologue_seeds; 3 more | crates/disrobe-pass-native/src/disasm_ir/aarch64_seeds.rs |
disrobe-pass-native | MAX_DYNAMIC_ENTRIES | while condition in read_dynamic_entries | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_ELF_PROGRAM_HEADERS | return in is_well_formed_elf_executable; return in validate_section_table | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_GNU_HASH_BUCKETS | return in gnu_hash_symbol_count | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_NEEDED | .min() clamp in read_pointer_array; continue in analyze | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_RELOCATIONS | return in read_rel; return in read_rela | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_STRING_BYTES | .min() clamp in read_interpreter; .min() clamp in resolve_dynstr | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_SYMBOLS | .min() clamp in bounded_symbol_scan; .min() clamp in read_dynamic_symbols; return in gnu_hash_symbol_count; 2 more | crates/disrobe-pass-native/src/elf.rs |
disrobe-pass-native | MAX_BUFFERS_PER_CANDIDATE | .take() in emulate_string_decoders_inner | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_CANDIDATES | .take() in emulate_string_decoders_inner | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_DECODE_SPAN | .min() clamp in emulate_string_decoders_inner | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_HARVEST_PER_RUN | break in merge_harvests; return in harvest_ascii; return in harvest_utf16; 3 more | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_STRING_LEN | return in insert_static_run; return in push_candidate; return in push_wide_candidate | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | PER_CANDIDATE_STEP_CAP | break in run | crates/disrobe-pass-native/src/emu_strings.rs |
disrobe-pass-native | MAX_ENTROPY_BITS | .clamp() clamp in normalized_entropy | crates/disrobe-pass-native/src/entropy_viz.rs |
disrobe-pass-native | SCAN_LIMIT | slice in bytes_find | crates/disrobe-pass-native/src/identify.rs |
disrobe-pass-native | MAX_ASPACK_IMPORT_DESCRIPTORS | break in find_aspack_runtime_import_directory; return in find_aspack_runtime_import_directory; return in reconstruct_aspack_import_descriptors | crates/disrobe-pass-native/src/packers/aspack_phase2.rs |
disrobe-pass-native | MAX_ASPACK_MODULE_NAME_LEN | continue in collect_aspack_import_layouts; for range in read_guest_cstr; return in reconstruct_aspack_import_descriptors | crates/disrobe-pass-native/src/packers/aspack_phase2.rs |
disrobe-pass-native | MAX_ASPACK_THUNK_CANDIDATES | return in find_unique_thunk_tables | crates/disrobe-pass-native/src/packers/aspack_phase2.rs |
disrobe-pass-native | MAX_POS_BITS | fallback value in decode_bit | crates/disrobe-pass-native/src/packers/mpress_lzma.rs |
disrobe-pass-native | MAX_POS_STATES | fallback value in decode_bit | crates/disrobe-pass-native/src/packers/mpress_lzma.rs |
disrobe-pass-native | MAX_IMPORTED_MODULES | break in locate_import_record; while condition in locate_import_descriptors | crates/disrobe-pass-native/src/packers/nspack_unpack.rs |
disrobe-pass-native | MAX_IMPORTS_PER_MODULE | break in locate_import_record | crates/disrobe-pass-native/src/packers/nspack_unpack.rs |
disrobe-pass-native | MAX_MODULE_NAME_BYTES | slice in module_name_is_plausible | crates/disrobe-pass-native/src/packers/nspack_unpack.rs |
disrobe-pass-native | MAX_GAP_SEARCH_BYTES | return in forced_leaf_placements | crates/disrobe-pass-native/src/packers/pe_resource.rs |
disrobe-pass-native | MAX_RESOURCE_DEPTH | return in walk_resource_dir | crates/disrobe-pass-native/src/packers/pe_unbind.rs |
disrobe-pass-native | MAX_BLOCKS | return in decode_elf_extents_with_budget; return in walk_block_chain | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_BRUTE_FORCE_OFFSETS | .min() clamp in decode_image_with_budget; .min() clamp in decode_multiblock_with_budget; .min() clamp in locate_structural | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_L_INFO_SCAN | .min() clamp in elf_first_block_offset | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_RESYNC_OFFSETS | while condition in decode_elf_extents_with_budget | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_STRUCTURAL_CHECKSUM_BYTES | return in reserve | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_VERIFY_CANDIDATES | break in locate_structural | crates/disrobe-pass-native/src/packers/upx_decoder.rs |
disrobe-pass-native | MAX_CARVED_PROTECTED_SECTIONS | .take() in carve_themida; .take() in carve_vmprotect | crates/disrobe-pass-native/src/packers/vmprotect_carve.rs |
disrobe-pass-native | ADDRESS_SPACE_CAP | return in flatten_address_space | crates/disrobe-pass-native/src/pass.rs |
disrobe-pass-native | DEOBF_SECTION_CAP | .min() clamp in executable_sections | crates/disrobe-pass-native/src/pass.rs |
disrobe-pass-native | MAX_FIELDLIST_CHAIN | for range in collect_fieldlist | crates/disrobe-pass-native/src/pdb_cxx/emit.rs |
disrobe-pass-native | MAX_MODULES | continue in recover_module_procedures | crates/disrobe-pass-native/src/pdb_cxx/procedures.rs |
disrobe-pass-native | MAX_PROCEDURES | continue in recover_module_procedures | crates/disrobe-pass-native/src/pdb_cxx/procedures.rs |
disrobe-pass-native | MAX_RECURSION_BUDGET | return in resolve_spelling_bounded | crates/disrobe-pass-native/src/pdb_cxx/spelling.rs |
disrobe-pass-native | MAX_UNWRAP_DEPTH | for range in resolve_spelling_bounded | crates/disrobe-pass-native/src/pdb_cxx/spelling.rs |
disrobe-pass-native | MAX_MACHO_IMPORT_NAME_BYTES | return in resolve_macho_stub_imports | crates/disrobe-pass-native/src/plt_resolve.rs |
disrobe-pass-native | MAX_MACHO_IMPORT_STUBS | return in resolve_macho_stub_imports | crates/disrobe-pass-native/src/plt_resolve.rs |
disrobe-pass-native | MAX_MACHO_SCANNED_NAME_BYTES | return in resolve_macho_stub_imports; slice in resolve_macho_stub_imports | crates/disrobe-pass-native/src/plt_resolve.rs |
disrobe-pass-native | MAX_MACHO_SYMBOL_NAME_BYTES | slice in resolve_macho_stub_imports | crates/disrobe-pass-native/src/plt_resolve.rs |
disrobe-pass-native | ACYCLIC_JOIN_BLOCK_CAP | return in acyclic_join_lowering_plan; return in join_plan_preserves_blocks | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | FORWARD_JOIN_PLAN_CAP | return in forward_join_lowering_candidates | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | LOOP_EXIT_TAIL_ABSORPTION_BUDGET | for range in absorb_private_exit_tails | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_LOCAL_NORETURN_BYTES | return in local_noreturn_leaf_is_proven; return in outlined_noreturn_exit | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_LOCAL_NORETURN_CALLEES | continue in object_transfer_facts; skipped in object_transfer_facts | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_LOCAL_NORETURN_RELOCATIONS | .take() in read; return in read | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_OUTLINED_EXIT_SLOTS | return in outlined_noreturn_exit | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | PURE_TAIL_CLONE_BUDGET | for range in emit_cloned_pure_tail | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | RUST_RESUME_LABEL_CAP | return in rs_forward_exit_labels; return in rs_resume_paths | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | RUST_RESUME_NODE_CAP | return in rs_forward_exit_labels; return in rs_resume_paths | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | TAIL_JOIN_WALK_BUDGET | return in joins_every_non_tail_path | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | TAIL_SPLIT_BLOCK_CAP | return in closed_loop_body; return in render_cfg_blocks_via_cns; return in split_tail_regions | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | TAIL_SUBTREE_CAP | return in private_tail_subtree | crates/disrobe-pass-native/src/pseudo_c.rs |
disrobe-pass-native | MAX_SWITCH_CASES | return in readable_switch_table; return in recover_aarch64_switch | crates/disrobe-pass-native/src/pseudo_c/aarch64.rs |
disrobe-pass-native | MAX_SWITCH_SLICE_INSTRUCTIONS | for range in matching_switch_guard; for range in single_block_definition; for range in single_block_pc_relative_definition; 1 more | crates/disrobe-pass-native/src/pseudo_c/aarch64.rs |
disrobe-pass-native | MAX_SWITCH_TABLE_BYTES | return in readable_switch_table | crates/disrobe-pass-native/src/pseudo_c/aarch64.rs |
disrobe-pass-native | REGISTER_ARGUMENT_LIMIT | for range in prove_arguments | crates/disrobe-pass-native/src/pseudo_c/aarch64_callsite.rs |
disrobe-pass-native | MAX_CALLEE_BYTES | return in clobbers | crates/disrobe-pass-native/src/pseudo_c/call_clobber.rs |
disrobe-pass-native | MAX_CALLEE_FUNCTIONS | return in clobbers | crates/disrobe-pass-native/src/pseudo_c/call_clobber.rs |
disrobe-pass-native | MAX_AFFINE_SHIFT | fallback value in remainder_register | crates/disrobe-pass-native/src/pseudo_c/idiom.rs |
disrobe-pass-native | MAX_DIVIDEND_BITS | return in disjoint_or; return in divisor_reproduces_witness; return in quotient_ceiling; 2 more | crates/disrobe-pass-native/src/pseudo_c/idiom.rs |
disrobe-pass-native | MAX_BLOCKS | return in specialize | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_EXPR_NODES | return in push_value | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_FOLDS | for range in specialize | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_PROOFS | ? on a checked operation in prove_one | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_STATEMENTS | return in specialize | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_VALUES | return in definitions | crates/disrobe-pass-native/src/pseudo_c/invariant_branches.rs |
disrobe-pass-native | MAX_INLINED_DEFINITIONS | for range in inline_single_use_definitions | crates/disrobe-pass-native/src/pseudo_c/spill.rs |
disrobe-pass-native | MAX_RECORDED_DECISIONS | return in record | crates/disrobe-pass-native/src/pseudo_c/spill.rs |
disrobe-pass-native | SCAN_LIMIT | slice in analyze; slice in dotnet_bundle_finding; slice in pkr_ce1a_finding; 1 more | crates/disrobe-pass-native/src/sig_engine.rs |
disrobe-pass-native | VERSION_TAIL_CAP | slice in dotted_after; slice in literal_tail | crates/disrobe-pass-native/src/sig_engine.rs |
disrobe-pass-native | ADRP_PAIR_SCAN_LIMIT | for range in paired_low_bits | crates/disrobe-pass-native/src/similarity.rs |
disrobe-pass-native | WIDE_MOVE_CHAIN_LIMIT | while condition in fold_wide_move | crates/disrobe-pass-native/src/similarity.rs |
disrobe-pass-native | WINDOW_INSTRUCTION_LIMIT | while condition in window_start | crates/disrobe-pass-native/src/similarity/opaque.rs |
disrobe-pass-native | MAX_GROUP_SPAN | no action in reassemble_group | crates/disrobe-pass-native/src/stack_string.rs |
disrobe-pass-native | MAX_SCAN_INSNS | break in harvest_stack_stores | crates/disrobe-pass-native/src/stack_string.rs |
disrobe-pass-native | MAX_RIP_REFS | break in scan_rip_relative_refs | crates/disrobe-pass-native/src/stream_disasm.rs |
disrobe-pass-native | MAX_CHAIN_PAGES | ? on a checked operation in apply_chains | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_CHAIN_STEPS | ? on a checked operation in apply_chains | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_FIXUP_BYTES | return in apply | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_SECTIONS | return in loaded_section_ranges; return in validate_loaded_sections | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_SEGMENTS | return in apply_chains; return in apply | crates/disrobe-pass-native/src/vm_devirt/detect/chained_fixups.rs |
disrobe-pass-native | MAX_GUARDIAN_BYTECODE_BYTES | .min() clamp in devirtualize_guardian_rs | crates/disrobe-pass-native/src/vm_devirt/guardian.rs |
disrobe-pass-native | MAX_HANDLERS | return in read_pointer_table; return in recover_via_codescan; return in recover_via_exports; 1 more | crates/disrobe-pass-native/src/vm_devirt/mod.rs |
disrobe-pass-nativelang | MAX_EMITTED_NAME_CHARS | .take() in emitted_identifier | crates/disrobe-pass-nativelang/src/bodies.rs |
disrobe-pass-nativelang | MAX_DEPTH | fallback value in enter | crates/disrobe-pass-nativelang/src/d_mangle.rs |
disrobe-pass-nativelang | MAX_NIM_DEPTH | return in read_nim_type; return in split_itanium_params | crates/disrobe-pass-nativelang/src/demangle.rs |
disrobe-pass-nativelang | MAX_NIM_GENERATED_SYMBOL_BYTES | return in demangle_nim_generated_itanium | crates/disrobe-pass-nativelang/src/demangle.rs |
disrobe-pass-nativelang | MAX_NIM_GENERATED_UID_DIGITS | return in decode_nim_itanium_identifier | crates/disrobe-pass-nativelang/src/demangle.rs |
disrobe-pass-nativelang | MAX_ARRAY_DIMENSIONS | while condition in array_dimensions | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_AGGREGATES | break in walk_dwarf; skipped in collect_aggregates; skipped in push_aggregate | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_AGGREGATE_DEPTH | skipped in collect_aggregates | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_AGGREGATE_ITEMS | return in collect_aggregates; return in take_aggregate_item | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_DIE_VISITS | break in walk_dwarf; return in collect_aggregates; return in visit_die | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_FUNCS | break in walk_dwarf; return in collect_unit; skipped in push_function | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_FUNCTION_PARAMS | return in collect_unit; return in take_function_param | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_REFERENCE_DEPTH | continue in resolve_attr_queue; skipped in resolve_attr_queue | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_REFERENCE_VISITS | return in enqueue_references; while condition in resolve_attr_queue | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_DWARF_TYPE_DEPTH | return in resolve_type_name | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_LINE_ROWS | break in assign_line_ranges; break in fill_line_ranges | crates/disrobe-pass-nativelang/src/dwarf.rs |
disrobe-pass-nativelang | MAX_REPORTED_TYPES | .take() in recover_types | crates/disrobe-pass-nativelang/src/dwarf_types.rs |
disrobe-pass-nativelang | MAX_EH_FRAME_BYTES | return in recover_eh_frame_functions | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_EH_FRAME_FDES | while condition in recover_eh_frame_functions | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_RECOVERED_FUNCTIONS | break in recover_functions | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_TRAVERSAL_TEXT | return in run_traversal | crates/disrobe-pass-nativelang/src/functions.rs |
disrobe-pass-nativelang | MAX_STRING_COUNT | return in push_capped | crates/disrobe-pass-nativelang/src/image.rs |
disrobe-pass-nativelang | MAX_TABLE_FUNCTION_STARTS | .take() in parse; .take() in pe_unwind_table_starts; break in macho_function_starts | crates/disrobe-pass-nativelang/src/image.rs |
disrobe-pass-nativelang | MAX_NIR_FUNCTIONS | .take() in lift_native_nir | crates/disrobe-pass-nativelang/src/nir.rs |
disrobe-pass-nativelang | MAX_NIR_SYMBOLS | .take() in lift_native_nir | crates/disrobe-pass-nativelang/src/nir.rs |
disrobe-pass-nativelang | MAX_D_RTTI_NAME_LEN | return in accept_d_rtti_name; return in demangle_d_struct_type; return in mapped_d_slice | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_SEGMENTS | return in accept_d_rtti_name | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_SLICE_LEN | return in mapped_d_slice | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nativelang | MAX_D_RTTI_VECTOR_LEN | return in d_class_info_at; return in d_class_info_name_at | crates/disrobe-pass-nativelang/src/recover.rs |
disrobe-pass-nuitka | MAX_CONTAINER_LEN | return in walk_sequence; return in walk_value | crates/disrobe-pass-nuitka/src/blob_scan.rs |
disrobe-pass-nuitka | MAX_DEPTH | return in walk_value | crates/disrobe-pass-nuitka/src/blob_scan.rs |
disrobe-pass-nuitka | MAX_LEAF_BYTES | .min() clamp in scan_constants_blob; ? on a checked operation in read_zero_terminated_bytes; break in scan_constants_blob; 1 more | crates/disrobe-pass-nuitka/src/blob_scan.rs |
disrobe-pass-nuitka | MAX_LEAVES | return in push_int; return in push_str | crates/disrobe-pass-nuitka/src/blob_scan.rs |
disrobe-pass-nuitka | MAX_LIFT_DEPTH | return in eval_atom; return in eval_value; return in lift_block | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_PREPROCESSOR_NESTING | return in parse_primary | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_TOP_LEVEL_ARGUMENTS | return in split_top_args | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_TOP_LEVEL_ARGUMENT_BYTES | return in split_top_args | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_VALUE_DIAMOND_DEPTH | return in arm_value | crates/disrobe-pass-nuitka/src/body.rs |
disrobe-pass-nuitka | MAX_FIELD_LEN | continue in decode_record | crates/disrobe-pass-nuitka/src/buildinfo.rs |
disrobe-pass-nuitka | MAX_RECORD_LEN | .min() clamp in scan_build_info | crates/disrobe-pass-nuitka/src/buildinfo.rs |
disrobe-pass-nuitka | MAX_C_CALL_ARGUMENT_BYTES | return in split_top_level_args_with_mask | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_C_DIRECT_STATEMENT_BYTES | return in direct_statement_suffix | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MAX_FACTORY_TOP_LEVEL_STATEMENTS | return in factory_top_level_statements | crates/disrobe-pass-nuitka/src/c_module.rs |
disrobe-pass-nuitka | MANIFEST_ENTRY_EXTRACT_CAP | fallback value in render_manifest_light | crates/disrobe-pass-nuitka/src/chain_detector.rs |
disrobe-pass-nuitka | MAX_ONEFILE_MAIN_DECOMPILE_BYTES | skipped in extract_children | crates/disrobe-pass-nuitka/src/chain_detector.rs |
disrobe-pass-nuitka | MAX_CHUNK_BYTES | return in plausible_table_header; return in try_chunk_with_layout | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_CHUNK_COUNT | return in big_int; return in plausible_table_header; return in sequence; 2 more | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_DEPTH | return in value | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_NAME_LEN | return in plausible_table_header; return in try_chunk_with_layout; slice in plausible_table_header; 1 more | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_PREVIOUS_CLONE_WEIGHT | return in value_body | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_STORED_LAST_WEIGHT | fallback value in value | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_TABLE_HEADER_HINTS | while condition in table_header_hints | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_VALUE_BYTES | return in bounded_len | crates/disrobe-pass-nuitka/src/const_blob.rs |
disrobe-pass-nuitka | MAX_SIBLING_BINARY_BYTES | .take() in read_file_bounded; return in read_file_bounded | crates/disrobe-pass-nuitka/src/decompile.rs |
disrobe-pass-nuitka | MAX_PYTHON_ABI_MINOR | for range in find_python_runtime_name; for range in find_python_version_marker | crates/disrobe-pass-nuitka/src/detect.rs |
disrobe-pass-nuitka | MAX_FROZEN_MODULES | while condition in recover_frozen_bytecode | crates/disrobe-pass-nuitka/src/frozen.rs |
disrobe-pass-nuitka | MAX_MARSHAL_BYTES | slice in load_code | crates/disrobe-pass-nuitka/src/frozen.rs |
disrobe-pass-nuitka | MAX_ENTRIES | break in map_names | crates/disrobe-pass-nuitka/src/name_map.rs |
disrobe-pass-nuitka | MAX_NAMES | .take() in map_names | crates/disrobe-pass-nuitka/src/name_map.rs |
disrobe-pass-nuitka | MAX_NAME_LEN | continue in map_names; return in map_names; slice in read_c_string | crates/disrobe-pass-nuitka/src/name_map.rs |
disrobe-pass-nuitka | MAX_NAME_MAP_TEXT_BYTES | for range in map_names | crates/disrobe-pass-nuitka/src/name_map.rs |
disrobe-pass-nuitka | MAX_API_CALLS | break in collect_api_calls | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | MAX_FUNCTIONS | .min() clamp in parse_pdata; break in locate_impls; skipped in collect_ctor_sites | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | MAX_IMPL_INSNS | while condition in decode_function | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | MAX_TEXT_BYTES | .min() clamp in parse_pe | crates/disrobe-pass-nuitka/src/native_body.rs |
disrobe-pass-nuitka | GLOBAL_CANDIDATE_LOG_CAP | skipped in locate_onefile_payload | crates/disrobe-pass-nuitka/src/onefile_locator.rs |
disrobe-pass-nuitka | MAX_ANNOTATION_EXPRESSION_BYTES | return in is_safe_annotation_expression | crates/disrobe-pass-nuitka/src/surface.rs |
disrobe-pass-nuitka | MAX_ANNOTATION_NESTING | return in enter_nesting | crates/disrobe-pass-nuitka/src/surface.rs |
disrobe-pass-nuitka | MAX_STATIC_PICKLE_DEPTH | return in contains_nonfinite_float; return in is_static_pickle_hashable; return in is_static_pickle_value; 1 more | crates/disrobe-pass-nuitka/src/surface.rs |
disrobe-pass-php | MAX_PARSE_DEPTH | return in parse_destructure_targets | crates/disrobe-pass-php/src/decode_loop.rs |
disrobe-pass-php | MAX_STATEMENTS | return in parse_block_body; return in parse_destructure_targets; return in parse_program | crates/disrobe-pass-php/src/decode_loop.rs |
disrobe-pass-php | MAX_UNRECOVERED_RECORDS | break in emit_body; skipped in limit; skipped in record_opaque_literals; 2 more | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CATCH_CLAUSE_CAP | return in catch_region_end; return in lift_catch_arms | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CATCH_TYPE_CAP | return in catch_clause | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CLOSURE_USE_CAP | return in fold_closure | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_CONDITION_RENDER_CAP | return in fold_test_graph | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_FOR_STEP_CAP | return in for_step_start | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_IF_TEST_CHAIN_CAP | while condition in if_test_chain | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LIST_ELEMENT_CAP | return in list_entries | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LIST_RENDER_CAP | return in fold_list_assign; return in list_entries; return in push_list_text | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LOOP_EXIT_FREE_CAP | return in exit_frees_match | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_LOOP_RELIFT_WORK_CAP | ? on a checked operation in loop_relift_charge | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | SANE_SWITCH_STATE_WORK_CAP | return in structure_linear_match; return in structure_switch_dispatch | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | USE_SCAN_BUDGET | break in read_after_jump; return in free_unconsumed; return in structure_switch_dispatch | crates/disrobe-pass-php/src/decompile.rs |
disrobe-pass-php | MAX_LINEARIZE_DEPTH | return in try_emit_braced | crates/disrobe-pass-php/src/deflatten.rs |
disrobe-pass-php | ZEND_OPTIMIZER_OBF_KEY_CAP | return in read_zend_optimizer_key | crates/disrobe-pass-php/src/encoder/container.rs |
disrobe-pass-php | ZEND_OBFUSCATION_KEY_CAP | return in recover_zend_optimizer_obfuscation_key | crates/disrobe-pass-php/src/key_extractor.rs |
disrobe-pass-php | MAX_OPAQUE_STATEMENT | skipped in parse_statements | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | MAX_PARSE_DEPTH | return in parse_expr; return in parse_var_ref | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | STR_REPEAT_OUTPUT_CAP | return in str_repeat | crates/disrobe-pass-php/src/loader.rs |
disrobe-pass-php | EVAL_PROBE_MIN_BUDGET | ? on a checked operation in next_eval_call_arg | crates/disrobe-pass-php/src/peel.rs |
disrobe-pass-php | RESOLVE_DEPTH_CAP | return in classify_inner_at_depth; return in resolve_arg | crates/disrobe-pass-php/src/peel.rs |
disrobe-pass-php | MAX_RESTRUCTURE_DEPTH | return in emit_units; return in structure_region; fallback value in emit_unit | crates/disrobe-pass-php/src/restructure.rs |
disrobe-pass-pickle | MAX_RENDER_DEPTH | return in inline_unused_refs; return in render | crates/disrobe-pass-pickle/src/decompile.rs |
disrobe-pass-pickle | MAX_STACKED_STREAMS | break in disassemble_streams; no action in analyze_streams; no action in run | crates/disrobe-pass-pickle/src/disasm.rs |
disrobe-pass-pickle | ANCHOR_OPCODE_BUDGET | .min() clamp in scan_for_embedded_with_work | crates/disrobe-pass-pickle/src/ml.rs |
disrobe-pass-pickle | MAX_NESTED_PICKLE_BYTES | return in analyze_nested_pickle | crates/disrobe-pass-pickle/src/safety.rs |
disrobe-pass-pickle | MAX_NESTED_PICKLE_DEPTH | return in analyze_nested_pickle | crates/disrobe-pass-pickle/src/safety.rs |
disrobe-pass-pickle | MAX_SCAN_DEPTH | return in scan_nested_pickles; return in scan_value | crates/disrobe-pass-pickle/src/safety.rs |
disrobe-pass-py-decompile | MAX_PATTERN_NEST_DEPTH | return in classify_mapping_pattern; return in classify_sequence_pattern | crates/disrobe-pass-py-decompile/src/ast/builder/branches.rs |
disrobe-pass-py-decompile | MAX_IMPORT_LEVEL | continue in build_linear_stmts_sim_seed; fallback value in bounded_import_level | crates/disrobe-pass-py-decompile/src/ast/builder/exprs.rs |
disrobe-pass-py-decompile | MAX_LAMBDA_BRANCH_DEPTH | return in returned_expr | crates/disrobe-pass-py-decompile/src/ast/builder/function_meta.rs |
disrobe-pass-py-decompile | MAX_SYNTH_OPERANDS | .min() clamp in pop_n; for range in build_linear_stmts_sim_seed | crates/disrobe-pass-py-decompile/src/ast/builder/mod.rs |
disrobe-pass-py-decompile | STRUCTURE_REENTRY_LIMIT | return in enter_active_region | crates/disrobe-pass-py-decompile/src/ast/builder/mod.rs |
disrobe-pass-py-decompile | MAX_SCANNED_LITERAL_BYTES | .min() clamp in collect_byte_tokens | crates/disrobe-pass-py-decompile/src/emit/marker_guard.rs |
disrobe-pass-py-decompile | MAX_SCANNED_STRINGS | return in collect_code; return in collect_object | crates/disrobe-pass-py-decompile/src/emit/marker_guard.rs |
disrobe-pass-py-decompile | MAX_SCAN_DEPTH | return in collect_code; return in collect_object | crates/disrobe-pass-py-decompile/src/emit/marker_guard.rs |
disrobe-pass-py-decompile | MAX_FRAME_NEST_DEPTH | no action in attach_into | crates/disrobe-pass-py-decompile/src/frame_tree/builder.rs |
disrobe-pass-py-decompile | MAX_CANDIDATES | .take() in accept_reordering_core | crates/disrobe-pass-py-decompile/src/selfcheck/opcontent.rs |
disrobe-pass-py-decompile | MAX_DEPTH | return in lower_seq; return in lower_try | crates/disrobe-pass-py-decompile/src/selfcheck/relower.rs |
disrobe-pass-py-decompile | MAX_HOIST_CANDIDATES | .take() in repair_else_tail | crates/disrobe-pass-py-decompile/src/selfcheck/repair.rs |
disrobe-pass-py-deob | MAX_KEY_CANDIDATES | .truncate() in dedup_and_rank | crates/disrobe-pass-py-deob/src/cipher.rs |
disrobe-pass-py-deob | MAX_REPEATING_KEYLEN | for range in best_keylengths | crates/disrobe-pass-py-deob/src/cipher.rs |
disrobe-pass-py-deob | MAX_FOLDED_LEN | return in fold_binop | crates/disrobe-pass-py-deob/src/constant_fold.rs |
disrobe-pass-py-deob | MAX_PASSES | for range in fold | crates/disrobe-pass-py-deob/src/constant_fold.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | return in collect_code_objects | crates/disrobe-pass-py-deob/src/hyperion_v2v3.rs |
disrobe-pass-py-deob | MAX_CHAIN_DEPTH | for range in peel_to_marshal_blob | crates/disrobe-pass-py-deob/src/marshal.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | return in collect_nested_blobs; no action in decompile_code | crates/disrobe-pass-py-deob/src/marshal.rs |
disrobe-pass-py-deob | MAX_CODEPOINT | return in apply_shift; return in stage1_codepoints | crates/disrobe-pass-py-deob/src/obfuscators/de4py_family.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | return in walk | crates/disrobe-pass-py-deob/src/obfuscators/obfuxtreme.rs |
disrobe-pass-py-deob | MAX_LOADER_BYTECODE | return in looks_like_loader | crates/disrobe-pass-py-deob/src/obfuscators/pyc_zipper.rs |
disrobe-pass-py-deob | MAX_STORE_DISTANCE | .take() in store_target | crates/disrobe-pass-py-deob/src/obfuscators/pyc_zipper/reverse.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | return in collect_code_objects | crates/disrobe-pass-py-deob/src/obfuscators/pyobfus.rs |
disrobe-pass-py-deob | MAX_NESTED_CODE_DEPTH | return in collect_code_objects | crates/disrobe-pass-py-deob/src/obfuscators/pypacker.rs |
disrobe-pass-py-deob | MAX_TOKEN_CHARS | return in recover | crates/disrobe-pass-py-deob/src/shuffled_base64.rs |
disrobe-pass-py-deob | MAX_OUTER_PASSES | for range in cleanup_source | crates/disrobe-pass-py-deob/src/source_cleanup.rs |
disrobe-pass-py-deob | MAX_CANONICAL_NAMES | continue in canonicalize_homoglyph_names | crates/disrobe-pass-py-deob/src/unrename.rs |
disrobe-pass-py-disasm | MAX_CODE_UNITS | break in disassemble_code_tree | crates/disrobe-pass-py-disasm/src/alt_runtimes/pypy.rs |
disrobe-pass-py-disasm | MAX_RENDER_DEPTH | return in repr_object | crates/disrobe-pass-py-disasm/src/const_repr.rs |
disrobe-pass-py-disasm | MAX_REPR_LONG_DIGITS | return in repr_bigint | crates/disrobe-pass-py-disasm/src/const_repr.rs |
disrobe-pass-py-disasm | MAX_SET_SIMULATION | return in cpython_set_order | crates/disrobe-pass-py-disasm/src/const_repr.rs |
disrobe-pass-pyarmor | MAX_NAME_LEN | return in resolve_name | crates/disrobe-pass-pyarmor/src/bcc/dispatch.rs |
disrobe-pass-pyarmor | MAX_RECORDS | while condition in parse_records | crates/disrobe-pass-pyarmor/src/bcc/dispatch.rs |
disrobe-pass-pyarmor | MAX_SECTIONS | .min() clamp in enumerate_elf_sections | crates/disrobe-pass-pyarmor/src/bcc/dispatch.rs |
disrobe-pass-pyarmor | EXECUTION_BUDGET | return in run | crates/disrobe-pass-pyarmor/src/bcc/dispatch_recover.rs |
disrobe-pass-pyarmor | MAX_TREE_DEPTH | no action in build_node; no action in walk_artifacts | crates/disrobe-pass-pyarmor/src/bcc/residual.rs |
disrobe-pass-pyarmor | MAX_TREE_NODES | break in build_node; break in walk_artifacts | crates/disrobe-pass-pyarmor/src/bcc/residual.rs |
disrobe-pass-pyarmor | MAX_STEPS | return in recover_idealized | crates/disrobe-pass-pyarmor/src/bcc/stmt_structure.rs |
disrobe-pass-pyarmor | MAX_PACKAGE_DEPTH | break in derive_module_path | crates/disrobe-pass-pyarmor/src/bcc/stub.rs |
disrobe-pass-pyarmor | MAX_CALL_TARGETS_SCANNED | .take() in resolve_sibling_calls | crates/disrobe-pass-pyarmor/src/bcc_lift.rs |
disrobe-pass-pyarmor | MAX_DISASM_LINES | break in render_unmodeled | crates/disrobe-pass-pyarmor/src/bcc_lift.rs |
disrobe-pass-pyarmor | MAX_FUNCTIONS | while condition in discover_functions | crates/disrobe-pass-pyarmor/src/bcc_lift.rs |
disrobe-pass-pyarmor | MAX_RESOLVED_CALLS | break in resolve_sibling_calls | crates/disrobe-pass-pyarmor/src/bcc_lift.rs |
disrobe-pass-pyarmor | MAX_READ | .min() clamp in extract_runtime_key | crates/disrobe-pass-pyarmor/src/key.rs |
disrobe-pass-pyarmor | MAX_IMPORT_SCAN_BYTES | slice in scan_import_symbols; slice in scan_printable_strings | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_IMPORT_SYMBOLS | return in scan_import_symbols | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_STRING_BYTES | .min() clamp in push_printable_string | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_STRING_CONSTANTS | return in scan_printable_strings | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_STRING_SCAN_BYTES | slice in scan_printable_strings | crates/disrobe-pass-pyarmor/src/static_unpack/mod.rs |
disrobe-pass-pyarmor | MAX_BCC_SEGMENTS | while condition in peel_bcc | crates/disrobe-pass-pyarmor/src/v8v9.rs |
disrobe-pass-pyfreeze | MAX_ENTRY_BYTES | continue in carve_zip_members | crates/disrobe-pass-pyfreeze/src/chain_detector.rs |
disrobe-pass-pyfreeze | MAX_ZIP_ENTRIES | .min() clamp in carve_zip_members | crates/disrobe-pass-pyfreeze/src/chain_detector.rs |
disrobe-pass-pyfreeze | MAX_COMMENT | for range in locate | crates/disrobe-pass-pyfreeze/src/common/zip_tail.rs |
disrobe-pass-pyfreeze | SEARCH_BUDGET | for range in locate | crates/disrobe-pass-pyfreeze/src/common/zip_tail.rs |
disrobe-pass-pyfreeze | MAX_FREEZE_DIR_ENTRIES | .take() in find_python_runtime; break in sibling_native_extensions | crates/disrobe-pass-pyfreeze/src/lib.rs |
disrobe-pass-pyfreeze | MAX_BLOB_SECTIONS | return in parse_blob_index | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_BLOB_SLICE | .min() clamp in extract_resources_blob | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_NAME_LEN | while condition in scan_name_start | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_RESOURCE_ENTRIES | break in heuristic_walk; return in extract_modules_structured; return in parse_structured_region | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_STRUCTURED_VERSION | for range in extract_resources_blob; no action in find_packed_magic | crates/disrobe-pass-pyfreeze/src/pyoxidizer/signatures.rs |
disrobe-pass-pyfreeze | MAX_DISASM_BYTES | slice in surface_native | crates/disrobe-pass-pyfreeze/src/recover.rs |
disrobe-pass-pyfreeze | SAMPLE_INSTRUCTION_CAP | .take() in surface_native | crates/disrobe-pass-pyfreeze/src/recover.rs |
disrobe-pass-pyinstaller | MAX_ZIP_COMMENT | return in find_eocd | crates/disrobe-pass-pyinstaller/src/base_library.rs |
disrobe-pass-pyinstaller | MAX_ZIP_ENTRIES | while condition in walk_central_directory | crates/disrobe-pass-pyinstaller/src/base_library.rs |
disrobe-pass-pyinstaller | MAX_NATIVE_SURFACE_BYTES | skipped in extract_children | crates/disrobe-pass-pyinstaller/src/chain_detector.rs |
disrobe-pass-pyinstaller | MAX_DEEP_ANALYZE_BYTES | skipped in surface_native_entry | crates/disrobe-pass-pyinstaller/src/native_surface.rs |
disrobe-pass-pyinstaller | MAX_CODE_WALK_DEPTH | return in collect_byte_consts | crates/disrobe-pass-pyinstaller/src/pyc_zipper.rs |
disrobe-pass-pyinstaller | MAX_DECOMPRESS_ATTEMPTS | break in unzip_pyc_with_limits; return in take | crates/disrobe-pass-pyinstaller/src/pyc_zipper.rs |
disrobe-pass-pyinstaller | MAX_RECOVERED_BYTES | .take() in read_capped; return in read_capped | crates/disrobe-pass-pyinstaller/src/pyc_zipper.rs |
disrobe-pass-ruby | MAX_REGS | skipped in set_pending; skipped in set | crates/disrobe-pass-ruby/src/mruby/lift.rs |
disrobe-pass-ruby | MAX_EXPR_LEN | fallback value in push | crates/disrobe-pass-ruby/src/yarv/decompile.rs |
disrobe-pass-ruby | MAX_NEST_DEPTH | return in emit_send; return in massign_targets; return in render_iseq_statements; 1 more | crates/disrobe-pass-ruby/src/yarv/decompile.rs |
disrobe-pass-ruby | IBF_ARRAY_LEN_CAP | .min() clamp in decode_object; for range in parse_ci_entries | crates/disrobe-pass-ruby/src/yarv/ibf.rs |
disrobe-pass-ruby | IBF_OBJECT_LIST_ENTRY_CAP | .min() clamp in parse_image | crates/disrobe-pass-ruby/src/yarv/ibf.rs |
disrobe-pass-ruby | IBF_STRING_LEN_CAP | break in decode_iseq_body; skipped in decode_object | crates/disrobe-pass-ruby/src/yarv/ibf.rs |
disrobe-pass-scriptlang | MAX_SWF_BYTES | return in inflate_cws | crates/disrobe-pass-scriptlang/src/lang/haxe.rs |
disrobe-pass-scriptlang | MAX_RDS_BYTES | .take() in read_bounded; return in maybe_gunzip_rds_with_limit; return in read_bounded | crates/disrobe-pass-scriptlang/src/lang/mod.rs |
disrobe-pass-scriptlang | MAX_OPS | while condition in read_bytecode | crates/disrobe-pass-scriptlang/src/lang/perl_bytecode.rs |
disrobe-pass-scriptlang | MAX_MULTICONCAT_SEGMENTS | .take() in parse_multiconcat | crates/disrobe-pass-scriptlang/src/lang/perl_decompile.rs |
disrobe-pass-scriptlang | COMPLEX_VECTOR_CAP | .min() clamp in walk_item_body | crates/disrobe-pass-scriptlang/src/lang/r_rds.rs |
disrobe-pass-scriptlang | MAX_ENTRIES | for range in extract_zip_with_limits; while condition in scan_metakit_files | crates/disrobe-pass-scriptlang/src/lang/tcl.rs |
disrobe-pass-scriptlang | MAX_METAKIT_NAME_LEN | return in read_metakit_token; skipped in scan_metakit_files | crates/disrobe-pass-scriptlang/src/lang/tcl.rs |
disrobe-pass-scriptlang | MAX_BASE64_CHUNK_BYTES | for range in base64_decode | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-scriptlang | MAX_BASE64_INPUT_BYTES | return in base64_decode; skipped in base64_blobs | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-scriptlang | MAX_INFLATE_BYTES | break in rebuild_replace; return in base64_decode; return in read_inflate_text; 1 more | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-scriptlang | MAX_INFLATE_READ_BYTES | .take() in read_inflate_text | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-scriptlang | MAX_LAYERS | while condition in recover | crates/disrobe-pass-scriptlang/src/lang/winscript.rs |
disrobe-pass-shell | MAX_ARITH_DEPTH | return in parse_expression; return in parse_unary | crates/disrobe-pass-shell/src/bash/arith.rs |
disrobe-pass-shell | MAX_ARRAY_ELEMENTS | return in parse_array_assignment | crates/disrobe-pass-shell/src/bash/bash_eval.rs |
disrobe-pass-shell | MAX_FOR_INDICES | return in parse_for_lookup_loop | crates/disrobe-pass-shell/src/bash/bash_eval.rs |
disrobe-pass-shell | MAX_PRINTF_BYTES | return in try_string_split_indirection | crates/disrobe-pass-shell/src/bash/bash_eval.rs |
disrobe-pass-shell | MAX_TAG_LEN | return in parse_md5_cut_chunk | crates/disrobe-pass-shell/src/bash/bash_eval.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | return in try_compress_payload | crates/disrobe-pass-shell/src/bash/bashfuscator.rs |
disrobe-pass-shell | MAX_DECOMPRESS_BYTES | return in try_compress_payload | crates/disrobe-pass-shell/src/bash/bashfuscator.rs |
disrobe-pass-shell | MAX_PEEL_ROUNDS | for range in reverse_bashfuscator; no action in reverse_bashfuscator | crates/disrobe-pass-shell/src/bash/bashfuscator.rs |
disrobe-pass-shell | MAX_DEPTH | return in eval_wrapped_command; no action in wall | crates/disrobe-pass-shell/src/bash/decode.rs |
disrobe-pass-shell | MAX_OUTPUT | break in decode_pipeline; break in evaluate | crates/disrobe-pass-shell/src/bash/decode.rs |
disrobe-pass-shell | MAX_REPEAT | no action in expand_tr_set | crates/disrobe-pass-shell/src/bash/decode.rs |
disrobe-pass-shell | MAX_GZIP_OUTPUT | .take() in peel_non_eval_layers; .truncate() in peel_non_eval_layers; fallback value in peel_non_eval_layers | crates/disrobe-pass-shell/src/bash/indirect.rs |
disrobe-pass-shell | MAX_PEELED_OUTPUT | break in peel_indirection_with_policy | crates/disrobe-pass-shell/src/bash/indirect.rs |
disrobe-pass-shell | MAX_PEEL_ROUNDS | break in peel_indirection_with_policy | crates/disrobe-pass-shell/src/bash/indirect.rs |
disrobe-pass-shell | MAX_TOKEN_COUNT | while condition in tokenize_bash | crates/disrobe-pass-shell/src/bash/lexer.rs |
disrobe-pass-shell | MAX_RECOVERED_OUTPUT | break in reverse_node_bash_obfuscate | crates/disrobe-pass-shell/src/bash/node_bash_obfuscate.rs |
disrobe-pass-shell | MAX_TABLE_ENTRIES | while condition in parse_chunk_table | crates/disrobe-pass-shell/src/bash/node_bash_obfuscate.rs |
disrobe-pass-shell | MAX_GLOB_ANCHORED_PATTERN_LEN | return in substitute; return in trim_prefix; return in trim_suffix | crates/disrobe-pass-shell/src/bash/param_expand.rs |
disrobe-pass-shell | MAX_GLOB_ANCHORED_TEXT_LEN | return in substitute; return in trim_prefix; return in trim_suffix | crates/disrobe-pass-shell/src/bash/param_expand.rs |
disrobe-pass-shell | MAX_GLOB_SCAN_PATTERN_LEN | return in substitute | crates/disrobe-pass-shell/src/bash/param_expand.rs |
disrobe-pass-shell | MAX_GLOB_SCAN_TEXT_LEN | return in substitute | crates/disrobe-pass-shell/src/bash/param_expand.rs |
disrobe-pass-shell | MAX_ARITH_DEPTH | return in parse_expr; return in parse_unary | crates/disrobe-pass-shell/src/batch/arith.rs |
disrobe-pass-shell | MAX_CIPHERTEXT | continue in recover_stages | crates/disrobe-pass-shell/src/batch/chain.rs |
disrobe-pass-shell | MAX_EXPANSION_ROUNDS | for range in expand_repeated | crates/disrobe-pass-shell/src/batch/engine.rs |
disrobe-pass-shell | MAX_LINES | break in deobfuscate_batch | crates/disrobe-pass-shell/src/batch/engine.rs |
disrobe-pass-shell | MAX_TOTAL_OUTPUT | break in deobfuscate_batch | crates/disrobe-pass-shell/src/batch/engine.rs |
disrobe-pass-shell | MAX_EXPANSION_OUTPUT | break in expand_sigil; return in reserve_expansion_bytes | crates/disrobe-pass-shell/src/batch/expand.rs |
disrobe-pass-shell | MAX_FOR_ITERATIONS | return in numeric_sequence | crates/disrobe-pass-shell/src/batch/forloop.rs |
disrobe-pass-shell | MAX_REVERSE_ADDED_BYTES | return in reserve_expansion_bytes | crates/disrobe-pass-shell/src/batch/mod.rs |
disrobe-pass-shell | MAX_DECODE_LEN | continue in extract_base64_blobs; return in decode_base64_flexible | crates/disrobe-pass-shell/src/batch/payload.rs |
disrobe-pass-shell | MAX_POWERSHELL_LAYER_ROUNDS | for range in reverse_powershell_layers | crates/disrobe-pass-shell/src/chain_detector.rs |
disrobe-pass-shell | MAX_SCRIPT_SCAN_BYTES | slice in detect | crates/disrobe-pass-shell/src/detect.rs |
disrobe-pass-shell | MAX_ACTION_DEPTH | return in handle_action | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_ARRAY_ELEMENTS | break in parse_array | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_DICT_ENTRIES | break in parse_dictionary_or_stream | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_DOCUMENT_BYTES | slice in analyze | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_FILTER_CHAIN | break in decode_stream | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_FINDINGS | break in collect_name_tree; break in scan_hex_obfuscated_names; return in add_embedded; 2 more | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_FINDING_TEXT | .truncate() in extract_javascript; while condition in cutoff; no action in cutoff | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_LZW_CODES | skipped in lzw_decode | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_NAME_BYTES | break in parse_name; break in scan_hex_obfuscated_names | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_NAME_TREE_NODES | break in collect_name_tree | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_OBJECTS | break in brute_force; return in insert_object | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_OBJECT_DEPTH | return in parse_object | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_OBJSTM_OBJECTS | .min() clamp in expand_object_streams | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_PREDICTOR_COLUMNS | .clamp() clamp in apply_predictor | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_RESOLVE_STEPS | return in resolve | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_STRING_BYTES | break in parse_hex_string; break in parse_literal_string | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_STRING_CONCAT | break in extract_javascript | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_WALK_NODES | break in global_sweep; break in walk_acroform; break in walk_pages; 3 more | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_XREF_CHAIN | break in parse_xref_chain | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_XREF_ENTRIES | .min() clamp in parse_xref_stream; for range in parse_xref_table | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | MAX_XREF_FIELD_WIDTH | return in parse_xref_stream | crates/disrobe-pass-shell/src/pdf/limits.rs |
disrobe-pass-shell | STATIC_EVAL_DEPTH_CAP | break in peel_indirection_with_policy; continue in unwrap; return in eval_wrapped_command; 2 more | crates/disrobe-pass-shell/src/policy.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | return in decode_frombase64_payload | crates/disrobe-pass-shell/src/powershell/chameleon.rs |
disrobe-pass-shell | MAX_DECOMPRESSED | .take() in reverse_compress; .truncate() in reverse_compress; fallback value in reverse_compress | crates/disrobe-pass-shell/src/powershell/invoke_obfuscation.rs |
disrobe-pass-shell | MAX_BASE64_INPUT | return in reverse_then_b64_decode | crates/disrobe-pass-shell/src/powershell/invoke_stealth.rs |
disrobe-pass-shell | MAX_TOKEN_COUNT | while condition in tokenize | crates/disrobe-pass-shell/src/powershell/lexer.rs |
disrobe-pass-shell | MAX_DECOMPRESSED | .take() in reverse_psobf; .truncate() in reverse_psobf; fallback value in reverse_psobf | crates/disrobe-pass-shell/src/powershell/psobf.rs |
disrobe-pass-shell | PROJECT_INFORMATION_RECORD_LIMIT | for range in project_codepage | crates/disrobe-pass-shell/src/vba/extract.rs |
disrobe-pass-shell | MAX_CALL_ARGS | .min() clamp in pop_n | crates/disrobe-pass-shell/src/vba/pcode_lift.rs |
disrobe-pass-shell | MAX_CFB_ENTRIES | .take() in locate_vba_storages | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_FUNC_ARG_CHAIN | while condition in disasm_func | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_TYPE_DESCRIPTOR_DEPTH | return in named_type_from_descriptor | crates/disrobe-pass-shell/src/vba/pcode_real.rs |
disrobe-pass-shell | MAX_ARRAY_VALUES | return in read_array_constant | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_EXTERN_NAMES | continue in build | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_RECORDS | while condition in iter_biff12; while condition in iter_biff8 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_RECORD_BODY | .min() clamp in iter_biff12; .min() clamp in iter_biff8; fallback value in iter_biff8 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_RGCE | return in parse_fmla_biff12; return in parse_formula_biff8; return in parse_lbl; 1 more | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_SHEETS | break in enumerate_sheets | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_STRING_CHARS | .min() clamp in decode_chars; return in read_utf16_units | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_WORKBOOK_BYTES | .take() in read_cfb_stream; return in read_cfb_stream | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_XTI | .min() clamp in parse_externsheet | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_ZIP_ENTRIES | return in open_biff12 | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-shell | MAX_ZIP_ENTRY_BYTES | .take() in read_zip_entry; return in read_zip_entry | crates/disrobe-pass-shell/src/xlm/limits.rs |
disrobe-pass-swift-objc | MAX_BLOB_LEN | break in parse | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_IDENTIFIER_LEN | ? on a checked operation in read_cstr_bounded | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_SLOT_COUNT | .min() clamp in parse | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_VERIFIED_PAGES | .min() clamp in verify_page_hashes | crates/disrobe-pass-swift-objc/src/code_signature.rs |
disrobe-pass-swift-objc | MAX_NODES | ? on a checked operation in spend | crates/disrobe-pass-swift-objc/src/demangle.rs |
disrobe-pass-swift-objc | MAX_REPEAT_COUNT | return in demangle_repeated_standard_substitution; return in demangle_substitution_chain; return in demangle_substitution | crates/disrobe-pass-swift-objc/src/demangle.rs |
disrobe-pass-swift-objc | MAX_RECORDED_AUTH_POINTERS | skipped in unapply_segment_slide | crates/disrobe-pass-swift-objc/src/dyld_cache.rs |
disrobe-pass-swift-objc | MAX_DYLIBS | skipped in parse_slice | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_EXPORT_DEPTH | return in walk_export_node | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_EXPORT_NAME | ? on a checked operation in cstr_in; continue in walk_export_node | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_EXPORT_NODES | return in walk_export_node | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_FUNCTION_STARTS | while condition in function_starts | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_INDIRECT_SYMBOLS | .min() clamp in import_thunks | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_RPATHS | skipped in parse_slice | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_SYMBOLS | .min() clamp in function_symbols; .min() clamp in symbol_names | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_SYMBOL_LEN | ? on a checked operation in read_cstr_bounded | crates/disrobe-pass-swift-objc/src/macho.rs |
disrobe-pass-swift-objc | MAX_FUNCTION_BYTES | .min() clamp in end_boundary; return in carve | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_LINES_PER_FUNCTION | .take() in lines_for | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_LISTED_FUNCTIONS | .take() in lift_native_nir; break in build_function_bodies | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_NIR_SYMBOLS | .take() in lift_native_nir | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_REPORTED_TYPES | .take() in recover_native_bodies | crates/disrobe-pass-swift-objc/src/native_bodies.rs |
disrobe-pass-swift-objc | MAX_SELECTOR_HINT_WORK | continue in index_selectors | crates/disrobe-pass-swift-objc/src/objc.rs |
disrobe-pass-swift-objc | MAX_BIND_OPS | while condition in interpret_bind | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CALL_SITES | break in annotate_instructions | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CFG_DEPTH | return in reaching_def_from; return in reaching_slot | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CFG_STEPS | return in build | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CHAINED_IMPORTS | .min() clamp in parse_chained_imports | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CHAINED_PAGES | .min() clamp in walk_chained_pages; for range in walk_chained_pages | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CHAINED_SEGMENTS | .min() clamp in chained_segment_infos | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CSTR | ? on a checked operation in chained_symbol_at; ? on a checked operation in cstr_at_offset | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_MOVE_HOPS | for range in trace_pointer_slot | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_SLOTS | .min() clamp in build_classref_map; .min() clamp in build_selref_map; .min() clamp in interpret_bind | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_STUB_ENTRIES | while condition in build_arm64_stub_map; while condition in build_x86_stub_map | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_TOTAL_BINDS | break in interpret_bind; for range in walk_chain; while condition in interpret_bind | crates/disrobe-pass-swift-objc/src/objc_dispatch.rs |
disrobe-pass-swift-objc | MAX_CATEGORIES | .take() in recover_categories | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_CLASSES | .take() in recover_interfaces | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_CSTR | ? on a checked operation in cstr_at_offset | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_LIST_COUNT | return in read_entsize_list_header | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_PROTOCOLS | .take() in recover_protocols | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_PROTOCOL_REFS | return in parse_protocol_refs | crates/disrobe-pass-swift-objc/src/objc_records.rs |
disrobe-pass-swift-objc | MAX_REPORTED_INSTALL_NAMES | .take() in dyld_cache_report | crates/disrobe-pass-swift-objc/src/pass.rs |
disrobe-pass-swift-objc | MAX_CSTR | ? on a checked operation in cstr_at_offset; ? on a checked operation in mangled_name_at_offset | crates/disrobe-pass-swift-objc/src/swift_reflect.rs |
disrobe-pass-swift-objc | MAX_DESCRIPTORS | while condition in parse_field_descriptors | crates/disrobe-pass-swift-objc/src/swift_reflect.rs |
disrobe-pass-swift-objc | MAX_FIELDS_PER_TYPE | .min() clamp in read_field_list; break in parse_field_descriptors | crates/disrobe-pass-swift-objc/src/swift_reflect.rs |
disrobe-pass-swift-objc | MAX_NAME_LEN | ? on a checked operation in cstr_at_offset | crates/disrobe-pass-swift-objc/src/swift_symbolic.rs |
disrobe-pass-swift-objc | MAX_PARENT_WALK | break in synthesize_nominal_mangling | crates/disrobe-pass-swift-objc/src/swift_symbolic.rs |
disrobe-pass-swift-objc | MAX_NAME_LEN | ? on a checked operation in cstr_at_offset | crates/disrobe-pass-swift-objc/src/swift_typedump.rs |
disrobe-pass-swift-objc | MAX_PARENT_WALK | break in walk_parent_names | crates/disrobe-pass-swift-objc/src/swift_typedump.rs |
disrobe-pass-swift-objc | MAX_PROTOCOL_REQUIREMENTS | .min() clamp in read_protocol_requirements | crates/disrobe-pass-swift-objc/src/swift_typedump.rs |
disrobe-pass-swift-objc | MAX_TOOLCHAIN_HINTS | .take() in report | crates/disrobe-pass-swift-objc/src/toolchain.rs |
disrobe-pass-wasm-deob | MAX_BODY_OPS | break in fingerprint_body | crates/disrobe-pass-wasm-deob/src/fingerprint.rs |
disrobe-pass-wasm-deob | MAX_RENDER_INDENT | .min() clamp in pad; .min() clamp in render_operators | crates/disrobe-pass-wasm-deob/src/lib.rs |
disrobe-pass-wasm-deob | MAX_SYNTHETIC_STRUCT_FIELDS | .clamp() clamp in record_struct_field_count; .min() clamp in record_struct_new_field_types; return in record_struct_field_index | crates/disrobe-pass-wasm-deob/src/lift_wat.rs |
disrobe-pass-wasm-deob | MAX_TREE_NODES | return in lower_inner | crates/disrobe-pass-wasm-deob/src/obfuscators/mba.rs |
disrobe-pass-wasm-deob | MAX_ITERATIONS | break in unflatten; for range in unflatten_to_fixed_point | crates/disrobe-pass-wasm-deob/src/obfuscators/tigress/unflatten.rs |
disrobe-pass-wasm-deob | MAX_EXPR_NODES | return in parse_value | crates/disrobe-pass-wasm-deob/src/recover.rs |
disrobe-pass-wasm-deob | MAX_GUARD_LEN | return in match_diamond | crates/disrobe-pass-wasm-deob/src/recover/opaque.rs |
disrobe-pass-wasm-deob | MAX_CALL_DEPTH | return in invoke | crates/disrobe-pass-wasm-deob/src/recover/pure_eval.rs |
disrobe-pass-wasm-deob | MAX_STEPS | return in eval_guard; return in run_seq | crates/disrobe-pass-wasm-deob/src/recover/pure_eval.rs |
disrobe-pass-wasm-deob | MAX_VALUE_STACK | return in run_seq | crates/disrobe-pass-wasm-deob/src/recover/pure_eval.rs |
disrobe-pass-wasm-deob | NODE_LIMIT | .take() in collect_branch_transitions; return in accesses_cell_outside_root; return in accesses_cell; 8 more | crates/disrobe-pass-wasm-deob/src/recover/reloop.rs |
disrobe-pass-wasm-deob | STATE_EXPRESSION_LIMIT | ? on a checked operation in expression_suffix; ? on a checked operation in state_write_expression; return in eval_value; 5 more | crates/disrobe-pass-wasm-deob/src/recover/reloop.rs |
disrobe-pass-wasm-deob | TRANSITION_INSTRUCTION_LIMIT | return in classify_select_conditional; return in condition_has_isolated_value_stack; return in structured_work_is_bounded | crates/disrobe-pass-wasm-deob/src/recover/reloop.rs |
disrobe-pass-webview | COMPRESSED_SAMPLE_CAP | .min() clamp in looks_compressed | crates/disrobe-pass-webview/src/decompress.rs |
disrobe-pass-webview | MAX_EVIDENCE_MARKERS | .truncate() in classify_all; .truncate() in marker_evidence | crates/disrobe-pass-webview/src/detect.rs |
disrobe-pass-webview | MAX_ENTRY_PATH_BYTES | return in bounded_join; while condition in bounded_join; slice in bounded_join | crates/disrobe-pass-webview/src/electron.rs |
disrobe-pass-webview | MAX_EXTENSION_LEN | continue in scan; no action in best_window | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_HASH_HAMMING | fallback value in hash_window | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_PATH_LEN | return in validate | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_SCAN_RECORDS | return in collect_runs; skipped in collect_runs | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_UNREADABLE_GAP | break in collect_runs | crates/disrobe-pass-webview/src/embedded.rs |
disrobe-pass-webview | MAX_FAT_SLICES | .take() in build_slices | crates/disrobe-pass-webview/src/resolve.rs |
disrobe-pass-webview | MAX_OVERLAP_WALK | slice in containing | crates/disrobe-pass-webview/src/resolve.rs |
disrobe-pass-webview | MAX_SPANS | break in build | crates/disrobe-pass-webview/src/resolve.rs |
disrobe-playground | MAX_CIRCULAR_FILES_SCANNED | break in scan_circularity | crates/disrobe-playground/src/circular.rs |
disrobe-playground | MAX_CIRCULAR_FILE_BYTES | .take() in read_text_bounded; return in read_text_bounded | crates/disrobe-playground/src/circular.rs |
disrobe-playground | MAX_DISCOVERED_PACKED_PAIRS | break in discover_packed_pairs | crates/disrobe-playground/src/manifest.rs |
disrobe-playground | MAX_DISCOVERED_RECOMPILE_PYC | break in discover_recompile_pyc | crates/disrobe-playground/src/manifest.rs |
disrobe-playground | MAX_MANIFEST_FILES | break in build | crates/disrobe-playground/src/manifest.rs |
disrobe-playground | MAX_MANIFEST_TOML_BYTES | .take() in read_text_bounded; return in read_text_bounded | crates/disrobe-playground/src/manifest.rs |
disrobe-pyarmor-pytrace | MAX_CAPTURED | skipped in _trace_callback | crates/disrobe-pyarmor-pytrace/src/lib.rs |
disrobe-semdiff | MAX_LINEAGE_VARIANTS | slice in variant_lineage | crates/disrobe-semdiff/src/lineage.rs |
disrobe-semdiff | MAX_ADDRESS_PEEL_STEPS | while condition in address_form | crates/disrobe-semdiff/src/summary.rs |
disrobe-similarity | REFINEMENT_ROUND_CAP | for range in refine | crates/disrobe-similarity/src/fingerprint.rs |
disrobe-similarity | PROPAGATION_ROUND_CAP | for range in propagate | crates/disrobe-similarity/src/matcher/propagation.rs |
disrobe-sleigh | MAX_FIXED_BITS_MEMO_ENTRIES | skipped in table_bits | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | MAX_TABLE_CLAUSE_MEMO_CLAUSES | return in remember_table_clauses | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | MAX_TABLE_CLAUSE_MEMO_ENTRIES | return in remember_table_clauses | crates/disrobe-sleigh/src/compiler.rs |
disrobe-sleigh | UNSUPPORTED_ENCODING_CAPTURE_LIMIT | .min() clamp in unsupported_length | crates/disrobe-sleigh/src/lifter/riscv.rs |
disrobe-sleigh | MAX_CONDITION_DEPTH | return in parse_unary | crates/disrobe-sleigh/src/preprocessor.rs |
disrobe-sleigh | MAX_ITEM_DEPTH | return in parse_with | crates/disrobe-sleigh/src/syntax.rs |
disrobe-sleigh | MAX_PATTERN_NESTING | return in pattern_nesting_exceeds | crates/disrobe-sleigh/src/syntax.rs |
disrobe-taint | MAX_OUT_ARGUMENTS_PER_SOURCE | skipped in insert_out_argument | crates/disrobe-taint/src/config.rs |
disrobe-taint | MAX_PATH_STEPS | .truncate() in append_step; no action in append_step | crates/disrobe-taint/src/engine.rs |
disrobe-taint | MAX_RECORDED_UNRESOLVED_CALLS | skipped in collect_unresolved_calls | crates/disrobe-taint/src/engine.rs |
disrobe-testkit | MAX_RECORD_NAME | .take() in record_name | crates/disrobe-testkit/src/prerequisite.rs |
disrobe-tool-process | MAX_GROUP_MEMBERS | return in macos_group_contains_only_zombies | crates/disrobe-tool-process/src/unix.rs |
disrobe-tool-process | MAX_NORMAL_PROGRAM_PATH_UNITS | return in child_visible_path | crates/disrobe-tool-process/src/windows.rs |
disrobe-typerec | MAX_COPY_DEPTH | return in reg_slot_source | crates/disrobe-typerec/src/callsite.rs |
disrobe-typerec | MAX_THUNK_INSNS | .take() in follow_thunk; slice in follow_thunk | crates/disrobe-typerec/src/callsite.rs |
disrobe-typerec | MIN_SOLVE_BUDGET | break in solve | crates/disrobe-typerec/src/constraint.rs |
disrobe-typerec | MAX_DECODE_INSNS | while condition in decode_all | crates/disrobe-typerec/src/decode.rs |
disrobe-typerec | MAX_DIE_VISITS | break in collect_unit; break in walk_functions | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_FIELDS | return in flatten_members | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_PARAMS | skipped in collect_unit | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_TYPE_DEPTH | return in flatten_members; return in name_through_origin; return in resolve_int_type; 2 more | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_UNITS | break in walk_functions | crates/disrobe-typerec/src/dwarf_gt.rs |
disrobe-typerec | MAX_EXPRESSION_OPERATIONS | return in classify_expression | crates/disrobe-typerec/src/dwarf_location.rs |
disrobe-typerec | MAX_LOCATION_LIST_ENTRIES | while condition in frame_slots; while condition in resolve_frame_base; skipped in push_slots; 1 more | crates/disrobe-typerec/src/dwarf_location.rs |
disrobe-typerec | MAX_PROLOGUE_INSTRUCTIONS | while condition in frame_pointer_delta_from_prologue | crates/disrobe-typerec/src/dwarf_location.rs |
disrobe-typerec | MAX_DESCRIPTORS | break in collect_pe_delay; break in collect_pe_imports | crates/disrobe-typerec/src/import_map.rs |
disrobe-typerec | MAX_ENTRIES | break in collect_pe_delay; break in collect_pe_imports; break in collect_pe_thunks; 3 more | crates/disrobe-typerec/src/import_map.rs |
disrobe-typerec | MAX_THUNKS | break in collect_pe_delay; break in collect_pe_thunks | crates/disrobe-typerec/src/import_map.rs |
disrobe-typerec | MAX_HEAP_BLOCKS | return in heap_registers | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_HEAP_ROUNDS | .min() clamp in heap_registers | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_HEAP_SLOTS | skipped in heap_transfer | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_STACK_SLOTS | return in group_offsets | crates/disrobe-typerec/src/memssa.rs |
disrobe-typerec | MAX_ALLOCATOR_SITES | return in record_allocator_site | crates/disrobe-typerec/src/region.rs |
disrobe-typerec | MAX_ALLOCATOR_SYMBOLS | .take() in absorb_allocator_definitions | crates/disrobe-typerec/src/region.rs |
disrobe-typerec | MAX_RELOC_TARGETS | return in record_reloc_target | crates/disrobe-typerec/src/region.rs |
disrobe-typerec | MAX_SECTIONS | .take() in absorb_allocator_thunks; .take() in absorb_relocations; .take() in absorb_sections | crates/disrobe-typerec/src/region.rs |
disrobe-typerec | MAX_THUNK_SCAN | return in absorb_allocator_thunks; slice in absorb_allocator_thunks | crates/disrobe-typerec/src/region.rs |
disrobe-validator | MAX_CORPUS_DEPTH | return in collect | crates/disrobe-validator/src/corpus.rs |
disrobe-validator | MAX_CORPUS_ENTRIES | return in collect | crates/disrobe-validator/src/corpus.rs |
disrobe-wasm | MAX_ENTROPY_BLOCKS | while condition in entropy | crates/disrobe-wasm/src/entry.rs |
disrobe-wasm | MAX_GUEST_ALLOC | return in disrobe_alloc; return in disrobe_free | crates/disrobe-wasm/src/lib.rs |
disrobe-wasm | MAX_RESULT_PAYLOAD | return in disrobe_result_free; return in pack_prefixed_result | crates/disrobe-wasm/src/lib.rs |
Panics
0 bounds panic when input exceeds them. Each is a defect: malformed input is a typed error, never a panic.
Legal
This page states the project's legal policy, its per-protector stances, and the takedown channel. An authorization flag records the user's assertion of permission; it does not establish that a particular use satisfies the applicable law or contract.
Responsible use
This document states the project's posture, its intended use, and the procedure for legal-adjacent contact. If your use of disrobe may implicate copyright, computer-misuse, or contract law in your jurisdiction, obtain your own legal counsel.
Intended use
disrobe is intended for, and supports:
- Security research and malware analysis. Reverse-engineering hostile binaries to understand their behavior, build detections, or publish findings.
- Interoperability research. Reverse-engineering an artifact you lawfully possess in order to enable interoperation with an independently created program. This applies when no information needed for that interoperation is otherwise readily available.
- Recovery of your own source. Reconstructing software you authored and have lost the source for.
- Education, archaeology, and curation. Studying program behavior, preserving historical bytecode, teaching reverse-engineering.
disrobe is not intended for:
- Bypassing technological protection measures applied to copyrighted content you do not own and have no lawful right to access.
- Circumventing license-key validation or terms-of-service enforcement of software you have not lawfully obtained.
- Building or distributing pirated or counterfeit software.
- Producing derivative works that infringe a copyright holder's exclusive rights.
The line between research and infringement is jurisdiction- and fact-specific. Where the line falls is your responsibility, not the project's.
Statutory framing the project relies on
United States: DMCA §1201(f)
17 U.S.C. §1201(f) is the "interoperability" exemption from the anti-circumvention rule. It permits the circumvention of technological protection measures, and the development of tools for that purpose, under two conditions. The activity must be undertaken solely to identify and analyze the elements of a program necessary to achieve interoperability with an independently created program, and the information must not have previously been readily available. disrobe is a tool of that kind. See: https://www.law.cornell.edu/uscode/text/17/1201.
disrobe also relies on the periodic anti-circumvention exemptions promulgated by the Librarian of Congress. Those include the exemptions covering security research, most recently renewed and expanded by the 2024 rulemaking.
European Union: Software Directive 2009/24/EC
Article 6 of Directive 2009/24/EC ("the Software Directive") permits decompilation of a computer program where the decompilation is indispensable to obtain the information necessary to achieve the interoperability of an independently created program with other programs. The conditions of paragraphs (a)-(c) must be met. disrobe is a tool that supports this analysis. See: https://eur-lex.europa.eu/eli/dir/2009/24.
Article 5(3) of the same Directive permits the lawful acquirer of a program to observe, study, or test the functioning of the program in order to determine the underlying ideas and principles. That right covers acts of loading, displaying, running, transmitting, or storing the program which the acquirer is entitled to perform.
Other jurisdictions
Comparable provisions exist in the United Kingdom (CDPA §50B/50BA), Canada (Copyright Act s.30.61), Australia (Copyright Act ss.47D-47F), Japan (Copyright Act Art. 47-3/47-6), and elsewhere. Users in those jurisdictions should consult local counsel. The project does not represent that its tools fit those frameworks identically.
What disrobe does and does not ship
- The repository does not ship third-party copyrighted obfuscated bytecode in its public test corpus. Test inputs include project-authored fixtures, licensed third-party regression inputs identified in NOTICE, and samples referenced by hash whose bytes must be fetched separately under their applicable terms.
- The repository does ship parsers, decoders, decompilers, and orchestrator wrappers (Ghidra / jadx / CFR / Vineflower / ILSpy / de4dot, headless). Applied to a sample, those can produce output that may be considered a derivative work of that sample under applicable copyright law. Producing that output lawfully is the user's responsibility.
Responsible disclosure
If you believe a release of disrobe is being used to infringe your rights, contact the maintainer before pursuing public action. The project is operated in good faith and responds to substantiated concerns.
Takedown contact
For copyright concerns, EULA concerns, or any other rights-based contact regarding this repository or its release artifacts:
- Open a private security advisory at https://github.com/1-3-7/disrobe/security/advisories/new
Please include: (1) a description of the rights you assert, (2) the specific artifact or commit at issue, (3) a clear statement of the action you are requesting, and (4) the contact information of an authorized representative. Vague or boilerplate notices may not receive a substantive response.
Warranty disclaimer
The Work is licensed under the Disrobe Source-Available License, Version 1.1, and provided "AS IS" without warranties of any kind (see LICENSE). Nothing on this page modifies that disclaimer or any other term of the License.
Limitations
This document does not exhaustively enumerate every statute, case, regulation, or contract that may bear on a particular use of disrobe. It is a starting point, not a substitute for legal counsel.
The authorization gate
Legally sensitive recovery paths that expose --i-have-authorization require the flag before they run. Passing the flag is your assertion that you are authorized to analyze the input under the statutory framing above. Use is your responsibility.
The same flag unlocks the decryption-keys category of the --llm sidecar; without it, requesting that category fails with DR-CLI-0420.
What disrobe will not do
- It does not ship copyrighted third-party obfuscated bytecode in its public corpus. Fixtures are baked locally from known-good inputs.
- Grey-zone protectors ship recognizers first; escalation to a full peel only happens after a written legal-posture review recorded under Per-protector stances.
- Local static analysis does not require a network service.
prowland optional tool installation make network requests;serveexposes the explicitly selected server transport. Consult each command's options before enabling it.
Per-protector stances
Each section records the project's posture toward one protector's output and the engineering defaults that posture produces. If your use of disrobe against that output may implicate copyright, anti-circumvention, or contract law in your jurisdiction, obtain your own counsel.
Jscrambler
Jscrambler is a commercial JavaScript protection platform. It ships a free tier and paid tiers, and it applies protection as a configurable list of named transforms grouped into obfuscation, optimization, runtime application self-protection (RASP), and code locks. disrobe ships a Jscrambler detector, a reverser for each of the 36 transforms, 12 template chains, and an integrity-loop strip, so the project owes an explicit account of what it acts on, when, and why. The project commits to a written stance in this section before any gray-zone protector escalates from recognition to a peel; this is that file for Jscrambler.
This file also serves as the gate document for the whole JavaScript deobfuscation pass. DR-JSDEOB-0010, the authorization-required error, names this page whenever a gated reverser refuses to run. The other protectors that pass gates share it and keep their own stance files: PreEmptive JSDefender, PACE (JS), and Digital.ai / Arxan (JS).
What disrobe does to Jscrambler input
The legal posture rests on which transform category the act touches, so each item below states the capability exactly.
- Detect.
disrobescans the head of the input for a Jscrambler banner, counts hex-suffixed identifiers, and counts self-reference integrity loops. It then runs all 36 transform detectors and reports which transforms are present and which of the four code locks (browser, date, domain, OS) are present. Detection emits a tier label, a confidence, the markers, the detected transform set, and the code-lock set. Nothing more. The tier label is a signature heuristic. It gates nothing. - Reverse the obfuscation and optimization transforms. 21 obfuscation reversers run without an authorization assertion: boolean-to-anything, char-to-ternary, comma-operator unfolding, control-flow flattening, dead-code injection, dot-to-bracket notation, duplicate-literals removal, extend-predicates, function outlining, function reordering, global-variable indirection, identifiers renaming, number-to-string, object-properties sparsing, property-keys obfuscation, property-keys reordering, regex obfuscation, string concealing, string encoding, variable grouping, and variable masking. 5 optimization reversers run on the same terms: assertions removal, constant folding, dead-code elimination, debug-code elimination, and whitespace removal.
- Strip the integrity loop. Before any transform reverser runs,
disroberemoves the self-reference integrity construct, in both its wrapped and bare forms, and reports how many it removed and how many bytes that freed. - Reverse the RASP guards only when authorized. 6 reversers are gated: anti-debugging, anti-monkey-patching, anti-tampering, dead objects, self-defending, and self-healing. Each deletes the matched guard construct. Without the authorization assertion, the tolerant entry point leaves the input unchanged and records the match as skipped with an authorization note, and the strict entry point returns
DR-JSDEOB-0010. - Reverse the code locks only when authorized. 4 reversers are gated on the same terms: browser lock, date lock, domain lock, and OS lock. Each replaces the matched guard expression with a constant true, so the locked branch becomes reachable for analysis.
- Run a template chain. 12 named chains match Jscrambler's published templates. Each runs its transform list in order and reports per-stage statistics. A RASP or code-lock stage inside a chain obeys the same gate as the standalone reverser.
- What it does not do.
disrobedoes not execute protected code, recover a runtime key, or defeat a server-side licensing check. It recovers nothing Jscrambler keeps off the static surface. It does not restore original identifier names; the renaming reverser assigns readable placeholders. - Validation. The detector and default pipeline are exercised against seven SHA-pinned free-tier Jscrambler 8.5 protected bundles. Tests check static transform results, parsed output, and recovered literals. The acquired bundles contain no original source, so these checks do not establish behavioral equivalence. The paid templates are the weak point: their configuration files are on file, but their protected output is subscription-gated, so the end-to-end tests for those templates are marked pending rather than passing. There is no real-sample oracle for the paid RASP and code-lock templates. Treat those reversers as pattern-grounded, not as a measured defeat of a real protected artifact.
Traffic-light verdict: AMBER
disrobe classifies every protector on a three-color scale:
| Color | Meaning | Default behavior |
|---|---|---|
| GREEN | Free / open / no commercial EULA restriction on analysis | Deobfuscate by default. |
| AMBER | Commercial protection with mixed, jurisdiction-sensitive EULA terms | Detect and reverse obfuscation by default; gate RASP and code-lock reversal behind --i-have-authorization. |
| RED | Protection of third-party copyrighted content with no interoperability nexus | Recognize only; never peel. |
Jscrambler is AMBER. The split is by capability category, not by license tier. Reversing an obfuscation or optimization transform recovers program structure, so it runs by default. Reversing a RASP guard or a code lock acts on the protection mechanism itself, so it runs only after the operator asserts authorization. The detector's free / paid tier label reports a signature, and it does not decide what runs.
That distinction matters because the two lines do not coincide. Self-defending and dead objects are available in Jscrambler's free tier, and disrobe gates both of them anyway. The gate tracks what the construct does, not what the customer paid.
The gate is an assertion by the operator, not an adjudication by the tool. Passing --i-have-authorization is the operator's representation that they are authorized to analyze the input for the intended activity. The operator carries that responsibility.
The contractual surface
Jscrambler is licensed commercially, and a deployment that embeds its output is typically governed by a EULA or enterprise agreement. The project does not enumerate specific clause text it cannot reliably attribute to a given version or license. It does not represent any clause as enforceable or unenforceable. The posture is procedural: where such an agreement's anti-reverse-engineering or no-circumvention clause might bear on the act, disrobe declines to reverse a RASP guard or a code lock absent the operator's explicit authorization assertion. Whether such a clause binds a lawful acquirer performing acts a statute expressly permits is a jurisdiction-specific question, and disrobe does not answer it for the operator.
Statutory scope
17 U.S.C. §1201(f) provides a conditional interoperability exception. It requires a lawfully obtained right to use the program and limits the purpose, necessity, use, and disclosure of the information or means involved. It does not establish that every use or distribution of this tool qualifies.
Directive 2009/24/EC, Articles 5(3) and 6, addresses study and decompilation under stated conditions; Article 8 makes contrary contractual provisions ineffective within those exceptions. Applicability depends on the activity and the governing law. A product classification or authorization flag does not decide that question.
What the stance produces in the tool
The stance is wired into the pass defaults:
- Detection runs by default. Identifying Jscrambler, its transforms, and its code locks needs no authorization gate.
- Obfuscation and optimization reversal runs by default. The 21 obfuscation reversers and the 5 optimization reversers carry no gate. The integrity-loop strip carries no gate.
- RASP and code-lock reversal is gated. The 6 RASP reversers and the 4 code-lock reversers run only after the authorization assertion. Without it, the tolerant path leaves the input unchanged and reports the match as skipped; the strict path returns
DR-JSDEOB-0010. - Template chains inherit the gate. A chain that includes a RASP or code-lock stage still refuses that stage without the assertion, and reports the skip in its per-stage statistics.
- Fixture provenance. The corpus includes seven acquired free-tier Jscrambler 8.5 protected bundles and template configuration files. The acquired bundles have no accompanying original source, so they support static recovery checks only. Paid-tier protected output is not in the corpus.
Takedown and rights contact
If you assert that disrobe's Jscrambler handling infringes your rights, contact the maintainer before public action. Use a private security advisory at https://github.com/1-3-7/disrobe/security/advisories/new. Include the rights asserted, the specific artifact or commit at issue, the action requested, and an authorized representative's contact. The project operates in good faith and responds to substantiated, specific concerns. See Responsible use for the general procedure.
JSDefender
PreEmptive Solutions licenses JSDefender as a commercial JavaScript protector. disrobe ships a JSDefender recognizer and a static-layer peel, so the project owes an explicit account of what it acts on, when, and why. The project commits to a written stance in this section before any gray-zone protector escalates from recognition to a peel; this is that file for JSDefender.
What disrobe does to JSDefender input
The legal posture rests on the narrowness of the act, so each item below states the capability exactly.
- Detect.
disrobematches JSDefender on four self-identifying static markers: the PreEmptive Solutions copyright string, a JSDefender banner, the_PreEmptivesymbol prefix, and the__JSD__runtime token. It adds two structural signals: aswitchdispatcher paired with a string-array declaration, and a repeated always-true / always-false branch idiom. Each signal raises confidence, and the total is capped at 0.99. Detection emits a family identification, a confidence, and the marker list. Nothing more. - Peel the static layers. When the caller asserts authorization,
disroberuns four static reversers in order: string-array recovery, which removes the rotator and inlines decoder call sites; control-flow unflattening of theswitchdispatcher; dead-code-injection removal; and string-encoding decode. The result reports bytes in, bytes out, and a matched / reversed / skipped count per stage. - The peel is generic, not JSDefender-tuned. Those four reversers are the project's shared static reversers, also used for its Jscrambler and obfuscator.io handling.
disrobeships no reverser written against JSDefender's own output shapes. The_PreEmptiveand__JSD__tokens are read as detection markers only; the peel never strips or rewrites them. - What it does not do.
disroberecovers nothing that JSDefender keeps off the static surface. It does not defeat a runtime check, recover a hidden key, or restore original identifier names. The peel reverses generic obfuscation on input the operator already possesses. - Validation is indirect. The peel is graded against real output from an independent open-source JavaScript obfuscator, using a differential token oracle taken from the clean source plus two falsification controls that fail if recovery invents tokens or if the raw input already carried them. The JSDefender fixture in the public corpus is synthesized and drives detection only. There is no real-sample JSDefender oracle; the project does not ship or test against third-party JSDefender-protected bytes. Treat the peel as a structural deobfuscation aid, not a measured defeat of a real protected artifact.
Traffic-light verdict: AMBER, leaning green
disrobe classifies every protector on a three-color scale:
| Color | Meaning | Default behavior |
|---|---|---|
| GREEN | Free / open / no commercial EULA restriction on analysis | Deobfuscate by default. |
| AMBER | Commercial protection with mixed, jurisdiction-sensitive EULA terms | Detect by default; gate the peel behind --i-have-authorization. |
| RED | Protection of third-party copyrighted content with no interoperability nexus | Recognize only; never peel. |
JSDefender is AMBER, leaning green. The project records two positions inside AMBER, and JSDefender holds the lighter one. Digital.ai / Arxan and PACE sit at the detect-only position, because what disrobe acts on there is a runtime integrity or licensing guard. JSDefender sits lower because every layer the peel touches is generic obfuscation: a string array, a flattened dispatcher, injected dead code, and encoded literals. Reversing those layers recovers program structure. It does not act on a protection mechanism.
The AMBER floor still applies. JSDefender is a commercial product, and its deployment normally attaches EULA terms. Those terms commonly include anti-reverse-engineering or no-circumvention language. Enforceability of that language against a lawful acquirer performing statutorily permitted acts is jurisdiction-sensitive. disrobe therefore detects JSDefender by default and runs the static-layer peel only after the caller asserts authorization.
The gate is an assertion by the operator, not an adjudication by the tool. Passing --i-have-authorization is the operator's representation that they are authorized to analyze the input for the intended activity. The operator carries that responsibility. The peel entry point refuses to run without the assertion and returns DR-JSDEOB-0010, which names the flag and points to the pass-wide gate document, Jscrambler. Detection output names this file as the governing stance.
The contractual surface
JSDefender is licensed commercially, and a deployment that embeds its output is typically governed by a EULA. The project does not enumerate specific clause text it cannot reliably attribute to a given version or license. It does not represent any clause as enforceable or unenforceable. The posture is procedural: where a EULA's anti-reverse-engineering or no-circumvention clause might bear on the act, disrobe declines to run the peel absent the operator's explicit authorization assertion. Whether such a clause binds a lawful acquirer performing acts a statute expressly permits is a jurisdiction-specific question, and disrobe does not answer it for the operator.
Statutory scope
17 U.S.C. §1201(f) provides a conditional interoperability exception. It requires a lawfully obtained right to use the program and limits the purpose, necessity, use, and disclosure of the information or means involved. It does not establish that every use or distribution of this tool qualifies.
Directive 2009/24/EC, Articles 5(3) and 6, addresses study and decompilation under stated conditions; Article 8 makes contrary contractual provisions ineffective within those exceptions. Applicability depends on the activity and the governing law. A product classification or authorization flag does not decide that question.
What the stance produces in the tool
The posture is wired into the tool's defaults:
- Detection runs by default. Identifying JSDefender and reporting its markers needs no authorization gate.
- The static-layer peel is gated. Without the authorization assertion the entry point returns
DR-JSDEOB-0010and does not modify the input. - The peel is limited to four generic static reversers. String-array recovery, control-flow unflattening, dead-code-injection removal, and string-encoding decode. No JSDefender-specific reverser exists.
- No runtime bypass exists.
disrobeships no defeat of any JSDefender runtime behavior; the gate would govern any such future capability. - No third-party JSDefender bytes in the public corpus. The fixture is synthesized to carry the documented marker shapes and drives detection only. The repository ships the recognizer and the peel logic, not protected sample bytes.
Takedown and rights contact
If you assert that disrobe's JSDefender handling infringes your rights, contact the maintainer before public action. Use a private security advisory at https://github.com/1-3-7/disrobe/security/advisories/new. Include the rights asserted, the specific artifact or commit at issue, the action requested, and an authorized representative's contact. The project operates in good faith and responds to substantiated, specific concerns. See Responsible use for the general procedure.
Arxan
Digital.ai Application Protection (formerly Arxan) is a commercial application-hardening product. Its JavaScript output wraps a program in self-identifying integrity guards, checksum loops, and tamper callouts rather than encrypting the program itself. Because disrobe ships a Digital.ai / Arxan recognizer and a static-marker strip, the project owes an explicit account of what it acts on, when, and why. The project commits to a written stance in this section before any gray-zone protector escalates from recognition to a peel; this is that file for Digital.ai / Arxan.
What disrobe does to Digital.ai / Arxan input
The legal posture rests on the narrowness of the act.
- Detect.
disrobematches the family by its self-identifying static markers: the Digital.ai / Arxan banner comments, the_ARXAN_runtime tokens, the__guard_<hex>symbol shape, and the implemented guard patterns. Those patterns are the base64 checksum guard, the deterministic XOR checksum loop, and the integrity callout that compares against a constant. Detection emits a family identification and confidence, nothing more. - Strip matched static markers. When authorized,
disroberemoves those self-identifying static guard fragments so the surrounding application JavaScript reads cleanly for analysis. The patterns stripped are the specific shapes the recognizer keys on, not arbitrary code. - What it does not do.
disrobedoes not circumvent Digital.ai / Arxan's runtime anti-tamper or integrity protection. It does not recover hidden keys, defeat a runtime integrity verdict, or reconstruct anything the product keeps off the static surface. The strip removes self-identifying static guard text from input the operator already possesses. It is not a bypass of the commercial runtime protection. - Validation is synthetic only. The tests grade the behavior against synthesized fixtures matching the implemented guard patterns. There is no real-sample oracle; the project does not ship or test against third-party Digital.ai / Arxan-protected bytes. Treat the strip as a structural deobfuscation aid, not a measured defeat of a real protected artifact.
Traffic-light verdict: AMBER
disrobe classifies every protector on a three-color scale:
| Color | Meaning | Default behavior |
|---|---|---|
| GREEN | Free / open / no commercial EULA restriction on analysis | Deobfuscate by default. |
| AMBER | Commercial application-hardening with mixed, jurisdiction-sensitive EULA terms | Detect by default; gate the static-marker strip behind --i-have-authorization. |
| RED | Protection of third-party copyrighted content with no interoperability nexus | Recognize only; never peel. |
Digital.ai / Arxan is AMBER. It is a commercial application-hardening product, and its deployment normally attaches EULA terms. Those terms commonly include anti-reverse-engineering or no-circumvention language. Whether that language is enforceable against a lawful acquirer performing statutorily permitted acts is jurisdiction-sensitive. disrobe therefore detects the family by default but runs the static-marker strip only when the operator asserts authorization via --i-have-authorization. Any deeper handling of the runtime anti-tamper or integrity protection is not implemented; were it ever built, it would sit behind the same explicit authorization gate and never run otherwise.
The gate is an assertion by the operator, not an adjudication by the tool. Passing --i-have-authorization is the operator's representation that they are authorized to analyze the input for the intended activity; the responsibility for that representation is the operator's.
The contractual surface
Digital.ai / Arxan is licensed commercially, and a deployment that embeds its guards is typically governed by a EULA or enterprise agreement. The project does not enumerate specific clause text it cannot reliably attribute to a given version or license, and it does not represent any clause as enforceable or unenforceable. The posture is procedural: if such an agreement's anti-reverse-engineering or no-circumvention clause might bear on the act, disrobe runs the strip only after the operator asserts authorization. Whether such a clause binds a lawful acquirer performing acts a statute expressly permits is jurisdiction-specific, and this stance does not resolve that question for the operator.
Statutory scope
17 U.S.C. §1201(f) provides a conditional interoperability exception. It requires a lawfully obtained right to use the program and limits the purpose, necessity, use, and disclosure of the information or means involved. It does not establish that every use or distribution of this tool qualifies.
Directive 2009/24/EC, Articles 5(3) and 6, addresses study and decompilation under stated conditions; Article 8 makes contrary contractual provisions ineffective within those exceptions. Applicability depends on the activity and the governing law. A product classification or authorization flag does not decide that question.
What the stance produces in the tool
The stance is wired into the tool's defaults:
- Detection runs by default. Identifying the family and reporting its markers needs no authorization gate.
- The static-marker strip is gated. It runs only with
--i-have-authorization. Without the flag, the operation returns an authorization-required error and does not modify the input. - No runtime bypass exists.
disrobeships no defeat of the product's runtime anti-tamper or integrity protection; the gate would govern any such future capability. - No third-party protected bytes in the public corpus. Fixtures are synthesized to match the implemented guard patterns. The repository ships the recognizer and strip logic, not protected sample bytes.
Takedown and rights contact
If you assert that disrobe's Digital.ai / Arxan handling infringes your rights, contact the maintainer before public action via a private security advisory at https://github.com/1-3-7/disrobe/security/advisories/new. Include the rights asserted, the specific artifact or commit at issue, the action requested, and an authorized representative's contact. The project is operated in good faith and will respond to substantiated, specific concerns. See Responsible use for the general procedure.
PACE
PACE is a commercial application-hardening protector in the anti-piracy and integrity-guard class. The family covers PACE Anti-Piracy, PACE Fusion, and the iLok binding that PACE ships into JavaScript. PACE wraps a program in self-identifying runtime guards rather than encrypting the program itself. Because disrobe ships a PACE recognizer and a static-marker strip, the project owes an explicit account of what it acts on, when, and why. The project commits to a written stance in this section before any gray-zone protector escalates from recognition to a peel; this is that file for PACE.
What disrobe does to PACE input
The legal posture rests on the narrowness of the act, so each item below states the capability exactly.
- Detect.
disrobematches PACE by its self-identifying static guard markers: the PACE Anti-Piracy / PACE Fusion banner comments, iLok binding tokens, the__PACE__and_PACE_FUSION_runtime tokens, and the documented static shapes of the presence check and the self-check interval. Detection emits a family identification and confidence, nothing more. - Strip static markers. When authorized,
disroberemoves those self-identifying static guard fragments (banner comments, thewindow['__PACE__'] === undefinedpresence-reload check, thesetIntervalself-check, the static_PACE_FUSION_config object, the static iLok token assignment) so the surrounding application JavaScript reads cleanly for analysis. - What it does not do.
disrobedoes not circumvent PACE's runtime anti-tamper or integrity protection. It does not recover an iLok-bound key, defeat a license check at runtime, or reconstruct anything PACE keeps off the static surface. The strip removes self-identifying static guard text from input the operator already possesses. That is a text edit, not a bypass of the commercial runtime protection. - Validation is synthetic only.
disrobegrades the PACE behavior against synthesized fixtures matching the implemented marker patterns. There is no real-sample oracle; the project does not ship or test against third-party PACE-protected bytes. Treat the strip as a structural deobfuscation aid, not a measured defeat of a real protected artifact.
Traffic-light verdict: AMBER
disrobe classifies every protector on a three-color scale:
| Color | Meaning | Default behavior |
|---|---|---|
| GREEN | Free / open / no commercial EULA restriction on analysis | Deobfuscate by default. |
| AMBER | Commercial application-hardening with mixed, jurisdiction-sensitive EULA terms | Detect by default; gate the static-marker strip behind --i-have-authorization. |
| RED | Protection of third-party copyrighted content with no interoperability nexus | Recognize only; never peel. |
PACE is AMBER. It is a commercial application-hardening product, and its deployment normally attaches EULA terms. Those terms commonly include anti-reverse-engineering or no-circumvention language. Enforceability of that language against a lawful acquirer performing statutorily permitted acts is jurisdiction-sensitive. disrobe therefore detects PACE by default but runs the static-marker strip only when the operator asserts authorization via --i-have-authorization. Any deeper handling of the runtime anti-tamper or integrity protection is not implemented; were it ever built, it would sit behind the same explicit authorization gate and never run otherwise.
The gate is an assertion by the operator, not an adjudication by the tool. Passing --i-have-authorization is the operator's representation that they are authorized to analyze the input for the intended activity. The operator carries that responsibility.
The contractual surface
PACE is licensed commercially, and a deployment that embeds its guards is typically governed by a EULA. The project does not enumerate specific clause text it cannot reliably attribute to a given version or license. It does not represent any clause as enforceable or unenforceable. The posture is procedural: where a EULA's anti-reverse-engineering or no-circumvention clause might bear on the act, disrobe declines to run the strip absent the operator's explicit authorization assertion. Whether such a clause binds a lawful acquirer performing acts a statute expressly permits is a jurisdiction-specific question, and disrobe does not answer it for the operator.
Statutory scope
17 U.S.C. §1201(f) provides a conditional interoperability exception. It requires a lawfully obtained right to use the program and limits the purpose, necessity, use, and disclosure of the information or means involved. It does not establish that every use or distribution of this tool qualifies.
Directive 2009/24/EC, Articles 5(3) and 6, addresses study and decompilation under stated conditions; Article 8 makes contrary contractual provisions ineffective within those exceptions. Applicability depends on the activity and the governing law. A product classification or authorization flag does not decide that question.
What the stance produces in the tool
The posture is wired into the tool's defaults:
- Detection runs by default. Identifying PACE and reporting its markers needs no authorization gate.
- The static-marker strip is gated. It runs only with
--i-have-authorization. Without the flag, the operation returns an authorization-required error and does not modify the input. - No runtime bypass exists.
disrobeships no defeat of PACE's runtime anti-tamper, integrity, or iLok-binding protection; the gate would govern any such future capability. - No third-party PACE bytes in the public corpus. The project synthesizes fixtures matching the implemented marker patterns. The repository ships the recognizer and strip logic, not protected sample bytes.
Takedown and rights contact
If you assert that disrobe's PACE handling infringes your rights, contact the maintainer before public action. Use a private security advisory at https://github.com/1-3-7/disrobe/security/advisories/new. Include the rights asserted, the specific artifact or commit at issue, the action requested, and an authorized representative's contact. The project operates in good faith and responds to substantiated, specific concerns. See Responsible use for the general procedure.
PyArmor
PyArmor is a commercial Python obfuscator. This page records Disrobe's handling of protected input and the limits of its authorization controls.
Input handling and authorization
Disrobe classifies PyArmor as AMBER because permission to analyze protected output depends on the operator's rights and the applicable law and contract. A free or paid license tier alone does not determine those rights.
The dedicated pyarmor unpack command does not enforce a free-versus-paid authorization gate. Its static v8/v9 recovery paths are available without --i-have-authorization; callers must establish permission independently. The decryption-keys LLM category separately requires that assertion. This flag records the user's assertion and does not establish legal permission.
Dynamic execution in the v6/v7 fallback requires --allow-dynamic and runs the wrapper in a watchdog-controlled subprocess. BCC native-body lifting separately requires --allow-bcc and analyzes native blobs in process. These flags select technical behavior; they do not grant rights to the input. See Forensics and malware safety.
Statutory scope
17 U.S.C. §1201(f) provides a conditional interoperability exception. It requires a lawfully obtained right to use the program and limits the purpose, necessity, use, and disclosure of the information or means involved. It does not establish that every use or distribution of this tool qualifies.
Directive 2009/24/EC, Articles 5(3) and 6, addresses study and decompilation under stated conditions; Article 8 makes contrary contractual provisions ineffective within those exceptions. Applicability depends on the activity and the governing law. A product classification or authorization flag does not decide that question.
Takedown and rights contact
If you assert that disrobe's PyArmor handling infringes your rights, contact the maintainer before public action. Use a private security advisory at https://github.com/1-3-7/disrobe/security/advisories/new. Include the rights asserted, the specific artifact or commit at issue, the action requested, and an authorized representative's contact. The maintainer operates the project in good faith and responds to substantiated, specific concerns. See Responsible use for the general procedure.
License
disrobe is proprietary, source-available software under the Disrobe Source-Available License, Version 1.1, which supersedes the Elastic License 2.0 and Version 1.0 for every version as described in the relicensing notice. Free use is limited to individuals' own hobby projects, learning, and independent security research, nonprofit education and research, and bona fide journalism. Any use by or for a company or other for-profit organization requires a prior signed paid license; see commercial licensing. Redistribution, forks other than for contributing, rebranding, hosted or embedded offerings, and building competing products from exposure to Disrobe are prohibited. Every publication, report, filing, or deliverable that used Disrobe or its output must carry the credit "This work used Disrobe, created by 1-3-7: https://github.com/1-3-7/disrobe"; see the attribution guide. The software is provided as is, and its author has no responsibility for how anyone uses it. Contributions require accepting the contributor terms. The LICENSE and NOTICE govern; the plain-language summary is not the license.

