Push remaining files and update README

This commit is contained in:
Hamza-Ayed
2026-06-09 08:44:23 +03:00
parent d8901e1a87
commit 9bc7a31c94
61 changed files with 2283 additions and 3 deletions

View File

@@ -0,0 +1,145 @@
import UIKit
import Flutter
import FirebaseCore
import CoreLocation
@main
@objc class AppDelegate: FlutterAppDelegate {
let locationManager = CLLocationManager()
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Now continue with the rest of the app initialization.
FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
// التأكد من أن الجهاز غير مخترق قبل تشغيل التطبيق
if SecurityChecks.isDeviceCompromised() {
showSecurityAlert()
return false
}
// تهيئة قنوات الاتصال مع Flutter
setupMethodChannel()
// ضبط مدير الموقع لمتابعة تغييرات الأذونات
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// MARK: - تهيئة القناة بين Swift و Flutter
func setupMethodChannel() {
guard let controller = window?.rootViewController as? FlutterViewController else {
return
}
let channel = FlutterMethodChannel(name: "com.siro.siro_driver/security",
binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { call, result in
switch call.method {
case "isNativeRooted":
result(SecurityChecks.isDeviceCompromised())
default:
result(FlutterMethodNotImplemented)
}
}
}
// MARK: - عرض تنبيه عند اكتشاف جهاز مخترق
func showSecurityAlert() {
guard let rootVC = UIApplication.shared.keyWindow?.rootViewController else {
exit(0)
}
let alert = UIAlertController(
title: "Security Warning".localized,
message: "Compromised device detected. Exiting.".localized,
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK".localized, style: .destructive) { _ in
self.obfuscatedExit()
})
if #available(iOS 15.0, *) {
alert.popoverPresentationController?.sourceView = rootVC.view
alert.popoverPresentationController?.sourceRect = CGRect(x: rootVC.view.bounds.midX, y: rootVC.view.bounds.midY, width: 0, height: 0)
alert.popoverPresentationController?.permittedArrowDirections = []
alert.presentationController?.delegate = self
if let presentationController = alert.presentationController as? UISheetPresentationController {
presentationController.detents = [.medium()]
presentationController.preferredCornerRadius = 20
presentationController.prefersEdgeAttachedInCompactHeight = true
presentationController.prefersGrabberVisible = false
}
}
rootVC.present(alert, animated: true, completion: nil)
}
// MARK: - إخفاء عملية الخروج بطريقة مشفرة
func obfuscatedExit() {
let selector = NSSelectorFromString(String(format: "%@%@", "ex", "it:"))
if responds(to: selector) {
perform(selector, with: 0)
}
}
}
// MARK: - التعامل مع أذونات الموقع بطريقة آمنة
extension AppDelegate: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if #available(iOS 14.0, *) {
let status = manager.authorizationStatus
switch status {
case .authorizedWhenInUse, .authorizedAlways:
print("Authorization granted")
case .denied, .restricted:
print("Authorization denied")
case .notDetermined:
manager.requestWhenInUseAuthorization()
@unknown default:
break
}
} else {
// لنظام iOS 13 وما قبله، نستخدم الطريقة القديمة
let status = CLLocationManager.authorizationStatus()
switch status {
case .authorizedWhenInUse, .authorizedAlways:
print("Authorization granted")
case .denied, .restricted:
print("Authorization denied")
case .notDetermined:
manager.requestWhenInUseAuthorization()
@unknown default:
break
}
}
}
}
// MARK: - منع إغلاق التنبيهات الأمنية
extension AppDelegate: UIAdaptivePresentationControllerDelegate {
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
return false
}
}
// MARK: - دعم الترجمة للنصوص
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -0,0 +1 @@
{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]}

View File

