
Zero-dependency Linux memory forensics, leveraging kernel-embedded BTF and kallsyms for type-aware memory analysis without external debug info.
mquire, a play on the memory and inquire words, is a memory querying tool inspired by osquery.
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:
Kernel version requirements:
scripts/kallsyms.c format)mquire analyzes kernel memory by reading two types of information that are embedded in modern Linux kernels:
/proc/kallsyms)By combining type information with symbol locations, mquire can find and read complex kernel data structures like:
This makes it possible to extract files directly from the kernel's file cache, even if they've been deleted from disk.
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.
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 MATERIALIZEDto avoid redundant scans (see Query Optimization), and provide constraints liketaskwhen querying per-process tables liketask_open_filesandmemory_mappingsto 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: notpidor 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 underlyingLinuxOperatingSystemAPI are built around this convention.
/proc/kallsyms)dmesg command)task constraint for targeted analysis, or query all tasks at once)task constraint for targeted analysis, or query all tasks at once)task constraint, so join it against tasks/processes (e.g. JOIN task_capabilities c ON c.task = p.virtual_address).task constraint.mem entries from a kernel module object. Requires a kernel_module constraint, so join it against kernel_modules (e.g. JOIN kernel_module_mem_entries r ON r.kernel_module = m.virtual_address).struct ftrace_ops nodes, walked from the ftrace_ops_list symbol by default. Constrain virtual_address to read a single node, or start_vaddr (optionally bounded by end_vaddr) to walk from an arbitrary node.mquire provides three main commands:
mquire shell - Start an interactive SQL shell to query memory snapshotsmquire 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)mquire provides special commands prefixed with a dot (.) to distinguish them from SQL queries.
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)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_versionDisplay the operating system version information.
This is a convenience command equivalent to SELECT * FROM os_version, but with formatted output.
.task_treeDisplay 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:
[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..carveCarve 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.