SysWhispers4
AV/EDR evasion via direct and indirect system calls Windows NT 3.1 through Windows 11 24H2 · x64 · x86 · WoW64 · ARM64
Install / Use
/learn @JoasASantos/SysWhispers4README
SysWhispers4
AV/EDR evasion via direct and indirect system calls Windows NT 3.1 through Windows 11 24H2 · x64 · x86 · WoW64 · ARM64
SysWhispers4 is a Python-based syscall stub generator that produces C/ASM code for invoking NT kernel functions directly, bypassing user-mode hooks placed by AV/EDR products on ntdll.dll.
Built on the lineage of SysWhispers → SysWhispers2 → SysWhispers3, this version adds the most comprehensive set of SSN resolution strategies, invocation methods, and evasion capabilities to date.
Evolution: SysWhispers 1 → 4
Feature Comparison Matrix
| Feature | SW1 | SW2 | SW3 | SW4 |
|---|:-:|:-:|:-:|:-:|
| SSN Resolution | | | | |
| Static embedded table | ✅ | ✅ | ✅ | ✅ |
| Hell's Gate (runtime ntdll parse) | ❌ | ✅ | ✅ | ✅ |
| Halo's Gate (hook-neighbor scan) | ❌ | ❌ | ✅ | ✅ |
| Tartarus' Gate (near+far JMP) | ❌ | ❌ | Partial | ✅ |
| FreshyCalls (sort-by-VA) | ❌ | ❌ | ❌ | ✅ New |
| SyscallsFromDisk (clean ntdll from KnownDlls) | ❌ | ❌ | ❌ | ✅ New |
| RecycledGate (FreshyCalls + opcode validation) | ❌ | ❌ | ❌ | ✅ New |
| HW Breakpoint (DR registers + VEH) | ❌ | ❌ | ❌ | ✅ New |
| Static + dynamic fallback | ❌ | ❌ | ❌ | ✅ New |
| Invocation Methods | | | | |
| Embedded (direct syscall) | ✅ | ✅ | ✅ | ✅ |
| Indirect (jmp to ntdll gadget) | ❌ | ❌ | ✅ | ✅ |
| Randomized indirect (per-call entropy) | ❌ | ❌ | Partial† | ✅ Fixed |
| Egg hunt (no static 0F 05 on disk) | ❌ | ❌ | ✅ | ✅ |
| Architecture | | | | |
| x64 | ✅ | ✅ | ✅ | ✅ |
| x86 (32-bit sysenter) | ❌ | ❌ | ✅ | ✅ |
| WoW64 (Heaven's Gate) | ❌ | ❌ | ✅ | ✅ |
| ARM64 (SVC #0, w8) | ❌ | ❌ | ❌ | ✅ New |
| Compiler Support | | | | |
| MSVC (MASM) | ✅ | ✅ | ✅ | ✅ |
| MinGW / GCC (GAS inline) | ❌ | ❌ | ✅ | ✅ |
| Clang (GAS inline) | ❌ | ❌ | ✅ | ✅ |
| Evasion / Obfuscation | | | | |
| Function name hashing | ❌ | ✅ | ✅ | ✅ (DJB2) |
| Stub ordering randomization | ❌ | ❌ | ❌ | ✅ New |
| Junk instruction injection (14 variants) | ❌ | ❌ | ❌ | ✅ New |
| XOR-encrypted SSN at rest | ❌ | ❌ | ❌ | ✅ New |
| Gadget pool (up to 64 gadgets) | ❌ | ❌ | ❌ | ✅ New |
| Call stack spoof helper | ❌ | ❌ | ❌ | ✅ New |
| User-mode ETW bypass | ❌ | ❌ | ❌ | ✅ New |
| AMSI bypass | ❌ | ❌ | ❌ | ✅ New |
| ntdll unhooking (remap from KnownDlls) | ❌ | ❌ | ❌ | ✅ New |
| Anti-debugging (6 checks) | ❌ | ❌ | ❌ | ✅ New |
| Sleep encryption (Ekko-style) | ❌ | ❌ | ❌ | ✅ New |
| Syscall Table | | | | |
| Windows XP → Win10 20H2 | ✅ | ✅ | ✅ | ✅ |
| Windows 11 21H2–24H2 | ❌ | ❌ | Partial | ✅ Full |
| Windows Server 2022/2025 | ❌ | ❌ | ❌ | ✅ New |
| Auto-update from j00ru | ❌ | ❌ | ❌ | ✅ New |
| Tool | | | | |
| Supported NT functions | ~12 | ~12 | ~35 | 64 |
| Python version | 2/3 | 3 | 3 | 3.10+ |
| Type annotations | ❌ | ❌ | Partial | ✅ Full |
† SW3's randomized method had a register-corruption bug —
RDTSCoverwritesedx(arg2). SW4 correctly savesrdx → r11beforerdtscand restores it without touching the stack.
What's New in v4.1
New SSN Resolution Methods
SyscallsFromDisk (--resolve from_disk)
Maps a clean copy of ntdll from \KnownDlls\ntdll.dll and reads SSNs from the unhooked .text section. Completely bypasses all inline hooks — the EDR never sees the read.
// Flow: NtOpenSection → NtMapViewOfSection → read clean SSNs → NtUnmapViewOfSection
// SSNs come from the on-disk image, guaranteed hook-free
SW4_SyscallsFromDisk(pNtdll);
RecycledGate (--resolve recycled)
Combines the reliability of FreshyCalls (sort-by-VA) with opcode validation from Hell's Gate. For each function:
- Get candidate SSN from sorted position (FreshyCalls)
- If stub is clean, verify SSN matches opcode (double-check)
- If stub is hooked, trust the sorted-index SSN (hook-resistant)
The most resilient method available — even if hooks reorder stubs or modify opcodes, the VA-sort gives the correct SSN.
HW Breakpoint (--resolve hw_breakpoint)
Uses debug registers (DR0–DR3) and a Vectored Exception Handler (VEH) to extract SSNs without reading the (potentially hooked) function bytes:
- Set DR0 = address of
syscallinstruction in ntdll stub - Register VEH handler
- Call into the stub — VEH catches
EXCEPTION_SINGLE_STEP - At breakpoint, EAX contains the SSN — capture it
- Clear DR0, skip the syscall, continue
Works even when hooks redirect execution, because the breakpoint fires after mov eax, <SSN>.
New Evasion Techniques
AMSI Bypass (--amsi-bypass)
Patches amsi.dll!AmsiScanBuffer to return E_INVALIDARG, making AMSI think scan arguments are invalid. If amsi.dll isn't loaded, returns success (nothing to patch).
SW4_PatchAmsi(); // Call early, before any suspicious operations
ntdll Unhooking (--unhook-ntdll)
Maps a clean copy of ntdll from \KnownDlls\ and overwrites the hooked .text section with the clean bytes:
// 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
This completely removes all inline hooks from ntdll, making subsequent NT API calls go through original code paths.
Anti-Debugging (--anti-debug)
Performs 6 checks to detect debugger/analysis presence:
| Check | Technique | Detects |
|-------|-----------|---------|
| 1 | PEB.BeingDebugged | Standard debugger attachment |
| 2 | NtGlobalFlag (0x70) | Heap debug flags set by debuggers |
| 3 | RDTSC timing delta | Single-stepping / tracing |
| 4 | NtQueryInformationProcess(ProcessDebugPort) | Kernel debug port |
| 5 | Heap flags analysis | Debug heap indicators |
| 6 | Instrumentation callback detection | EDR instrumentation hooks |
if (!SW4_AntiDebugCheck()) {
// Debugger detected — bail out or take evasive action
ExitProcess(0);
}
Sleep Encryption (--sleep-encrypt)
Ekko-style memory encryption during sleep to evade periodic memory scanners:
- Generate random XOR key via
RDTSC - XOR-encrypt own
.textsection - Set waitable timer + queue APC to decrypt
- Sleep in alertable state
- Timer fires → APC decrypts
.text→ execution resumes
// Instead of Sleep(5000), use:
SW4_SleepEncrypt(5000); // .text is encrypted during the entire sleep
Defeats:
- Memory scanners during sleep (code is encrypted gibberish)
- Periodic module scans (signatures won't match)
- YARA/signature scans on in-memory PE
All Features (Existing + New)
SSN Resolution Methods (8 total)
| Method | Flag | Hook Resistance | Speed | Notes |
|--------|------|:-:|:-:|-------|
| Static | --resolve static | None | Fastest | Embedded j00ru table, no runtime parsing |
| Hell's Gate | --resolve hells_gate | Low | Fast | Reads opcode bytes — fails if hooked |
| Halo's Gate | --resolve halos_gate | Medium | Fast | Neighbor scan (±8 stubs) |
| Tartarus' Gate | --resolve tartarus | High | Fast | Detects E9/FF25/EB/CC hooks, ±16 neighbors |
| FreshyCalls | --resolve freshycalls | Very High | Medium | Sort by VA — doesn't read function bytes |
| SyscallsFromDisk | --resolve from_disk | Maximum | Slow | Maps clean ntdll from disk |
| RecycledGate | --resolve recycled | Maximum | Medium | FreshyCalls + opcode cross-validation |
| HW Breakpoint | --resolve hw_breakpoint | Maximum | Slow | DR registers + VEH |
Invocation Methods (4 total)
| Method | Flag | RIP in ntdll | Syscall on Disk | Random per Call |
|--------|------|:-:|:-:|:-:|
| Embedded | --method embedded | ❌ | ✅ | ❌ |
| Indirect | --method indirect | ✅ | ❌ | ❌ |
| Randomized | --method randomized | ✅ | ❌ | ✅ (64 gadgets) |
| Egg Hunt | --method egg | ❌ | ❌ | ❌ |
Evasion Options (8 total)
| Feature | Flag | Description |
|---------|------|-------------|
| Obfuscation | --obfuscate | Stub reordering + 14 junk instruction variants |
| SSN Encryption | --encrypt-ssn | XOR with random compile-time key |
| Stack Spoofing | --stack-spoof | Synthetic return address from ntdll |
| ETW Bypass | --etw-bypass | Patch EtwEventWrite to return ACCESS_DENIED |
| AMSI Bypass | --amsi-bypass | Patch AmsiScanBuffer to return E_INVALIDARG |
| ntdll Unhooking | --unhook-ntdll | Remap clean .text from \KnownDlls\ |
| Anti-Debug | --anti-debug | 6 detection checks (PEB, timing, heap, etc.) |
| Sleep Encryption | --sleep-encrypt | Ekko-style XOR .text during sleep |
Quick Start
git clone https://github.com/CyberSecurityUP/SysWhispers4
cd SysWhispers4
# Optional: update syscall table from j00ru (for --resolve static)
python scripts/update_syscall_table.py
# Common preset — FreshyCalls + direct syscall (recommended start)
python syswhispers.py --preset common
# Injection preset — indirect via Tartarus' Gate
python syswhispers.py --preset injection --method indirect --resolve tartarus
# 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
# Clean ntdll from disk — bypasses ALL hooks
python syswhispers.py --preset injection \
--method indirect --resolve from_disk \
--unhook-ntdll
# Hardware breakpoint SSN extraction
python syswhispers.py --functions NtAllocateVirtualMemory,NtCreateThreadEx \
--resolve hw_breakpoint
# Egg hunt (no syscall opcode on disk)
python syswhispers.py \
--functions NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx \
--method egg --resolve halos_gate
# ARM64 (Windows on ARM)
python syswhispers.py --preset common --arch arm64
# x86 / WoW64
python syswhispers.py --preset injection --ar
