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.The Problem: Inline Hooks
AV/EDR products commonly place inline hooks on NT functions inntdll.dll by modifying the first few bytes:
mov eax, <SSN> opcode fail when hooks overwrite these bytes.
How FreshyCalls Works
Core Principle
NT syscall stubs inntdll.dll are laid out sequentially in memory, ordered by their syscall numbers. The virtual address order directly corresponds to SSN order:
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
- VA order is canonical: Microsoft’s NT kernel assigns SSNs sequentially during build.
ntdll.dllstubs are laid out in memory matching this order. - Export table is rarely hooked: EDR hooks target function code, not the export directory entries. VAs remain accurate.
- 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: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
| Method | Hook Resistance | Speed | Complexity | Export Table Dependency |
|---|---|---|---|---|
| Static | None | Instant | Low | ❌ |
| Hell’s Gate | Low | Fast | Low | ❌ |
| Halo’s Gate | Medium | Fast | Medium | ❌ |
| Tartarus’ Gate | High | Fast | High | ❌ |
| FreshyCalls | Very High | Fast | Low | ✅ |
| SyscallsFromDisk | Maximum | Slow | Medium | ❌ |
| RecycledGate | Maximum | Medium | Medium | ✅ |
When to Use
Recommended For
Recommended For
- General-purpose evasion: Excellent default choice for most scenarios
- Fast initialization: Minimal overhead during startup
- Standard EDR environments: Works against all common inline hook patterns
- Red team operations: Reliable without excessive complexity
Consider Alternatives When
Consider Alternatives When
- 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
- Export table enumeration: Iterating
ntdllexports is common for legitimate software (loaders, debuggers) - qsort usage: Generic sorting is not inherently suspicious
- 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
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
