← maldev README · docs/index
The win/syscall package composes three orthogonal concerns
behind a single *Caller. Operators tune each axis independently;
downstream packages (inject/*, evasion/*, c2/shell) accept a
*Caller and inherit the chosen posture without recompiling.
flowchart LR
subgraph callsite [Call site<br>e.g. inject.RemoteThread]
C["*wsyscall.Caller"]
end
subgraph axis1 [1. Calling method<br>HOW the syscall fires]
A1["MethodWinAPI / NativeAPI / Direct /<br>Indirect / IndirectAsm"]
end
subgraph axis2 [2. SSN resolver<br>WHERE the syscall number comes from]
A2["HellsGate / HalosGate / Tartarus /<br>HashGate / Chain"]
end
subgraph axis3 [3. API hashing<br>HOW the symbol is found without a string]
A3["ROR13 / FNV / Jenkins / custom HashFunc"]
end
C --> A1
C --> A2
A2 --> A3
The three axes answer different questions:
Axis Question it answers Pages
1 — Calling method How does the implant issue the syscall once the SSN is known? Which userland boundary do we cross / skip? direct-indirect.md
2 — SSN resolver Where does the SSN come from? What happens when the canonical source (the unhooked ntdll prologue) is unavailable? ssn-resolvers.md
3 — API hashing How do we identify the right Nt* export without a plaintext name in the binary? api-hashing.md
Tuning one axis does NOT imply tuning the others. You can:
pick MethodIndirect (axis 1) with HellsGate (axis 2) — no api-hashing.
pick MethodWinAPI (axis 1) with HashGate (axis 2 — uses axis 3 internally).
swap the hash function on HashGate (axis 3) without touching axis 1 / 2.
graph TD
subgraph "Consumer Packages"
INJ[inject/]
EVA[evasion/]
C2[c2/shell]
end
subgraph "win/syscall"
CALLER["*Caller"]
CALLER -->|method| WINAPI[MethodWinAPI]
CALLER -->|method| NATIVE[MethodNativeAPI]
CALLER -->|method| DIRECT[MethodDirect]
CALLER -->|method| INDIRECT[MethodIndirect]
CALLER -->|resolver| HG[HellsGate]
CALLER -->|resolver| HAG[HalosGate]
CALLER -->|resolver| TG[TartarusGate]
CALLER -->|resolver| HGR[HashGate]
CALLER -->|resolver| CH[Chain]
end
subgraph "win/api"
PEB["PEB Walk"]
HASH["API Hashing"]
RESOLVE["ResolveByHash"]
end
INJ -->|"*Caller (nil = WinAPI)"| CALLER
EVA -->|"*Caller (nil = WinAPI)"| CALLER
C2 -->|"*Caller (nil = WinAPI)"| CALLER
HGR --> PEB
HGR --> HASH
RESOLVE --> PEB
RESOLVE --> HASH
Method Hook Bypass Stack Clean Memory Clean Stealth
WinAPI None N/A N/A Lowest
NativeAPI kernel32 N/A N/A Low
Direct All userland No No Medium
Indirect All userland Yes Yes High (heap stub, RW↔RX cycle)
IndirectAsm All userland Yes Yes Highest (Go-asm stub, no writable code)
Resolver Unhooked ntdll JMP-hooked ntdll Fully hooked ntdll String-free
HellsGate Yes No No No
HalosGate Yes Yes (neighbor) No No
TartarusGate Yes Yes (trampoline) Yes (neighbor fallback) No
HashGate Yes No No Yes
Chain Depends on composition Depends on composition Depends on composition Depends
You want to… Use
…call a Windows API with no plaintext name in the binary api-hashing.md (HashGate)
…skip kernel32-level hooks but stay in ntdll direct-indirect.md — MethodNativeAPI
…skip every userland hook (kernel32 + ntdll) direct-indirect.md — MethodIndirect / MethodIndirectAsm
…make the syscall return inside ntdll's .text (call-stack stealth) direct-indirect.md — MethodIndirect family
…avoid any writable code page in the implant direct-indirect.md — MethodIndirectAsm
…randomise the syscall return address per call direct-indirect.md — gadget pool
…auto-fall-back when the target stub is hooked ssn-resolvers.md — Halo's / Tartarus / Chain
…read the SSN even when the entire ntdll text section is hooked ssn-resolvers.md — TartarusGate
…swap in your own hash function (defeat ROR13 fingerprints) NewHashGateWith(fn) + Caller.WithHashFunc(fn)
Document Description
Direct & Indirect Syscalls The five invocation methods (incl. Go-asm IndirectAsm) and when to use each
API Hashing PEB walk + ROR13 hashing to eliminate plaintext strings
SSN Resolvers Hell's Gate, Halo's Gate, Tartarus Gate, HashGate
Technique ID Description
Native API T1106 Directly interact with the native OS API
Countermeasure ID Description
System Call Analysis D3-SCA Monitor syscall origins and patterns
Function Call Restriction D3-FCR Restrict dynamic function resolution