steipete / InterposeKit

A modern library to swizzle elegantly in Swift.
https://interposekit.com/
MIT License
989 stars 49 forks source link

Bad access when trying to call original selector #21

Closed PushpakNarasimhan closed 4 years ago

PushpakNarasimhan commented 4 years ago

Trying to swizzle following:

  1. CLLocationManager.location [works fine]
  2. CLLocationManagerDelegate.locationManager(_:didUpdateLocations:) [Bad access when try to call original selector]

`

    do {
        _ = try Interpose(CLLocationManager.self, builder: {
            try $0.hook(#selector(getter: CLLocationManager.location),
                        methodSignature: (@convention(c) (AnyObject, Selector) -> CLLocation?).self,
                        hookSignature: (@convention(block) (AnyObject) -> CLLocation?).self) { store in {
                            `self` in
                            print("Before Interposing \(`self`)")
                            let originalLocation = store.original(`self`, store.selector) // free to skip
                            print("After Interposing \(`self`)")

                            return originalLocation
                            }

            }
        })
    } catch {
        print(error)
    }

    let classList = AppDelegate.getClassList().filter { class_conformsToProtocol($0, CLLocationManagerDelegate.self) }
    for c in classList {

        if !c.instancesRespond(to: #selector(CLLocationManagerDelegate.locationManager(_:didUpdateLocations:))) {
            continue
        }
        do {
            _ = try Interpose(c.self, builder: {
                try $0.hook(#selector(CLLocationManagerDelegate.locationManager(_:didUpdateLocations:)),
                            methodSignature: (@convention(c) (AnyObject, Selector, [CLLocation]) -> ()).self,
                            hookSignature: (@convention(block) (AnyObject, Selector, [CLLocation]) -> ()).self) { store in {

                                print("Before Interposing")
                                print($0)
                                print($1)
                                print($2)

                                store.original($0, store.selector, $2) // free to skip
                                print("After Interposing \($0)")
                                }
                }
            })
        } catch {
            print(error)
        }
    }

` Not able to figure out what is causing the issue.

PushpakNarasimhan commented 4 years ago

My bad, was not setting parameters right.

`

    do {
        _ = try Interpose(CLLocationManager.self, builder: {
            try $0.hook(#selector(getter: CLLocationManager.location),
                        methodSignature: (@convention(c) (AnyObject, Selector) -> CLLocation?).self,
                        hookSignature: (@convention(block) (AnyObject) -> CLLocation?).self) { store in {
                            `self` in
                            print("Before Interposing \(`self`)")
                            let originalLocation = store.original(`self`, store.selector) // free to skip
                            print("After Interposing \(`self`)")

                            return originalLocation
                            }

            }
        })
    } catch {
        print(error)
    }

    let classList = AppDelegate.getClassList().filter { class_conformsToProtocol($0, CLLocationManagerDelegate.self) }
    for c in classList {

        if !c.instancesRespond(to: #selector(CLLocationManagerDelegate.locationManager(_:didUpdateLocations:))) {
            continue
        }
        do {
            _ = try Interpose(c.self, builder: {
                try $0.hook(#selector(CLLocationManagerDelegate.locationManager(_:didUpdateLocations:)),
                            methodSignature: (@convention(c) (AnyObject, Selector, CLLocationManager, [CLLocation]) -> ()).self,
                            hookSignature: (@convention(block) (AnyObject, CLLocationManager, [CLLocation]) -> ()).self) { store in {
                                `self`, manager, locations in
                                print("Before Interposing")
                                print(locations)
                                store.original(`self`, store.selector, manager,locations) // free to skip
                                print("After Interposing")
                                }
                }
            })
        } catch {
            print(error)
        }
    }

`