Iterators
Iterators
An iterator is the technique used to resolve the correct Syscall Service Number (SSN) for each Nt* function at runtime — without relying on the hooked stubs inside ntdll.dll.
All 7 iterators are fully documented and battle-tested techniques from the offensive security community. Sysplant packages them as plug-in components so you can swap techniques without rewriting your project.
Comparison table
| Name | Origin / Year | Technique | Default method |
|---|---|---|---|
hell | Hell's Gate — @RtlMateusz / @am0nsec (2020) | Reads SSN from ntdll in-memory stubs | direct |
halo | Halo's Gate — @Sektor7net (2021) | Walks neighbouring stubs when the target is hooked | direct |
tartarus | Tartarus' Gate — @trickster0 (2021) | Deeper neighbour-traversal variant of Halo | direct |
freshy | FreshyCalls — @crummie5 (2020) | Collects Zw* exports, sorts by address, index = SSN | direct |
syswhispers | SysWhispers2 — @Jackson_T (2021) | Sorts Zw* exports by address; lowest addr = SSN 0 | indirect |
syswhispers3 | SysWhispers3 — @klezVirus (2022) | SysWhispers2 + random-jump SC_Address variant | random |
canterlot | Canterlot's Gate — @MDSecLabs / @0x42en (2022) | PE RUNTIME_FUNCTION exception table, ordered by BeginAddress | random |
Iterator details
hell — Hell's Gate
The original gate technique (2020). At runtime, the stub reads its own first bytes from the in-memory ntdll export to extract the mov eax, SSN instruction and derive the SSN directly.
Limitation: If ntdll is hooked (the stub's first bytes have been replaced by a jmp), Hell's Gate cannot recover the SSN.
halo — Halo's Gate
Halo's Gate extends Hell's Gate: when the target stub is hooked, it walks neighbouring Zw* stubs (±1, ±2, …) whose addresses are still intact, and computes the missing SSN from the known offset.
Good for: environments where a few common functions are hooked but most are still clean.
tartarus — Tartarus' Gate
A deeper variant of Halo's Gate that performs more aggressive neighbour traversal, making it resilient against scenarios where multiple adjacent stubs are hooked.
freshy — FreshyCalls
FreshyCalls filters all Zw* exports from the in-memory ntdll, sorts them by function address in ascending order, and assigns SSNs by array index. It never reads stub opcodes, making it resilient against any in-process hooking of the stubs themselves.
syswhispers — SysWhispers2
Enumerates all Zw* exports from the in-memory ntdll, sorts them by virtual address, and assigns SSNs ascending from 0 (the lowest address gets SSN 0, matching Windows's internal ordering). Works without reading from potentially hooked stubs.
Default method: indirect — jumps into the real ntdll stub past the hook.
syswhispers3 — SysWhispers3
Extends SysWhispers2 with two additional execution variants: an egg-hunter (8-byte marker patched at runtime by SPT_SanitizeSyscalls()) and a random-stub jump. This makes the syscall return address appear to be inside ntdll, defeating stack-based EDR telemetry.
Default method: random.
canterlot — Canterlot's Gate
The most recently developed iterator. It parses the IMAGE_DIRECTORY_ENTRY_EXCEPTION table of the in-memory ntdll to obtain RuntimeFunctions sorted by BeginAddress, cross-references export names to find Zw* entries, and counts matches to assign SSNs — without relying on stub opcodes. Recommended for modern environments.
Default method: random.
Which iterator should I use?
- Start with
canterlot— it is the most robust and usesrandomexecution by default. - Use
syswhispers3as an alternative when you need the egg-hunter variant. - Use
hellorhalofor legacy compatibility or when environment constraints prevent runtime table parsing. - Use
custommode to pick any iterator + method combination explicitly.