Git Product home page Git Product logo

interposekit's People

Contributors

colinhumber avatar dependabot[bot] avatar hannesoid avatar mattia avatar pedrovereza avatar rmigneco avatar steipete avatar zrzka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

interposekit's Issues

Crash when compiled in Release

I am seeing crashes when compiled in Release mode with Xcode 15.3 and integrated with SPM with the following stack trace:

image (1)

Bad access when trying to call original selector

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.

globalWatchers.append & filtering not synced via globalWatcherQueue

Quickly checked the code and I'm wondering ...

Global image watcher utilizes the globalWatcherQueue queue to filter globalWatchers:

InterposeWatcher.globalWatcherQueue.sync {

But there's another place where this queue isn't used, access to globalWatchers is not synced:

InterposeWatcher.globalWatchers.append(self)

Additional thing is that the globalWatchers.append(self) should be probably replaced by the InterposeWatcher.append(...) to encapsulate this whole watching stuff (globalWatchers).

Incompatible with bitcode

After adopting InterposeKit in my app, uploading a build to Apple fails when bitcode is enabled with the following error:

ITMS-90562: Invalid Bundle - The app submission can not be successfully recompiled from bitcode due to missing symbols during linking. You can try to reproduce and diagnose such issues locally by following the instructions from: https://developer.apple.com/library/archive/technotes/tn2432/_index.html

Uploading with bitcode disabled is fine. After reading the linked page I suspect it has something to do with the inline assembly in ITKSuperBuilder.m. I removed InterposeKit from my app and uploaded with bitcode without error to confirm that it was indeed InerposeKit causing the issue. Please challenge my assumption if you think something else is the issue.

Do you think this can be fixed? At least I think it would make sense to document this limitation in the readme.

Proposal: Match hook and callback type

Just a suggestion, perhaps you've thought of this and it won't work - I might be missing something.

Since the underlying implementation uses imp_implementationWithBlock, the hooked function has a different type than the block you supply (notably no selector). Would it be possible to instead pass an IMP directly, and then it might be possible to make sure they both have the same type? (type check that the callAsFunction and the block you supply have the same type)

Example here although I haven't tested it with the calling convention requirements:

func genericFunction<T>(_ selName: String, _ callback: @escaping (String, T.Type) -> T) {
  print("hi")
  callback("foo", T.self)
}

func noop() {}

genericFunction("test") { (str, type) -> () -> Void in
  print("Called with \(str)")
  print(type)
  return noop
}

This example passes the type into the method but you could potentially capture it into Task itself/make Task generic.

EDIT: Oh I think I see the issue, it has to be a block if you want to be able to reference the task.

How to use selector with number of parameters?

Hi there,
from example:
let hook = try testObj.hook( #selector(TestClass.sayHi), methodSignature: (@convention(c) (AnyObject, Selector) -> String).self, hookSignature: (@convention(block) (AnyObject) -> String).self) { store in {self in return store.original(self, store.selector) + "just this instance" } }

But i need to set hook with the following signature:

methodSignature: (@convention(c) (AnyObject, Selector, AnyObject, AnyObject, AnyObject) -> Void).self, { store in {self in //to call the original method i need these three AnyObject values to pass. return store.original(self, store.selector, ?, ?, ?) } }

How to access these three AnyObject ?

Thanks in advance.

`_dyld_register_func_for_add_image` callback is run before Objective-C classes are loaded

_dyld_register_func_for_add_image is called during dlopen but before the Objective-C classes in the image are loaded. The effect of this is that the interposition(s) for a given class are run on the next dlopen after the class is loaded. This may be too late depending on the interposition use case. Thoughts on clever ways to install a callback just after the Objective-C classes for a given image are loaded?

Crash when hooking NSURL

let object = NSURL.init(string: "https://www.google.com")!
let hook = try? object.hook(
    #selector(getter: NSURL.host),
    methodSignature: (@convention(c) (AnyObject, Selector) -> String).self,
    hookSignature: (@convention(block) (AnyObject) -> String).self) { store in { `self` in
    return "http://www.facebook.com"
        }
}
let host = object.host

Screenshot 2020-11-19 at 10 27 15 AM

it's similar with this issue. steipete/Aspects#177

Assert that swizzled implementation type signature matches original method

To make swizzling more robust, it would be ideal if the return/argument types of the swizzled implementation could be checked against the original method.

As for how to do that… I guess the only way would be to accept an Objective-C method (via target/selector parameters) instead of an Objective-C block?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.