Memory acquisition devlog: coverage without a completeness claim
An executable page outside a module list is a lead, not an ownership verdict. This investigation started with a question narrower than whether we got everything: what did the VTL0 collector actually cover, which pages can be tied to sample bytes, and where does the evidence stop? The retained work combines a physical-RAM scan, current-CR3 translation, live module captures, page fingerprints, disk PE comparisons, negative controls, a collector self-check, and a write-path review. The result is bounded: two exact anonymous .text reference copies and 28 directly referenced anonymous executable data pages are confirmed; CPU execution, lower trust-domain state, and complete acquisition remain unresolved.
Start with the acquisition window
The physical scan ran from 06:57:37 to 06:59:34. The first runtime-image set was captured at 06:44:52 and a second set at 07:09:12. A later module capture ran from 07:40:27 to 07:40:56, followed by anonymous executable-page selection at 07:41:03. Those timestamps describe the order of observation, not one frozen system state.
The full-RAM scan and the later module and anonymous-page snapshots were not atomic. The newest module images and anonymous executable pages were separated by roughly 7–36 seconds, leaving room for a short-lived mapping to appear, disappear, or change between observations. The investigation therefore treats each window as its own evidence set and does not merge them into a claim about a single perfect instant.
| Evidence window | What it can answer | Boundary |
|---|---|---|
| 06:57:37–06:59:34 | Which readable physical pages were present for the scan | Not an atomic view of later snapshots |
| 07:40:27–07:41:03 | Which module and anonymous executable pages were selected | Short-lived state can fall between captures |
| 07:27 and 07:41 comparison | Which referenced pages and hashes persisted | Persistence does not establish purpose or execution |
Quantify coverage before interpreting a match
The physical scan attempted 34,159,435,776 bytes and successfully read 34,052,968,448 bytes: 99.688322% of the requested range. The unread remainder was 106,467,328 bytes, or 101.535156 MiB (0.311678%), covering 25,993 4 KiB pages merged into 44 contiguous intervals. In that snapshot, the unread pages did not overlap the six known module images' mapped physical pages or the executable mappings visible through the current CR3. Every non-zero page in the six saved runtime images had an exact page-level fingerprint somewhere in the physical scan.
The later anonymous executable snapshot contained 5,724 unique 4 KiB pages, or 23,445,504 bytes. All pages were read successfully and both the merged dump and per-page manifest hashes verified. Of those pages, 5,710 were Supervisor, Writable, Executable and 14 were Supervisor, Read-only, Executable; no page had the User bit set. Comparing it with the 07:32 snapshot found 5,722 shared virtual pages, but only 1,701 had the same virtual page, physical page number, and content hash. The changing remainder is consistent with a dynamic kernel-memory set. It is not safe to label every executable page as belonging to the sample.
Entropy is another measurement, not a verdict. The snapshot had 531 pages with entropy at least 7.5. That can help prioritize inspection, but it does not identify encryption, compression, code ownership, or intent.
Fingerprints narrow the search, then stop
Scanning physical memory found 876 Native x64 PE-header candidates, representing 823 unique headers. After correlating them with current-page executability and known module ownership, the candidate group that was both executable and ownerless was zero. That is a result about standard PE-shaped evidence in the observed state; it says nothing about code with its headers removed, VM bytecode, or a mapping that was gone before the scan.
Cross-correlating every ACE page fingerprint with the 06:57 executable aliases found 57 exact code-page matches with an unregistered executable alias: 30 from the report's CORE1 module and 27 from CORE2. All 57 were in .text; the other four modules contributed zero. Two earlier CORE1 RVAs each had three exact physical matches, but only the normal loaded page and not the two additional matches had a current-CR3 executable alias at that time. The 07:41 selection contained 32 complete unregistered CORE1 .text pages. The difference proves that the mapping view changed; it does not identify why.
Three fingerprint records each matched 2,281 physical pages. They were single-byte, zero-entropy fill pages, and the scan file retained only the first 16 addresses for each record. Those truncated address lists cannot support a negative statement such as there being no other aliases.
// Illustrative classification, not a collector protocol.
if (fingerprint_hits > 0 && current_cr3_shows_execute)
record_as_candidate();
else
keep_as_unresolved();Two anonymous .text copies: data use is confirmed, execution is not
Two complete reference copies were recovered outside the loaded-module ranges. CORE1's .text begins at RVA 0x1000, is exactly 0x20679 bytes across 33 pages, and hashes to 7C10C87D35D8A0AE1BCCC8446AA4ECD01122E9A1B8AED7974CDA589B07F9EAC3. CORE2's .text is 0x1BEF9 bytes across 28 pages and hashes to AB691F2842CD9B0C5E0119D9F86543069B26B8C31F513003F63A9813A92ED877. Each anonymous copy, the corresponding live .text, and the disk PE mapped layout agree over the exact length with zero differing bytes. Every reference page was Supervisor, Writable, Executable.
| Sample label | Exact length | Pages | Data use |
|---|---|---|---|
CORE1 .text | 0x20679 | 33, none missing | Anonymous start, live start, and length are stored in .data |
CORE2 .text | 0x1BEF9 | 28, none missing | Anonymous start, live start, and length are stored in .data |
The referenced integrity routines compare the live image with these copies in blocks capped at 0x1000, using the imported RtlCompareMemory, and take a bugcheck path when a block differs. That proves the pages are used as reference data. Offline inspection of the captured .text found no direct call or jump to the comparison-function entry and no absolute pointer to that entry. It does not prove that the CPU never executed a reference copy: indirect dispatch, a VM layer, another section, or a dynamic call was outside that negative check.
Other anonymous executable pages carry direct references
The latest six-module images contained 85 exact pointers to 28 unique anonymous executable pages. The source counts were 6 from ADVT, 14 from BOOT, 22 from CORE1, 22 from CORE2, 21 from CORE3, and zero from SSC. Eighty-four pointers were in .data and one in .rdata. All 28 target pages were Supervisor, Writable, Executable.
The pointer targets decoded to service identifiers, installation-like path strings, version strings, device names, and other system-related objects. That confirms direct reference relationships and gives the pages a useful content description. It does not explain why the pages have write and execute permissions, identify their intended owner, or establish code execution or transfer of personal data.
The same 85 reference keys were present in both the 07:27 and 07:41 snapshots. All 28 target virtual pages were shared; 16 page hashes were unchanged and 12 changed while the pointers stayed the same. Stable pointers with changing contents are evidence of a live data structure, not proof of a hidden execution path.
Negative controls reject a simpler cache explanation
Four controls produced zero exact-page matches in the anonymous executable snapshot: 64 deterministic user-mapped pages, collector-image pages captured after the connection was closed, collector-image pages read and retained during an active connection, and pages from a SEC_IMAGE mapping of the collector image. These controls make a simple explanation—every page recently read by the collector is copied into the anonymous executable set—less plausible.
They do not prove that every acquisition path is clean. A selective rule could affect only particular objects, and a targeted change could evade a control that was not identical in timing or content. The controls are therefore support for a narrower interpretation, not a certificate of collector independence.
Self-check the collector, then separate PTE writes from content writes
The retained whql.sys self-check compared the current collector image with its disk sample. Its executable section was 16,873 bytes and its PAGE section 9,676 bytes; each pair had a matching SHA-256 and zero differing bytes. The last two pages holding INIT or relocation content were not currently mapped, so they could not be compared. A complete memory-image hash retained at 07:51 also matched the earlier saved image hash.
This reduces the chance that the collector's currently visible executable code was directly patched. It does not validate runtime data, function pointers, page-table inputs, lower-layer return values, or any forwarding path outside the compared sections. A Medium Integrity module query returned an image base of zero for the collector, all six sample modules, and unrelated system drivers alike, so that symptom cannot be assigned to the sample. Saved bases were still usable for the code comparison. Object-directory checks were incomplete because the current token could not open the relevant kernel directories. Platform queries reported a hypervisor and VBS status, but those values do not identify who controls a lower trust domain.
The write-path review found Create, Close, DeviceControl, and Read dispatch assignments, with no Write dispatch and no Fast I/O write routine. DeviceControl completes with STATUS_INVALID_PARAMETER. The accepted message set is exactly initialization, single-segment read, and scatter read. Every observed copy runs from a mapped source toward user/output memory. Separately, an internal routine can rewrite the PFN in a rogue-page PTE when its caller supplies a page-aligned physical address, and a release path restores the original PFN. That is a confirmed driver-internal page-table write. The review did not find a Ring3-controlled arbitrary-content write interface in this sample: no reviewed copy takes Ring3 bytes as the source for the target mapping.
Keep confirmed, unresolved, and threat model separate
Confirmed. The observed collection covered 99.688322% of the requested physical range, found exact aliases for 57 sample code pages in one window, recovered two complete anonymous .text reference copies, and documented 85 direct pointers to 28 anonymous executable data pages. The reference copies are demonstrably compared as data. The controls and write-path review support the stated acquisition boundary.
Unresolved. The evidence does not establish that a reference copy was executed, why the data pages are RWX, or whether a short-lived page was missed. It cannot identify the contents of the unread 101.535156 MiB, secure-kernel or VTL1 memory, EPT/NPT-presented views, SMM or firmware regions, removed PE headers, JIT or VM bytecode, or pages changed between windows. It also does not establish malicious intent, use of an unknown vulnerability, or transfer of personal data.
Threat model. For check design, the report considers a target that may actively evade VTL0 acquisition, including page-table forks, selective responses, or lower-layer views. That is a worst-case assumption used to choose controls, not evidence that the sample used any of those capabilities. The strongest honest statement is narrower: the saved material documents what this VTL0, same-host, time-separated model observed and where it cannot speak.
Evidence note: This entry transcribes the retained memory_coverage_audit.md and write_path_reaudit.md findings, including their sample-specific counts, hashes, controls, and limitations. It does not rerun acquisition, reverse engineering, or the historical self-check. Scope: conclusions apply to the captured sample and windows only; they are not a claim of complete memory acquisition or of behavior outside the observed trust and time boundaries.