SysWhispers4

repository·main·Indexed 19 days ago

https://github.com/joasasantos/syswhispers4

A Python-based syscall stub generator that produces C/ASM code for invoking NT kernel functions directly. It is designed to bypass user-mode hooks placed by AV/EDR products on ntdll.dll through various SSN resolution methods (such as FreshyCalls, Halo's Gate, and Tartarus' Gate) and invocation methods (including Indirect, Randomized, and Egg Hunt). The tool includes evasion features such as stack spoofing, ETW/AMSI bypass, ntdll unhooking, anti-debugging checks, and Ekko-style sleep encryption.

Tokens
3.9K
Snippets
9
Records
18
Agent score
19%

What's inside SysWhispers4

  1. Understand Syscall Invocation Methods

    main

    SysWhispers4 supports different ways to execute the actual syscall instruction to evade detection:

    • Embedded (Direct Syscall): The syscall instruction is located within your own stub. At kernel entry, the Instruction Pointer (RIP) points to your PE, which can be detected by EDRs.
    • Indirect: The stub jumps to a syscall;ret gadget located inside ntdll.dll. At kernel entry, RIP appears to be inside ntdll, mimicking a legitimate API call.
    • Randomized Indirect: Similar to Indirect, but selects a random gadget from a pool of up to 64 gadgets in ntdll on every call using RDTSC for entropy. This defeats EDR heuristics that whitelist specific gadget addresses.
    • Egg Hunt: The stubs contain an 8-byte random marker instead of a syscall opcode. At startup, SW4_HatchEggs() scans the .text section and replaces these markers with the actual 0F 05 opcode. This ensures no syscall opcode exists in the binary on disk.
  2. Use SysWhispers4 presets for common tasks

    main

    SysWhispers4 provides predefined function sets called presets to simplify common security research tasks. Instead of selecting individual functions, you can use a preset name to include a specific group of NT functions in your generated code.

    Available presets:

    • common: General process, thread, and memory operations.
    • injection: Shellcode injection, APC injection, and section mapping.
    • evasion: AV/EDR evasion, process querying, and memory manipulation.
    • token: Token manipulation, impersonation, and privilege escalation.
    • stealth: Maximum evasion (includes injection + evasion + unhooking support).
    • file_ops: File I/O via NT syscalls.
    • transaction: Process doppelganging and transaction rollback.
    • all: Every supported function (64 total).
    # Example: Using the 'common' preset
    python syswhispers.py --preset common
  3. How Sleep Encryption works

    main

    The --sleep-encrypt option implements Ekko-style memory encryption to evade periodic memory scanners.

    1. A random XOR key is generated via RDTSC.
    2. The .text section is XOR-encrypted.
    3. A waitable timer and an APC are queued.
    4. The thread sleeps in an alertable state.
    5. When the timer fires, the APC decrypts the .text section, and execution resumes.

    This prevents memory scanners from finding signatures or seeing plain-text code while the thread is sleeping.

  4. Understand SSN Resolution Methods

    main

    SysWhispers4 provides several ways to resolve System Service Numbers (SSNs) to bypass EDR hooks:

    • Static: Uses a bundled table from j00ru at generation time. No runtime parsing. Fast but easily detected as a signature.
    • FreshyCalls (Default): Sorts Nt* exports from ntdll by virtual address. The index in the sorted list is the SSN. Works even if all Nt* stubs are hooked because it only reads Virtual Addresses (VAs).
    • Hell's Gate: Reads the mov eax, <SSN> opcode directly from the ntdll stub. Fails if the stub is hooked.
    • Halo's Gate: If a stub is hooked, it scans neighboring stubs ($\pm 8$) in the sorted export list to infer the SSN via offset arithmetic.
    • Tartarus' Gate: An advanced version of Halo's Gate that scans up to 16 neighbors to detect various EDR hook patterns (JMP, CALL, INT3, etc.).
    • SyscallsFromDisk: Maps a clean copy of ntdll.dll from \KnownDlls\ and reads SSNs from the pristine .text section, bypassing all hooks in the current process.
    • RecycledGate: A resilient combination of FreshyCalls and Hell's Gate. It uses VA-sorting as primary and validates via opcode cross-check, falling back to VA-sorting if hooks are detected.
    • HW Breakpoint: Uses CPU debug registers (DR0–DR3) to set hardware breakpoints on syscall instructions. A Vectored Exception Handler (VEH) catches the breakpoint and reads the SSN from EAX.
  5. How ntdll unhooking works

    main

    The --unhook-ntdll option maps a clean copy of ntdll.dll from \KnownDlls\ and overwrites the hooked .text section of the currently loaded ntdll.dll with the clean bytes. This removes all inline hooks, allowing subsequent NT API calls to proceed through original code paths.

    For best results, call the unhooking function before initializing SysWhispers4 stubs.

    // Call BEFORE SW4_Initialize() for best results
    SW4_UnhookNtdll();     // Remove ALL inline hooks from ntdll
    SW4_Initialize();       // Now FreshyCalls/Hell's Gate reads clean stubs
  6. How Anti-Debugging checks work

    main

    The --anti-debug option performs 6 distinct checks to detect the presence of debuggers or analysis tools:

    1. PEB.BeingDebugged: Detects standard debugger attachment.
    2. NtGlobalFlag (0x70): Detects heap debug flags set by debuggers.
    3. RDTSC timing delta: Detects single-stepping or tracing.
    4. NtQueryInformationProcess(ProcessDebugPort): Detects kernel debug ports.
    5. Heap flags analysis: Detects debug heap indicators.
    6. Instrumentation callback detection: Detects EDR instrumentation hooks.
    if (!SW4_AntiDebugCheck()) {
        // Debugger detected — bail out or take evasive action
        ExitProcess(0);
    }
  7. Integrate SysWhispers4 into a MinGW/Clang Project

    main

    For MinGW or Clang environments, compile the source files using the following command structure:

    x86_64-w64-mingw32-gcc -masm=intel \
        example.c SW4Syscalls.c SW4Syscalls_stubs.c \
        -o example.exe -lntdll
    x86_64-w64-mingw32-gcc -masm=intel \
        example.c SW4Syscalls.c SW4Syscalls_stubs.c \
        -o example.exe -lntdll
  8. Integrate SysWhispers4 into an MSVC Project

    main

    To use the generated files in a Visual Studio (MSVC) project:

    1. Add the four generated files (SW4Syscalls_Types.h, SW4Syscalls.h, SW4Syscalls.c, and SW4Syscalls.asm) to your project.
    2. Enable MASM: Right-click your project $\rightarrow$ Build Customizations $\rightarrow$ check masm (.targets).
    3. Initialize the library at application startup following this sequence:
    #include "SW4Syscalls.h"
    
    int main(void) {
        // 1. Optional: Unhook ntdll before initialization
        SW4_UnhookNtdll();
    
        // 2. Required: Resolve SSNs
        if (!SW4_Initialize()) return 1;
    
        // 3. Optional: Apply evasion patches
        SW4_PatchEtw();    // Suppress user-mode ETW
        SW4_PatchAmsi();   // Bypass AMSI
    
        // 4. Optional: Anti-debug check
        if (!SW4_AntiDebugCheck()) {
            return 0; // Debugger detected
        }
    
        // 5. Use NT functions directly via syscalls
        PVOID base = NULL;
        SIZE_T size = 0x1000;
        NTSTATUS st = SW4_NtAllocateVirtualMemory(
            GetCurrentProcess(), &base, 0, &size,
            MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE
        );
    
        return NT_SUCCESS(st) ? 0 : 1;
    }
    #include "SW4Syscalls.h"
    
    int main(void) {
        SW4_UnhookNtdll();
    
        if (!SW4_Initialize()) return 1;
    
        SW4_PatchEtw();
        SW4_PatchAmsi();
    
        if (!SW4_AntiDebugCheck()) {
            return 0;
        }
    
        PVOID base = NULL;
        SIZE_T size = 0x1000;
        NTSTATUS st = SW4_NtAllocateVirtualMemory(
            GetCurrentProcess(), &base, 0, &size,
            MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE
        );
    
        return NT_SUCCESS(st) ? 0 : 1;
    }
  9. Update the syscall table from j00ru

    main

    To ensure the generator uses the most recent System Service Numbers (SSNs) for various Windows builds, you can run the update script. This fetches the latest data from the j00ru/windows-syscalls repository.

    This is particularly useful when using the --resolve static flag to ensure accuracy across Windows 7 through Windows 11 24H2.

    python scripts/update_syscall_table.py
  10. Quick Start with SysWhispers4

    main

    SysWhispers4 is a Python-based generator that produces C/ASM code for direct or indirect NT kernel function invocation to bypass AV/EDR hooks.

    To use the tool, clone the repository and run the syswhispers.py script with your desired configuration. You can use presets for common use cases or specify individual flags for fine-grained control over SSN resolution, invocation methods, and evasion techniques.

    git clone https://github.com/CyberSecurityUP/SysWhispers4
    cd SysWhispers4
    
    # Common preset — FreshyCalls + direct syscall (recommended start)
    python syswhispers.py --preset common
    
    # Maximum evasion: all techniques combined
    python syswhispers.py --preset stealth \
        --method randomized --resolve recycled \
        --obfuscate --encrypt-ssn --stack-spoof \
        --etw-bypass --amsi-bypass --unhook-ntdll \
        --anti-debug --sleep-encrypt
  11. List Supported NT Functions

    main

    SysWhispers4 supports 64 specific NT functions across several categories (Memory, Process, Thread, File, etc.). To see the full list of supported functions, run:

    python syswhispers.py --list-functions
    python syswhispers.py --list-functions
  12. Compare EDR Detection Vectors for Invocation Methods

    main

    Use this matrix to choose the best combination of invocation and resolution methods based on your threat model:

    Detection VectorEmbeddedIndirectRandomizedEgg
    User-mode hook bypass
    RIP inside ntdll at syscall
    No 0F 05 in binary on disk✅¹
    Random gadget per call
    Clean call stackwith --stack-spoofwith --stack-spoofwith --stack-spoofwith --stack-spoof
    Memory scan evasion during sleepwith --sleep-encryptwith --sleep-encryptwith --sleep-encryptwith --sleep-encrypt

    ¹ Note: With 'Embedded', the syscall opcode is in your PE's .text section, not ntdll.

    Important Note on ETW-Ti: The Microsoft-Windows-Threat-Intelligence (ETW-Ti) provider fires inside the kernel. No user-mode technique can bypass it without kernel-mode access.