Iterators

FreshyCalls

Detailed walkthrough of the FreshyCalls syscall resolution algorithm as implemented in Sysplant.

FreshyCalls

Origin: @crummie5 — 2020
Default method: direct


Principle

FreshyCalls takes a fundamentally different approach from the opcode-scanning gates (Hell/Halo/Tartarus): it never reads stub bytes. Instead it exploits the fact that Windows assigns SSNs to Zw* functions in ascending order of their virtual address.

By collecting all Zw* function addresses from the Export Directory and sorting them, the position of each function in the sorted array gives its SSN directly — with no byte scanning, no pattern matching, and no sensitivity to hook bytes.


Algorithm (from source)

  1. Locate ntdll — PEB walk, same as other iterators.
  2. Collect Zw* exports — iterate the Export Directory. For each export, check the first two bytes of the name:
    if (*(USHORT*)FunctionName == 0x775a)   // 'Z'=0x5A, 'w'=0x77 → little-endian USHORT 0x775A
    
    If the prefix matches, store the function's hash, address, and SyscallAddress (found via SPT_DetectPadding).
  3. Sort by address — apply a bubble sort on the collected entries, ascending by Entries[i].Address.
  4. Index = SSN — after sorting, the entry at index 0 has SSN 0, index 1 has SSN 1, and so on.

Why address order = SSN order

Microsoft assigns SSNs to the native API in the same order as the function addresses appear in the loaded module. This is not documented but has been consistently observed across Windows versions. Sorting by address therefore recovers the correct SSN mapping without ever reading opcode bytes.


Sensitivity to hooks

Because FreshyCalls does not read the bytes of the stub, hooks do not interfere with SSN resolution — the bytes at the function start are entirely irrelevant to this algorithm.

However, SPT_DetectPadding is still called to locate the syscall/sysenter instruction offset within clean stubs. This is only needed for the indirect and random methods that JMP to the stub's syscall instruction. For the direct method, the SyscallAddress field is unused during execution.


When to use

  • Any environment where stub bytes may be unreliable or hooked.
  • When you want a simpler, hook-agnostic resolution approach.
  • A good choice for direct method generation where stub addresses are not needed at call time.
Copyright © 2026