@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@@ -0,0 +1,13 @@
//
// Constants.swift
// Runner
//
// Created by Hamza Aleghwairyeen on 26/07/2025.
//
import Foundation
struct Constants {
static let googleMapsAPIKey = "AIzaSyDzGO9a-1IDMLD2FxhmOO9ONL1gMssFa9g"
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>API_KEY</key>
<string>AIzaSyDk6x6KZUY0IQtxoCMXX0F7N_yik8O19eA</string>
<key>GCM_SENDER_ID</key>
<string>825988584191</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.siro.driver</string>
<key>PROJECT_ID</key>
<string>siro-a6957</string>
<key>STORAGE_BUCKET</key>
<string>siro-a6957.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:825988584191:ios:4002b88e618f0c4e1632ca</string>
</dict>
</plist>

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Siro Driver</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>siro_driver</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.133</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>33</string>
<key>FirebaseAppDelegateProxyEnabled</key>
<string>NO</string>
<key>GMSApiKey</key>
<string>YOUR_API_KEY</string>
<key>LSApplicationCategoryType</key>
<string></string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlechromes</string>
<string>comgooglemaps</string>
</array>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSBonjourServices</key>
<array>
<string>_dartVmService._tcp</string>
<string>_dartobservatory._tcp</string>
</array>
<key>NSCameraUsageDescription</key>
<string>This app requires access to your camera in order to scan QR codes and capture images
for uploading and access to connect to a call.</string>
<key>NSContactsUsageDescription</key>
<string>This app requires contacts access to function properly.</string>
<key>NSFaceIDUsageDescription</key>
<string>Use Face ID to securely authenticate payment accounts.</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSLocalNetworkUsageDescription</key>
<string>Allow debugging over the local network.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to your location to provide you with the best ride experience.
Your location data will be used to find the nearest available cars and connect you with
the closest captain for efficient and convenient rides.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to your location to provide you with the best ride experience.
Your location data will be used to find the nearest available cars and connect you with
the closest captain for efficient and convenient rides.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires access to your microphone to record audio, allowing you to add
voice recordings to your photos and videos and access to connect to a call.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to your photo library to allow you to upload and manage
images.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>location</string>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View File

@@ -0,0 +1,27 @@
//
// JailbreakDetection.swift
// Runner
//
// Created by Hamza Aleghwairyeen on 26/07/2025.
//
import Foundation
class JailbreakDetection {
static func isJailbroken() -> Bool {
let paths = [
"/Applications/Cydia.app",
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/usr/sbin/sshd",
"/etc/apt"
]
for path in paths {
if FileManager.default.fileExists(atPath: path) {
return true
}
}
return false
}
}

View File

@@ -0,0 +1,2 @@
#import "GeneratedPluginRegistrant.h"
#import "SecurityChecks.h"

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>

View File

@@ -0,0 +1,20 @@
//
// SecurityChecks.h
// Runner
//
// Created by Hamza Aleghwairyeen on 26/07/2025.
//
#ifndef SecurityChecks_h
#define SecurityChecks_h
#endif /* SecurityChecks_h */
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> // Import UIKit
@interface SecurityChecks : NSObject
+ (BOOL)isDeviceCompromised; // Combined check
@end

View File

@@ -0,0 +1,198 @@
//
// SecurityChecks.m
// Runner
//
// Created by Hamza Aleghwairyeen on 26/07/2025.
//
#import <Foundation/Foundation.h>
#import "SecurityChecks.h"
#import <sys/stat.h>
#include <dlfcn.h>
#import <sys/sysctl.h>
#include <mach-o/dyld.h> // For _dyld_image_count and _dyld_get_image_name
#include <unistd.h> // for fork()
#include <sys/socket.h> //for socket, connect
#include <netinet/in.h> // for sockaddr_in
#include <arpa/inet.h> // for inet_pton
@implementation SecurityChecks
+ (BOOL)isDeviceJailbroken {
// (Same jailbreak checks as before - from previous responses)
// 1. Check for common jailbreak files
NSArray *jailbreakPaths = @[
@"/Applications/Cydia.app",
// #if !TARGET_IPHONE_SIMULATOR
// @"/bin/bash",
// #endif
@"/Library/MobileSubstrate/MobileSubstrate.dylib",
@"/bin/bash",
@"/usr/sbin/sshd",
@"/etc/apt",
@"/private/var/lib/apt/",
@"/private/var/tmp/cydia.log",
];
for (NSString *path in jailbreakPaths) {
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSLog(@"Jailbreak file detected: %@", path);
return YES;
}
}
// 2. Check if we can write outside the sandbox (a strong indicator)
NSError *error = nil;
NSString *testPath = @"/private/jailbreaktest.txt";
[@"test" writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (!error) {
// If we can write, it's jailbroken. Remove the file immediately.
[[NSFileManager defaultManager] removeItemAtPath:testPath error:nil];
NSLog(@"Sandbox write test indicates jailbreak.");
return YES;
}
//3: Check for existence of the symbolic link /Applications.
struct stat s;
if (lstat("/Applications", &s) == 0) {
if (S_ISLNK(s.st_mode)) {
NSLog(@"Symbolic link /Applications exists, jailbroken");
return YES;
}
}
//4:Check for dyld Libraries
uint32_t count = _dyld_image_count();
for (uint32_t i = 0 ; i < count ; ++i) {
const char *dyld = _dyld_get_image_name(i);
if (strstr(dyld, "MobileSubstrate") != NULL || strstr(dyld, "libcycript") != NULL) {
NSLog(@"Suspicious dyld library found: %s", dyld);
return YES;
}
}
//5 Check if fork() is available. Sandboxed apps should not be able to call fork().
#if !TARGET_IPHONE_SIMULATOR // Don't run this on the simulator
int pid = fork();
if (pid == 0)
{
//in child, exit immediately to avoid crashing.
exit(0);
} else if (pid > 0)
{
NSLog(@"Fork available. Likely jailbroken.");
return YES; // Fork succeeded; likely jailbroken
}
#endif
return NO; // No jailbreak indicators found
}
+ (BOOL)isDebuggerAttached {
int mib[4];
struct kinfo_proc info;
size_t size = sizeof(info);
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = getpid();
sysctl(mib, 4, &info, &size, NULL, 0);
return (info.kp_proc.p_flag & P_TRACED) != 0;
}
// Check for Frida's default port
+ (BOOL)isFridaListeningOnDefaultPort {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
return NO; // Couldn't create socket
}
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(27042); // Default Frida port
inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr);
if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) != -1) {
NSLog(@"Frida default port (27042) is open.");
close(sock);
return YES;
}
close(sock);
return NO;
}
+ (BOOL)isFridaDetected {
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
size_t length;
struct kinfo_proc *procs, *proc;
sysctl(name, 3, NULL, &length, NULL, 0);
procs = malloc(length);
sysctl(name, 3, procs, &length, NULL, 0);
for (proc = procs; (char *)proc < (char *)procs + length; proc++) {
if (strstr(proc->kp_proc.p_comm, "frida") != NULL) {
free(procs);
return YES;
}
}
free(procs);
return NO;
}
// Check for loaded dylibs that indicate Frida
+(BOOL) checkForFridaDylib{
uint32_t count = _dyld_image_count();
for (uint32_t i = 0 ; i < count ; ++i) {
const char *dyld = _dyld_get_image_name(i);
if (strstr(dyld, "FridaGadget") != NULL) { // Look for FridaGadget
NSLog(@"FridaGadget dylib found: %s", dyld);
return YES;
}
}
return NO;
}
// Check process name
+ (BOOL)checkProcessName {
NSString* processName = [[NSProcessInfo processInfo] processName];
if ([processName containsString:@"Frida"]) {
return YES;
}
return NO;
}
// A combined check for jailbreak and Frida
+ (BOOL)isDeviceCompromised {
if ([SecurityChecks isDeviceJailbroken]) {
return YES;
}
if ([SecurityChecks isFridaListeningOnDefaultPort]) {
return YES;
}
if ([SecurityChecks checkForFridaDylib]) {
return YES;
}
if([SecurityChecks checkProcessName]){
return YES;
}
// if ([SecurityChecks isDebuggerAttached]) {
// return YES;
// }
// if ([SecurityChecks isFridaDetected]) {
// return YES;
// }
return NO;
}
@end

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>APIKey</key>
<string>AIzaSyDdqkLMCrqjVrn7XmadIqynyoBa7P27OeM</string>
</dict>
</plist>