Skip to main content

Overview

SyscallsFromDisk achieves maximum hook resistance by mapping a completely clean, unhookedcopy of ntdll.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.
This technique is slower (~10-20ms initialization) than FreshyCalls due to file mapping operations. Use when maximum reliability is critical.

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)
SyscallsFromDisk bypasses all of these by reading from a hook-free source.

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:
Mitigation: Fallback to reading from 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

  • 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:
  • 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

  1. KnownDlls access: Calling NtOpenSection("\\KnownDlls\\ntdll.dll") is visible via kernel callbacks
  2. Section mapping: EDRs can track NtMapViewOfSection calls
  3. 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