D
DioProcess

Process Hiding

Ring -1

Hide processes from ring 0 enumeration using hypervisor EPT manipulation.

Advanced Feature

Process hiding at Ring -1 is extremely powerful. Hidden processes cannot be seen by the kernel, security products, or standard tools. Use responsibly.

Overview

The hypervisor intercepts kernel enumeration by hooking the memory pages that contain process-related data structures. When the kernel or any ring 0 code attempts to walk the process list, the hypervisor presents a modified view that excludes hidden processes.

What Gets Hidden

  • ActiveProcessLinks — The main doubly-linked list in EPROCESS
  • PspCidTable — Client ID handle table entries
  • Process handles — Obfuscated from handle table enumeration
  • Thread enumeration — Threads of hidden processes

Implementation

Algorithm
// Hide process via EPT hooking
NTSTATUS HvHideProcess(ULONG ProcessId) {
    // 1. Get EPROCESS pointer for target process
    PEPROCESS Process;
    PsLookupProcessByProcessId(ProcessId, &Process);
    
    // 2. Get physical address of EPROCESS.ActiveProcessLinks
    PHYSICAL_ADDRESS PhysAddr = MmGetPhysicalAddress(
        &Process->ActiveProcessLinks
    );
    
    // 3. Set up EPT hook for read operations
    EptSetupHook(
        PhysAddr,
        EPT_HOOK_TYPE_READ,
        HiddenProcessReadHandler
    );
    
    // 4. Store original link values for restoration
    SaveOriginalLinks(ProcessId, Process);
    
    return STATUS_SUCCESS;
}

// EPT violation handler - called when kernel reads ActiveProcessLinks
VOID HiddenProcessReadHandler(PVOID Address, ULONG Size) {
    PLIST_ENTRY Links = (PLIST_ENTRY)Address;
    
    // Present modified links that skip the hidden process
    // Effectively: Prev->Flink = Hidden->Flink
    //              Next->Blink = Hidden->Blink
    ModifyLinksToSkipHidden(Links);
}

API

Usage
use callback::{hv_hide_process, hv_unhide_process, hv_list_hidden_processes};

// Hide a process
let pid: u32 = 1234;
hv_hide_process(pid)?;

// List all hidden processes
let hidden: Vec<u32> = hv_list_hidden_processes()?;
println!("Hidden PIDs: {:?}", hidden);

// Unhide a process
hv_unhide_process(pid)?;

IOCTLs

IOCTLCodeDescription
HV_HIDE_PROCESS0x850Hide process by PID
HV_UNHIDE_PROCESS0x851Unhide process by PID
HV_LIST_HIDDEN0x852List all hidden PIDs

Detection Evasion

Process hiding at Ring -1 evades:

  • ✓ Task Manager
  • ✓ Process Explorer / Process Hacker
  • ✓ CreateToolhelp32Snapshot (ring 3)
  • ✓ NtQuerySystemInformation (ring 0)
  • ✓ PspCidTable enumeration (ring 0)
  • ✓ EDR/AV process scanning
  • ✓ Kernel debugger !process command

Limitations

  • • Process must be running when hide is applied
  • • Does not persist across reboots
  • • Resource usage (CPU, memory) may still be observable indirectly
  • • Another hypervisor could detect the manipulation
  • • Network connections from hidden process are still visible (use port hiding)

UI Access

Two ways to hide processes:

  • 1. Process context menu → Miscellaneous → Hide Process (Ring -1)
  • 2. Hypervisor tab → Enter PID → Hide

Hidden processes show in the Hypervisor tab's "Hidden Processes" list with unhide option.

Use Cases

  • • Red team operations requiring process stealth
  • • Testing security product visibility
  • • Research on process hiding detection
  • • Demonstrating hypervisor capabilities