How to Collect Meaning Without Trusting the Kernel
HyperAudit’s isolation boundary solves one problem by creating another: the collector can no longer ask the guest kernel to explain everything it sees. The specific focus here is how HyperAudit captures raw syscall facts at entry and exit, then reconstructs process, file, and descriptor context later in the Secure VM. Understanding that lifecycle shows both the engineering cost of kernel independence and the reason the design can preserve useful evidence without restoring the kernel’s authority over the collector.
Isolation removes convenient abstractions
The guest kernel is a convenient source of information because it already interprets system calls. It knows which process is running, which file descriptor refers to which object, where a pointer points, and what result the operation returned. A conventional auditing module can use kernel interfaces that expose those facts in a form close to what an analyst wants.
HyperAudit treats those interfaces as untrusted after the guest kernel is compromised. If the collector relies on the kernel to provide its symbols, data structures, or high-level interpretation, the same attacker who can alter the kernel may be able to alter what the collector is told. Independence therefore means more than placing the collector in protected memory. It means obtaining enough information from the processor and memory system that the collector does not need the potentially compromised kernel to vouch for its own state.
That decision changes the shape of a record. Instead of asking the kernel for a finished sentence such as “process X opened file Y,” the isolated collector first captures low-level facts: which syscall was entered, what arguments were presented, which execution context issued it, what memory a pointer referred to, and what result came back. The Secure VM can then organise those facts into a form a person can query. Raw capture happens near the event; interpretation is deferred until the record is on the protected side of the boundary.
The division is necessary because the information is time-sensitive. At syscall entry, some arguments are in registers or on the caller’s accessible memory path. After the syscall returns, the return value is available and pointer data may have become readable after the kernel has handled a page fault. Later still, the process may exit or reuse a file descriptor. A collector that waits until query time may no longer find the original context. HyperAudit therefore records what it can at the transition and uses later history to fill in meaning.
Entry, execution, and return are separate states
HyperAudit redirects the syscall path to the injected collector before the original executor runs. At entry, the collector obtains the syscall number and the arguments that the architecture makes available. It also derives process, thread, and CPU context from architectural state and per-thread or per-CPU information. The collector then calls the original syscall executor so the application’s requested operation proceeds normally.
When the executor returns, control passes back through the collector. The collector can now record the return value and collect additional information that was not safe or possible to obtain at entry.