Swift 函数调用逆向分析
简介: 逆向分析Swift代码 为了研究Swift的动态性,我们将Swift的类、成员变量、函数调用等代码进行反编译。
逆向分析Swift代码
为了研究Swift的动态性,我们将Swift的类、成员变量、函数调用等代码进行反编译。
Swift代码如下:
得到反编译结果及对应调用逻辑如下:
(其中用灰色矩形框代表的是这一段逻辑对应哪个Swift的代码)
作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这有个iOS交流群:642363427,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术!
可以得出以下结论:
Swift函数编译为C函数(Swift Name Mangling)
testReturnVoidWithaId
编译成 _TFC9TestSwift15TestASwiftClass21testReturnVoidWithaIdfS0_FCSo6UIViewT_
testNeverInlineMethod
编译成_TTSf4n_d___TFC9TestSwift15TestASwiftClass21testNeverInlineMethodfS0_FPSs9AnyObject_PS1__
可以知道Swift的函数按照一定的规则重新编译为新的C函数。具体每个字符的含义可找谷歌
可以通过命令还原C函数对应的Swift函数原型,如:
得到的结果与我们的Swift代码里定义的一致。
dynamic修饰走objc runtime
dynamic func testDynamicMethod
反编译的代码如下,很明显调了objc_msgSend
走的是objc runtime
部分函数被inline优化
我们只看到了testNeverInlineMethod
被编译成_TTSf4n_d___TFC9TestSwift15TestASwiftClass21testNeverInlineMethodfS0_FPSs9AnyObject_PS1__
然后被调用,却没有看到testReturnObjectWithObject
和testAtObjcMethod
对应的函数调用。
而他们两者里面的代码逻辑直接被插入到testReturnVoidWithaId
的调用中,也就是说被编译器给inline优化了。
通过@inline(never)
修饰符可以强制让函数不被inline优化。
@objc修饰不走objc runtime
虽然testAtObjcMethod
加了@objc的修饰,但是完全没有没有走objc runtime。
hook Swift函数难点
从上面的结论可以看出,hook Swift函数的问题变成了hook C函数的问题,而这是iOS上的难点。
以下是一些分析过的能hook C函数的开源库:
fishhook可以hook系统库的C函数(有些hook有bug),但是不能hook app自身内部的C函数
SWRoute且只能在Mac上运行hook Swift可见函数,但在Swift2.0已经失效
rd_route只能在Mac上运行hook C函数
libevil能在iOS上 hook C函数,但是不支持arm64,且可用性风险极大。
cycript能在越狱环境hook C函数
评论