MORIA(1)
π MORIA(1) β User Commands β identify files and embedded firmware structures π
okay bestie, welcome to the moria manual page. If you're doing firmware or IoT assessments, this is your new hyperfixation. No cap.
β¨ NAME β¨
moria β identify files and embedded firmware structures. She's the friend who looks at a mysterious blob and goes, "bestie, I know her." π
πΈ SYNOPSIS πΈ
moria [options] <file|dir>
π¦ DESCRIPTION π¦
okay so moria maps what a file is and what known structures live inside it, with confidence scores and sourced metadata. It is identification only: it locates and names embedded formats (filesystems, containers, bootloaders, executables, compression, media) with byte offsets and confidence tiers. Iconic behavior, honestly.
She is identification-first; with --extract she also unpacks SquashFS, ext2/3/4, F2FS, JFFS2, UBIFS, romfs, YAFFS2, cramfs, FAT, exFAT, NTFS, HFS+, XFS, btrfs, EROFS, and ISO9660 filesystems, ZIP/tar/cpio/MS-CAB archives, CFBF compound files (Windows Installer .msi), U-Boot uImage/FIT containers, Windows CE XIP ROM images and registry hives, and RAE Systems/Honeywell RFP firmware packages (LZARI-decompressing their sections) internally (no sudo). That's a lot of unpacking, and she ate. Every other format is still identified and located by offset, ready for another tool such as binwalk.
Output is human-readable by default. A single file shows a findings tree (containers nest their contents) followed by a run-stats footer; a directory shows per-type counts and the notable findings grouped by directory, then the same footer. The one-line assessment is carried in the JSON output only. Pass -j/--json for a single JSON object, designed to be consumed by an LLM tool caller during firmware and IoT assessments. Tool-caller bestie behavior, fr fr.
π ARGUMENTS π
<file|dir>β A file to identify, or a directory to scan recursively. That's the whole argument, periodt.
π OPTIONS π
π«Ά Output
-j,--jsonβ Emit JSON instead of the human-readable view (which is the default). Use this when a tool or model will parse the output.-A,--allβ Keep interior compressed streams. By defaultmoriadrops compression-category findings (xz/gzip/lzonodes) that fall inside a filesystem/container region β the internal data nodes of a UBI/UBIFS or similar per-node flash filesystem, which the filesystem extractor already recovers as real files. This applies to both identification and--extract(so extraction does not emit hundreds of redundant single-node blobs).-Arestores them in both. Very "don't talk to me or my redundant single-node blobs ever again" energy. π-E,--entropyβ Entropy analysis (off by default). Adds theunidentified_regionslist β byte ranges no finding claims, each with its Shannon entropy β and high-entropy "possible encryption" hints in the assessment. The analysis is region-aware: a filesystem's compressed interior (e.g. thexzdata nodes inside a UBIFS volume) is not reported as an unidentified high-entropy region, so the hint fires only on genuinely unclaimed high-entropy data.--listβ List tar/cpio/zip/MS-CAB member names and sizes, or a Windows CE ROM's modules and files. Does not extract. Sometimes you just want the guest list, not the whole party. π
π§ Extract
-e,--extractβ Unpack identified SquashFS, ext2/3/4, F2FS, JFFS2, UBIFS (incl. UBI), romfs, YAFFS2, cramfs, FAT, exFAT, NTFS, EROFS, and ISO9660 filesystems, ZIP/tar/cpio/MS-CAB archives, CFBF compound files such as Windows Installer.msipackages, U-Boot uImage/FIT containers, Android boot/sparse images, Windows CE XIP ROM images, Windows CE registry hives, and RAE Systems/Honeywell RFP firmware packages intofile.extracted/(one subdir per region, named0x<offset>-<type>). Recurses into nested containers by default (a gzip-wrapped filesystem, a filesystem embedded in another), re-scanning each produced file and unpacking what it finds, bounded by--depth,--max-files, and--max-bytes. ext extraction is read-only and needs no sudo. Other formats are identification-only. Takes a single file, not a directory.
bestie, read this again: -e takes a single file, not a directory. Point it at a file, not a whole directory. π
-C,--outdir dirβ Write extraction output to dir instead of the defaultfile.extracted/.--depth Nβ Maximum extraction recursion depth (default8).--depth 1extracts one level only (no recursion).--max-files Nβ Stop extraction afterNfiles have been produced across the whole run (default500000); the manifest is marked capped.--max-bytes Nβ Stop extraction afterNoutput bytes (default4294967296= 4 GiB); the manifest is marked capped. A per-extraction decompression-ratio guard (output/input over 1000:1 above 10 MiB) also stops descent into a likely decompression bomb.
not me warning you about a literal decompression bomb. stay safe out there. π
--unpack-executablesβ Also unpack installer/document containers (CFBF/MSI) that are found inside other extracted output. By default these are unpacked only when they are the root container because a single.msiexpands to several hundred database-table streams and burying the rest of the findings under them is rarely what you want. She said "main character energy only for root containers," and honestly valid.
πͺ¦ Carve
-c,--carveβ Dump the raw byte range of each finding, and the unidentified gaps between them, tofile.carved/as<offset>-<type>.binfiles, WITHOUT parsing. This is the fallback when--extractcannot reconstruct a filesystem (vendor obfuscation, an unsupported or corrupt variant): the researcher still gets the raw bytes on disk to hand to another tool or inspect by hand. Amanifest.jsonrecords each blob's offset, size, and type. Independent of--extract; when both are given, carve writes to a siblingfile.carved/directory. By default sub-kilobyte gaps (usually padding) are not carved;-Acarves every gap. Obeys-Cand--max-bytes. Takes a single file, not a directory.
when parsing said "I can't make it make sense," carving said "bet, raw bytes on disk." iconic fallback behavior. π
π₯ Scan
--broadβ Also match the ~2500 generated general-format signatures (file(1)Magdir, magic tier) on top of the firmware core set.
βοΈ Configuration
--sigs dirβ Use a specific signatures directory instead of the bundled ones.--threads Nβ Worker count for directory scans. Default:min(cores, 16).
π Information
-h,--helpβ Print help and exit.--versionβ Print version and exit.
π EXIT STATUS π
0β Success.1β Runtime error (unreadable file, no signatures loaded).2β Usage error (unknown option, missing argument).
π ENVIRONMENT π
MORIA_SIGDIRβ Overrides the signatures directory (same effect as--sigs).XDG_DATA_HOMEβ If set,morialooks for signatures under$XDG_DATA_HOME/moria(else~/.local/share/moria) as part of its search path.NO_COLORβ Disables bold section headers in--helpoutput.
π FILES π
When no --sigs or MORIA_SIGDIR is given, signatures are searched for, in order, next to the binary (<exe>/../signatures and the install sibling <exe>/../share/moria/), then ~/.local/share/moria, then /usr/local/share/moria and /usr/share/moria. cmake --install populates <prefix>/share/moria/. The search path is giving "I know a spot." πΊοΈ
π EXAMPLES π
- Identify one file (human-readable):
moria firmware.bin
- Identify one file as JSON (for a tool or model):
moria -j firmware.bin
- Unpack its filesystems:
moria -e firmware.bin
- Carve raw byte ranges to disk without parsing:
moria -c firmware.bin
- List archive contents without unpacking:
moria --list update.tar
π¦ SEE ALSO π¦
Full documentation: skills/moria/README.md
okay that's the whole vibe β this is moria 0.3.0, dated 2026-10-05, and she's literally iconic. πβ¨π¦π
π¦ where this page comes from
- nixpkgs unstable: moria 0.3.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms