Skip to content

SunrisePlatform/SunriseLib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

English

SunriseLib

SunriseLib - Windows-ориентированный C/C++ SDK для низкоуровневых проектов, которым нужен компактный runtime-слой без прямой зависимости от стандартных WinAPI/CRT/std-вызовов в основном коде приложения.

Основная идея библиотеки: дать одну точку входа через Sunrise.h, сохранить стиль, близкий к C, C++, WinAPI и NT API, но по возможности вести работу через собственные реализации, lazy import и прямые системные вызовы. Это помогает уменьшить зависимость от обычных импортов и снизить риск перехвата или отслеживания вызовов, которые делает приложение.

Для Чего Это Нужно

SunriseLib полезна, когда проекту важны:

  • прямой контроль над Windows API, NT-level механизмами и syscall-first сценариями;
  • работа как в обычных CRT-compatible конфигурациях, так и в NoCRT-сценариях без стандартного runtime;
  • единый набор типов, макросов, C/C++ helpers и compatibility-заголовков;
  • компактные filesystem, memory, thread, sync и network утилиты;
  • lazy import, syscall helpers и compile-time obfuscation строк, целых чисел и чисел с плавающей запятой;
  • возможность подключать SDK рядом с обычными Windows-заголовками.

Библиотека ориентирована на Windows и x64-сборки под MSVC и Clang.

Что Входит В SDK

  • include/Sunrise.h - основной umbrella-header, который подключает C, C++, CExt, CPPExt и PP-слои.
  • include/C/ - C/CRT/WinAPI-compatible заголовки, типы и объявления.
  • include/CExt/ - project-level C helpers: память, файлы, пути, консоль, процессы, синхронизация, DNS, HTTP, TCP/IPv4 и NT primitives, включая сценарии работы через системные вызовы.
  • include/CPP/ - C++ compatibility/std-like слой с контейнерами, строками, filesystem/fstream, expected и related utilities.
  • include/CPPExt/ - C++ расширения: TcpClient, TcpListener, DnsClient, HttpClient, FileSystem, LazyImport, Syscall, Obfuscator, Random, NoCRT и другие helpers.
  • include/PP/ - препроцессорная инфраструктура, import-макросы, документационные метки и служебные compile-time helpers.
  • Examples/ - минимальные CRT и NoCRT примеры интеграции.
  • Tests/ - C и C++ тесты, включая сценарии подключения после стандартных Windows-заголовков.
  • Готовые release-библиотеки для MSVC/Clang в CRT-compatible и NoCRT-compatible вариантах.

Быстрый Старт

Если include/ добавлен в include paths проекта, минимальный CRT-compatible entry point может выглядеть так:

#include <Sunrise.h>

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;
    return _SR_ObfInt(0);
}

Если include path не настроен, можно подключить заголовок относительно корня репозитория:

#include "include/Sunrise.h"

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;
    return _SR_ObfInt(0);
}

То же подключение можно использовать в C translation units:

#include <Sunrise.h>

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;
    return _SR_ObfInt(0);
}

В NoCRT EXE entry point задаётся без стандартного CRT startup. В готовом примере Examples/NoCRTBase/ для этого используется NoCRTMain:

#include <Sunrise.h>

int NoCRTMain(void) {
    int argc = _SR_ObfInt(0);
    wchar_t** argv = nullptr;

    if (!Sunrise::CPP::NoCRT::BuildWideArgv(&argc, &argv)) {
        return _SR_ObfInt(1);
    }

    (void)argv;
    return argc > _SR_ObfInt(0) ? _SR_ObfInt(0) : _SR_ObfInt(2);
}

Для CRT-compatible DLL используется обычный DllMain:

#include <Sunrise.h>

_SR_BOOL WINAPI DllMain(_SR_HMODULE hModule, _SR_DWORD reason, _SR_PVOID param) {
    (void)hModule;
    (void)param;

    if (reason != _SR_ObfInt(DLL_PROCESS_ATTACH)) {
        return (_SR_BOOL)_SR_ObfInt(TRUE);
    }

    return (_SR_BOOL)_SR_ObfInt(TRUE);
}

Для NoCRT DLL вместо DllMain определяется NoCRTDllMain:

#include <Sunrise.h>

int NoCRTDllMain(_SR_HMODULE hModule, _SR_DWORD reason, _SR_PVOID param) {
    (void)hModule;
    (void)param;

    if (reason != _SR_ObfInt(DLL_PROCESS_ATTACH)) {
        return _SR_ObfInt(TRUE);
    }

    return _SR_ObfInt(TRUE);
}

