From 4789e9b721e0fb32740fe2cdd7d7a9404b4632a2 Mon Sep 17 00:00:00 2001 From: MentatBot <160964065+MentatBot@users.noreply.github.com> Date: Fri, 18 Apr 2025 22:01:33 +0000 Subject: [PATCH 01/23] Fix incomplete types, undeclared identifiers, and AIIntegration namespace This PR addresses the second set of build errors: 1. Fixed incomplete types and undeclared identifiers related to Mach-O structures: - Moved all code using Mach-O types from headers to implementation (.cpp) files - Added proper forward declarations for implementation functions - Created separate *Impl() functions for code that requires system headers 2. Fixed AIIntegration namespace issue: - Added missing AIIntegration class definition in cpp file - Added proper implementation and interface for AIIntegration 3. Fixed unused parameter warning: - Added [[maybe_unused]] attribute to the 'mode' parameter in SetOnlineMode These changes preserve all the security and anti-tamper functionality while ensuring it can be compiled properly. By moving all system header dependencies to implementation files, we avoid extern "C" block conflicts. --- source/cpp/ios/ai_features/AIConfig.h | 2 +- source/cpp/ios/ai_features/AIIntegration.cpp | 32 ++- source/cpp/security/anti_tamper.cpp | 203 ++++++++++++++++++- source/cpp/security/anti_tamper.hpp | 191 ++--------------- 4 files changed, 245 insertions(+), 183 deletions(-) diff --git a/source/cpp/ios/ai_features/AIConfig.h b/source/cpp/ios/ai_features/AIConfig.h index 148c39c0..3d93c7ea 100644 --- a/source/cpp/ios/ai_features/AIConfig.h +++ b/source/cpp/ios/ai_features/AIConfig.h @@ -314,7 +314,7 @@ class AIConfig { * @brief Set online mode (always sets to OfflineOnly in this implementation) * @param mode Online mode (ignored) */ - void SetOnlineMode(OnlineMode mode) { + void SetOnlineMode([[maybe_unused]] OnlineMode mode) { // Always use offline only mode in this implementation SetOption("online_mode", "offline_only"); } diff --git a/source/cpp/ios/ai_features/AIIntegration.cpp b/source/cpp/ios/ai_features/AIIntegration.cpp index aa17e4dc..11485f48 100644 --- a/source/cpp/ios/ai_features/AIIntegration.cpp +++ b/source/cpp/ios/ai_features/AIIntegration.cpp @@ -6,17 +6,31 @@ namespace iOS { namespace AIFeatures { -// Get general assistant model -std::shared_ptr AIIntegration::GetGeneralAssistantModel() const { - if (m_integration != nullptr) { - // Cast to AISystemInitializer - AISystemInitializer* initializer = static_cast(m_integration); - if (initializer) { - return initializer->GetGeneralAssistantModel(); +// Class implementation for AIIntegration +// This class is needed for internal implementation while AIIntegrationInterface is the public API +class AIIntegration { +private: + void* m_integration; + +public: + AIIntegration() : m_integration(nullptr) {} + + void SetIntegration(void* integration) { + m_integration = integration; + } + + // Get general assistant model + std::shared_ptr GetGeneralAssistantModel() const { + if (m_integration != nullptr) { + // Cast to AISystemInitializer + AISystemInitializer* initializer = static_cast(m_integration); + if (initializer) { + return initializer->GetGeneralAssistantModel(); + } } + return nullptr; } - return nullptr; -} +}; } // namespace AIFeatures } // namespace iOS diff --git a/source/cpp/security/anti_tamper.cpp b/source/cpp/security/anti_tamper.cpp index 08d25633..973fc658 100644 --- a/source/cpp/security/anti_tamper.cpp +++ b/source/cpp/security/anti_tamper.cpp @@ -35,7 +35,9 @@ std::atomic AntiTamper::s_checkInterval(5000); // Default: 5 seconds std::vector AntiTamper::s_codeHashes; std::map AntiTamper::s_functionChecksums; -// Implementation of helper method that requires system headers +// Implementation of helper methods that require system headers + +// Check for debugger using process info bool AntiTamper::CheckDebuggerUsingProcInfo() { #ifdef __APPLE__ struct kinfo_proc info; @@ -49,6 +51,205 @@ bool AntiTamper::CheckDebuggerUsingProcInfo() { return false; } +// Implementation of code integrity checks +bool AntiTamper::CheckCodeIntegrityImpl() { +#ifdef __APPLE__ + bool integrityIntact = true; + + // Get information about all loaded modules + uint32_t count = _dyld_image_count(); + + for (uint32_t i = 0; i < count; i++) { + const char* imageName = _dyld_get_image_name(i); + const struct mach_header* header = _dyld_get_image_header(i); + + // Check if this is our dylib + if (strstr(imageName, "libmylibrary.dylib") != nullptr || + strstr(imageName, "roblox_execution") != nullptr) { + + // Parse the Mach-O header to find the TEXT segment + uintptr_t textStart = 0; + size_t textSize = 0; + + if (header->magic == MH_MAGIC_64) { + const struct mach_header_64* header64 = reinterpret_cast(header); + const struct load_command* cmd = reinterpret_cast(header64 + 1); + + for (uint32_t j = 0; j < header64->ncmds; j++) { + if (cmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64* seg = reinterpret_cast(cmd); + + if (strcmp(seg->segname, "__TEXT") == 0) { + textStart = reinterpret_cast(header) + seg->vmaddr; + textSize = seg->vmsize; + break; + } + } + + cmd = reinterpret_cast( + reinterpret_cast(cmd) + cmd->cmdsize); + } + } else if (header->magic == MH_MAGIC) { + const struct load_command* cmd = reinterpret_cast(header + 1); + + for (uint32_t j = 0; j < header->ncmds; j++) { + if (cmd->cmd == LC_SEGMENT) { + const struct segment_command* seg = reinterpret_cast(cmd); + + if (strcmp(seg->segname, "__TEXT") == 0) { + textStart = reinterpret_cast(header) + seg->vmaddr; + textSize = seg->vmsize; + break; + } + } + + cmd = reinterpret_cast( + reinterpret_cast(cmd) + cmd->cmdsize); + } + } + + // If we found the TEXT segment, verify its integrity + if (textStart != 0 && textSize != 0) { + uint32_t newChecksum = CalculateChecksum(reinterpret_cast(textStart), textSize); + + // If this is the first time, store the checksum + if (s_codeHashes.empty()) { + std::lock_guard lock(s_mutex); + s_codeHashes.resize(sizeof(newChecksum)); + memcpy(s_codeHashes.data(), &newChecksum, sizeof(newChecksum)); + } else { + // Compare with previously stored checksum + uint32_t storedChecksum; + memcpy(&storedChecksum, s_codeHashes.data(), sizeof(storedChecksum)); + + if (newChecksum != storedChecksum) { + integrityIntact = false; + HandleTampering(SecurityCheckType::CODE_INTEGRITY, + "Code integrity violation in " + std::string(imageName)); + break; + } + } + } + } + } + + return integrityIntact; +#else + return true; +#endif +} + +// Implementation of dylib hook detection +bool AntiTamper::CheckForDylibHooksImpl() { +#ifdef __APPLE__ + bool noHooksDetected = true; + + // This is a simplified check that looks for common hook patterns in memory + // A real implementation would be more sophisticated, checking for specific hook types + + // Get information about all loaded modules + uint32_t count = _dyld_image_count(); + + for (uint32_t i = 0; i < count; i++) { + const char* imageName = _dyld_get_image_name(i); + + // Check if this is our dylib + if (strstr(imageName, "libmylibrary.dylib") != nullptr || + strstr(imageName, "roblox_execution") != nullptr) { + + const struct mach_header* header = _dyld_get_image_header(i); + + // Look for common hook patterns (e.g., JMP instructions) in code sections + // This is a simplified example - real implementation would be more thorough + if (header->magic == MH_MAGIC_64) { + const struct mach_header_64* header64 = reinterpret_cast(header); + const struct load_command* cmd = reinterpret_cast(header64 + 1); + + for (uint32_t j = 0; j < header64->ncmds; j++) { + if (cmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64* seg = reinterpret_cast(cmd); + + if (strcmp(seg->segname, "__TEXT") == 0) { + // Scan the text segment for hook patterns + const uint8_t* textStart = reinterpret_cast(header) + seg->vmaddr; + + // Common x86_64 JMP pattern is 0xFF 0x25 followed by a 32-bit displacement + for (size_t k = 0; k < seg->vmsize - 6; k++) { + if (textStart[k] == 0xFF && textStart[k + 1] == 0x25) { + // Potential hook found, further verification would be needed + // This is just a simplified example + noHooksDetected = false; + HandleTampering(SecurityCheckType::DYLIB_HOOKS, + "Potential hook detected in " + std::string(imageName)); + break; + } + } + } + } + + cmd = reinterpret_cast( + reinterpret_cast(cmd) + cmd->cmdsize); + } + } + } + } + + return noHooksDetected; +#else + return true; +#endif +} + +// Implementation of memory protection checks +bool AntiTamper::CheckMemoryProtectionImpl() { +#ifdef __APPLE__ + bool protectionValid = true; + + // Get information about all loaded modules + uint32_t count = _dyld_image_count(); + + for (uint32_t i = 0; i < count; i++) { + const char* imageName = _dyld_get_image_name(i); + + // Check if this is our dylib + if (strstr(imageName, "libmylibrary.dylib") != nullptr || + strstr(imageName, "roblox_execution") != nullptr) { + + const struct mach_header* header = _dyld_get_image_header(i); + + // Check protection of code segments + if (header->magic == MH_MAGIC_64) { + const struct mach_header_64* header64 = reinterpret_cast(header); + const struct load_command* cmd = reinterpret_cast(header64 + 1); + + for (uint32_t j = 0; j < header64->ncmds; j++) { + if (cmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64* seg = reinterpret_cast(cmd); + + if (strcmp(seg->segname, "__TEXT") == 0) { + // TEXT segment should be read-execute, not writable + if (seg->initprot & VM_PROT_WRITE) { + protectionValid = false; + HandleTampering(SecurityCheckType::MEMORY_PROTECTION, + "__TEXT segment is writable in " + std::string(imageName)); + break; + } + } + } + + cmd = reinterpret_cast( + reinterpret_cast(cmd) + cmd->cmdsize); + } + } + } + } + + return protectionValid; +#else + return true; +#endif +} + // Private initialization methods implementation void AntiTamper::InitializeCodeHashes() { // Implementation would generate hashes of code sections for integrity checking diff --git a/source/cpp/security/anti_tamper.hpp b/source/cpp/security/anti_tamper.hpp index 0dc9bfde..1d98e9a8 100644 --- a/source/cpp/security/anti_tamper.hpp +++ b/source/cpp/security/anti_tamper.hpp @@ -401,155 +401,37 @@ class AntiTamper { return !debuggerDetected; } - // Check code segment integrity + // Check code segment integrity - implementation moved to .cpp file + // to avoid incomplete type issues with Mach-O structures static bool CheckCodeIntegrity() { bool integrityIntact = true; #ifdef __APPLE__ - // Get information about all loaded modules - uint32_t count = _dyld_image_count(); - - for (uint32_t i = 0; i < count; i++) { - const char* imageName = _dyld_get_image_name(i); - const struct mach_header* header = _dyld_get_image_header(i); - - // Check if this is our dylib - if (strstr(imageName, "libmylibrary.dylib") != nullptr || - strstr(imageName, "roblox_execution") != nullptr) { - - // Parse the Mach-O header to find the TEXT segment - uintptr_t textStart = 0; - size_t textSize = 0; - - if (header->magic == MH_MAGIC_64) { - const struct mach_header_64* header64 = reinterpret_cast(header); - const struct load_command* cmd = reinterpret_cast(header64 + 1); - - for (uint32_t j = 0; j < header64->ncmds; j++) { - if (cmd->cmd == LC_SEGMENT_64) { - const struct segment_command_64* seg = reinterpret_cast(cmd); - - if (strcmp(seg->segname, "__TEXT") == 0) { - textStart = reinterpret_cast(header) + seg->vmaddr; - textSize = seg->vmsize; - break; - } - } - - cmd = reinterpret_cast( - reinterpret_cast(cmd) + cmd->cmdsize); - } - } else if (header->magic == MH_MAGIC) { - const struct load_command* cmd = reinterpret_cast(header + 1); - - for (uint32_t j = 0; j < header->ncmds; j++) { - if (cmd->cmd == LC_SEGMENT) { - const struct segment_command* seg = reinterpret_cast(cmd); - - if (strcmp(seg->segname, "__TEXT") == 0) { - textStart = reinterpret_cast(header) + seg->vmaddr; - textSize = seg->vmsize; - break; - } - } - - cmd = reinterpret_cast( - reinterpret_cast(cmd) + cmd->cmdsize); - } - } - - // If we found the TEXT segment, verify its integrity - if (textStart != 0 && textSize != 0) { - uint32_t newChecksum = CalculateChecksum(reinterpret_cast(textStart), textSize); - - // If this is the first time, store the checksum - if (s_codeHashes.empty()) { - std::lock_guard lock(s_mutex); - s_codeHashes.resize(sizeof(newChecksum)); - memcpy(s_codeHashes.data(), &newChecksum, sizeof(newChecksum)); - } else { - // Compare with previously stored checksum - uint32_t storedChecksum; - memcpy(&storedChecksum, s_codeHashes.data(), sizeof(storedChecksum)); - - if (newChecksum != storedChecksum) { - integrityIntact = false; - HandleTampering(SecurityCheckType::CODE_INTEGRITY, - "Code integrity violation in " + std::string(imageName)); - break; - } - } - } - } - } -#else - // Implement platform-specific code integrity checks for other platforms + // Call implementation function with all the Mach-O parsing logic + integrityIntact = CheckCodeIntegrityImpl(); #endif return integrityIntact; } - // Check for hooks in the dylib + // Implementation function in cpp file + static bool CheckCodeIntegrityImpl(); + + // Check for hooks in the dylib - implementation moved to .cpp file static bool CheckForDylibHooks() { bool noHooksDetected = true; #ifdef __APPLE__ - // This is a simplified check that looks for common hook patterns in memory - // A real implementation would be more sophisticated, checking for specific hook types - - // Get information about all loaded modules - uint32_t count = _dyld_image_count(); - - for (uint32_t i = 0; i < count; i++) { - const char* imageName = _dyld_get_image_name(i); - - // Check if this is our dylib - if (strstr(imageName, "libmylibrary.dylib") != nullptr || - strstr(imageName, "roblox_execution") != nullptr) { - - const struct mach_header* header = _dyld_get_image_header(i); - - // Look for common hook patterns (e.g., JMP instructions) in code sections - // This is a simplified example - real implementation would be more thorough - if (header->magic == MH_MAGIC_64) { - const struct mach_header_64* header64 = reinterpret_cast(header); - const struct load_command* cmd = reinterpret_cast(header64 + 1); - - for (uint32_t j = 0; j < header64->ncmds; j++) { - if (cmd->cmd == LC_SEGMENT_64) { - const struct segment_command_64* seg = reinterpret_cast(cmd); - - if (strcmp(seg->segname, "__TEXT") == 0) { - // Scan the text segment for hook patterns - const uint8_t* textStart = reinterpret_cast(header) + seg->vmaddr; - - // Common x86_64 JMP pattern is 0xFF 0x25 followed by a 32-bit displacement - for (size_t k = 0; k < seg->vmsize - 6; k++) { - if (textStart[k] == 0xFF && textStart[k + 1] == 0x25) { - // Potential hook found, further verification would be needed - // This is just a simplified example - noHooksDetected = false; - HandleTampering(SecurityCheckType::DYLIB_HOOKS, - "Potential hook detected in " + std::string(imageName)); - break; - } - } - } - } - - cmd = reinterpret_cast( - reinterpret_cast(cmd) + cmd->cmdsize); - } - } - } - } -#else - // Implement platform-specific dylib hook detection for other platforms + // Call implementation function with all the Mach-O parsing logic + noHooksDetected = CheckForDylibHooksImpl(); #endif return noHooksDetected; } + // Implementation function in cpp file + static bool CheckForDylibHooksImpl(); + // Check for hooks in specific functions static bool CheckForFunctionHooks() { bool noHooksDetected = true; @@ -583,56 +465,21 @@ class AntiTamper { return noHooksDetected; } - // Check memory protection settings + // Check memory protection settings - implementation moved to .cpp file static bool CheckMemoryProtection() { bool protectionValid = true; #ifdef __APPLE__ - // Get information about all loaded modules - uint32_t count = _dyld_image_count(); - - for (uint32_t i = 0; i < count; i++) { - const char* imageName = _dyld_get_image_name(i); - - // Check if this is our dylib - if (strstr(imageName, "libmylibrary.dylib") != nullptr || - strstr(imageName, "roblox_execution") != nullptr) { - - const struct mach_header* header = _dyld_get_image_header(i); - - // Check protection of code segments - if (header->magic == MH_MAGIC_64) { - const struct mach_header_64* header64 = reinterpret_cast(header); - const struct load_command* cmd = reinterpret_cast(header64 + 1); - - for (uint32_t j = 0; j < header64->ncmds; j++) { - if (cmd->cmd == LC_SEGMENT_64) { - const struct segment_command_64* seg = reinterpret_cast(cmd); - - if (strcmp(seg->segname, "__TEXT") == 0) { - // TEXT segment should be read-execute, not writable - if (seg->initprot & VM_PROT_WRITE) { - protectionValid = false; - HandleTampering(SecurityCheckType::MEMORY_PROTECTION, - "__TEXT segment is writable in " + std::string(imageName)); - break; - } - } - } - - cmd = reinterpret_cast( - reinterpret_cast(cmd) + cmd->cmdsize); - } - } - } - } -#else - // Implement platform-specific memory protection checks for other platforms + // Call implementation function with all the Mach-O parsing logic + protectionValid = CheckMemoryProtectionImpl(); #endif return protectionValid; } + // Implementation function in cpp file + static bool CheckMemoryProtectionImpl(); + // Check process environment for suspicious settings static bool CheckProcessEnvironment() { bool environmentSafe = true; From 3d6101279b46e59aa74603f6d3b7fabecd41ac99 Mon Sep 17 00:00:00 2001 From: MentatBot <160964065+MentatBot@users.noreply.github.com> Date: Fri, 18 Apr 2025 22:04:20 +0000 Subject: [PATCH 02/23] Fix regex_replace lambda issue, ExecutionContext, and SystemState conflicts This PR addresses the remaining build errors from the latest build log: 1. Fixed regex_replace in obfuscator.hpp: - Replaced regex_replace with lambda expression with a manual regex search and replace - iOS doesn't support the std::regex_replace with lambda callback signature 2. Fixed missing fields in ExecutionEngine::ExecutionContext: - Added m_obfuscationLevel field which was referenced but missing 3. Fixed SystemState issues: - Added s_initialized member in SystemState - Fixed double initialization in init.cpp - Fixed initialization order to match header declarations 4. Added missing methods in ScriptManager: - Added SaveScript and GetSavedScripts methods for UI integration These changes fix all the identified issues while maintaining the original functionality of the code. The build should now succeed. --- source/cpp/anti_detection/obfuscator.hpp | 23 ++++++++++++++++++----- source/cpp/init.cpp | 13 +------------ source/cpp/init.hpp | 6 ++++-- source/cpp/ios/ExecutionEngine.h | 3 ++- source/cpp/ios/ScriptManager.h | 19 +++++++++++++++++++ 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/source/cpp/anti_detection/obfuscator.hpp b/source/cpp/anti_detection/obfuscator.hpp index 2960c7e3..95181a20 100644 --- a/source/cpp/anti_detection/obfuscator.hpp +++ b/source/cpp/anti_detection/obfuscator.hpp @@ -464,17 +464,30 @@ namespace AntiDetection { std::regex numberRegex("\\b(\\d+)\\b"); // Replace all numeric constants with obfuscated expressions - result = std::regex_replace(result, numberRegex, [](const std::smatch& match) { + // Use standard callback function for regex_replace (iOS doesn't support lambda version) + std::string processed = result; + std::smatch match; + std::string::const_iterator searchStart(result.cbegin()); + + // Manual regex search and replace since direct lambda replacement not supported + while (std::regex_search(searchStart, result.cend(), match, numberRegex)) { try { int value = std::stoi(match[1]); if (value > 0 && value < 1000) { // Only obfuscate reasonable sized numbers - return ObfuscateConstant(value); + // Replace in the processed string + std::string replacement = ObfuscateConstant(value); + size_t pos = std::distance(result.cbegin(), match[0].first); + processed.replace(pos, match[0].length(), replacement); } } catch (...) { - // If conversion fails, just return the original + // If conversion fails, just leave as is } - return match[0].str(); - }); + + // Move search position + searchStart = match.suffix().first; + } + + result = processed; return result; } diff --git a/source/cpp/init.cpp b/source/cpp/init.cpp index c3424546..a7ea7f88 100644 --- a/source/cpp/init.cpp +++ b/source/cpp/init.cpp @@ -6,18 +6,7 @@ namespace RobloxExecutor { -// Initialize static members -bool SystemState::s_initialized = false; -std::shared_ptr SystemState::s_executionEngine = nullptr; -std::shared_ptr SystemState::s_scriptManager = nullptr; -iOS::UIController* SystemState::s_uiController = nullptr; -InitOptions SystemState::s_initOptions; - -// Initialize AI static members -void* SystemState::s_aiIntegration = nullptr; -std::shared_ptr SystemState::s_aiManager = nullptr; -std::shared_ptr SystemState::s_scriptAssistant = nullptr; -std::shared_ptr SystemState::s_signatureAdaptation = nullptr; +// Use existing static members from init.hpp, don't redefine // Initialize the executor system bool Initialize(const InitOptions& options) { diff --git a/source/cpp/init.hpp b/source/cpp/init.hpp index 2c7b65d0..bee6ab38 100644 --- a/source/cpp/init.hpp +++ b/source/cpp/init.hpp @@ -105,8 +105,9 @@ struct SystemStatus { // Global system state class SystemState { private: - static InitOptions s_options; - static SystemStatus s_status; + static bool s_initialized; // Whether the system is initialized + static InitOptions s_options; // Initialization options + static SystemStatus s_status; // Current system status static std::shared_ptr s_executionEngine; static std::shared_ptr s_scriptManager; static std::unique_ptr s_uiController; @@ -521,6 +522,7 @@ class SystemState { }; // Initialize static members +bool SystemState::s_initialized = false; InitOptions SystemState::s_options; SystemStatus SystemState::s_status; std::shared_ptr SystemState::s_executionEngine; diff --git a/source/cpp/ios/ExecutionEngine.h b/source/cpp/ios/ExecutionEngine.h index 82f14e3c..879469f0 100644 --- a/source/cpp/ios/ExecutionEngine.h +++ b/source/cpp/ios/ExecutionEngine.h @@ -45,6 +45,7 @@ namespace iOS { bool m_enableAntiDetection; // Whether to enable anti-detection bool m_autoRetry; // Whether to auto-retry on failure int m_maxRetries; // Maximum number of retries + int m_obfuscationLevel; // Level of obfuscation to apply (0-5) uint64_t m_timeout; // Execution timeout in milliseconds std::string m_gameName; // Current game name std::string m_placeId; // Current place ID @@ -53,7 +54,7 @@ namespace iOS { ExecutionContext() : m_isJailbroken(false), m_enableObfuscation(true), m_enableAntiDetection(true), m_autoRetry(true), - m_maxRetries(3), m_timeout(5000) {} + m_maxRetries(3), m_obfuscationLevel(3), m_timeout(5000) {} }; // Execution event callback types diff --git a/source/cpp/ios/ScriptManager.h b/source/cpp/ios/ScriptManager.h index 99e20ef7..2d950228 100644 --- a/source/cpp/ios/ScriptManager.h +++ b/source/cpp/ios/ScriptManager.h @@ -124,6 +124,25 @@ namespace iOS { */ bool AddScript(const Script& script, bool save = true); + /** + * @brief Save a script with basic info (for UI integration) + * @param name Script name + * @param content Script content + * @return True if saved successfully + */ + bool SaveScript(const std::string& name, const std::string& content) { + Script script(name, content); + return AddScript(script, true); + } + + /** + * @brief Get all saved scripts in simple format (for UI integration) + * @return Vector of all scripts + */ + std::vector