在 resigned ipa 中注入 ObjectiveC-Swift 钩子,主要在 Swift 而不是 Objective C 中编写钩子

Inject ObjectiveC-Swift hook in resigned ipa, for writing the hook mainly in Swift rather than in Objective C

我正在尝试在未越狱的设备上挂接目标二进制文件的函数。

它实际上在 Objective C 中有效。我只是将自己的 dylib 添加到 ipa 的二进制文件中,就像往常一样 (insert_dylib),然后进行调配。

现在,当我挂接函数时,我想将数据传递给 Swift 并使用 Swift 处理数据。

我使用标准 tutorial 将 Swift 导入到 ObjC 中,这没有问题。

如果我将库注入 ipa,只要不调用我的 Swift 函数,ipa 就会工作。当它被调用时,应用程序冻结。 (它不会打印函数启动后立即打印的日志)。

我觉得库没有“连接到 swift 运行时”,也许它应该调用一些 swift 初始化?

请注意,挂钩的应用程序已使用 swift。事实上,otool -L,显示:

@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)

(和其他库swift*)

相比之下,我的库现在只有一个普通的@objc public static class 和@objc public static func 在 swift 代码中(它不使用花哨的库,它是一个空函数)。

所以我尝试了各种方法:

  1. 使用 optool uninstall -p ... -t ... 从 mylib.dylib 中删除对 libswift*.dylib 的引用 ( https://github.com/alexzielenski/optool ) 希望 mylib.dylib 会使用应用程序已经加载的

  2. 将 libswift*.dylib 库从 Xcode.app/..../iphoneos/swift-5.0/libswift*.dylib 复制到myapp.app/Frameworks/文件夹和

  3. 将 mylib.dylib 的 /usr/lib/libswift*..dylib 路径(由 otool -L 显示)更改为 @rpath/Framerworks/libswift...dylib 使用 install_name_tool -改变

但没有任何效果。实际上,2. 和 3. 似乎有效但它崩溃了:

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

任何提示,链接?非常感谢。

最后说明:当我构建一个独立的测试应用程序并使用模型 class 使用我的库时,一切正常。因此,从 ObjC 导入和使用 Swift 代码是可行的。注入第三方ipa无效

我找到了一个解决方案:我的库是作为另一个项目的子目标构建的。这生成了一个不太适合其他二进制文件的 .dylib。所以,我为这个库创建了另一个框架项目,我注入了这个库并且它工作了,没有额外的步骤(例如 optool,install_name_tool,等等......)。

让我找到正确方法的提示是这次崩溃:

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  

以及使用 lldb 进行一些调试。一切正常,但在执行 objc_msgSend 时,它以这种方式崩溃(在子帧中)。奇怪的是它试图访问二进制内存区域之外的地址。所以我觉得图书馆的建设过程有什么奇怪的。