Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SensorChaos — iOS Agent

In-process agent for full sensor injection on iOS. Intercepts CLLocationManager, CMMotionManager, and CMAltimeter delegate/handler calls via Objective-C method swizzling so the app receives modified sensor data through the same APIs it normally uses — it cannot distinguish injected data from real sensor readings.

Integration

Add the SensorChaosAgent package to your debug target only — the agent must never ship in a release build.

Package.swift / Xcode → Add Package:

https://github.com/sensorchaos/sensorchaos

Path: agents/ios, version 0.1.0+

Add SensorChaosAgent to the Debug configuration only (or a separate debug target).

Startup

If you want explicit control over when the agent starts — for example to defer it until after your own initialisation — call SensorChaos.start() manually:

AppDelegate.swift (UIKit):

import SensorChaosAgent

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    #if DEBUG
    SensorChaos.start()
    #endif
    return true
}

MyApp.swift (SwiftUI):

import SensorChaosAgent

@main struct MyApp: App {
    init() {
        #if DEBUG
        SensorChaos.start()
        #endif
    }
    var body: some Scene { WindowGroup { ContentView() } }
}

SensorChaos.start() is idempotent — safe to call multiple times.

Connecting the CLI

After launching your app with the agent installed, run a scenario with --agent:

iOS Simulator (shares the Mac's loopback interface — no port forwarding needed):

sensorchaos run gnss/gulf-spoofing-2026 --agent
# or target a specific simulator by UDID:
sensorchaos run gnss/gulf-spoofing-2026 --agent --device <simulator-udid>

Real device (requires idb companion installed):

idb forward 19847 19847
sensorchaos run gnss/gulf-spoofing-2026 --agent

How it works

Push-based apps (delegate callbacks):
  App → CLLocationManager.delegate = self
             ↓ setDelegate: swizzled
        ChaosLocationDelegate wraps self
        CLI sends location commands over TCP → LocationInjector
      → locationManager(_:didUpdateLocations:) called with [injectedLocation]

Pull-based apps (direct property access):
  App → manager.location
             ↓ location getter swizzled
        LocationInjector returns nil (signal loss) or injectedLocation

Signal loss suppresses all callbacks and returns nil from the location getter, covering both push-based and pull-based access patterns.

Sensor coverage

Sensor Injection method Notes
GPS / Location CLLocationManager.setDelegate: + location getter swizzled Signal loss supported (suppresses callbacks, returns nil from getter)
Accelerometer CMMotionManager.startAccelerometerUpdatesToQueue:withHandler: swizzled; wraps handler Writes _acceleration ivar in place
Gyroscope Same — startGyroUpdatesToQueue:withHandler: Writes _rotationRate ivar
Magnetometer Same — startMagnetometerUpdatesToQueue:withHandler: Writes _magneticField ivar
Barometer CMAltimeter.startRelativeAltitudeUpdatesToQueue:withHandler: swizzled Writes _pressure / _relativeAltitude NSNumber ivars
WiFi scan Not available — Apple doesn't expose scan APIs Command accepted silently
Cell tower Not available Command accepted silently

TCP Protocol

Same JSON Lines protocol as the Android agent. One JSON object per line. CLI sends, agent responds.

// Health check
{"cmd":"ping"}
// → {"ok":true,"agent":"sensorchaos-ios","version":"0.1.0"}

// Location fix
{"cmd":"location","lat":25.197,"lng":55.274,"accuracy_m":5.0,"satellites":12}

// Location — optional fields
{"cmd":"location","lat":25.197,"lng":55.274,"accuracy_m":5.0,
 "satellites":12,"altitude_m":10.0,"speed_mps":1.4,"bearing_deg":90.0}

// Signal loss (null or absent lat/lng)
{"cmd":"location","lat":null,"lng":null}

// Sensor overrides — persist until the next command on the same type
{"cmd":"sensor","type":"accelerometer","values":[0.0,0.0,9.81]}  // x,y,z m/s²
{"cmd":"sensor","type":"gyroscope","values":[0.0,0.0,0.0]}       // x,y,z rad/s
{"cmd":"sensor","type":"magnetometer","values":[19.0,1.0,-47.0]} // x,y,z µT
{"cmd":"sensor","type":"barometer","values":[1013.25]}            // hPa

// WiFi / cell — accepted, not injected (iOS restriction)
{"cmd":"wifi","results":[...]}
{"cmd":"cell","towers":[...]}

Implementation status

Component Status
SensorChaos.swiftstart() / stop() entry points
Auto-init via +load ⬜ Not possible in Swift-only SPM packages — use SensorChaos.start()
ChaosTcpServer.swift — JSON Lines protocol on :19847
LocationInjector.swiftCLLocationManager delegate proxy + location getter
MotionInjector.swift — accelerometer, gyroscope, magnetometer
AltimeterInjector.swiftCMAltimeter pressure/altitude
WiFi / Cell injection ⬜ Not available on iOS

Requirements

  • iOS 14+
  • Xcode 15+ / Swift 5.9+
  • NSLocationWhenInUseUsageDescription in Info.plist
  • NSMotionUsageDescription in Info.plist (for CMMotionManager)
  • Agent must only be linked in debug builds

Sample app

SampleApp/SensorChaosSample/ contains a SwiftUI app that exercises all injected sensors. Open or create an Xcode project targeting SampleApp/SensorChaosSample/, add the SensorChaosAgent local package, and run on Simulator or a real device.

About

iOS SPM agent for SensorChaos

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages