Iterators

SysWhispers3

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

SysWhispers3

Origin: @klezVirus — 2022
Default method: random


Principle

SysWhispers3 extends SysWhispers2 with an additional SC_Address() helper function that locates the syscall; ret byte sequence within a stub — including by walking to a neighbouring stub if the target stub's syscall sequence is not at the expected offset.

The resolution list is assembled identically to SysWhispers2 (sort Zw* by address). The extension lies in the SC_Address() function and the use of the random method by default.


Algorithm (from source)

SPT_PopulateSyscallList

Identical to SysWhispers2:

  1. PEB walk → ntdll base.
  2. Filter Zw* exports, collect addresses.
  3. Bubble sort ascending by address.
  4. SPT_DetectPaddingSyscallAddress.

SC_Address(NtApiAddress)

This function locates a syscall; ret (or sysenter; ret on x86) gadget given a function address:

// x64 target bytes: syscall(0F 05) + ret(C3)
distance_to_syscall = 0x12;  // expected offset within a typical x64 stub

SyscallAddress = NtApiAddress + distance_to_syscall;
if (bytes_match(SyscallAddress, {0x0f, 0x05, 0xc3}))
    return SyscallAddress;

If not found at the expected offset, it walks neighbouring stubs:

for (num_jumps = 1; num_jumps < 512; num_jumps++) {
    // Try stub below (+num_jumps * 0x20 bytes)
    if (bytes_match(NtApiAddress + 0x12 + num_jumps * 0x20, syscall_code))
        return that address;
    // Try stub above (-num_jumps * 0x20 bytes)
    if (bytes_match(NtApiAddress + 0x12 - num_jumps * 0x20, syscall_code))
        return that address;
}

The step size of 0x20 bytes corresponds to the size of a typical ntdll stub body.


Random default

The default method for SysWhispers3 is random. The generated stub resolves the correct SSN, then jumps to the SyscallAddress of a randomly selected entry from the list (see Random method). This means the syscall instruction is executed from a different stub's location in ntdll on every call.


When to use

  • When you want random execution out of the box.
  • When you need the additional SC_Address-style neighbour lookup for syscall gadget resolution in heavily patched environments.
Copyright © 2026