
Основополагающая библиотека на C для создания оперативно достоверных наступательных возможностей
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/735/ac7a3259ddf602d9e7d0c2f683f22497afec347da32bb930d5369acf66ae34f5.png" width="100%">
</p>
<h1 align="center">SindriKit</h1>
<p align="center">
<strong>Наступательная разработка заслуживает лучшей архитектуры.</strong><br>
<em>Библиотека на C для создания наступательных возможностей.</em>
</p>
---
## Основная концепция
Большинство наступательных утилит жёстко зашивают механику выполнения внутри логики техники. Рефлективный загрузчик не просто отображает образ; он отображает его с использованием конкретной, жёстко заданной цепочки вызовов `VirtualAlloc` или нативных NTAPI. Когда EDR начинает отслеживать эту конкретную цепочку, вы вынуждены переписывать весь инструмент.
SindriKit решает эту проблему, обеспечивая разделение ответственности через таблицы абстракции интерфейсов:
1. **Логика техники:** (например, загрузчики, инжекторы, патчеры) занимается отслеживанием состояния и оркестрацией данных. Она ничего не знает о том, как выделяется память или как создаются потоки.
2. **Механика выполнения:** (например, Win32 API, Native NTAPI, Direct Syscalls) находится внутри независимых таблиц API и внедряется в технику во время выполнения.
Перенося механику выполнения в указатели на функции времени выполнения, вы можете заменить всю свою стратегию с вызовов Win32 на сырые прямые системные вызовы одной строкой кода — без изменения логики выполнения полезной нагрузки.
---
## Архитектура дизайна
* **Развязанные профили выполнения:** Замена механики памяти, модулей, отображения, процессов, потоков и файлов через независимые таблицы указателей на функции (`snd_memory_api_t`, `snd_module_api_t`, `snd_process_api_t`, `snd_thread_api_t`, `snd_mapping_api_t`, `snd_file_api_t`) без изменения логики техники.
* **Покрытие техник:** Рефлективная загрузка **PE** (EXE/DLL) и **COFF/BOF**, **классическая** и **early-bird APC** инъекция поверх shellcode/PE/COFF, а также архитектурно-зависимый FFI и Heaven's Gate — всё поверх одних и тех же композируемых профилей.
* **Каскадный конвейер системных вызовов:** Подключаемые резолверы SSN (`snd_syscall_resolve_ssn_scan`, `snd_syscall_resolve_ssn_sort`) с цепочкой приоритетов, развязанные от инвокеров: **прямые**, **косвенные** (гаджет NTDLL) или **спуфированные** (динамический спуфинг стека вызовов Fat-Frame).
* **Статус с кодированием средства:** Каждый вызов, способный завершиться ошибкой, возвращает `snd_status_t` — упакованный код средства/локальный код плюс захваченная ошибка ОС, со строками контекста, которые исключаются при компиляции в тихом уровне.
* **Обфускация времени компиляции:** Алгоритмы хеширования строк и API (DJB2, FNV1A) можно глобально переключать через CMake. Компиляция автоматически рандомизирует глобальное зерно для изменения статических сигнатур.
* **Движок мутаций:** Обеспечивает глубокий полиморфизм через `SND_MORPH`. Генерирует уникальные бинарные сигнатуры при каждой сборке, внедряя волатильные непрозрачные предикаты в код C, функционально эквивалентные математические операции/NOP в ассемблерные заглушки и перемешивая расположение в памяти ключевых структур.
* **Релизные сборки:** Тихий уровень удаляет все диагностические строки, дескрипторы файлов и кадры отслеживания; сборки с `SND_CRTLESS` идут дальше с `/NODEFAULTLIB`, без заголовков SDK, с фронтендом PEB и только нативными бэкендами.
---
## Быстрый старт
Репозиторий поставляет единый CLI `unified`, который задействует каждый профиль:
```sh
build.bat pocs
build64\pocs\Release\unified.exe load pe -f payload.dll -e Run --sys
```
`unified` поддерживает `load pe|coff`, `inject classic|apc|hijack` (shell, PE, COFF) и `hg`, каждый поверх `--win`/`--nt`/`--sys`. См. [Примеры и PoC](https://github.com/youssefnoob003/sindrikit/blob/main/docs/examples/README.md) и [Начало работы](https://github.com/youssefnoob003/sindrikit/blob/main/docs/getting_started/README.md).
---
## Интеграция SindriKit
```cmake
cmake_minimum_required(VERSION 3.16)
project(MyTool C ASM_MASM)
set(SND_BUILD_PAYLOADS OFF CACHE BOOL "")
set(SND_ENABLE_DEBUG OFF CACHE BOOL "")
set(SND_HASH_ALGO "DJB2" CACHE STRING "")
set(SND_RANDOMIZE_SEED ON CACHE BOOL "")
set(SND_MORPH ON CACHE BOOL "")
add_subdirectory(libs/SindriKit)
add_executable(my_tool src/main.c)
target_link_libraries(my_tool PRIVATE sindri::engine)
```
```sh
cmake -B build && cmake --build build --config Release
```
Всего две строки, чтобы ваш инструмент унаследовал все возможности SindriKit: парсинг PE и COFF, рефлективную загрузку, каскадные системные вызовы и профили инъекции.
---
## Движок
### Слой абстракции API
```
┌────────────────────────────────────────────────────────────────────────────┐
│ ЛЮБОЕ НАСТУПАТЕЛЬНОЕ НАМЕРЕНИЕ │
│ Загрузчик · Инжектор · Спуфер · Патчер · Обходчик · Сборщик · ... │
├────────────────────────────────────────────────────────────────────────────┤
│ СЛОЙ АБСТРАКЦИИ API SINDRIKIT │
│ snd_memory_api_t -> alloc · free · protect │
│ snd_module_api_t -> load_library · get_proc_address · ... │
│ snd_process_api_t -> open · alloc_remote · write · protect · thread │
│ snd_mapping_api_t -> open · view · close (KnownDlls bootstrap) │
│ snd_thread_api_t -> queue_apc · resume · suspend │
│ snd_file_api_t -> load │
├──────────────────┬──────────────────────┬──────────────────────────────────┤
│ Профиль Win32 │ Нативный профиль │ Своя механика │
│ VirtualAlloc │ NtAllocateVirtual │ Драйвер · ROP · Экзотика │
│ LoadLibraryA │ PEB Walk + EAT │ Функции, заданные оператором │
└──────────────────┴──────────────────────┴──────────────────────────────────┘
```
На практике это означает, что каждый домен следует одному и тому же контракту:
```c
// Reflective loader
snd_ldr_pe_ctx_t ctx = {0};
ctx.raw_source = &payload;
ctx.mem_api = &snd_mem_win; // or snd_mem_nt / snd_mem_sys
ctx.mod_api = &snd_mod_win; // or snd_mod_nt
snd_ldr_pe_prepare_image(&ctx);
snd_ldr_pe_execute_image(&ctx);
// Classic injection
snd_inj_ctx_t inj = {0};
inj.target_pid = 1337;
inj.payload = &shellcode;
inj.proc_api = &snd_proc_sys; // or snd_proc_win / snd_proc_nt
snd_inj_classic_shell(&inj);
snd_inj_cleanup(&inj);
```
### Каскадный конвейер системных вызовов
SindriKit рассматривает разрешение системных вызовов как внедряемую механику, выстраивая стратегии в порядке приоритета. Движок перебирает их, пока одна не завершится успешно:
```c
snd_ntdll_set_clean(clean_ntdll);
snd_syscall_set_resolver(snd_syscall_resolve_ssn_scan);
snd_syscall_add_resolver(snd_syscall_resolve_ssn_sort);
snd_syscall_set_invoker(snd_syscall_direct_invoke_asm);
// or for indirect syscalls:
// snd_syscall_set_invoker(snd_syscall_indirect_invoke_asm);
// snd_syscall_set_gadget_finder(snd_syscall_find_gadget_scan);
// or for spoofed syscalls:
// snd_syscall_set_invoker(snd_syscall_spoofed_invoke_asm);
// snd_syscall_set_spoof_finder(snd_syscall_find_spoof_scan);
```
Инвокер развязан от разрешения SSN — переключайтесь между прямыми, косвенными и спуфированными системными вызовами без изменения кода домена. Косвенный вызов переходит на легитимный гаджет NTDLL, так что адрес возврата остаётся внутри `ntdll.dll`; спуфированный вызов дополнительно помещает подлинный адрес возврата вызывающего внутри динамически обнаруженного "Fat Frame", так что развёртывание стека вызовов остаётся согласованным.
### Гибкость алгоритмов времени компиляции
Каждое имя API и строка модуля удаляются из финального бинарника во время компиляции через одну переменную CMake:
```cmake
set(SND_HASH_ALGO "FNV1A") # or DJB2 recomputes everything automatically
set(SND_RANDOMIZE_SEED ON) # generates a fresh 32-bit seed on next configure
```
Каждый хеш вычисляется со случайно сгенерированным зерном (если `SND_RANDOMIZE_SEED=ON`). Статический отпечаток полностью меняется между компиляциями без изменения ни одной строки C.
### Архитектурно-зависимый динамический FFI
Пользовательский ассемблерный мост MASM для вызова произвольных функций во время выполнения. Сборки x64 точно следуют соглашению о вызовах Microsoft x64 (shadow space, размещение аргументов в регистрах, выравнивание стека). Сборки x86 помещают аргументы в обратном порядке с поддержкой целей как `cdecl`, так и `stdcall`.
### Парсер PE с проверкой границ
Унифицированный парсер PE32/PE32+ с флагом `is_mapped`, который корректно обрабатывает как сырые образы на диске, так и отображённые в память представления. Каждый доступ к каталогу данных проверяется на соответствие отслеживаемым границам буфера перед разыменованием. Разрешение экспортов поддерживает цепочки форвардеров глубиной до 4 с поиском на основе хеша.
Протестировано на:
- 40+ основных тестовых комбинациях, нацеленных на граничные случаи EXE, DLL, некорректные аргументы, отсутствующие экспорты и TLS-колбэки на x86 и x64.
- 100+ динамических мутациях PE, сгенерированных модулем `pe_mutator`: обнулённые имена секций, целочисленные переполнения, недопустимые границы `e_lfanew`, искажённые импорты.
- Полном корпусе Corkami: чисто загружает валидные образцы, чисто отклоняет некорректные без падений на 99% образцов.
### Загрузчик COFF / BOF
Вторая техника загрузчика обрабатывает несвязанные объектные файлы COFF (Beacon Object Files): ограниченный парсинг заголовков, секций, символов и релокаций; разрешение внешних символов `MODULE$Function` через внедрённый `mod_api`; трамплины x64 `JMP [RIP+0]` для вызовов вне диапазона; и выполнение именованной точки входа (по умолчанию `go`) — локально или маршалингом в удалённый процесс.
### Контексты доменов с отслеживанием состояния
Каждая наступательная операция управляется через дискретную структуру контекста с перечислением стадий. Операции можно приостанавливать между стадиями для обфускации сна или поэтапного развёртывания, чисто возобновлять и инспектировать точную точку отказа вплоть до подсистемы и причины.
---
## Философия дизайна API
Однократная инициализация конвейера системных вызовов (типичный шаблон):
```c
PVOID clean_ntdll = NULL;
snd_om_knowndll_map(&snd_map_nt, L"ntdll.dll", &clean_ntdll);
snd_ntdll_set_clean(clean_ntdll);
snd_syscall_set_resolver(snd_syscall_resolve_ssn_scan);
snd_syscall_add_resolver(snd_syscall_resolve_ssn_sort);
snd_syscall_set_invoker(snd_syscall_direct_invoke_asm);
// or for indirect syscalls:
// snd_syscall_set_invoker(snd_syscall_indirect_invoke_asm);
// snd_syscall_set_gadget_finder(snd_syscall_find_gadget_scan);
// or for spoofed syscalls:
// snd_syscall_set_invoker(snd_syscall_spoofed_invoke_asm);
// snd_syscall_set_spoof_finder(snd_syscall_find_spoof_scan);
```
Инвокер развязан от разрешения SSN — переключайтесь между прямыми, косвенными и спуфированными системными вызовами без изменения кода домена. Косвенный вызов переходит на легитимный гаджет NTDLL, так что адрес возврата остаётся внутри `ntdll.dll`; спуфированный вызов дополнительно помещает подлинный адрес возврата вызывающего внутри динамически обнаруженного "Fat Frame", так что развёртывание стека вызовов остаётся согласованным.
Замена профиля выполнения одним присваиванием:
```c
ctx.mem_api = &snd_mem_win; // diagnostic
ctx.mem_api = &snd_mem_nt; // NT stubs via PEB + EAT
ctx.mem_api = &snd_mem_sys; // direct syscalls (pipeline required)
```
Разрешение модулей следует тому же шаблону (`snd_mod_win` против `snd_mod_nt`). Бэкенда модулей на системных вызовах нет — импорты используют PEB walk + EAT даже в полных профилях `_sys`.
---
## Уровни сборки
### Уровень отладки — `SND_ENABLE_DEBUG=ON`
Для локальной разработки. `snd_status_t` расширяется, включая `file`, `line` и буфер строки `context` на 128 байт. `SND_ERR_CTX` и `SND_DEBUG_PRINT` выводят переходы конечного автомата, значения разобранных полей PE и результаты разрешения системных вызовов. Используйте `SND_USE_PRINTF=ON`, чтобы направить вывод в `stdout` вместо консоли отладки.
### Тихий уровень — `SND_ENABLE_DEBUG=OFF`
Стандартная конфигурация развёртывания для операционных бинарников. Каждая диагностическая строка, ссылка на файл и номер строки полностью исключаются при компиляции. `snd_status_t` сжимается до двух целых чисел. И ничего больше. Сборка с `SND_CRTLESS=ON` добавляет `/NODEFAULTLIB`, отсутствие заголовков Windows SDK, фронтенд командной строки на PEB и только нативные бэкенды.
```cmake
set(SND_ENABLE_DEBUG OFF CACHE BOOL "")
set(SND_BUILD_PAYLOADS OFF CACHE BOOL "")
set(SND_RANDOMIZE_SEED ON CACHE BOOL "")
set(SND_USE_DEFAULTS ON CACHE BOOL "")
set(SND_HASH_ALGO "DJB2" CACHE STRING "")
add_subdirectory(vendor/SindriKit)
target_link_libraries(my_tool PRIVATE sindri::engine)
```
---
## Документация
Полный справочник в [`docs/`](https://github.com/youssefnoob003/sindrikit/blob/main/docs/README.md):
- **[Справочник API](https://github.com/youssefnoob003/sindrikit/blob/main/docs/api_reference.md)** — полный публичный C API (функции, типы, таблицы DI, коды статуса)
- **[Начало работы](https://github.com/youssefnoob003/sindrikit/blob/main/docs/getting_started/README.md)** — уровни сборки, интеграция с CMake, инициализация системных вызовов, первый рабочий процесс загрузчика/инъекции
- **[Архитектура](https://github.com/youssefnoob003/sindrikit/blob/main/docs/architecture/README.md)** — внедрение зависимостей, конечные автоматы, система статуса с кодированием средства
- **[Примитивы](https://github.com/youssefnoob003/sindrikit/blob/main/docs/primitives/README.md)** — память, модули, процессы, отображение, файлы, потоки, системные вызовы, выполнение (FFI, Heaven's Gate)
- **[Загрузчики](https://github.com/youssefnoob003/sindrikit/blob/main/docs/loaders/README.md)** — рефлективная загрузка PE и COFF/BOF
- **[Инъекция](https://github.com/youssefnoob003/sindrikit/blob/main/docs/injection/README.md)** — классическая, early-bird APC и thread-hijack инъекция (shellcode, PE, COFF)
- **[Парсеры](https://github.com/youssefnoob003/sindrikit/blob/main/docs/parsers/README.md)** — парсинг PE, COFF и env (PEB/NTDLL)
- **[Общее](https://github.com/youssefnoob003/sindrikit/blob/main/docs/common/README.md)** — CRT-free помощники, буферы, хеширование, статус
- **[Примеры и PoC](https://github.com/youssefnoob003/sindrikit/blob/main/docs/examples/README.md)** — CLI `unified` (`load pe|coff`, `inject classic|apc|hijack`, `hg`)
- **[Тесты](https://github.com/youssefnoob003/sindrikit/blob/main/docs/tests/README.md)** — интеграционные раннеры и мутатор PE
*Планируется: домен **Evasion**.*
---
## Отказ от ответственности
**SindriKit создан исключительно для образовательных, исследовательских целей и авторизованного Red Teaming.** Полный юридический отказ от ответственности и информацию о соображениях OpSec см. в [Политике безопасности](https://github.com/youssefnoob003/sindrikit/blob/main/SECURITY.md).
---
## Лицензия
[MIT](https://github.com/youssefnoob003/sindrikit/blob/main/LICENSE)
---
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/735/c6b18a5428e9f22275a36c38df781706c1ddd2639451b49276a6cc0634dcb175.png" width="100%">
</p>