
Заголовочная библиотека для Windows x64 с косвенными системными вызовами. Без CRT, без IAT, VEH anti-BP, обход AMSI/ETW, память W^X, динамические заглушки для каждого вызова.
Заголовочная библиотека для Windows x64, позволяющая вызывать любые NT-сискаллы без обращения к импортам ntdll, без оставления строк в бинарнике и без типичных «красных флагов», от которых у EDR сносит крышу.
Ни CRT, ни STL, ни IAT. Всё компилируется в ~19 КБ без единой DLL-зависимости.
Создана, чтобы избежать типовых недостатков существующих библиотек сискаллов — открытого текста строк, известных констант хешей, прямых сискаллов из памяти за пределами ntdll, импортов IAT, кричащих «я делаю что-то странное», IOC SEC_NO_CHANGE, раздутия от CRT. Здесь ничего такого нет.
Движок сискаллов
syscall; ret-гаджета ntdll, так что RIP всегда находится внутри ntdll в момент выполнения инструкции syscall\KnownDlls\ntdll.dll (без доступа к файловой системе, невидимо для ProcMon)Anti-Breakpoint
Обход
AmsiScanBuffer, заставляя возвращать S_OKEtwEventWrite, заставляя возвращать SUCCESSКачество кода
stealth/ в свой проект и работаете
initialize() открывает ntdll через секцию \KnownDlls, разбирает PE-экспорт, извлекает все номера сискаллов.text ntdll в поиске гаджета syscall; ret — именно из него будет выполняться настоящая инструкция syscallsc::invoke():
emit_stub() строит уникальную полиморфную заглушку — случайные мусорные инструкции до и после, XOR-замаскированный номер сискалла с уникальным на каждый вызов ключом, косвенный jmp на ntdll-гаджетНи в какой момент не существует RWX-памяти. Ни в какой момент инструкция syscall не выполняется за пределами ntdll. Ни в какой момент номера сискаллов не хранятся в открытом виде.
Вы вызываете tramp::invoke() с целевой функцией. Если брейкпоинта нет — функция просто выполняется без каких-либо накладных расходов. Если отладчик проставил 0xCC:
Список брейкпоинтов отладчика по-прежнему показывает, что точка остановки активна. Она просто никогда не срабатывает при наших вызовах.
cmake -B build -A x64
cmake --build build --config Release
Требуется MSVC (VS 2019+) и CMake 3.15+. Результат — ~19 КБ с нулевыми импортами.
#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"
// работает, даже если в x64dbg стоит BP на 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 — операции с памятью, спинлок, static_map, PRNG, отладочный вывод
hash.hpp — пользовательский хеш времени компиляции
xorstr.hpp — XOR-шифрование строк времени компиляции
peb.hpp — обход PEB, разбор экспорта PE, обнаружение хуков
syscall.hpp — движок косвенных сискаллов, генератор заглушек, W^X, защита от дампа
trampoline.hpp — VEH-антибрейкпоинт
bypass.hpp — патчинг AMSI и ETW
MIT — делайте с ним что хотите.