Overview
SyscallsFromDisk achieves maximum hook resistance by mapping a completely clean, unhookedcopy ofntdll.dll from \KnownDlls\ntdll.dll or directly from disk, then extracting SSNs from the pristine .text section. Since the mapped copy is never touched by EDR hooks, all opcode reads are guaranteed clean.
The Problem: All Stubs Hooked
In heavily monitored environments, EDRs may hook:- Every
Nt*function in the running ntdll (defeats Hell’s/Halo’s/Tartarus’ Gate) - Export table entries (could theoretically defeat FreshyCalls)
- Syscall return addresses (defeats some indirect methods)
How It Works
High-Level Flow
Step-by-Step
1
Open \KnownDlls\ntdll.dll
Windows maintains a shared section object at
\KnownDlls\ntdll.dll containing the original, unmodified ntdll.2
Map the Clean Section
Create a read-only view of the clean ntdll in our process address space:
3
Parse Export Table
Identical to FreshyCalls, but reading from the clean mapped copy:
4
Read SSNs from Opcodes
Read the
mov eax, <SSN> opcode (Hell’s Gate style) from the unhooked stubs:5
Cleanup
Unmap the section and close handles:
Implementation
Full C Code
Advantages
Absolute Hook Immunity
EDR hooks in the running ntdll are completely irrelevant — we read from an untouched copy
Opcode Validation
Can safely use Hell’s Gate opcode reading since the source is guaranteed clean
Export Table Independent
If EDR modifies the export table (extremely rare), we’re unaffected — we map from KnownDlls
Future-Proof
Works across all Windows versions — KnownDlls always contains the pristine image
Performance Cost
The overhead is one-time during
SW4_Initialize(). Once SSNs are cached, syscalls execute at full speed.Limitations & Edge Cases
1. KnownDlls Access Restrictions
In sandboxed or restricted processes,\KnownDlls\ may not be accessible:
C:\Windows\System32\ntdll.dll:
2. NTDLL Backed by Non-Standard Path
In rare cases (custom Windows PE loaders, Wine), ntdll may be loaded from a non-standard location. The System32 fallback handles this.3. Performance in Tight Loops
If you need to repeatedly re-resolve SSNs (unusual), cache results rather than re-mapping.Comparison with Alternatives
When to Use
Use SyscallsFromDisk When
Use SyscallsFromDisk When
- Maximum paranoia required (government, high-security targets)
- All stubs are hooked in the running ntdll
- Export table manipulation suspected (extremely rare)
- Single initialization acceptable (performance cost amortized)
- Combining with ntdll unhooking for layered defense:
Avoid When
Avoid When
- Speed is critical — use FreshyCalls instead
- Running in sandboxes (AppContainer, low-integrity) — KnownDlls may be blocked
- Repeated initialization needed — cache SSNs after first resolution
Usage in SysWhispers4
Generate with SyscallsFromDisk
Integration Example
Detection Vectors
What EDRs Can Observe
- KnownDlls access: Calling
NtOpenSection("\\KnownDlls\\ntdll.dll")is visible via kernel callbacks - Section mapping: EDRs can track
NtMapViewOfSectioncalls - Timing anomaly: 15ms initialization is longer than normal API calls
Mitigation Strategies
1
Combine with ntdll unhooking
EDRs see both operations but struggle to correlate:
2
Use indirect invocation
Keep RIP inside ntdll during syscalls:
3
Enable sleep encryption
Encrypt .text during idle periods:
Further Reading
FreshyCalls
Faster alternative with very high hook resistance
RecycledGate
Hybrid approach combining sorting + opcode validation
ntdll Unhooking
Complement by removing hooks from running ntdll
KnownDlls Deep Dive
Alex Ionescu on Windows KnownDlls
