diff --git a/source/cpp/ios/FloatingButtonController.mm b/source/cpp/ios/FloatingButtonController.mm index 600a9bbd..e5bf1158 100644 --- a/source/cpp/ios/FloatingButtonController.mm +++ b/source/cpp/ios/FloatingButtonController.mm @@ -203,8 +203,9 @@ - (void)snapToNearestEdge { UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:button action:@selector(handleTap:)]; [button addGestureRecognizer:tapGesture]; - // Store the button and apply initial position - m_buttonView = (__bridge_retained void*)button; + // Store the button and apply initial position (manual memory management) + m_buttonView = (void*)button; + [button retain]; // Explicitly retain the button since we're not using ARC UpdateButtonPosition(); // Initially hidden @@ -215,8 +216,9 @@ - (void)snapToNearestEdge { // Destructor FloatingButtonController::~FloatingButtonController() { if (m_buttonView) { - FloatingButton* button = (__bridge_transfer FloatingButton*)m_buttonView; + FloatingButton* button = (FloatingButton*)m_buttonView; [button removeFromSuperview]; + [button release]; // Explicitly release since we're manually retaining m_buttonView = nullptr; } } @@ -533,9 +535,9 @@ - (void)handleTap:(UITapGestureRecognizer *)gesture { } completion:^(BOOL finished) { // Call the tap callback - // Access tap callback through a public method instead + // Cast to id to avoid the warning about non-id receiver if (self.controller) { - [self.controller performTapAction]; + [(id)self.controller performTapAction]; } }]; }]; diff --git a/source/cpp/ios/JailbreakBypass.mm b/source/cpp/ios/JailbreakBypass.mm index b69e6817..14a13ffe 100644 --- a/source/cpp/ios/JailbreakBypass.mm +++ b/source/cpp/ios/JailbreakBypass.mm @@ -22,9 +22,9 @@ std::unordered_set JailbreakBypass::m_jailbreakProcesses; std::unordered_map JailbreakBypass::m_fileRedirects; - // Original function pointers - conditionally defined based on platform + // Define function pointers for non-iOS platforms #if !defined(IOS_TARGET) && !defined(__APPLE__) - // These are only used on non-iOS platforms + // These function pointers are populated with MSHookFunction static int (*original_stat)(const char* path, struct stat* buf); static int (*original_access)(const char* path, int mode); static FILE* (*original_fopen)(const char* path, const char* mode); @@ -33,9 +33,42 @@ static int (*original_fork)(void); static int (*original_execve)(const char* path, char* const argv[], char* const envp[]); #else - // For iOS, we'll use alternative approaches (method swizzling instead of function hooks) - // These are defined but not actually used with real function pointers - static int dummy_hook(void) { return 0; } + // For iOS, define function implementations that call the system functions directly + // This avoids using function pointers which are populated via MSHookFunction + static int original_stat(const char* path, struct stat* buf) { + return ::stat(path, buf); + } + + static int original_access(const char* path, int mode) { + return ::access(path, mode); + } + + static FILE* original_fopen(const char* path, const char* mode) { + return ::fopen(path, mode); + } + + static char* original_getenv(const char* name) { + return ::getenv(name); + } + + static int original_system(const char* command) { + // system() is often unavailable on iOS, just log and return success + std::cout << "iOS: system() call would execute: " << (command ? command : "null") << std::endl; + return 0; + } + + static int original_fork(void) { + // fork() usually fails on iOS, return error + errno = EPERM; + return -1; + } + + static int original_execve(const char* path, char* const argv[], char* const envp[]) { + // execve() might not work as expected on iOS, log and return error + std::cout << "iOS: execve() call would execute: " << (path ? path : "null") << std::endl; + errno = EPERM; + return -1; + } #endif void JailbreakBypass::InitializeTables() { diff --git a/source/cpp/ios/MemoryAccess.mm b/source/cpp/ios/MemoryAccess.mm index 024860df..a8383b52 100644 --- a/source/cpp/ios/MemoryAccess.mm +++ b/source/cpp/ios/MemoryAccess.mm @@ -84,30 +84,24 @@ regions.clear(); - mach_vm_address_t address = 0; - mach_vm_size_t size = 0; + // Variables for memory region iteration + vm_address_t vm_address = 0; // Use vm_address_t for compatibility with vm_region_64 + vm_size_t vm_size = 0; // Use vm_size_t for compatibility with vm_region_64 vm_region_basic_info_data_64_t info; mach_msg_type_number_t infoCount = VM_REGION_BASIC_INFO_COUNT_64; mach_port_t objectName = MACH_PORT_NULL; kern_return_t kr = KERN_SUCCESS; while (true) { - // kr is already declared above, don't redeclare it - - #if defined(IOS_TARGET) || defined(__APPLE__) - // On iOS we use vm_region_64 instead of mach_vm_region - kr = vm_region_64(m_targetTask, &address, &size, - VM_REGION_BASIC_INFO_64, - (vm_region_info_t)&info, - &infoCount, - &objectName); - #else - kr = mach_vm_region(m_targetTask, &address, &size, - VM_REGION_BASIC_INFO_64, - (vm_region_info_t)&info, - &infoCount, - &objectName); - #endif + // Use variables with correct types for vm_region_64 + kr = vm_region_64( + m_targetTask, + &vm_address, + &vm_size, + VM_REGION_BASIC_INFO_64, + (vm_region_info_t)&info, + &infoCount, + &objectName); if (kr != KERN_SUCCESS) { if (kr != KERN_INVALID_ADDRESS) { @@ -116,8 +110,11 @@ break; } + // Store region size in the upper bits of the protection field so we can access it later + info.protection |= ((uint64_t)vm_size & 0xFFFFFFFF) << 32; + regions.push_back(info); - address += size; + vm_address += vm_size; } return !regions.empty(); @@ -236,33 +233,31 @@ mach_vm_address_t address = 0; for (const auto& region : regions) { // Skip regions that are not readable - #if defined(IOS_TARGET) || defined(__APPLE__) - // On iOS, protection is a different field - if (!(region.protection & VM_PROT_READ)) { - #else if (!(region.protection & VM_PROT_READ)) { - #endif continue; } - // Scan this region - #if defined(IOS_TARGET) || defined(__APPLE__) - // On iOS, the field is called 'size' not 'virtual_size' - mach_vm_address_t result = FindPattern(address, region.size, pattern, mask); - #else - mach_vm_address_t result = FindPattern(address, region.virtual_size, pattern, mask); - #endif + // Extract region size from the upper bits of protection where we stored it + mach_vm_size_t regionSize = (region.protection >> 32) & 0xFFFFFFFF; + + // Use a reasonable default if size wasn't properly stored + if (regionSize == 0) { + #if defined(IOS_TARGET) || defined(__APPLE__) + // For iOS, use a reasonable default scan size + regionSize = 4 * 1024 * 1024; // 4MB default scan size + #else + regionSize = region.virtual_size; + #endif + } + + // Scan this region with the correct size + mach_vm_address_t result = FindPattern(address, regionSize, pattern, mask); if (result != 0) { return result; } - // Move to next region - #if defined(IOS_TARGET) || defined(__APPLE__) - // On iOS, the field is called 'size' not 'virtual_size' - address += region.size; - #else - address += region.virtual_size; - #endif + // Move to next region using the extracted size + address += regionSize; } return 0; diff --git a/source/cpp/ios/ai_features/OfflineAISystem.h b/source/cpp/ios/ai_features/OfflineAISystem.h index 91b03316..7dfc0726 100644 --- a/source/cpp/ios/ai_features/OfflineAISystem.h +++ b/source/cpp/ios/ai_features/OfflineAISystem.h @@ -191,6 +191,12 @@ class OfflineAISystem { */ std::unordered_map GetScriptTemplates() const; + /** + * @brief Get template cache + * @return Map of template names to templates + */ + std::unordered_map GetTemplateCache() const; + /** * @brief Generate response for a detection event * @param detectionType Detection type diff --git a/source/cpp/ios/ai_features/OfflineAISystem.mm b/source/cpp/ios/ai_features/OfflineAISystem.mm index 04c021b8..c4a23147 100644 --- a/source/cpp/ios/ai_features/OfflineAISystem.mm +++ b/source/cpp/ios/ai_features/OfflineAISystem.mm @@ -68,7 +68,7 @@ if (scriptGenInitialized) { m_scriptGeneratorModel = scriptGenerator.get(); - m_modelCache["script_generator"] = scriptGenerator; + m_modelCache["script_generator"] = scriptGenerator.get(); m_loadedModelNames.push_back("script_generator"); } else { std::cerr << "OfflineAISystem: Failed to initialize script generator model" << std::endl; @@ -82,7 +82,7 @@ if (vulnerabilityInitialized) { m_patternRecognitionModel = vulnerabilityDetector.get(); - m_modelCache["vulnerability_detector"] = vulnerabilityDetector; + m_modelCache["vulnerability_detector"] = vulnerabilityDetector.get(); m_loadedModelNames.push_back("vulnerability_detector"); } else { std::cerr << "OfflineAISystem: Failed to initialize vulnerability detector" << std::endl; @@ -368,6 +368,7 @@ std::regex varRegex("\\b([a-zA-Z][a-zA-Z0-9_]*)\\s*="); std::regex useRegex("\\b([a-zA-Z][a-zA-Z0-9_]*)\\b"); + // Define variable sets before using them std::set definedVars; std::set usedVars; std::set builtinVars = { @@ -405,7 +406,9 @@ // Find undefined variables std::vector undefinedVars; for (const auto& var : usedVars) { - if (definedVars.find(var) == definedVars.end()) { + // Check if this variable is defined + auto it = definedVars.find(var); + if (it == definedVars.end()) { undefinedVars.push_back(var); } } @@ -661,7 +664,8 @@ void* OfflineAISystem::GetModel(const std::string& modelName) const { auto it = m_modelCache.find(modelName); if (it != m_modelCache.end()) { - return it->second.get(); + // Direct access to pointer instead of using get() since we're storing raw pointers now + return it->second; } return nullptr; } @@ -871,11 +875,11 @@ local function getClosestPlayer() // Get script templates std::unordered_map OfflineAISystem::GetScriptTemplates() const { - return m_templateCache; + return m_scriptTemplates; } -// Get a list of script templates -std::unordered_map OfflineAISystem::GetScriptTemplates() const { +// Get template cache +std::unordered_map OfflineAISystem::GetTemplateCache() const { return m_templateCache; }