Дальнейшие примеры используют int main(int argc, char** argv) как короткую CRT-compatible форму. В NoCRT EXE тот же полезный код обычно переносится в тело NoCRTMain, а аргументы командной строки принимаются через Sunrise::CPP::NoCRT::BuildWideArgv. В CRT-compatible DLL код размещается в DllMain, а в NoCRT DLL - в NoCRTDllMain.

Для старта с готовой конфигурацией удобнее открыть один из примеров:

  • Examples/CRTBase/ - обычная CRT-compatible сборка с main и DllMain.
  • Examples/NoCRTBase/ - минимальная NoCRT-oriented сборка с NoCRTMain и NoCRTDllMain.

При линковке с готовыми библиотеками выбирайте вариант под ваш compiler и runtime mode. Для CRT-compatible сборок используются SunriseLib-MSVC-Release-CRT.lib и SunriseLib-Clang-Release-CRT.lib; для NoCRT-compatible сборок - SunriseLib-MSVC-Release.lib и SunriseLib-Clang-Release.lib.

Управление Памятью

SunriseLib не привязывает основной код к обычному CRT allocator. Базовая memory-policy проекта задаётся тремя функциями, которые должно определить приложение или integration-пример:

#include <Sunrise.h>

void* _SR_MemAlloc(_SR_size_t size, bool zeroMemory) {
    return _SR_MemHeapAlloc(size, zeroMemory);
}

void* _SR_MemReAlloc(void* ptr, _SR_size_t newSize, bool zeroMemory) {
    return _SR_MemHeapReAlloc(ptr, newSize, zeroMemory);
}

void _SR_MemFree(void* ptr) {
    _SR_MemHeapFree(ptr);
}

_SR_MemHeapAlloc, _SR_MemHeapReAlloc и _SR_MemHeapFree используют внутреннюю heap-систему Sunrise, работающую поверх низкоуровневых NT/system-call primitives. Через _SR_MemAlloc/_SR_MemReAlloc/_SR_MemFree эту политику используют C helpers, CRT-compatible malloc/calloc/realloc/free, C++ std-like контейнеры, строки и части CPPExt, которым нужна динамическая память.

Если нужно полностью контролировать область выделения, можно завести memory region вручную. Например, буфер байт может лежать в стеке или статической памяти, а default allocator проекта будет выдавать память только из этого региона:

#include <Sunrise.h>

static _SR_BYTE gMemory[64 * 1024];
static const _SR_StackRegion gRegion = { gMemory, sizeof(gMemory) };

void* _SR_MemAlloc(_SR_size_t size, bool zeroMemory) {
    return _SR_MemStackAlloc(&gRegion, size, zeroMemory);
}

void* _SR_MemReAlloc(void* ptr, _SR_size_t newSize, bool zeroMemory) {
    return _SR_MemStackReAlloc(&gRegion, ptr, newSize, zeroMemory);
}

void _SR_MemFree(void* ptr) {
    _SR_MemStackFree(&gRegion, ptr);
}

Для более гибкого C++ сценария часть std-like контейнеров принимает _SR_IAllocatorVtbl: так можно использовать heap по умолчанию для одних объектов и отдельный stack-backed или custom allocator для других. Если allocator привязан к конкретному _SR_StackRegion, адаптер обычно хранит выбранный регион рядом с таблицей функций или в другой контролируемой области состояния.

Пример: Чтение Файла

#include <Sunrise.h>

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;

    using Sunrise::CPP::FileSystem::ReadFile;
    using Sunrise::CPP::std::vector;

    auto data = ReadFile<vector<char>>(_SR_ObfWStr(L"data.bin").CStr());
    if (!data.has_value()) {
        return _SR_ObfInt(1);
    }

    return data.value().empty() ? _SR_ObfInt(2) : _SR_ObfInt(0);
}

FileSystem::ReadFile, WriteFile и AppendFile работают с контейнерами и возвращают Sunrise::CPP::std::expected, чтобы ошибка оставалась явной частью результата.

Пример: TCP Client

#include <Sunrise.h>

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;

    using Sunrise::CPP::Network::IPv4Endpoint;
    using Sunrise::CPP::Network::TcpClient;

    TcpClient client = {};

    auto connected = client.Connect(IPv4Endpoint::Loopback(_SR_ObfInt(8080)));
    if (!connected.has_value()) {
        return _SR_ObfInt(1);
    }

    const auto message = _SR_ObfStr("ping");
    auto sent = client.SendAll(reinterpret_cast<const _SR_BYTE*>(message.CStr()), (_SR_ULONG)_SR_strlen(message.CStr()));

    return sent.has_value() ? _SR_ObfInt(0) : _SR_ObfInt(2);
}

