
En-tête uniquement pour bibliothèque d'appels système indirects Windows x64. Zéro CRT, zéro IAT, VEH anti-BP, contournement AMSI/ETW, mémoire W^X, stubs dynamiques par appel.
Bibliothèque header-only pour Windows x64 qui vous permet d'invoquer n'importe quel syscall NT sans toucher aux imports ntdll, sans laisser de chaînes de caractères dans votre binaire, et sans les signaux d'alerte habituels qui font perdre la tête aux EDR.
Pas de CRT. Pas de STL. Pas d'IAT. Le tout se compile en ~19KB avec littéralement zéro dépendance DLL.
Conçue pour éviter les pièges courants des bibliothèques de syscalls existantes — chaînes en clair, constantes de hachage connues, syscall direct depuis une mémoire hors ntdll, imports IAT qui crient « je fais quelque chose de bizarre », IOC SEC_NO_CHANGE, bloat CRT. Rien de tout ça ici.
Moteur de syscalls
syscall; ret propre à ntdll, donc RIP est toujours à l'intérieur de ntdll lorsque l'instruction syscall s'exécute\KnownDlls\ntdll.dll (aucun accès au système de fichiers, invisible pour ProcMon)Anti-Breakpoint
Évasion
AmsiScanBuffer pour retourner S_OKEtwEventWrite pour retourner SUCCESSQualité du code
stealth/ dans votre projet et c'est parti
initialize() ouvre ntdll via la section \KnownDlls, analyse les exports PE, récupère chaque numéro de syscall.text de ntdll pour trouver un gadget syscall; ret — c'est là que l'instruction syscall réelle s'exécuterasc::invoke() :
emit_stub() construit un stub polymorphe unique — instructions de bruit aléatoires avant/après, numéro de syscall obfusqué par XOR avec une clé par appel, jmp indirect vers le gadget ntdllÀ aucun moment la mémoire RWX n'existe. À aucun moment une instruction syscall ne s'exécute en dehors de ntdll. À aucun moment les numéros de syscall ne sont stockés en clair.
Vous appelez tramp::invoke() avec la fonction cible. S'il n'y a pas de breakpoint — la fonction s'exécute normalement avec zéro surcoût. Si un débogueur a placé un 0xCC :
La liste des breakpoints du débogueur affiche toujours le breakpoint comme actif. Le breakpoint ne se déclenche simplement jamais sur nos appels.
cmake -B build -A x64
cmake --build build --config Release
Nécessite MSVC (VS 2019+) et CMake 3.15+. La sortie fait ~19KB avec zéro import.
#include "stealth/syscall.hpp"
stealth::sc::initialize();
PVOID base = nullptr;
SIZE_T size = 0x1000;
NTSTATUS status = stealth::sc::invoke<NTSTATUS>(
HASH("NtAllocateVirtualMemory"),
NtCurrentProcess(), &base, (ULONG_PTR)0, &size,
(ULONG)(MEM_COMMIT | MEM_RESERVE), (ULONG)PAGE_READWRITE
);
#include "stealth/trampoline.hpp"
// fonctionne même si x64dbg a un BP sur MessageBoxA
int ret = stealth::tramp::invoke<int>(
HASH_CI("user32.dll"), HASH("MessageBoxA"),
(HWND)nullptr, (LPCSTR)"hello", (LPCSTR)"title", (UINT)MB_OK
);
#include "stealth/bypass.hpp"
stealth::bypass::patch_etw();
stealth::bypass::patch_amsi();
stealth::tramp::shutdown();
stealth::sc::shutdown();
stealth/
common.hpp — opérations mémoire, spinlock, static_map, PRNG, sortie de débogage
hash.hpp — hachage personnalisé au moment de la compilation
xorstr.hpp — chiffrement de chaînes XOR au moment de la compilation
peb.hpp — parcours du PEB, analyseur d'exports PE, détection de hooks
syscall.hpp — moteur de syscalls indirects, générateur de stubs, W^X, anti-dump
trampoline.hpp — anti-breakpoint basé sur VEH
bypass.hpp — patching AMSI + ETW
MIT — faites-en ce que vous voulez.