Reputation: 61
I am trying to hook a function of a target binary on a non-jailbroken device.
It actually works in Objective C. I simply add my own dylib to the binary of the ipa, as it is usual (insert_dylib), and do my swizzling.
Now when I hook the function I'd like to pass the data to Swift and process the data using Swift.
I imported Swift into ObjC using the standard tutorial and this gives no problems.
If I inject the library into the ipa, the ipa works as long my Swift function is not called. When it is called, the app freezes. (It does not print the log that would be printed as soon as the function starts).
My feel is that the library does not "connect to the swift runtime", perhaps it should call some swift initialization?.
Note that the hooked app already uses swift. In fact, otool -L, shows:
@rpath/libswiftCore.dylib (compatibility version 1.0.0, current version 1200.2.40)
@rpath/libswiftAVFoundation.dylib (compatibility version 1.0.0, current version 1995.38.2, weak)
@rpath/libswiftAccelerate.dylib (compatibility version 1.0.0, current version 10.40.1, weak)
@rpath/libswiftAssetsLibrary.dylib (compatibility version 1.0.0, current version 310.2.210, weak)
@rpath/libswiftCloudKit.dylib (compatibility version 1.0.0, current version 962.0.0)
(and others libswift*)
In contrast my lib has right now just a plain @objc public static class and @objc public static func in the swift code (it does not use fancy libs, it is an empty function).
So I tried various things:
remove references to libswift*.dylib from mylib.dylib using optool uninstall -p ... -t ... ( https://github.com/alexzielenski/optool ) in the hope that mylib.dylib would use the one already loaded by the app
Copy libswift*.dylib libs from Xcode.app/..../iphoneos/swift-5.0/libswift*.dylib to myapp.app/Frameworks/ folder and
change the /usr/lib/libswift*..dylib path of mylib.dylib (showed by otool -L) to @rpath/Framerworks/libswift...dylib using install_name_tool -change
but nothing worked. Actually, 2. and 3. seems to work but it crashes:
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001a81c1ec4 __pthread_kill + 8
1 libsystem_c.dylib 0x00000001a8031844 abort + 100
2 libswiftCore.dylib 0x0000000104df0028 swift_vasprintf(char**, char const*, char*) + 0
3 libswiftCore.dylib 0x0000000104de81c8 swift::nameForMetadata(swift::TargetMetadata<swift::InProcess> const*, bool) + 0
4 cy-bVKQhY.dylib 0x0000000104aa61b8 ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 428
5 cy-bVKQhY.dylib 0x0000000104aa658c ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 52
any hint, links? Thank you very much.
Final note: when I build a standalone test app and use my library using a mock-up class, everything works fine. So the importing and usage of Swift code from ObjC works. It does not work when injected in the third-party ipa.
Upvotes: 1
Views: 425
Reputation: 61
I found a solution: my library was built as a sub-target of another project. This generated a .dylib not really suitable for other binaries. So, I created another framework-project just for this library, I injected the library and it worked, without an additional steps (e.g. optool, install_name_tool, etc...).
The hint that led me to the right way was this crash:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000d5000006840
VM Region Info: 0xd5000006840 is not in any region. Bytes after previous region: 14625974282305
and some debugging with lldb. Everything was working, but when doing objc_msgSend, it was crashing (in subframes) in this way. Strange that it was trying to access an address outside of the binary memory region. So I thought there was something strange in the building process of the library.
Upvotes: 1