Skip to main content

Overview

FreshyCalls is a robust SSN (System Service Number) resolution technique that determines syscall numbers by sorting NT function exports by their virtual addresses. Unlike traditional methods that read potentially-hooked opcode bytes, FreshyCalls only examines export table addresses — making it highly resistant to inline hooks.
FreshyCalls is the default resolution method in SysWhispers4 due to its excellent balance of speed, reliability, and hook resistance.

The Problem: Inline Hooks

AV/EDR products commonly place inline hooks on NT functions in ntdll.dll by modifying the first few bytes:
Techniques like Hell’s Gate that read the mov eax, <SSN> opcode fail when hooks overwrite these bytes.

How FreshyCalls Works

Core Principle

NT syscall stubs in ntdll.dll are laid out sequentially in memory, ordered by their syscall numbers. The virtual address order directly corresponds to SSN order:
By sorting all Nt* exports by VA and using the sorted index as the SSN, we never need to read potentially-hooked function bytes.

Algorithm

Why It Works

  1. VA order is canonical: Microsoft’s NT kernel assigns SSNs sequentially during build. ntdll.dll stubs are laid out in memory matching this order.
  2. Export table is rarely hooked: EDR hooks target function code, not the export directory entries. VAs remain accurate.
  3. No opcode reading: Unlike Hell’s/Halo’s Gate, we never inspect potentially-tampered bytes inside the function.

Implementation Details

Parsing the Export Table

Strengths

Hook Resistant

Works even when every Nt* stub is hooked — never reads function bytes, only VAs from export table

Fast

Single ntdll parse + qsort — completes in ~1-2ms on modern systems

Simple

No complex neighbor scanning or opcode validation logic

Reliable

Handles all common EDR hook patterns (E9 JMP, FF 25 JMP, EB short JMP, CC int3)

Limitations

Export Table Manipulation

If an EDR modifies the export directory itself (extremely rare, as it breaks Windows API resolution), FreshyCalls can be defeated:
Mitigation: Use RecycledGate, which combines FreshyCalls with opcode validation for cross-checking.

Syscall Number Changes

SSNs change between Windows builds (e.g., NtAllocateVirtualMemory is SSN 0x18 on Win10 21H2, but 0x1A on Win11 24H2). FreshyCalls automatically adapts because it derives SSNs from the running system’s ntdll layout.

Comparison with Other Methods

When to Use

  • Maximum paranoia required: Use SyscallsFromDisk or RecycledGate
  • Export table manipulation detected: Extremely rare; switch to SyscallsFromDisk
  • Kernel callbacks in use: No user-mode technique bypasses ETW-Ti; requires kernel-mode evasion

Usage in SysWhispers4

Generate with FreshyCalls (Default)

Integration

Detection Considerations

What EDRs Can See

  1. Export table enumeration: Iterating ntdll exports is common for legitimate software (loaders, debuggers)
  2. qsort usage: Generic sorting is not inherently suspicious
  3. Memory reads of ntdll: Standard PE parsing behavior

Detection Vectors

  • Behavioral: Syscall execution with RIP outside ntdll (if using embedded method)
  • Memory scanning: Signature detection of SysWhispers4 code patterns
  • Call stack analysis: Abnormal return addresses (mitigated by --stack-spoof)

Best Practices

1

Use indirect invocation

Combine with --method indirect to keep RIP inside ntdll during syscalls:
2

Enable obfuscation

Randomize stub ordering and inject junk instructions:
3

Unhook ntdll first (optional)

Remove hooks before FreshyCalls runs for maximum stealth:

Further Reading

RecycledGate

Enhanced version combining FreshyCalls with opcode validation

SyscallsFromDisk

Alternative that maps clean ntdll from disk

Invocation Methods

How to execute syscalls after SSN resolution

Original Research

FreshyCalls by crummie5