Swift函数调用逆向分析

简介: ##逆向分析Swift代码 为了研究Swift的动态性,我们将Swift的类、成员变量、函数调用等代码进行反编译。 Swift代码如下: ``` class TestASwiftClass { var aBool:Bool = true; var aInt:UInt = 0; var aFloat:Float = 123.45; var aDou

逆向分析Swift代码

为了研究Swift的动态性,我们将Swift的类、成员变量、函数调用等代码进行反编译。
Swift代码如下:

class TestASwiftClass {
    var aBool:Bool = true;
    var aInt:UInt = 0;
    var aFloat:Float = 123.45;
    var aDouble:Double = 1234.567;
    var aString:String = "abc";
    var aObject:AnyObject! = nil;

    func testReturnVoidWithaId(aId:UIView){
        NSLog("aId=%@", aId);
        NSLog("F:%s L:%d", __FUNCTION__, __LINE__)
        self.aBool = false
        self.aInt = 123
        self.aString = "efg"
        let a = self.testReturnObjectWithObject("abc")
        let b = self.testAtObjcMethod("efg")
        let c = self.testNeverInlineMethod("lmn");
        let d = self.testDynamicMethod("hij");
        print(a, b, c, d);
    }
    func testReturnObjectWithObject(aObject:AnyObject) -> AnyObject{
        print("testReturnObjectWithObject", __FUNCTION__, __LINE__)
        return aObject
    }
    @inline(never) func testNeverInlineMethod(aObject:AnyObject) -> AnyObject{
        print("testNeverInlineMethod", __FUNCTION__, __LINE__)
        return aObject;
    }
    @objc func testAtObjcMethod(aObject:AnyObject) -> AnyObject{
        print("testAtObjcMethod", __FUNCTION__, __LINE__)
        return aObject
    }
    dynamic func testDynamicMethod(aObject:AnyObject)-> AnyObject{
        print("testDynamicMethod", __FUNCTION__, __LINE__)
        return aObject
    }
}

得到反编译结果及对应调用逻辑如下:


(其中用灰色矩形框代表的是这一段逻辑对应哪个Swift的代码)
可以得出以下结论:

Swift函数编译为C函数(Swift Name Mangling)

testReturnVoidWithaId编译成 _TFC9TestSwift15TestASwiftClass21testReturnVoidWithaIdfS0_FCSo6UIViewT_

testNeverInlineMethod编译成_TTSf4n_d___TFC9TestSwift15TestASwiftClass21testNeverInlineMethodfS0_FPSs9AnyObject_PS1__

可以知道Swift的函数按照一定的规则重新编译为新的C函数。具体每个字符的含义可找谷歌
可以通过命令还原C函数对应的Swift函数原型,如:

  ~ xcrun swift-demangle _TFC9TestSwift15TestASwiftClass21testReturnVoidWithaIdfS0_FCSo6UIViewT_
_TFC9TestSwift15TestASwiftClass21testReturnVoidWithaIdfS0_FCSo6UIViewT_ ---> TestSwift.TestASwiftClass.testReturnVoidWithaId (TestSwift.TestASwiftClass)(ObjectiveC.UIView) -> ()
  ~ xcrun swift-demangle _TTSf4n_d___TFC9TestSwift15TestASwiftClass21testNeverInlineMethodfS0_FPSs9AnyObject_PS1__
_TTSf4n_d___TFC9TestSwift15TestASwiftClass21testNeverInlineMethodfS0_FPSs9AnyObject_PS1__ ---> function signature specialization <Arg[1] = Dead> of TestSwift.TestASwiftClass.testNeverInlineMethod (TestSwift.TestASwiftClass)(Swift.AnyObject) -> Swift.AnyObject

得到的结果与我们的Swift代码里定义的一致。

dynamic修饰走objc runtime

dynamic func testDynamicMethod反编译的代码如下,很明显调了objc_msgSend走的是objc runtime

  v37 = _TFE10FoundationSS19_bridgeToObjectiveCfSSFT_CSo8NSString("hij", 3, 0);
  v38 = v37;
  v39 = objc_msgSend(v3, "testDynamicMethod:", v37);
  v40 = objc_retainAutoreleasedReturnValue(v39);

部分函数被inline优化

我们只看到了testNeverInlineMethod被编译成_TTSf4n_d___TFC9TestSwift15TestASwiftClass21testNeverInlineMethodfS0_FPSs9AnyObject_PS1__然后被调用,却没有看到testReturnObjectWithObjecttestAtObjcMethod对应的函数调用。
而他们两者里面的代码逻辑直接被插入到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函数

看完文章如果你对Swift有想法感兴趣不妨动动小手,添加一下咱们的交流群642363427来获取一份详细的Swift资料为你的技术多添一份光彩。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 1. 逆向知识 通过usb或者wifi连接ssh通道、登录iPhone,通过Cycript命令行调试iPhone ...
    海利昂阅读 597评论 1 0
  • 声明:本教程仅用于学习交流,有任何侵权问题请联系本人删除 本教程案例请关注微信公众号:逆向小白,联系作者获取 使用...
    xfs_coder阅读 4,145评论 0 9
  • Swift 的函数是怎么派发的呢? 我没能找到一个很简明扼要的答案, 但这里有四个选择具体派发方式的因素存在: 声...
    CrystalZhu阅读 535评论 0 0
  • 前言 对于Swift的学者来说函数派发有很大的误区:就是认为Swift沿用Objective-C的消息派发机制,且...
    顶级蜗牛阅读 2,387评论 0 2
  • 前言 阿里云APP组件化过程中,我们拆分出了若干基础组件库和业务代码库,由于代码是采用Swift编写的,所以这些库...
    xycn阅读 6,662评论 8 58