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
    }
}

得到反编译结果及对应调用逻辑如下:
_2016_03_11_7_36_56
_2016_03_11_5_48_14
_2016_03_11_5_48_28
_2016_03_11_5_50_25
_2016_03_11_5_50_46

(其中用灰色矩形框代表的是这一段逻辑对应哪个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函数
目录
相关文章
|
5月前
|
存储 Swift
Swift中,函数和闭包
Swift中,函数和闭包
35 1
|
Swift
Swift中文教程(四)--函数与闭包
原文:Swift中文教程(四)--函数与闭包 Function 函数   Swift使用func关键字来声明变量,函数通过函数名加小括号内的参数列表来调用。使用->来区分参数名和返回值的类型: 1 func greet(name: String, day: String) -> String { 2 return "Hello \(name), today is \(day).
697 0
|
Swift
Swift中文教程(四)--函数与闭包
Function 函数   Swift使用func关键字来声明函数,函数通过函数名加小括号内的参数列表来调用。使用->来区分参数名和返回值的类型: 1 func greet(name: String, day: String) -> String { 2 return "Hello \(name), today is \(day).
1006 0
|
4月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
106 2
|
3月前
|
监控 API Swift
用Swift开发iOS平台上的上网行为管理监控软件
在当今数字化时代,随着智能手机的普及,人们对于网络的依赖日益增加。然而,对于一些特定场景,如家庭、学校或者企业,对于iOS设备上的网络行为进行管理和监控显得尤为重要。为了满足这一需求,我们可以利用Swift语言开发一款iOS平台上的上网行为管理监控软件。
213 2
|
4月前
|
监控 Swift iOS开发
局域网计算机监控软件中利用Swift构建iOS端的移动监控应用
在局域网计算机监控软件的开发中,构建iOS端的移动监控应用是一项关键任务。本文将介绍如何利用Swift语言实现这一目标,通过多个代码示例展示关键功能的实现。
225 1
|
4月前
|
安全 JavaScript 前端开发
IOS开发基础知识:介绍一下 Swift 和 Objective-C,它们之间有什么区别?
IOS开发基础知识:介绍一下 Swift 和 Objective-C,它们之间有什么区别?
77 0

相关课程

更多