
Header-only Windows x64 indirect syscall library. Zero CRT, zero IAT, VEH anti-BP, AMSI/ETW bypass, W^X memory, per-call dynamic stubs. Biblioteca de syscall indireto para Windows x64 apenas com header. Zero CRT, zero IAT, VEH anti-BP, bypass de AMSI/ETW, memória W^X, stubs dinâmicos por chamada.
Biblioteca header-only para Windows x64 que permite invocar qualquer syscall do NT sem tocar em imports do ntdll, sem deixar strings no binário e sem os habituais sinais de alerta que fazem os EDRs perderem a cabeça.
Sem CRT. Sem STL. Sem IAT. Tudo compila para ~19KB com literalmente zero dependências de DLL.
Construída para evitar as armadilhas comuns das bibliotecas de syscall existentes — strings em texto puro, constantes de hash conhecidas, syscall direto a partir de memória fora do ntdll, imports de IAT que gritam "estou a fazer algo estranho", IOC SEC_NO_CHANGE, inchaço de CRT. Nada disso aqui.
syscall; ret do próprio ntdll, para que o RIP esteja sempre dentro do ntdll quando a instrução syscall é executada\KnownDlls\ntdll.dll (sem acesso ao sistema de ficheiros, invisível para o ProcMon)Anti-Breakpoint
Evasão
AmsiScanBuffer para retornar S_OKEtwEventWrite para retornar SUCCESSQualidade de Código
stealth/ no projeto e avançar
initialize() abre o ntdll através da secção \KnownDlls, analisa os exports do PE e recolhe todos os números de syscall.text do ntdll um gadget syscall; ret — é daqui que a instrução syscall real será executadasc::invoke():
emit_stub() constrói um stub polimórfico único — instruções de lixo aleatórias antes/depois, número de syscall ofuscado com XOR e chave por chamada, jmp indireto para o gadget do ntdllEm nenhum momento existe memória RWX. Em nenhum momento uma instrução syscall é executada fora do ntdll. Em nenhum momento os números de syscall são armazenados em texto puro.
Chamas tramp::invoke() com a função alvo. Se não houver breakpoint — a função simplesmente executa normalmente com zero overhead. Se um debugger colocou 0xCC:
A lista de breakpoints do debugger ainda mostra o breakpoint como ativo. Simplesmente nunca é acionado nas nossas chamadas.
cmake -B build -A x64
cmake --build build --config Release
Requer MSVC (VS 2019+) e CMake 3.15+. O output é ~19KB com zero imports.
#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"
// funciona mesmo que o x64dbg tenha um BP em 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 — operações de memória, spinlock, static_map, PRNG, output de debug
hash.hpp — hash personalizado em tempo de compilação
xorstr.hpp — encriptação de strings XOR em tempo de compilação
peb.hpp — walk do PEB, parser de exports PE, deteção de hooks
syscall.hpp — motor de syscall indireto, gerador de stubs, W^X, anti-dump
trampoline.hpp — anti-breakpoint baseado em VEH
bypass.hpp — patching de AMSI + ETW
MIT — faz o que quiseres com isto.