• swift-类结构源码探寻(二)


    紧跟 swift-类结构源码探寻(一),继续 TargetClassDescriptor分析

    在这里插入图片描述
    在这里插入图片描述

    TargetClassDescriptor 中包含了超长的基类描述,超多的using

    我们分析主干思路,重在检索数据结构,暂时无关的信息暂时忽略掉

    先从 TargetClassDescriptor 属性信息 整理

    TargetClassDescriptor {
        var SuperclassType: TargetRelativeDirectPointer // Int32
        var MetadataNegativeSizeInWords: uint32_t
        var MetadataPositiveSizeInWords: uint32_t
        var NumImmediateMembers: uint32_t
        var NumFields: uint32_t
        var FieldOffsetVectorOffset: uint32_t
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    TargetTypeContextDescriptor {
        var Name: TargetRelativeDirectPointer // Int32
        var AccessFunctionPtr: TargetRelativeDirectPointer // Int32
        var Fields: TargetRelativeDirectPointer // Int32
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    TargetContextDescriptor {
        var Flags: ContextDescriptorFlags  // uint32
        var Parent: TargetRelativeContextPointer // Int32
    }
    
    • 1
    • 2
    • 3
    • 4

    汇总

    TargetClassDescriptor {
        var Flags: ContextDescriptorFlags  // uint32
        var Parent: TargetRelativeContextPointer // Int32
        var Name: TargetRelativeDirectPointer // Int32
        var AccessFunctionPtr: TargetRelativeDirectPointer // Int32
        var Fields: TargetRelativeDirectPointer // Int32
        var SuperclassType: TargetRelativeDirectPointer // Int32
        var MetadataNegativeSizeInWords: uint32_t
        var MetadataPositiveSizeInWords: uint32_t
        var NumImmediateMembers: uint32_t
        var NumFields: uint32_t
        var FieldOffsetVectorOffset: uint32_t
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    注意FieldOffsetVectorOffset 注释信息

    在这里插入图片描述

    结合 探寻(一) 关于 Description: TargetClassDescriptor 越界描述

    大概意思是 偏移出 metadata结构 之外,还存在的一些信息

    接下来就是 进一步分析偏移出 metadata结构 之外的信息了, 既然提到了vector,不妨看下 探寻(一) 中生成的sil文件

    既然暂时线性逻辑分析 遇到阻碍,进一步猜想,根据前面的 FieldOffsetVectorOffset 注释说明,需要找到 Descriptor 结构之后的偏移数据

    跳转到 sil

    在这里插入图片描述

    继续在 Metadata.h 中搜索vtable 关键字

    在这里插入图片描述

    发现了 vtable判断逻辑,有vtable的条件下,获取trailingObjects, 说白了 就是尾部的偏移逻辑了

    TargetClassDescriptor 继承父类

    在这里插入图片描述

    其中包含一个 TargetVTableDescriptorHeader,继续分析

    在这里插入图片描述

    这样,跟前面的分析中断处有了 衔接,VtableOffset 与 VtableSize 分别是

    TargetClassDescriptor 结构之后的 偏移结构的 offset 与 偏移结构大小

    继续补充结构

    TargetClassDescriptor {
        var Flags: ContextDescriptorFlags  // uint32
        var Parent: TargetRelativeContextPointer // Int32
        var Name: TargetRelativeDirectPointer // Int32
        var AccessFunctionPtr: TargetRelativeDirectPointer // Int32
        var Fields: TargetRelativeDirectPointer // Int32
        var SuperclassType: TargetRelativeDirectPointer // Int32
        var MetadataNegativeSizeInWords: uint32_t
        var MetadataPositiveSizeInWords: uint32_t
        var NumImmediateMembers: uint32_t
        var NumFields: uint32_t
        var FieldOffsetVectorOffset: uint32_t
        var VTableOffset: uint32_t
        var VTableSize: uint32_t
        // ......... VTable部分
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Metadata 结构基本梳理完

    swift oc 兼容缘由

    在这里插入图片描述

    注释很明确,所有堆开辟类型的元数据 通用结构 – TargetHeapMetadata

    全局搜索 HeapMetadata, 其中慢慢筛选过滤, HeapObject.h 中有包含 HeapMetadata 属性

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    struct HeapObject {
        var metadata: HeapMetadata // UnsafeRawPointer 8字节
        var refCount1 // UInt32
        var refCount2 // UInt32
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    验证HeapObject结构

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    阅读vtable部分源码

    全局搜索 VTableOffset

    好在 结果不多,方便筛选

    筛选掉明显不需要花精力阅读的文件及sil文件,锁定两个文件 GenMeta.cpp 与 MedataLayout.cpp 两个文件

    先通过 MedataLayout.cpp 中查看

    找到 addVTableEntries

    在GenMeta.cpp 中搜索结果定位的位置 发现关键字 VTableEntries

    在这里插入图片描述

    在 GenMeta.cpp 中搜索 addVTableEntries, 找到了调用

    在这里插入图片描述
    目光之余 发现了 addVTable()

    通过继承关系,找到父类 layout()

    在这里插入图片描述

    通过跋涉,终于看到了直给的东西

    正好对应 前面整理的结构
    在这里插入图片描述

    addVTable 逻辑

    在这里插入图片描述

    正好对应 TargetClassDescriptor结构最后部分

    var VTableOffset: uint32_t
    var VTableSize: uint32_t
    // ......... VTable部分
    
    • 1
    • 2
    • 3

    复习MachO验证

    回想swift-类结构源码探寻(一) 中的验证部分逻辑

    在这里插入图片描述

    这里存放的就是 clsss/struct/enumor descriptor的内存地址信息

    0x7ABC + 0xFFFFFB80 = 0x10000763C

    0x10000763C - 虚拟基址0x100000000 = 0x763C

    在这里插入图片描述

    通过这里 结合 Descriptor 结构信息 进行地址偏移,偏移13个4字节

    在这里插入图片描述

    0x7670 就是VTable部分

    在这里插入图片描述

    其中 0x7670 基址开始的第一个4字节为 method描述 Flags

    0x7670 + 0x4 + offset(0xFFFFC4D0) - 虚拟基址0x100000000 + ALSR = 方法内存地址

  • 相关阅读:
    多探头高频读写器|读卡器CK-FR104ANS系列安装与新旧功能对比分析
    FPGA基础协议三:SPI读取FLASH
    leetCode 1035.不相交的线 动态规划 + 滚动数组 (最长公共子序列)
    《自动机理论、语言和计算导论》阅读笔记:p261-p314
    Kotlin学习(一)
    Go中的错误处理
    Git快速入门一篇文章就够了。Git基础使用。如何将本地的文件上传到Gitee?
    python计算机毕业设计基于django的空闲教室爬虫系统
    小米汽车SU7全色系H5自适应展示源码
    c语言中的字符函数
  • 原文地址:https://blog.csdn.net/qq_42431419/article/details/127809242