From 0c5c3e21f7c424cc0ecd5e23fd8971702a4b929d Mon Sep 17 00:00:00 2001 From: xnxkzeu Date: Wed, 2 Sep 2026 17:21:00 +0400 Subject: [PATCH 1/2] Implemented factory pattern instead of splitting initialization in constructor and "initialize" method Replaced getCurrentProcess constexpr with static since reinterpret_cast is not allowed in constexpr functions Updated move-constructor to remove unnecessary default-constructing + move-assignment Updated examples accordingly --- examples/basic-usage.cpp | 9 +- examples/custom-generator.cpp | 6 +- include/syscalls-cpp/aliases.hpp | 42 +++++--- include/syscalls-cpp/shared.hpp | 2 +- include/syscalls-cpp/syscall.hpp | 176 +++++++++++++++++-------------- 5 files changed, 134 insertions(+), 101 deletions(-) diff --git a/examples/basic-usage.cpp b/examples/basic-usage.cpp index 9457b3a..86a5d57 100644 --- a/examples/basic-usage.cpp +++ b/examples/basic-usage.cpp @@ -1,14 +1,15 @@ #include #include -int main() +int main() { - syscall::Manager syscallManager; - if (!syscallManager.initialize()) - { + std::optional optSyscallManager = syscall::Manager::initialize(); + if (!optSyscallManager.has_value()) { std::cerr << "initialization failed!\n"; return 1; } + auto& syscallManager = optSyscallManager.value(); + PVOID pBaseAddress = nullptr; SIZE_T uSize = 0x1000; diff --git a/examples/custom-generator.cpp b/examples/custom-generator.cpp index 8f9c451..fd56889 100644 --- a/examples/custom-generator.cpp +++ b/examples/custom-generator.cpp @@ -240,13 +240,15 @@ struct EncryptedShellGenerator int main() { - syscall::Manager < syscall::policies::allocator::section, EncryptedShellGenerator> syscallManager; - if (!syscallManager.initialize()) + std::optional optSyscallManager = syscall::Manager::initialize(); + if (!optSyscallManager.has_value()) { std::cerr << "failed to initialize syscall manager" << std::endl; return 1; } + auto& syscallManager = optSyscallManager.value(); + std::cout << "syscall manager initialized successfully" << std::endl; NTSTATUS status; diff --git a/include/syscalls-cpp/aliases.hpp b/include/syscalls-cpp/aliases.hpp index 453fdfb..09c1d33 100644 --- a/include/syscalls-cpp/aliases.hpp +++ b/include/syscalls-cpp/aliases.hpp @@ -5,27 +5,41 @@ namespace syscall { - using DefaultParserChain = syscall::ParserChain_t< - syscall::policies::parser::directory, - syscall::policies::parser::signature - >; - - // @note / sapdragon: fucking templates, is that a legal cpp hack? unpack overloads... template - class Manager : public Manager + class Manager; + + template + class Manager + : public Manager { + public: + static std::optional initialize( const std::vector& vecModuleKeys = { SYSCALL_ID("ntdll.dll") } ) + { + std::optional optManager = Manager::initialize(vecModuleKeys); + + if (!optManager.has_value()) + return std::nullopt; + + return Manager(std::move(optManager.value())); + } }; template< typename AllocPolicy, typename StubPolicy, IsSyscallParsingPolicy... ParsersInChain > - class Manager> + class Manager : public ManagerImpl { - }; - - template< typename AllocPolicy, typename StubPolicy, typename FirstParser, typename... FallbackParsers> - class Manager - : public ManagerImpl - { + Manager(ManagerImpl&& managerImpl) + : ManagerImpl(std::move(managerImpl)) + { } + public: + static std::optional initialize(const std::vector& vecModuleKeys = { SYSCALL_ID("ntdll.dll") }) + { + std::optional optManagerImpl = ManagerImpl::initialize(vecModuleKeys); + if (!optManagerImpl.has_value()) + return std::nullopt; + + return Manager(std::move(optManagerImpl.value())); + } }; #if SYSCALL_PLATFORM_WINDOWS_64 diff --git a/include/syscalls-cpp/shared.hpp b/include/syscalls-cpp/shared.hpp index 66fc816..173069d 100644 --- a/include/syscalls-cpp/shared.hpp +++ b/include/syscalls-cpp/shared.hpp @@ -17,7 +17,7 @@ namespace syscall::native } - [[nodiscard]] constexpr HANDLE getCurrentProcess() noexcept + [[nodiscard]] static HANDLE getCurrentProcess() noexcept { return reinterpret_cast(-1); } diff --git a/include/syscalls-cpp/syscall.hpp b/include/syscalls-cpp/syscall.hpp index 5bce018..b341c6b 100644 --- a/include/syscalls-cpp/syscall.hpp +++ b/include/syscalls-cpp/syscall.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -124,12 +124,6 @@ namespace syscall { T::parse(module) } -> std::convertible_to>; }; - template - struct ParserChain_t - { - static_assert(sizeof...(IParsers) > 0, "Parsedchain_t cannot be empty."); - }; - template< typename IAllocationPolicy, typename IStubGenerationPolicy, @@ -160,16 +154,31 @@ namespace syscall "1. 'static std::vector parse(const ModuleInfo_t&);'" ); - std::mutex m_mutex; + ManagerImpl(std::vector&& vecParsedSyscalls, void* pSyscallRegion, std::vector&& vecSyscallGadgets, std::size_t uRegionSize, HANDLE hObjectHandle, void* pVehHandle) + : m_vecParsedSyscalls(std::move(vecParsedSyscalls)) + , m_pSyscallRegion(pSyscallRegion) + , m_vecSyscallGadgets(std::move(vecSyscallGadgets)) + , m_uRegionSize(uRegionSize) + , m_hObjectHandle(hObjectHandle) + , m_pVehHandle(pVehHandle) + { + } + std::vector m_vecParsedSyscalls; void* m_pSyscallRegion = nullptr; std::vector m_vecSyscallGadgets; size_t m_uRegionSize = 0; - bool m_bInitialized = false; HANDLE m_hObjectHandle = nullptr; void* m_pVehHandle = nullptr; + + struct SyscallInitInfo_t + { + void* m_pSyscallRegion = nullptr; + std::size_t m_uRegionSize = 0; + HANDLE m_hObjectHandle = nullptr; + }; + public: - ManagerImpl() = default; ~ManagerImpl() { if constexpr (platform::isWindows64) @@ -182,53 +191,56 @@ namespace syscall ManagerImpl(const ManagerImpl&) = delete; ManagerImpl& operator=(const ManagerImpl&) = delete; ManagerImpl(ManagerImpl&& other) noexcept + : m_vecParsedSyscalls(std::move(other.m_vecParsedSyscalls)) + , m_pSyscallRegion(other.m_pSyscallRegion) + , m_vecSyscallGadgets(std::move(other.m_vecSyscallGadgets)) + , m_uRegionSize(other.m_uRegionSize) + , m_hObjectHandle(other.m_hObjectHandle) + , m_pVehHandle(other.m_pVehHandle) { - std::lock_guard lock(other.m_mutex); - m_vecParsedSyscalls = std::move(other.m_vecParsedSyscalls); - m_pSyscallRegion = other.m_pSyscallRegion; - m_vecSyscallGadgets = std::move(other.m_vecSyscallGadgets); - m_uRegionSize = other.m_uRegionSize; - m_bInitialized = other.m_bInitialized; - m_hObjectHandle = other.m_hObjectHandle; other.m_pSyscallRegion = nullptr; other.m_hObjectHandle = nullptr; + other.m_pVehHandle = nullptr; } ManagerImpl& operator=(ManagerImpl&& other) noexcept { if (this != &other) { - std::scoped_lock lock(m_mutex, other.m_mutex); IAllocationPolicy::release(m_pSyscallRegion, m_hObjectHandle); + + if constexpr (platform::isWindows64) + if (m_pVehHandle) + RemoveVectoredExceptionHandler(m_pVehHandle); + m_vecParsedSyscalls = std::move(other.m_vecParsedSyscalls); m_pSyscallRegion = other.m_pSyscallRegion; m_vecSyscallGadgets = std::move(other.m_vecSyscallGadgets); m_uRegionSize = other.m_uRegionSize; - m_bInitialized = other.m_bInitialized; m_hObjectHandle = other.m_hObjectHandle; + m_pVehHandle = other.m_pVehHandle; other.m_pSyscallRegion = nullptr; other.m_hObjectHandle = nullptr; + other.m_pVehHandle = nullptr; } return *this; } - [[nodiscard]] bool initialize(const std::vector& vecModuleKeys = { SYSCALL_ID("ntdll.dll") }) + protected: + [[nodiscard]] static std::optional initialize(const std::vector& vecModuleKeys) { - if (m_bInitialized) - return true; - - std::lock_guard lock(m_mutex); - - if (m_bInitialized) - return true; + std::vector vecSyscallGadgets = {}; #if SYSCALL_PLATFORM_WINDOWS_64 if constexpr (IStubGenerationPolicy::bRequiresGadget) - if (!findSyscallGadgets()) - return false; + { + vecSyscallGadgets = findSyscallGadgets(); + if (vecSyscallGadgets.empty()) + return std::nullopt; + } #endif - m_vecParsedSyscalls.clear(); + std::vector vecParsedSyscalls = {}; for (const auto& moduleKey : vecModuleKeys) { ModuleInfo_t moduleInfo; @@ -237,52 +249,46 @@ namespace syscall std::vector moduleSyscalls = tryParseSyscalls(moduleInfo); - m_vecParsedSyscalls.insert(m_vecParsedSyscalls.end(), moduleSyscalls.begin(), moduleSyscalls.end()); + vecParsedSyscalls.insert(vecParsedSyscalls.end(), moduleSyscalls.begin(), moduleSyscalls.end()); } - if (m_vecParsedSyscalls.empty()) - return false; + if (vecParsedSyscalls.empty()) + return std::nullopt; + + if (vecParsedSyscalls.size() > 1) + for (size_t i = vecParsedSyscalls.size() - 1; i > 0; --i) + std::swap(vecParsedSyscalls[i], vecParsedSyscalls[native::rdtscp() % (i + 1)]); + + for (size_t i = 0; i < vecParsedSyscalls.size(); ++i) + vecParsedSyscalls[i].m_uOffset = static_cast(i * IStubGenerationPolicy::getStubSize()); - if (m_vecParsedSyscalls.size() > 1) - for (size_t i = m_vecParsedSyscalls.size() - 1; i > 0; --i) - std::swap(m_vecParsedSyscalls[i], m_vecParsedSyscalls[native::rdtscp() % (i + 1)]); - for (size_t i = 0; i < m_vecParsedSyscalls.size(); ++i) - m_vecParsedSyscalls[i].m_uOffset = static_cast(i * IStubGenerationPolicy::getStubSize()); + std::ranges::sort(vecParsedSyscalls, std::less{}, &SyscallEntry_t::m_key); + std::optional optSyscallInitInfo = createSyscalls(vecParsedSyscalls, vecSyscallGadgets); + if (!optSyscallInitInfo.has_value()) + return std::nullopt; - std::ranges::sort(m_vecParsedSyscalls, std::less{}, &SyscallEntry_t::m_key); + const SyscallInitInfo_t& syscallInitInfo = optSyscallInitInfo.value(); - m_bInitialized = createSyscalls(); - if (m_bInitialized) + void* pVehHandle = nullptr; + if constexpr (std::is_same_v) { - if constexpr (std::is_same_v) + pVehHandle = AddVectoredExceptionHandler(1, VectoredExceptionHandler); + if (!pVehHandle) { - m_pVehHandle = AddVectoredExceptionHandler(1, VectoredExceptionHandler); - if (!m_pVehHandle) - { - IAllocationPolicy::release(m_pSyscallRegion, m_hObjectHandle); - m_pSyscallRegion = nullptr; - m_bInitialized = false; - } + IAllocationPolicy::release(syscallInitInfo.m_pSyscallRegion, syscallInitInfo.m_hObjectHandle); + return std::nullopt; } } - return m_bInitialized; + return ManagerImpl(std::move(vecParsedSyscalls), syscallInitInfo.m_pSyscallRegion, std::move(vecSyscallGadgets), syscallInitInfo.m_uRegionSize, syscallInitInfo.m_hObjectHandle, pVehHandle); } + + public: template [[nodiscard]] SYSCALL_FORCE_INLINE Ret invoke(const SyscallKey_t& syscallId, Args... args) { - if (!m_bInitialized) - { - if (!initialize()) - { - if constexpr (std::is_same_v) - return native::STATUS_UNSUCCESSFUL; - - return Ret{}; - } - } auto it = std::ranges::lower_bound(m_vecParsedSyscalls, syscallId, std::less{}, &SyscallEntry_t::m_key); if (it == m_vecParsedSyscalls.end() || it->m_key != syscallId) @@ -322,7 +328,7 @@ namespace syscall } private: template - std::vector tryParseSyscalls(const ModuleInfo_t& moduleInfo) + static std::vector tryParseSyscalls(const ModuleInfo_t& moduleInfo) { auto vecSyscalls = CurrentParser::parse(moduleInfo); @@ -336,22 +342,22 @@ namespace syscall } - bool createSyscalls() + static std::optional createSyscalls(const std::vector& vecParsedSyscalls, const std::vector& vecSyscallGadgets) { - if (m_vecParsedSyscalls.empty()) - return false; + if (vecParsedSyscalls.empty()) + return std::nullopt; #if SYSCALL_PLATFORM_WINDOWS_64 if constexpr (IStubGenerationPolicy::bRequiresGadget) - if (m_vecSyscallGadgets.empty()) - return false; + if (vecSyscallGadgets.empty()) + return std::nullopt; #endif - m_uRegionSize = m_vecParsedSyscalls.size() * IStubGenerationPolicy::getStubSize(); - std::vector vecTempBuffer(m_uRegionSize); + std::size_t uRegionSize = vecParsedSyscalls.size() * IStubGenerationPolicy::getStubSize(); + std::vector vecTempBuffer(uRegionSize); - const size_t uGadgetsCount = m_vecSyscallGadgets.size(); + const size_t uGadgetsCount = vecSyscallGadgets.size(); - for (const SyscallEntry_t& entry : m_vecParsedSyscalls) + for (const SyscallEntry_t& entry : vecParsedSyscalls) { uint8_t* pStubLocation = vecTempBuffer.data() + entry.m_uOffset; void* pGadgetForStub = nullptr; @@ -359,17 +365,27 @@ namespace syscall if constexpr (IStubGenerationPolicy::bRequiresGadget) { const size_t uRandomIndex = native::rdtscp() % uGadgetsCount; - pGadgetForStub = m_vecSyscallGadgets[uRandomIndex]; + pGadgetForStub = vecSyscallGadgets[uRandomIndex]; } #endif IStubGenerationPolicy::generate(pStubLocation, entry.m_uSyscallNumber, pGadgetForStub); } - return IAllocationPolicy::allocate(m_uRegionSize, vecTempBuffer, m_pSyscallRegion, m_hObjectHandle); + void* pSyscallRegion = nullptr; + HANDLE hObjectHandle = {}; + + if (!IAllocationPolicy::allocate(uRegionSize, vecTempBuffer, pSyscallRegion, hObjectHandle)) + return std::nullopt; + + return SyscallInitInfo_t { + .m_pSyscallRegion = pSyscallRegion, + .m_uRegionSize = uRegionSize, + .m_hObjectHandle = hObjectHandle, + }; } - bool getModuleInfo(SyscallKey_t moduleKey, ModuleInfo_t& info) + static bool getModuleInfo(SyscallKey_t moduleKey, ModuleInfo_t& info) { HMODULE hModule = native::getModuleBase(moduleKey); if (!hModule) @@ -395,11 +411,11 @@ namespace syscall } #if SYSCALL_PLATFORM_WINDOWS_64 - bool findSyscallGadgets() + static std::vector findSyscallGadgets() { ModuleInfo_t ntdll; if (!getModuleInfo(SYSCALL_ID("ntdll.dll"), ntdll)) - return false; + return {}; IMAGE_SECTION_HEADER* pSections = IMAGE_FIRST_SECTION(ntdll.m_pNtHeaders); uint8_t* pTextSection = nullptr; @@ -415,14 +431,14 @@ namespace syscall } if (!pTextSection || !uTextSectionSize) - return false; + return {}; - m_vecSyscallGadgets.clear(); + std::vector vecSyscallGadgets = {}; for (DWORD i = 0; i < uTextSectionSize - 2; ++i) if (pTextSection[i] == 0x0F && pTextSection[i + 1] == 0x05 && pTextSection[i + 2] == 0xC3) - m_vecSyscallGadgets.push_back(&pTextSection[i]); + vecSyscallGadgets.push_back(&pTextSection[i]); - return !m_vecSyscallGadgets.empty(); + return vecSyscallGadgets; } #endif @@ -431,4 +447,4 @@ namespace syscall #include "aliases.hpp" -#endif +#endif From 3c26ce0610a450a088e7f32ac37e2c076451a079 Mon Sep 17 00:00:00 2001 From: xnxkzeu Date: Wed, 2 Sep 2026 17:41:15 +0400 Subject: [PATCH 2/2] Updated integration tests --- tests/test_integration.cpp | 191 +++++++++++++------------------------ 1 file changed, 68 insertions(+), 123 deletions(-) diff --git a/tests/test_integration.cpp b/tests/test_integration.cpp index 412a602..e0773b3 100644 --- a/tests/test_integration.cpp +++ b/tests/test_integration.cpp @@ -6,74 +6,52 @@ class SyscallManagerTest : public ::testing::Test {}; TEST_F(SyscallManagerTest, InitializesWithSectionDirect) { - syscall::Manager< - syscall::policies::allocator::section, - syscall::policies::generator::direct - > manager; + std::optional optManager = syscall::Manager::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); } TEST_F(SyscallManagerTest, InitializesWithHeapDirect) { - syscall::Manager< - syscall::policies::allocator::heap, - syscall::policies::generator::direct - > manager; + std::optional optManager = syscall::Manager::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); } TEST_F(SyscallManagerTest, InitializesWithMemoryDirect) { - syscall::Manager< - syscall::policies::allocator::memory, - syscall::policies::generator::direct - > manager; + std::optional optManager = syscall::Manager::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); } #if SYSCALL_PLATFORM_WINDOWS_64 TEST_F(SyscallManagerTest, InitializesWithGadgetX64) { - syscall::Manager< - syscall::policies::allocator::section, - syscall::policies::generator::gadget - > manager; + std::optional optManager = syscall::Manager::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); } TEST_F(SyscallManagerTest, InitializesWithExceptionX64) { - syscall::Manager< - syscall::policies::allocator::section, - syscall::policies::generator::exception - > manager; + std::optional optManager = syscall::Manager::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); } #endif -TEST_F(SyscallManagerTest, DoubleInitSucceeds) -{ - syscall::SectionDirectManager manager; - EXPECT_TRUE(manager.initialize()); - EXPECT_TRUE(manager.initialize()); -} - TEST_F(SyscallManagerTest, MoveConstructorWorks) { - syscall::SectionDirectManager manager1; - ASSERT_TRUE(manager1.initialize()); + std::optional optManager = syscall::SectionDirectManager::initialize(); + ASSERT_TRUE(optManager.has_value()); - syscall::SectionDirectManager manager2 = std::move(manager1); + syscall::SectionDirectManager movedManager = std::move(optManager.value()); PVOID pBaseAddress = nullptr; SIZE_T uRegionSize = 0x1000; - NTSTATUS status = manager2.invoke( + NTSTATUS status = movedManager.invoke( SYSCALL_ID("NtAllocateVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -88,7 +66,7 @@ TEST_F(SyscallManagerTest, MoveConstructorWorks) if (pBaseAddress) { uRegionSize = 0; - manager2.invoke( + movedManager.invoke( SYSCALL_ID("NtFreeVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -101,11 +79,12 @@ TEST_F(SyscallManagerTest, MoveConstructorWorks) class SyscallInvokeTest : public ::testing::Test { protected: - syscall::SectionDirectManager manager; + std::optional optManager; void SetUp() override { - ASSERT_TRUE(manager.initialize()); + optManager = syscall::SectionDirectManager::initialize(); + ASSERT_TRUE(optManager.has_value()); } }; @@ -114,7 +93,7 @@ TEST_F(SyscallInvokeTest, NtAllocateVirtualMemory) PVOID pBaseAddress = nullptr; SIZE_T uRegionSize = 0x1000; - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtAllocateVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -131,7 +110,7 @@ TEST_F(SyscallInvokeTest, NtAllocateVirtualMemory) if (pBaseAddress) { uRegionSize = 0; - manager.invoke( + optManager->invoke( SYSCALL_ID("NtFreeVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -144,7 +123,7 @@ TEST_F(SyscallInvokeTest, NtAllocateVirtualMemory) TEST_F(SyscallInvokeTest, NtQuerySystemInformation) { ULONG uReturnLength = 0; - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtQuerySystemInformation"), 0, nullptr, @@ -158,7 +137,7 @@ TEST_F(SyscallInvokeTest, NtQuerySystemInformation) TEST_F(SyscallInvokeTest, InvalidSyscallReturnsNotFound) { - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtThisFunctionDoesNotExist123456") ); @@ -167,7 +146,7 @@ TEST_F(SyscallInvokeTest, InvalidSyscallReturnsNotFound) TEST_F(SyscallInvokeTest, NtCloseInvalidHandle) { - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtClose"), reinterpret_cast(0xDEADBEEF) ); @@ -272,11 +251,10 @@ TEST_F(NativeApiTest, RdtscpReturnsValue) TEST(ManagerOwnershipTest, MoveAssignmentWorks) { - syscall::SectionDirectManager manager1; - ASSERT_TRUE(manager1.initialize()); + std::optional manager1 = syscall::SectionDirectManager::initialize(); + ASSERT_TRUE(manager1.has_value()); - syscall::SectionDirectManager manager2; - manager2 = std::move(manager1); + syscall::SectionDirectManager manager2 = std::move(manager1.value()); PVOID pAddress = nullptr; SIZE_T uRegionSize = 0x1000; @@ -476,18 +454,18 @@ class SyscallPolicyTest : public ::testing::Test {}; TEST_F(SyscallPolicyTest, SignatureParserDirect) { - syscall::Manager< + std::optional optManager = syscall::Manager< syscall::policies::allocator::section, syscall::policies::generator::direct, syscall::policies::parser::signature - > manager; + >::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); PVOID pBaseAddress = nullptr; SIZE_T uRegionSize = 0x1000; - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtAllocateVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -502,7 +480,7 @@ TEST_F(SyscallPolicyTest, SignatureParserDirect) if (pBaseAddress) { uRegionSize = 0; - manager.invoke( + optManager->invoke( SYSCALL_ID("NtFreeVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -514,15 +492,15 @@ TEST_F(SyscallPolicyTest, SignatureParserDirect) TEST_F(SyscallPolicyTest, DirectoryParserDirect) { - syscall::Manager< + std::optional optManager = syscall::Manager< syscall::policies::allocator::section, syscall::policies::generator::direct, syscall::policies::parser::directory - > manager; + >::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtClose"), reinterpret_cast(0xDEADBEEF) ); @@ -532,16 +510,16 @@ TEST_F(SyscallPolicyTest, DirectoryParserDirect) TEST_F(SyscallPolicyTest, HeapAllocatorWithSignatureParser) { - syscall::Manager< - syscall::policies::allocator::heap, - syscall::policies::generator::direct, - syscall::policies::parser::signature - > manager; + std::optional optManager = syscall::Manager< + syscall::policies::allocator::heap, + syscall::policies::generator::direct, + syscall::policies::parser::signature + >::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); ULONG uReturnLength = 0; - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtQuerySystemInformation"), 0, nullptr, @@ -554,15 +532,15 @@ TEST_F(SyscallPolicyTest, HeapAllocatorWithSignatureParser) TEST_F(SyscallPolicyTest, MemoryAllocatorWithSignatureParser) { - syscall::Manager< + std::optional optManager = syscall::Manager< syscall::policies::allocator::memory, syscall::policies::generator::direct, syscall::policies::parser::signature - > manager; + >::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager->initialize()); - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtClose"), reinterpret_cast(0xDEADBEEF) ); @@ -573,15 +551,15 @@ TEST_F(SyscallPolicyTest, MemoryAllocatorWithSignatureParser) #if SYSCALL_PLATFORM_WINDOWS_64 TEST_F(SyscallPolicyTest, GadgetGeneratorWithSignatureParser) { - syscall::Manager< + std::optional optManager = syscall::Manager< syscall::policies::allocator::section, syscall::policies::generator::gadget, syscall::policies::parser::signature - > manager; + >::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtClose"), reinterpret_cast(0xDEADBEEF) ); @@ -591,15 +569,15 @@ TEST_F(SyscallPolicyTest, GadgetGeneratorWithSignatureParser) TEST_F(SyscallPolicyTest, ExceptionGeneratorWithSignatureParser) { - syscall::Manager< + std::optional optManager = syscall::Manager< syscall::policies::allocator::section, syscall::policies::generator::exception, syscall::policies::parser::signature - > manager; + >::initialize(); - EXPECT_TRUE(manager.initialize()); + EXPECT_TRUE(optManager.has_value()); - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtClose"), reinterpret_cast(0xDEADBEEF) ); @@ -608,50 +586,17 @@ TEST_F(SyscallPolicyTest, ExceptionGeneratorWithSignatureParser) } #endif -TEST_F(SyscallPolicyTest, InvokeWithoutInitialize) -{ - syscall::SectionDirectManager manager; - - PVOID pBaseAddress = nullptr; - SIZE_T uRegionSize = 0x1000; - - NTSTATUS status = manager.invoke( - SYSCALL_ID("NtAllocateVirtualMemory"), - syscall::native::getCurrentProcess(), - &pBaseAddress, - 0, - &uRegionSize, - MEM_COMMIT | MEM_RESERVE, - PAGE_READWRITE - ); - - EXPECT_TRUE(NT_SUCCESS(status)); - EXPECT_NE(pBaseAddress, nullptr); - - if (pBaseAddress) - { - uRegionSize = 0; - manager.invoke( - SYSCALL_ID("NtFreeVirtualMemory"), - syscall::native::getCurrentProcess(), - &pBaseAddress, - &uRegionSize, - MEM_RELEASE - ); - } -} - TEST_F(SyscallPolicyTest, MultipleSyscallsSequentially) { - syscall::SectionDirectManager manager; - ASSERT_TRUE(manager.initialize()); + std::optional optManager = syscall::SectionDirectManager::initialize(); + ASSERT_TRUE(optManager.has_value()); for (int i = 0; i < 100; ++i) { PVOID pBaseAddress = nullptr; SIZE_T uRegionSize = 0x1000; - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtAllocateVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -666,7 +611,7 @@ TEST_F(SyscallPolicyTest, MultipleSyscallsSequentially) if (pBaseAddress) { uRegionSize = 0; - manager.invoke( + optManager->invoke( SYSCALL_ID("NtFreeVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -679,13 +624,13 @@ TEST_F(SyscallPolicyTest, MultipleSyscallsSequentially) TEST_F(SyscallPolicyTest, NtProtectVirtualMemory) { - syscall::SectionDirectManager manager; - ASSERT_TRUE(manager.initialize()); + std::optional optManager = syscall::SectionDirectManager::initialize(); + ASSERT_TRUE(optManager.has_value()); PVOID pBaseAddress = nullptr; SIZE_T uRegionSize = 0x1000; - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtAllocateVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -702,7 +647,7 @@ TEST_F(SyscallPolicyTest, NtProtectVirtualMemory) SIZE_T uProtectSize = 0x1000; PVOID pProtectAddress = pBaseAddress; - status = manager.invoke( + status = optManager->invoke( SYSCALL_ID("NtProtectVirtualMemory"), syscall::native::getCurrentProcess(), &pProtectAddress, @@ -715,7 +660,7 @@ TEST_F(SyscallPolicyTest, NtProtectVirtualMemory) EXPECT_EQ(uOldProtect, PAGE_READWRITE); uRegionSize = 0; - manager.invoke( + optManager->invoke( SYSCALL_ID("NtFreeVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -726,13 +671,13 @@ TEST_F(SyscallPolicyTest, NtProtectVirtualMemory) TEST_F(SyscallPolicyTest, NtQueryVirtualMemory) { - syscall::SectionDirectManager manager; - ASSERT_TRUE(manager.initialize()); + std::optional optManager = syscall::SectionDirectManager::initialize(); + ASSERT_TRUE(optManager.has_value()); PVOID pBaseAddress = nullptr; SIZE_T uRegionSize = 0x1000; - NTSTATUS status = manager.invoke( + NTSTATUS status = optManager->invoke( SYSCALL_ID("NtAllocateVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress, @@ -747,7 +692,7 @@ TEST_F(SyscallPolicyTest, NtQueryVirtualMemory) MEMORY_BASIC_INFORMATION memInfo{}; SIZE_T uReturnLength = 0; - status = manager.invoke( + status = optManager->invoke( SYSCALL_ID("NtQueryVirtualMemory"), syscall::native::getCurrentProcess(), pBaseAddress, @@ -763,7 +708,7 @@ TEST_F(SyscallPolicyTest, NtQueryVirtualMemory) EXPECT_EQ(memInfo.State, MEM_COMMIT); uRegionSize = 0; - manager.invoke( + optManager->invoke( SYSCALL_ID("NtFreeVirtualMemory"), syscall::native::getCurrentProcess(), &pBaseAddress,