> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/JoasASantos/SysWhispers4/llms.txt
> Use this file to discover all available pages before exploring further.

# Invocation Methods

> Detailed documentation of syscall invocation techniques

## Overview

Once the **System Service Number (SSN)** is resolved, SysWhispers4 needs to actually **invoke** the syscall. The invocation method determines how the `syscall` 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

Use the `--method` flag to select an invocation method.

## Method Comparison

| Method                        | Stealth   | RIP Location    | Speed                    | Complexity | Runtime Init |
| ----------------------------- | --------- | --------------- | ------------------------ | ---------- | ------------ |
| [Embedded](#embedded-default) | ⭐ Low     | Your stub       | ⚡⚡⚡ Fastest              | Low        | No           |
| [Indirect](#indirect)         | ⭐⭐ Medium | ntdll.dll       | ⚡⚡ Fast                  | Low        | Yes          |
| [Randomized](#randomized)     | ⭐⭐⭐ High  | Random in ntdll | ⚡⚡ Fast                  | Medium     | Yes          |
| [Egg](#egg)                   | ⭐⭐⭐ High  | Your stub       | ⚡ Medium (runtime patch) | High       | Yes          |

<Note>
  **Recommended:** Use `embedded` for simplicity, `indirect` for better stealth, or `randomized` for maximum call stack evasion.
</Note>

***

## Embedded (Default)

### Description

The **embedded** method (also called **direct syscall**) places the `syscall` instruction directly in your generated stub code. This is the most straightforward approach.

### How It Works

1. Generated assembly includes the `syscall` instruction
2. When you call `SW4_NtAllocateVirtualMemory()`, execution flows:
   * Load SSN into `EAX`
   * Move arguments into registers
   * Execute `syscall` instruction **in your stub**
   * Kernel handles the syscall
   * Return to your code

### Usage

```bash theme={null}
python syswhispers.py --preset common --method embedded
```

This is the **default** if you don't specify `--method`.

### Generated Code (x64)

```asm theme={null}
SW4_NtAllocateVirtualMemory PROC
    mov r10, rcx              ; Save RCX (1st arg) to R10
    mov eax, 00000018h        ; SSN = 0x18
    syscall                   ; Execute syscall HERE
    ret
SW4_NtAllocateVirtualMemory ENDP
```

### Call Stack

When EDR inspects the call stack during the syscall:

```
[kernel32.dll] BaseThreadInitThunk
[Your.exe] main
[Your.exe] SW4_NtAllocateVirtualMemory  <-- RIP is HERE (suspicious!)
[ntoskrnl.exe] NtAllocateVirtualMemory
```

### 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:

1. **Call stack analysis** - RIP not in ntdll during syscall
2. **Binary scanning** - `syscall` instruction found in non-ntdll module
3. **Behavioral analysis** - Non-ntdll code calling kernel

***

## Indirect

### Description

The **indirect** method jumps to a `syscall; 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

1. At initialization (`SW4Initialize()`), scan ntdll.dll for a `syscall; ret` gadget (opcodes: `0F 05 C3`)
2. Store the address of this gadget
3. 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

### Usage

```bash theme={null}
python syswhispers.py --preset common --method indirect
```

### Generated Code (x64)

```asm theme={null}
SW4_NtAllocateVirtualMemory PROC
    mov r10, rcx              ; Save RCX (1st arg) to R10
    mov eax, 00000018h        ; SSN = 0x18
    jmp qword ptr [g_SyscallGadget]  ; Jump to ntdll gadget
SW4_NtAllocateVirtualMemory ENDP

; Initialization finds this gadget in ntdll:
; ntdll.dll+0x12345:
;   syscall
;   ret
```

### Call Stack

When EDR inspects the call stack during the syscall:

```
[kernel32.dll] BaseThreadInitThunk
[Your.exe] main
[Your.exe] SW4_NtAllocateVirtualMemory
[ntdll.dll] <gadget address>  <-- RIP is in ntdll (looks normal!)
[ntoskrnl.exe] NtAllocateVirtualMemory
```

### 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 call `SW4Initialize()` 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

```c theme={null}
void SW4Initialize() {
    HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
    BYTE* p = (BYTE*)hNtdll;
    SIZE_T size = GetModuleSize(hNtdll);
    
    // Scan for opcodes: 0F 05 C3 (syscall; ret)
    for (SIZE_T i = 0; i < size - 3; i++) {
        if (p[i] == 0x0F && p[i+1] == 0x05 && p[i+2] == 0xC3) {
            g_SyscallGadget = (PVOID)(p + i);
            return;
        }
    }
}
```

***

## 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

1. At initialization (`SW4Initialize()`), scan ntdll.dll and collect **multiple** `syscall; ret` gadgets
2. Store all gadget addresses in an array
3. 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

### Usage

```bash theme={null}
python syswhispers.py --preset common --method randomized
```

### Generated Code (x64)

```asm theme={null}
SW4_NtAllocateVirtualMemory PROC
    mov r10, rcx                    ; Save RCX (1st arg) to R10
    mov eax, 00000018h              ; SSN = 0x18
    call SW4_GetRandomSyscallGadget ; Get random gadget address
    jmp rax                         ; Jump to random gadget
SW4_NtAllocateVirtualMemory ENDP
```

### Call Stack

When EDR inspects the call stack during the syscall:

```
[kernel32.dll] BaseThreadInitThunk
[Your.exe] main
[Your.exe] SW4_NtAllocateVirtualMemory
[ntdll.dll] <random gadget address>  <-- RIP varies each call!
[ntoskrnl.exe] NtAllocateVirtualMemory
```

### 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

```bash theme={null}
python syswhispers.py --preset stealth \
  --method randomized \
  --resolve recycled \
  --obfuscate
```

### Gadget Collection

```c theme={null}
#define MAX_GADGETS 256
PVOID g_SyscallGadgets[MAX_GADGETS];
DWORD g_GadgetCount = 0;

void SW4Initialize() {
    HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
    BYTE* p = (BYTE*)hNtdll;
    SIZE_T size = GetModuleSize(hNtdll);
    
    // Scan for all syscall; ret gadgets
    for (SIZE_T i = 0; i < size - 3 && g_GadgetCount < MAX_GADGETS; i++) {
        if (p[i] == 0x0F && p[i+1] == 0x05 && p[i+2] == 0xC3) {
            g_SyscallGadgets[g_GadgetCount++] = (PVOID)(p + i);
        }
    }
}

PVOID SW4_GetRandomSyscallGadget() {
    DWORD index = (rand() * GetTickCount64()) % g_GadgetCount;
    return g_SyscallGadgets[index];
}
```

***

## 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

1. Generated stubs contain an egg marker instead of `syscall`:
   ```asm theme={null}
   mov eax, 0x18
   dq 0x4141414141414141  ; Egg marker (8 bytes)
   ret
   ```
2. 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
3. After hatching, syscalls work like embedded method

### Usage

```bash theme={null}
python syswhispers.py --preset common --method egg
```

### Generated Code (x64)

```asm theme={null}
SW4_NtAllocateVirtualMemory PROC
    mov r10, rcx              ; Save RCX (1st arg) to R10
    mov eax, 00000018h        ; SSN = 0x18
    dq 4141414141414141h      ; Egg marker (will be replaced with syscall)
    ret
SW4_NtAllocateVirtualMemory ENDP
```

### Runtime Initialization

```c theme={null}
int main() {
    // CRITICAL: Hatch eggs before calling any syscalls
    if (!SW4HatchEggs()) {
        printf("Failed to hatch eggs!\n");
        return 1;
    }
    
    // Now syscalls work
    SW4_NtAllocateVirtualMemory(...);
}
```

### Advantages

✅✅ **No static syscall instruction** - Binary doesn't contain `0x0F05` 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

```c theme={null}
#define EGG_MARKER 0x4141414141414141ULL

BOOL SW4HatchEggs() {
    PVOID pBase = GetModuleHandleA(NULL);  // Your executable
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBase;
    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((BYTE*)pBase + pDos->e_lfanew);
    
    // Find .text section
    PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNt);
    for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++, pSection++) {
        if (strcmp((char*)pSection->Name, ".text") == 0) {
            BYTE* pText = (BYTE*)pBase + pSection->VirtualAddress;
            SIZE_T size = pSection->Misc.VirtualSize;
            
            // Make .text writable
            DWORD oldProtect;
            VirtualProtect(pText, size, PAGE_EXECUTE_READWRITE, &oldProtect);
            
            // Scan for eggs and replace with syscall
            for (SIZE_T j = 0; j < size - 8; j++) {
                ULONGLONG* p = (ULONGLONG*)(pText + j);
                if (*p == EGG_MARKER) {
                    // Replace with: syscall; ret; nop; nop; nop; nop; nop
                    pText[j+0] = 0x0F;  // syscall
                    pText[j+1] = 0x05;
                    pText[j+2] = 0xC3;  // ret
                    pText[j+3] = 0x90;  // nop (padding)
                    pText[j+4] = 0x90;
                    pText[j+5] = 0x90;
                    pText[j+6] = 0x90;
                    pText[j+7] = 0x90;
                }
            }
            
            // Restore original protection
            VirtualProtect(pText, size, oldProtect, &oldProtect);
            return TRUE;
        }
    }
    return FALSE;
}
```

### Custom Egg Marker

You can customize the egg marker in generated code to avoid signature detection:

```c theme={null}
// In generator templates
#define SW4_EGG_MARKER 0xDEADBEEFCAFEBABEULL  // Custom marker
```

***

## 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     | ✅        | ✅        | ✅          | ✅   |

All combinations are supported! Choose based on your requirements.

### Recommended Combinations

**General Use:**

```bash theme={null}
python syswhispers.py --preset common \
  --resolve freshycalls \
  --method embedded
```

**Better Stealth:**

```bash theme={null}
python syswhispers.py --preset injection \
  --resolve freshycalls \
  --method indirect
```

**Maximum Stealth:**

```bash theme={null}
python syswhispers.py --preset stealth \
  --resolve recycled \
  --method randomized \
  --obfuscate
```

**Evade Static Analysis:**

```bash theme={null}
python syswhispers.py --preset stealth \
  --resolve from_disk \
  --method egg \
  --obfuscate
```

***

## 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) |

\*Egg method has a one-time patching overhead (\~200ms) but then performs like embedded.

***

## 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

```
Do you need to evade static binary analysis?
├─ Yes → `egg` (no static syscall bytes)
└─ No ↓

Do you need to evade call stack analysis?
├─ Yes ↓
│   ├─ Maximum stealth? → `randomized`
│   └─ Good balance? → `indirect`
└─ No ↓

Do you prioritize simplicity and speed?
└─ Yes → `embedded` (default)
```

### 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

```bash theme={null}
python syswhispers.py --preset common --method embedded
```

### Production Red Team

```bash theme={null}
python syswhispers.py --preset injection \
  --method indirect \
  --resolve freshycalls
```

### Maximum Evasion

```bash theme={null}
python syswhispers.py --preset stealth \
  --method randomized \
  --resolve recycled \
  --obfuscate \
  --encrypt-ssn \
  --stack-spoof
```

### Evade AV Scanning

```bash theme={null}
python syswhispers.py --preset stealth \
  --method egg \
  --resolve from_disk \
  --obfuscate
```

## See Also

* [Command Reference](/cli/command-reference) - All CLI flags
* [SSN Resolution Methods](/cli/ssn-resolution-methods) - How SSNs are resolved
* [Evasion Options](/cli/evasion-options) - Additional evasion techniques
* [Configuration Guide](/guides/basic-usage) - Choosing the right options
