
Nur-Header-Bibliothek für indirekte Syscalls unter Windows x64. Kein CRT, keine IAT, VEH-Anti-BP, AMSI/ETW-Umgehung, W^X-Speicher, dynamische Stubs pro Aufruf.
Nur-Header-Bibliothek für Windows x64, mit der Sie jeden NT-Syscall aufrufen können, ohne ntdll-Importe zu berühren, ohne Zeichenketten in Ihrer Binärdatei zu hinterlassen und ohne die üblichen Warnsignale, die EDRs aus der Fassung bringen.
Kein CRT. Keine STL. Kein IAT. Das Ganze kompiliert auf ~19 KB mit buchstäblich keinen DLL-Abhängigkeiten.
Entwickelt, um die üblichen Fallstricke bestehender Syscall-Bibliotheken zu vermeiden – Klartext-Zeichenketten, bekannte Hash-Konstanten, direkter Syscall aus Nicht-ntdll-Speicher, IAT-Importe, die schreien "Ich mache etwas Seltsames", SEC_NO_CHANGE IOC, CRT-Aufblähung. Nichts davon hier.
Syscall-Engine
syscall; ret-Gadget von ntdll, so dass RIP immer innerhalb von ntdll ist, wenn die Syscall-Anweisung ausgeführt wird\KnownDlls\ntdll.dll-Abschnittszuordnung (kein Dateisystemzugriff, für ProcMon unsichtbar)Anti-Breakpoint
Umgehung
AmsiScanBuffer, um S_OK zurückzugebenEtwEventWrite, um SUCCESS zurückzugebenCode-Qualität
stealth/ in Ihr Projekt und los geht's
initialize() öffnet ntdll über den Abschnitt \KnownDlls, parst PE-Exporte, schnappt sich jede Syscall-Nummer.text nach einem syscall; ret-Gadget — von hier aus wird die tatsächliche Syscall-Anweisung ausgeführtsc::invoke() aufrufen:
emit_stub() erstellt einen eindeutigen polymorphen Stub — zufällige Junk-Anweisungen davor/danach, XOR-verschleierte Syscall-Nummer mit einem Pro-Aufruf-Schlüssel, indirekter Sprung zum ntdll-GadgetZu keinem Zeitpunkt existiert RWX-Speicher. Zu keinem Zeitpunkt führt eine syscall-Anweisung außerhalb von ntdll aus. Zu keinem Zeitpunkt werden Syscall-Nummern im Klartext gespeichert.
Sie rufen tramp::invoke() mit der Zielfunktion auf. Wenn es keinen Breakpoint gibt — läuft die Funktion normal ohne zusätzlichen Overhead. Wenn ein Debugger 0xCC gesetzt hat:
Die Breakpoint-Liste des Debuggers zeigt ihn weiterhin als aktiv an. Der Breakpoint wird bei unseren Aufrufen einfach nie ausgelöst.
cmake -B build -A x64
cmake --build build --config Release
Benötigt MSVC (VS 2019+) und CMake 3.15+. Ausgabe ist ~19 KB ohne Importe.
#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"
// funktioniert sogar, wenn x64dbg einen BP auf MessageBoxA hat
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 — Speicheroperationen, Spinlock, static_map, PRNG, Debug-Ausgabe
hash.hpp — benutzerdefinierter Hash zur Compile-Zeit
xorstr.hpp — XOR-Zeichenkettenverschlüsselung zur Compile-Zeit
peb.hpp — PEB-Walk, PE-Export-Parser, Hook-Erkennung
syscall.hpp — Indirekte Syscall-Engine, Stub-Generator, W^X, Anti-Dump
trampoline.hpp — VEH-basierter Anti-Breakpoint
bypass.hpp — AMSI + ETW-Patching
MIT — tun Sie damit, was Sie wollen.