加入收藏 | 设为首页 | 会员中心 | 我要投稿 青岛站长网 (https://www.0532zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 动态 > 正文

Swift Hook 新思路

发布时间:2021-04-20 17:11:54 所属栏目:动态 来源:互联网
导读:历史包袱的原因,目前主流的大型APP基本都是以 Objective-C 为主要开发语言。 但是敏锐的同学应该能发现,从 Swift 的 ABI 稳定以后,各个大厂开始陆续加大对 Swift 的投入。 虽然在短期内 Swift 还难以取代 Objective-C,但是其与 Objective-C 并驾齐驱的趋

历史包袱的原因,目前主流的大型APP基本都是以 Objective-C 为主要开发语言。

但是敏锐的同学应该能发现,从 Swift 的 ABI 稳定以后,各个大厂开始陆续加大对 Swift 的投入。

虽然在短期内 Swift 还难以取代 Objective-C,但是其与 Objective-C 并驾齐驱的趋势是越来越明显,从招聘的角度就即可管中窥豹。

在过去一年的招聘过程中我们总结发现,有相当数量的候选人只掌握 Swift 开发,对Objective-C 开发并不熟悉,而且这部分候选人大多数比较年轻。

另外,以 RealityKit 等新框架为例,其只支持 Swift 不支持 Objective-C。上述种种现象意味着随着时间的推移,如果项目不能很好的支持 Swift 开发,那么招聘成本以及应用创新等一系列问题将会凸显出来。

因此,58 同城在 2020 年 Q4 的时候在集团内发起了跨部门协同项目,从各个层面打造 Objective-C 与 Swift 的混编生态环境——项目代号 ”混天“。

一旦混编生态构建完善,那么很多问题将迎刃而解。

2. 原理简述

本文的技术方案仅针对通过虚函数表调用的函数进行 Hook,不涉及直接地址调用和objc_msgSend 的调用的情况。

另外需要注意的是,Swift Compiler 设置为 Optimize for speed(Release默认)则TypeContext 的 VTable 的函数地址会清空。

设置为 Optimize for size 则 Swfit 可能会转变为直接地址调用。

以上两种配置都会造成方案失效。因此本文重点在介绍技术细节而非方案推

映射,我们不能像 Objective-C 那样根据函数的名字获取到对应的函数地址,因此修改 Swift 的虚函数是依靠函数索引来实现的。

简单理解就是将虚函数表理解为数组,假设有一个 FuncTable[],我们修改函数地址只能通过索引值来实现,就像 FuncTable[index] = replaceIMP 。但是这也涉及到一个问题,在版本迭代过程中我们不能保证代码是一层不变的,因此这个版本的第 index 个函数可能是函数 A,下个版本可能第 index 个函数就变成了函数 B。显然这对函数的替换会产生重大影响。

为此,我们通过 Swift 的 OverrideTable 来解决索引变更的问题。在 Swift 的OverrideTable 中,每个节点都记录了当前这个函数重写了哪个类的哪个函数,以及重写后函数的函数指针。

因此只要我们能获取到 OverrideTable 也就意味着能获取被重写的函数指针 IMP0 以及重写后的函数指针 IMP1。只要在 FuncTable[] 中找到 IMP0 并替换成 IMP1 即可完成方法替换。

接下来将详细介绍Swift的函数调用、TypeContext、Metadata、VTable、OverrideTable 等细节,以及他们彼此之间有何种关联。为了方便阅读和理解,本文所有代码及运行结果,都是基于 arm64 架构

3. Swift 的函数调用

首先我们需要了解 Swift 的函数如何调用的。与 Objectiv

(编辑:青岛站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!