Network-слой также содержит TcpListener, DnsClient, HttpClient, IPv4Address, IPv4Endpoint, HttpUrl и HttpResponse. Там, где это возможно, сетевой слой опирается на NT/syscall-подход вместо прямых вызовов обычных WinAPI-функций.

Пример: HTTP GET

#include <Sunrise.h>

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;

    Sunrise::CPP::Network::HttpClient http = {};

    auto response = http.Get(_SR_ObfStr("http://example.com/"));
    if (!response.has_value()) {
        return _SR_ObfInt(1);
    }

    return response.value().Ok() ? _SR_ObfInt(0) : _SR_ObfInt(2);
}

HttpClient предназначен для компактных HTTP GET сценариев и построен поверх network helpers библиотеки.

Пример: Lazy Import

#include <windows.h>
#include <Sunrise.h>

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;

    auto messageBoxW = Sunrise::CPP::LazyImport<L"user32.dll", MessageBoxW>(
        _SR_ObfWStr(L"user32.dll")
    );

    if (!messageBoxW) {
        return _SR_ObfInt(1);
    }

    messageBoxW(nullptr, _SR_ObfWStr(L"Hello"), _SR_ObfWStr(L"SunriseLib"), _SR_ObfInt(MB_OK));
    return _SR_ObfInt(0);
}

LazyImport используется, когда проекту нужно получить адрес export-функции лениво, без обычного прямого вызова через import table. Для короткой записи также есть алиас _SR_LazyImport.

Compile-Time Obfuscation

В SDK есть helpers для compile-time obfuscation строк, целых чисел и чисел с плавающей запятой. Их удобно использовать для литералов, которые не должны лежать в бинаре в прямом виде:

#include <Sunrise.h>

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;

    auto text = _SR_ObfStr("hidden text");
    int value = _SR_ObfInt(42);

    return text.CStr()[_SR_ObfInt(0)] == _SR_ObfInt('h') && value == _SR_ObfInt(42) ? _SR_ObfInt(0) : _SR_ObfInt(1);
}

Для .c файлов предусмотрены отдельные C-compatible obfuscator macros в include/CExt/Obfuscator/. C++ слой также поддерживает обфускацию строк, целых чисел и чисел с плавающей запятой на стадии компиляции с расшифровкой при использовании значения.

External API Markers

Часть функций и helpers помечается в SR-документации мета-полем uses-external-api. Такая метка помогает быстро понять, где реализация может обращаться к обычным внешним API-функциям, а не только к собственному коду библиотеки или системным вызовам.

Форма <meta name="uses-external-api" /> означает, что внешний API-вызов используется всегда. Если внутри meta-тега есть текст, он описывает условие, при котором такой вызов возможен, например загрузку модуля только когда он ещё не найден среди уже загруженных.

Структура Репозитория

  • include/ - заголовки SDK.
  • Examples/CRTBase/ - базовый CRT-compatible пример с main и DllMain.
  • Examples/NoCRTBase/ - базовый NoCRT-oriented пример с NoCRTMain и NoCRTDllMain.
  • Tests/ - наборы C и C++ тестов.
  • SunriseLib-MSVC-Release-CRT.lib - release-библиотека для MSVC CRT-compatible сборок.
  • SunriseLib-Clang-Release-CRT.lib - release-библиотека для Clang CRT-compatible сборок.
  • SunriseLib-MSVC-Release.lib - release-библиотека для MSVC NoCRT-compatible сборок.
  • SunriseLib-Clang-Release.lib - release-библиотека для Clang NoCRT-compatible сборок.
  • LICENSE - текст лицензии.

Сборка И Проверка

В репозитории есть Visual Studio project/solution files для примеров и тестов. Для проверки интеграции можно использовать:

  • Tests/Tests.sln;
  • Examples/CRTBase/CRTBase.sln;
  • Examples/NoCRTBase/NoCRTBase.sln.

Основной сценарий использования: подключить include/, выбрать подходящую release-библиотеку под ваш compiler и CRT/NoCRT режим, затем линковать её вместе с приложением или библиотекой.

Лицензия

Проект распространяется по кастомной лицензии Sunrise Reciprocal Application License 1.0.

Это не Apache License 2.0 и не OSI-approved open source license. Лицензия требует предоставлять Licensor исходный код производных или интегрированных приложений по запросу и предоставляет Licensor широкие права на использование, изменение, публикацию и распространение таких приложений и связанных материалов.

Полный текст лицензии: LICENSE

About

Windows C/C++ SDK for NoCRT and no-std-style development with CRT/std/WinAPI-compatible reimplementations, NT/syscall-oriented APIs, custom allocators, networking, and compile-time obfuscation.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors