SkillAgentSearch skills...

Mquire

Zero-dependency Linux memory forensics PoC — leverages kernel-embedded BTF and kallsyms for type-aware memory analysis without external debug info.

Install / Use

/learn @trailofbits/Mquire
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

mquire

mquire, a play on the memory and inquire words, is a memory querying tool inspired by osquery.

Key advantage: No external debug symbols needed

mquire can analyze Linux kernel memory snapshots without requiring external debug symbols.

Everything needed for analysis is already embedded in the memory dump itself. This means you can analyze:

  • Unknown or custom kernels you've never seen before
  • Any Linux distribution without preparation
  • Memory snapshots where external debug symbols are unavailable or lost

Requirements

Kernel version requirements:

  • BTF support: Kernel 4.18 or newer with BTF enabled (most modern distributions enable it by default)
  • Kallsyms support: Kernel 6.4 or newer (due to changes in scripts/kallsyms.c format)

How it works

mquire analyzes kernel memory by reading two types of information that are embedded in modern Linux kernels:

  1. Type information from BTF (BPF Type Format) - Describes the structure and layout of kernel data types. BTF data is parsed using the btfparse crate.
  2. Symbol information from Kallsyms - Provides the memory locations of kernel symbols (same data used by /proc/kallsyms)

By combining type information with symbol locations, mquire can find and read complex kernel data structures like:

  • Process memory mappings (using maple tree structures)
  • Cached file data (using XArray structures)
  • Kernel log messages

This makes it possible to extract files directly from the kernel's file cache, even if they've been deleted from disk.

Compatibility notes

The Kallsyms scanner depends on the data format from scripts/kallsyms.c in the kernel source. If future kernel versions change this format, the scanner heuristics may need updates.

Capabilities

Tables

mquire provides SQL tables to query different aspects of the system or the state of the tool itself.

mquire is not a database. Each query reconstructs kernel data structures by scanning memory and following pointers. There are no precomputed indexes or cached results: every table access is a traversal of kernel data. Use AS MATERIALIZED to avoid redundant scans (see Query Optimization), and provide constraints like task when querying per-process tables like task_open_files and memory_mappings to limit the scan to a single process.

Design principle: virtual addresses as join keys. Tables use virtual_address (the kernel address of the underlying data structure) as the canonical join key: not pid or other user-visible identifiers. This is intentional, because the same PID can appear multiple times across different discovery sources and root tasks, while a virtual address uniquely identifies a specific kernel object. Both the SQL tables and the underlying LinuxOperatingSystem API are built around this convention.

System information

  • os_version - Kernel version and architecture
  • system_info - Hostname and domain name
  • boot_time - System boot time
  • kallsyms - Kernel symbol addresses (same data as /proc/kallsyms)
  • dmesg - Kernel ring buffer messages (same data as dmesg command)

Process information

  • tasks - Running processes with command lines and binary paths. Each task is discovered via multiple independent sources, which is useful for rootkit detection. See Comparing task enumeration methods for rootkit detection and Deduplicated process list.
  • task_open_files - Files opened by each process (provide a task constraint for targeted analysis, or query all tasks at once)
  • memory_mappings - Memory regions mapped by each process (provide a task constraint for targeted analysis, or query all tasks at once)

Kernel modules

  • kernel_modules - Loaded kernel modules with metadata (name, state, version, parameters, taint flags)

Network information

  • network_connections - Active network connections (TCP sockets)
  • network_interfaces - Network interfaces with IP addresses and MAC addresses

File system

  • syslog_file - System logs read from the kernel's file cache (works even if log files are deleted or unavailable, as long as they're cached in memory)

Debugging

  • mquire_diagnostics - Internal mquire logs showing analysis progress, warnings, and errors

Commands

mquire provides three main commands:

  • mquire shell - Start an interactive SQL shell to query memory snapshots
  • mquire query - Execute a single SQL query and output results (supports JSON or table format)
  • mquire command - Execute custom commands on memory snapshots (e.g., .task_tree, .system_version, .dump)

Dot Commands

mquire provides special commands prefixed with a dot (.) to distinguish them from SQL queries.

