Windows places the DTB at the lowest free physical page at boot, making the
address a high water mark of early loader allocations. winload.efi has grown
from 1.52 MiB at build 14393 to 3.62 MiB at build 28000, so the DTB slides to
higher addresses with each release.
The three fast-path ranges in test_sets left two gaps:
0x2a0000 -- 0x550000 (2.7 MiB)
0x6f0000 -- 0x900000 (2.1 MiB)
A Windows 11 25H2 image (build 26200.8037, 8 GiB Hyper-V Gen2) has its System
DTB at 0x7b5000, inside the 2.1 MiB gap, causing every plugin to fail.
Merge the three ranges into a single contiguous span:
(0x150000, 0x150000), |
(0x550000, 0x1A0000), |-> (0x150000, 0x8B0000)
(0x900000, 0x100000), |
The merged range ends at 0xa00000, which is the start of the 'very large memory'
range added by PR #1971, so 0x150000--0x5a00000 is now one unbroken 84.7 MiB
span with no gaps.
Widening the fast path is safe because PR #1992 added translation-based DTB
validation: extra candidates cost scan time and nothing else.
kernel_cap_t only handles the 6.3+ layout and raised for everything else.
Before 6.3 the same name exists as a typedef of kernel_cap_struct, whose
implementation already decodes the two-element cap array, so fall back to
it instead of raising.
The kernel requirement listed "Intel33". Intel layers only ever report
Intel32 or Intel64, so on a 32-bit image the requirement could never be
satisfied and the plugin aborted with a misleading "Unsatisfied
requirement ... kernel.layer_name" instead of running.
The pyinstaller specs gather plugin modules two different ways. The .py
files are shipped verbatim by collect_data_files(include_py_files=True),
while collect_submodules() supplies the hiddenimports that pyinstaller
actually analyses for dependencies. The first walks the filesystem, the
second walks pkgutil, and pkgutil skips a directory with no __init__.py.
volatility3/framework/plugins/renderers has been such a directory since
the arrow and parquet renderers moved into it, so parquet_renderer.py was
copied into the binary but never analysed, and the pyarrow it imports was
left out. The frozen build still advertised the arrow and parquet
renderers, because the framework finds them at runtime with os.walk, and
then died with an unhandled RuntimeError when either was selected.
Adding the __init__.py makes pkgutil descend into the directory, which is
all collect_submodules needs, and matches every other plugin subpackage.
Both specs use the same collect_submodules line, so neither needs editing.
populate_config prefixed "file://" onto the result of pathname2url, which
already returns a leading "///" on Windows. Three slashes plus two gives
file://///C:/..., an empty authority that urlopen reads as a UNC path, so
every URIRequirement failed there before the file was ever opened. That
covers --single-location, --yara-file, --yara-compiled-file, --strings-file,
--isf and volshell's --script.
pathlib's as_uri produces the same string as the current code on POSIX for
every supported Python version, and the correct one on Windows, including
for UNC paths. It also sidesteps the Python 3.14 rewrite of pathname2url,
which gives POSIX the same leading "///" that Windows always returned.
The two other places in the codebase that build file URLs,
URIRequirement.location_from_file and volshell's run_script, were already
correct; this was the only one assembling the scheme by hand.
Per review feedback, the small next_id() closure that combined a
'nonlocal node_counter' assignment with an f-string formatter is more
naturally expressed as itertools.count. The counter generator yields
the integer sequence starting at 1 and the call site formats it as
'n<index>' on the spot, so the behaviour is unchanged: per-render,
strictly-increasing, plugin-agnostic Mermaid node identifiers.
Bring the new MermaidRenderer in line with the repository's ruff
formatting rules (introduced in the develop merge that this branch
just absorbed): double-quoted strings, trailing comma after the last
mapping entry, four-space hanging indent for the visitor signature,
and an additional blank line between top-level classes.
Address review feedback that the renderer was tightly coupled to plugins
exposing PID/PPID columns: the previous implementation looked up "PID"
and "PPID" by name to build parent->child edges and raised a generic
exception otherwise, which prevented any non-pstree tree plugin from
being rendered as Mermaid.
The relationship is already encoded in the TreeGrid -- every TreeNode
carries its path_depth -- so the new render() walks the rows in
traversal order and tracks ancestry with a parent stack:
* descending one or more levels pushes the previously-emitted node
once per level (so a level skip still produces sane pops);
* ascending pops the corresponding number of levels;
* the stack top is always the parent of the next emitted node, or
empty for a root-level node.
Each node is given a stable per-render identifier (n1, n2, ...) instead
of being keyed by a column value such as PID, since PIDs are not unique
across a TreeGrid and may contain characters that are unsafe in Mermaid
node IDs.
A small label-escaping helper replaces the previous ad-hoc string
replacement of parentheses, and embedded newlines in cell renderings
are folded to <br> so each row stays a single Mermaid node.
The unused tree_indent_column placeholder (flagged by code scanning)
is dropped as part of the rewrite.
The debug log emitted when writing out --save-config previously logged the
literal string "{args.save_config}" instead of the resolved filename, in both
vol.py and volshell. Add the f-string prefix so the actual destination path
appears in the log.