Recipe: Runtime attestation + integrity check
Continuously verify your process has not been tampered with after launch. Combine self-hashing, debugger detection, and ETW monitoring into a single attestation loop.
What you'll build
A background thread that hashes the in-memory .text section every 30 seconds, compares it against a link-time baseline, and fails closed if a mismatch is found. The loop also polls PEB.BeingDebugged and subscribes to the Microsoft-Windows-Threat-Intelligence ETW provider to catch suspicious handle operations.
Prerequisites
- Nimbus C++ loader with Ed25519-signed payload
- Link-time
.texthash embedded via post-build step - SeSystemProfilePrivilege for ETW subscription
- Direct-syscall stub for NtQueryVirtualMemory
Step 1 — Baseline hash
During the post-build step, compute SHA-256 over the raw .text section bytes and embed the digest as a compile-time constant. At runtime, walk your own PE headers via the DOS header in the module base to locate the section.
Step 2 — Attestation loop
Spawn a low-priority thread that sleeps for 30 seconds, then:
- Hashes the live
.textpages via a direct syscall to NtQueryVirtualMemory (avoids hooked IAT). - Compares the digest against the baseline. On mismatch, call the circuit breaker — wipe decryption keys and terminate.
- Reads
PEB.BeingDebuggedat offset 0x02 from the PEB pointer atgs:[0x60]. - If the flag is set, trigger the same fail-closed path.
Step 3 — ETW consumer
Open a real-time trace session against Microsoft-Windows-Threat-Intelligence. Filter for events where CallerProcessId matches your own PID and the operation targets your process. Log anomalies to an offline grace cache signed with HMAC so the dashboard can surface them later.
Step 4 — Circuit breaker
The circuit breaker zeroes the decryption key material in memory, calls TerminateProcess with exit code 0xC0000225 (STATUS_NOT_FOUND), and writes a signed tamper event to the offline cache. The next launch reads the cache and surfaces the event in the Meridian dashboard.