Built-in Commands

These commands work in the interactive shell and with mquire query:

  • .tables - List all available tables
  • .schema - Show schema for all tables
  • .schema <table> - Show schema for a specific table
  • .commands - List all available custom commands
  • .exit - Exit the interactive shell (shell only)

Custom Commands

These commands work in the interactive shell and with mquire command:

Use --help with any command to see available options and usage information. For example: .task_tree --help

.system_version

Display the operating system version information.

This is a convenience command equivalent to SELECT * FROM os_version, but with formatted output.

.task_tree

Display a hierarchical tree of running processes and threads, similar to the pstree command on Linux.

Options:

  • --show-threads - Include threads in addition to processes. When enabled, displays both TGID and TID for each entry.
  • --use-real-parent - Use the real_parent field instead of parent for building the tree structure. The real_parent field shows the original parent process before any reparenting (useful for tracking process creation chains even after parent processes exit).

Notes:

  • The format is [TGID TID] when showing threads, or [TGID] when threads are hidden. TGID (Thread Group ID) is what's commonly called PID. For main threads (where TGID == TID), both values will be the same.

.carve

Carve a region of virtual memory to disk. This command extracts raw memory content from a specific virtual address range using a given page table, useful for extracting process memory, heap contents, or other memory regions.

Arguments:

  • ROOT_PAGE_TABLE - The physical address of the root page table (hex string with optional 0x prefix). This determines the address space to use for translation.
  • VIRTUAL_ADDRESS - The virtual address to start carving from (hex string with optional 0x prefix).
  • SIZE - Number of bytes to carve.
  • DESTINATION_PATH - Output file path where the carved memory will be written.

Notes:

  • The command shows a summary of mapped vs unmapped regions before writing.
  • Unmapped regions are filled with zeros in the output file.

.dump

Extract files from the kernel's file cache to recover files directly from memory. This command iterates through all tasks and their open file descriptors, extracting file contents from the page cache.

Arguments:

  • OUTPUT - Output directory for extracted files. Files are organized by TGID (e.g., tgid_1234/path/to/file).

Notes:

  • Currently works with files opened through file descriptors (from the process file descriptor table).
  • Does not yet support extracting data from memory-mapped files.
  • Empty files (no data in page cache) are skipped.
  • Regions with read errors are zero-padded in the output.

Use cases

mquire is designed for:

  • Forensic analysis - Analyze memory snapshots from compromised systems to understand what was running and what files were accessed
  • Incident response - Quickly query memory dumps to find evidence of malicious activity
  • Security research - Study kernel internals and process behavior from memory snapshots
  • Malware analysis - Examine running processes and their file operations without detection
  • Custom tooling - Build your own analysis tools using the mquire library crate, which provides a reusable API for kernel memory analysis

Building and installation

Pre-built packages from CI

Pre-built packages are available as artifacts from CI runs. You can download them from the Actions tab by selecting a successful workflow run and downloading the artifacts. The following package formats are available:

  • linux-deb-package - Debian/Ubuntu .deb package
  • linux-rpm-package - Fedora/RHEL/CentOS .rpm package
  • linux-tgz-package - Generic Linux .tar.gz archive

Building from source

mquire is written in Rust. To build it:

# Clone the repository
git clone https://github.com/trailofbits/mquire
cd mquire

# Build the project
cargo build --release

# The binary will be in target/release/
# - mquire: Unified tool with shell, query, and command modes

Acquiring a memory snapshot

We recommend AVML for acquiring memory snapshots. LiME was previously suggested but is no longer actively maintained.

Using AVML

sudo avml output.lime

Important: Do not use --compress when acquiring snapshots for mquire. mquire does not support compressed AVML snapshots. If you have a compressed snapshot, use avml-convert to decompress it first: avml-convert compressed.lime uncompressed.lime

See the AVML documentation for additional options.

Getting started

Once you have a memory snap

View on GitHub
GitHub Stars120
CategoryData
Updated17h ago
Forks5

Languages

Rust

Security Score

100/100

Audited on Mar 26, 2026

No findings