ios - 在 resigned ipa 中注入 ObjectiveC-Swift 钩子,主要在 Swift 中而不是在 Objective C 中编写钩子
问题描述
我正在尝试在非越狱设备上挂钩目标二进制文件的功能。
它实际上在 Objective C 中工作。我只是像往常一样将我自己的 dylib 添加到 ipa 的二进制文件中 (insert_dylib),然后进行调配。
现在,当我挂钩函数时,我想将数据传递给 Swift 并使用 Swift 处理数据。
我使用标准教程将 Swift 导入到 ObjC 中,这没有任何问题。
如果我将库注入 ipa,只要不调用我的 Swift 函数,ipa 就会工作。当它被调用时,应用程序冻结。(它不会打印功能启动后立即打印的日志)。
我的感觉是该库没有“连接到快速运行时”,也许它应该调用一些快速初始化?
请注意,挂钩的应用程序已经使用了 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)
(和其他 libswift*)
相比之下,我的库现在在 swift 代码中只有一个普通的 @objc public static 类和 @objc public static func(它不使用花哨的库,它是一个空函数)。
所以我尝试了各种方法:
使用 optool uninstall -p ... -t ... ( https://github.com/alexzielenski/optool )从 mylib.dylib 中删除对 libswift*.dylib 的引用,希望 mylib.dylib 使用已经加载的那个通过应用程序
将 libswift*.dylib 库从 Xcode.app/..../iphoneos/swift-5.0/libswift*.dylib 复制到 myapp.app/Frameworks/ 文件夹和
使用 install_name_tool -change 将 mylib.dylib 的 /usr/lib/libswift*..dylib 路径(由 otool -L 显示)更改为 @rpath/Framerworks/libswift...dylib
但没有任何效果。实际上, 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
任何提示,链接?非常感谢。
最后一点:当我构建一个独立的测试应用程序并使用模型类使用我的库时,一切正常。所以从 ObjC 导入和使用 Swift 代码是可行的。注入第三方ipa时不起作用。
解决方案
我找到了一个解决方案:我的库是作为另一个项目的子目标构建的。这生成了一个 .dylib 并不真正适合其他二进制文件。所以,我只为这个库创建了另一个框架项目,我注入了这个库并且它工作了,没有额外的步骤(例如 opttool、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 时,它以这种方式崩溃(在子帧中)。奇怪的是它试图访问二进制内存区域之外的地址。所以我觉得图书馆的建设过程中有些奇怪的地方。
推荐阅读
- reactjs - Gatsby 的 gatsby-source-filesystem 的动态 graphQL 查询
- javascript - Vue.js 3 - 通过计算属性启用/禁用表单元素
- html - 如何在打印页面时删除 .tab-pane 边框?
- java - Gson JsonArray to List long 类型变成科学记数法
- git - git flow 扩展不断要求标签
- r - 在 R 闪亮的 kable 列名称中添加文本下标
- javascript - Sequelize 不会在 where 中连接 Ands
- python - 运行自定义模型的中间表示 (IR),OpenVino
- python-3.x - mypyc 有没有办法编译代理对象?
- reactjs - 单击按钮显示 GeoJSON 类的新 geojson 数据