时间:2021-05-02
Swift是苹果公司最新推出的编程语言,据很多人说,是用来”代替“Objective-C。但是没有确切的证据。我花了一些时间对Swift二进制和运行环境实施逆向工程技术,然后我对Swift有些少许的发现。目前为止,结论就是:Swift是没有消息机制的Objective-C。
对象
信不信由你,Swift中的对象就是Objective-C的对象。在Mach-O二进制文件中,__objc_classlist包含每个二进制文件中类的数据。其结构如下所示:
(注:所有结构都来自64位版本)
注意data记录,它指向了类中的一个列出方法、实例变量和协议等内容的结构体。通常,data是8个字节对齐的,但是对于Swift类,data的最后一位仅为1个字节。
类
Swift类的真正结构是有一点奇怪的。Swift类没有Objective-C方法。我们将在以后实现它。Swift类的变量存储为实例变量。Swift的getter和setter方法真正修改的是实例变量的值。奇怪的是swift类的实例变量没有类型编码。通常应该指向类型编码的指针为NULL。这大概是由于事实上Objective-C运行时是不支持处理Swift变量本身。
继承
Swift的继承是你所期待的。在Swift中,Square是shape的子类也是Objective-C类Shape的子类。然而,在Swift类中没有超类?
例如
复制代码 代码如下: class Shape { }在这个例子中,Shape类是SwiftObject的子类。SwiftObject是一个根Objective-C类,类似于NSObject。它没有超类,意味着isa指向自身。它的目的是使用Swift运行时方法比如allocation和deallocation代替标准的Objective-C运行时方法。例如,(void)retain不会调用objc_retain,但是它会调用swift_retain。
类方法
就像我之前提到的,Swift对象的类没有方法,以此代替的是类似C++的函数,名称改编和所有东西。这可能是为什么Swift声称比Objective-C更快的原因。不再需要为 objc_msgSend 寻找和调用方法实现。
在Objective-C里面,方法像这样实现:
复制代码 代码如下: type method(id self, SEL _cmd, id arg1, id arg2, ...)Swift 方法非常类似,但是轻微使用了不同的参数排布, self 作为最后一个参数传递,并且没有选择器。
复制代码 代码如下: type method(id arg1, id arg2, ..., id self)
虚表
类似C++一样,Swift类也具有一个虚表,用于列出类中的方法。它直接被放置在二进制文件中的类数据之后,并且看起来是这样的:
据我所知,Swift类中的虚表仅在编译期间可见时被使用。否则,它将看起来就是一堆乱糟糟的符号。
命名重整
Swift保持函数的元数据在各自的符号,这就叫做命名重整。元数据宝库奥函数的名称(显而易见的),属性,模块名称,参数类型,返回值类型,还有更多的数据,例如这个例子
simpleDescription方法的重整命名是:
_TFC9swifttest5Shape17simpleDescriptionfS0_FT_Si。下面是详细说明:
_T - 所有Swift符号的前缀,每一个符号都是从_T开始。
F - 函数
C - 类的函数(方法)
9swifttest - 带有长度前缀的模块名
5Shape - 函数所属的类,带有长度前缀
17simpleDescription - 函数名
f - 函数属性。 在这个例子中它是f,这是一个普通函数。
S0_FT- 我不是特别确定这是什么意思,但是它是参数和返回类型开始的标记
‘_' - 这个下划线分割了参数和返回值的类型。因为函数没有带参数,它直接跟在了S0_FT的后面
S - 返回值的开始。'S'代表Swift;返回类型是Swift的内建类型,下一个字符决定了类型
i - 这是Swift的内建类型。一个小写的"I"代表了Int.
函数属性
字符类型
f 普通函数
s setter
g getter
d 析构函数
D 释放器
c 构造函数
C 分配器
Swift内部函数
字符类型
a 数组
b 布尔型
c 字符常量
d 双精度浮点数
f 单精度浮点型
i 整型
u UInt类型
Q 隐式可选
S 字符串型
除了函数之外,还有很多命名转换机制,此处我仅给出一个简短的概述。
挂钩函数
受够了语义这部分,让我们接触点有趣的东西!比方说我们有一个像这样的类:
比如我们想将numberOfSides的值改为4,很多种方法可以做到。我们可以使用MobileSubstrate挂到getter方法中,然后更改返回值,就像这样:
复制代码 代码如下:如果我们创建了一个形状的实例,并且打印出numberOfSides的值,我们得到了4!看起来不错,对不?现在,我知道你可能在想,难道我们不应该是返回一个对象而非常量4吗?
好吧,在Swift里,许多内建类型是书面量来的。一个Int型, 举个例子,和C语言里面的int型一样(尽管它可以是一个长整形——不要让我碰到这种情况)。一个小小的提示,String 类型有点古老,这是一个低位优先的UTF-16字符串,所以没有C的字面量能用。
让我们来做同样的事情,但这一次,我们不是在获取器上,而是在获取器上设钩。
复制代码 代码如下:再尝试一下,然后。。。。。。还是5。怎么回事,你问?好吧,在Swift里某些地方,函数是内联化的。类构造器就是其中一个的地方。它直接设置numberOfSides 为ivar, 设置器将仅在数值再次被顶层代码设置的时候被调用。在那被调用,你知道么,我们得到了4。
最终,让我们通过直接设置实例变量的值来修改numberOfSides。
复制代码 代码如下:这个函数是可以实现功能的,虽然不建议这样做,但是确实有效果。
这是目前我所要写的内容。当然,还有很多其他的内容我正在看,包括witness表,由于我了解不多,所以这里我也没办法写出总结。很多内容在这篇文章里有变更,他们仅是我目前对运行和查看用Swift语言编译的二进制文件逆向工程操作所得到的东西。
我所发现的东西应该是非常不错的,这意味着MobileSubstrate不会随着Objective-C一同消亡,并且,微调仍然可以进行!我很想知道将来在越狱场景下的应用商店中将会是怎样一番情景……难道logo可以更新用来自动销毁命名?甚至是处理常见的 Swift 类型的库……
如果你发现更多的关于Swift如何工作的东西,不要犹豫,请让我知道!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C#是一门面向对象的语言,具有面向对象的基本特征,抽象、封装、继承、多态等性质。学习C#除了一些基本的语法,还得学习一些新的特性,比如说:泛型、多线程、集合、反
本文讲述了Javascript简单实现面向对象编程继承实例代码。分享给大家供大家参考,具体如下:面向对象的语言必须具备四个基本特征:1.封装能力(即允许将基本数
AndroidUI工具包提供了一些布局管理器,它们使用起来相当容易,而且,大多数的时候,你只需要使用它们最基本的特征来实现UI。执着于基本特征的使用对于创建UI
本文实例讲述了JavaScript面向对象三个基本特征。分享给大家供大家参考,具体如下:了解过面向对象的同学应该都知道,面向对象三个基本特征是:封装、继承、多态
SybaseSQLServer是个关系数据库管理系统,它具有如下一些基本特征:(1)SybaseSQLServer可以放在若干个磁盘设备上,初始安装时所需的磁盘