Overview
Once the System Service Number (SSN) is resolved, SysWhispers4 needs to actually invoke the syscall. The invocation method determines how thesyscall instruction is executed and where the instruction pointer (RIP) appears to be during the call.
Different invocation methods offer tradeoffs between:
- Stealth - Avoiding detection by EDR/AV call stack analysis
- Simplicity - Code complexity and maintainability
- Performance - Execution overhead
- Flexibility - Runtime adaptability
--method flag to select an invocation method.
Method Comparison
| Method | Stealth | RIP Location | Speed | Complexity | Runtime Init |
|---|---|---|---|---|---|
| Embedded | ⭐ Low | Your stub | ⚡⚡⚡ Fastest | Low | No |
| Indirect | ⭐⭐ Medium | ntdll.dll | ⚡⚡ Fast | Low | Yes |
| Randomized | ⭐⭐⭐ High | Random in ntdll | ⚡⚡ Fast | Medium | Yes |
| Egg | ⭐⭐⭐ High | Your stub | ⚡ Medium (runtime patch) | High | Yes |
Recommended: Use
embedded for simplicity, indirect for better stealth, or randomized for maximum call stack evasion.Embedded (Default)
Description
The embedded method (also called direct syscall) places thesyscall instruction directly in your generated stub code. This is the most straightforward approach.
How It Works
- Generated assembly includes the
syscallinstruction - When you call
SW4_NtAllocateVirtualMemory(), execution flows:- Load SSN into
EAX - Move arguments into registers
- Execute
syscallinstruction in your stub - Kernel handles the syscall
- Return to your code
- Load SSN into
Usage
--method.
Generated Code (x64)
Call Stack
When EDR inspects the call stack during the syscall:Advantages
✅ Simplest implementation - Just execute the instruction✅ No runtime initialization - No need to call
SW4Initialize()✅ Fastest - No indirection overhead
✅ No ntdll dependency - Doesn’t need to find gadgets in ntdll
Disadvantages
❌ Obvious to EDR - RIP is in your module during syscall, not ntdll❌ Easy to detect - Stack trace shows non-ntdll address
❌ Signature-prone - Syscall instruction in your binary is suspicious
When to Use
- You need maximum performance
- You’re not concerned about call stack analysis
- You want the simplest implementation
- You’re testing or prototyping
Detection Risk
EDRs can detect direct syscalls by:- Call stack analysis - RIP not in ntdll during syscall
- Binary scanning -
syscallinstruction found in non-ntdll module - Behavioral analysis - Non-ntdll code calling kernel
Indirect
Description
The indirect method jumps to asyscall; ret gadget inside ntdll.dll. This makes the instruction pointer (RIP) appear to be in ntdll during the syscall, mimicking normal behavior.
How It Works
- At initialization (
SW4Initialize()), scan ntdll.dll for asyscall; retgadget (opcodes:0F 05 C3) - Store the address of this gadget
- When calling a syscall:
- Load SSN into
EAX - Move arguments into registers
- Jump to the gadget in ntdll
- ntdll executes
syscall; ret - Return to your code
- Load SSN into
Usage
Generated Code (x64)
Call Stack
When EDR inspects the call stack during the syscall:Advantages
✅ Better stealth - RIP appears in ntdll, mimicking normal calls✅ Evades basic call stack checks - Looks like normal ntdll behavior
✅ No syscall instruction in your binary - Harder to detect via scanning
✅ Still fast - Single indirect jump
Disadvantages
⚠️ Requires initialization - Must callSW4Initialize() to find gadget⚠️ Scanning ntdll - Finding the gadget may trigger EDR heuristics
⚠️ Predictable RIP - Always the same gadget address (can be fingerprinted)
When to Use
- You need better stealth than embedded
- You’re okay with runtime initialization
- You want a good balance of stealth and performance
- Recommended for most red team engagements
Finding the Gadget
Randomized
Description
The randomized method is an enhancement of indirect that uses a different random syscall gadget for each call. This prevents EDRs from fingerprinting your syscalls by gadget address.How It Works
- At initialization (
SW4Initialize()), scan ntdll.dll and collect multiplesyscall; retgadgets - Store all gadget addresses in an array
- When calling a syscall:
- Load SSN into
EAX - Move arguments into registers
- Select a random gadget from the array
- Jump to the random gadget
- Return to your code
- Load SSN into
Usage
Generated Code (x64)
Call Stack
When EDR inspects the call stack during the syscall:Advantages
✅✅ Maximum call stack evasion - RIP location varies, hard to fingerprint✅ Anti-profiling - EDR can’t build a consistent signature
✅ Still appears in ntdll - Maintains the illusion of normal behavior
✅ Harder to detect - No consistent pattern
Disadvantages
⚠️ More complex - Needs gadget management and random selection⚠️ Slightly slower - Additional function call to get random gadget
⚠️ More initialization overhead - Must collect multiple gadgets
When to Use
- You need maximum stealth
- You’re evading advanced EDR with call stack profiling
- You want to prevent signature-based detection
- Recommended for stealth configurations
Example Configuration
Gadget Collection
Egg
Description
The egg method embeds an 8-byte “egg” marker (e.g.,0x4141414141414141) in place of the syscall instruction at generation time. At runtime, your code searches for these eggs and patches them with the actual syscall instruction.
How It Works
- Generated stubs contain an egg marker instead of
syscall: - At runtime, call
SW4HatchEggs():- Scan your module’s .text section for egg markers
- Replace each egg with
0x0F05C3(syscall; ret; nop; nop; nop…) - Change memory protection as needed
- After hatching, syscalls work like embedded method
Usage
Generated Code (x64)
Runtime Initialization
Advantages
✅✅ No static syscall instruction - Binary doesn’t contain0x0F05 at rest✅ Evades static scanning - AV/EDR can’t find syscall bytes in your binary
✅ Dynamic patching - Syscalls only “appear” at runtime
✅ Good for obfuscation - Combined with other techniques, very stealthy
Disadvantages
❌ Complex initialization - Must scan and patch memory❌ Memory protection changes -
VirtualProtect() may trigger EDR❌ Slower startup - Scanning and patching takes time
❌ RIP still in your module - Same call stack detection risk as embedded
When to Use
- You need to evade static binary analysis
- You’re combining with other obfuscation techniques
- You’re willing to trade initialization complexity for static stealth
- Your threat model includes AV signature scanning
Egg Hatching Implementation
Custom Egg Marker
You can customize the egg marker in generated code to avoid signature detection:Combining Invocation and Resolution
Compatibility Matrix
| Resolution Method | Embedded | Indirect | Randomized | Egg |
|---|---|---|---|---|
| Static | ✅ | ✅ | ✅ | ✅ |
| FreshyCalls | ✅ | ✅ | ✅ | ✅ |
| Hell’s Gate | ✅ | ✅ | ✅ | ✅ |
| Halo’s Gate | ✅ | ✅ | ✅ | ✅ |
| Tartarus’ Gate | ✅ | ✅ | ✅ | ✅ |
| From Disk | ✅ | ✅ | ✅ | ✅ |
| RecycledGate | ✅ | ✅ | ✅ | ✅ |
| HW Breakpoint | ✅ | ✅ | ✅ | ✅ |
Recommended Combinations
General Use:Performance Comparison
Benchmark (1000 syscalls)
| Method | Avg Time (µs) | Overhead vs Embedded | Initialization |
|---|---|---|---|
| Embedded | 1.2 | 0% (baseline) | None |
| Indirect | 1.5 | +25% | ~5ms (one-time) |
| Randomized | 1.8 | +50% | ~15ms (one-time) |
| Egg | 1.2 + 200* | +0% + hatch time | ~50ms (one-time) |
Detection Evasion Summary
Call Stack Analysis
| Method | RIP Location | EDR Detection Risk |
|---|---|---|
| Embedded | Your .exe | ⚠️ High - Obvious anomaly |
| Indirect | ntdll.dll (fixed) | ⭐ Medium - Looks normal but predictable |
| Randomized | ntdll.dll (varies) | ⭐⭐⭐ Low - Unpredictable, hard to profile |
| Egg | Your .exe | ⚠️ High - Same as embedded after hatching |
Binary Scanning
| Method | Static Syscall Bytes | Signature Risk |
|---|---|---|
| Embedded | ✅ Yes (0x0F 0x05) | ⚠️ High |
| Indirect | ❌ No | ⭐⭐ Low |
| Randomized | ❌ No | ⭐⭐ Low |
| Egg | ❌ No (at rest) | ⭐⭐⭐ Very Low |
Choosing the Right Method
Decision Tree
Quick Recommendations
| Scenario | Recommended Method | Reason |
|---|---|---|
| Prototyping | embedded | Simplest, fastest |
| Red team (general) | indirect | Good stealth/performance balance |
| Advanced EDR | randomized | Anti-profiling |
| Static detection | egg | No syscall bytes at rest |
| Maximum stealth | randomized + recycled + --obfuscate | All techniques combined |
Example Configurations
Development/Testing
Production Red Team
Maximum Evasion
Evade AV Scanning
See Also
- Command Reference - All CLI flags
- SSN Resolution Methods - How SSNs are resolved
- Evasion Options - Additional evasion techniques
- Configuration Guide - Choosing the right options
