找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 1559|回复: 1

越狱开发Swift之String内存结构分析

[复制链接]
发表于 2021-8-6 19:04:48 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 元始天尊 于 2021-8-8 16:46 编辑

  String是Swift的常见结构,下面来动手分析

let s1 = "abc" as String
test(s:s1)
let s2 = "abcabcabcabcabcabcabcabcabcabc" as String
test(s:s2)
let s3 = "bcd" as StaticString
test(s:s3)
let s4 = "bcdbcdbcdbcdbcdbcdbcdbcdbcdbcd" as StaticString
test(s:s4)  

  其伪代码如下:

v14.n128_u64[0] = 6513249LL;
  v16 = &_sSSN;
  v14.n128_u64[1] = -2089670227099910144LL;
  v1 = __swift_instantiateConcreteTypeFromMangledName(&_ss23_ContiguousArrayStorageCyypGMD);
  v2 = v1;
  v3 = swift_allocObject(v1, 64LL, 7LL);
  v4 = v3;
  *(_OWORD *)(v3 + 16) = xmmword_100006BE0;
  _sypWOc(&v14, v3 + 32);
  _ss5print_9separator10terminatoryypd_S2StF(v4, 32LL, -2233785415175766016LL, 10LL, -2233785415175766016LL);
  swift_release(v4);
  __swift_destroy_boxed_opaque_existential_0(&v14);
  v14.n128_u64[0] = -3458764513820540898LL;
  v16 = &_sSSN;
  v14.n128_u64[1] = (unsigned __int64)"" | 0x8000000000000000LL;
  v5 = swift_allocObject(v2, 64LL, 7LL);
  v6 = v5;
  *(_OWORD *)(v5 + 16) = xmmword_100006BE0;
  _sypWOc(&v14, v5 + 32);
  _ss5print_9separator10terminatoryypd_S2StF(v6, 32LL, -2233785415175766016LL, 10LL, -2233785415175766016LL);
  swift_release(v6);
  __swift_destroy_boxed_opaque_existential_0(&v14);
  v7 = vdupq_n_s64(3uLL);
  v16 = &_ss12StaticStringVN;
  v7.n128_u64[0] = (unsigned __int64)"bcd";
  v14 = v7;
  v15 = 2;
  v8 = swift_allocObject(v2, 64LL, 7LL);
  v9 = v8;
  *(_OWORD *)(v8 + 16) = xmmword_100006BE0;
  _sypWOc(&v14, v8 + 32);
  _ss5print_9separator10terminatoryypd_S2StF(v9, 32LL, -2233785415175766016LL, 10LL, -2233785415175766016LL);
  swift_release(v9);
  __swift_destroy_boxed_opaque_existential_0(&v14);
  v16 = &_ss12StaticStringVN;
  v10 = vdupq_n_s64(0x1EuLL);
  v10.n128_u64[0] = (unsigned __int64)"bcdbcdbcdbcdbcdbcdbcdbcdbcdbcd";
  v14 = v10;
  v15 = 2;
  v11 = swift_allocObject(v2, 64LL, 7LL);
  v12 = v11;
  *(_OWORD *)(v11 + 16) = xmmword_100006BE0;
  _sypWOc(&v14, v11 + 32);
  _ss5print_9separator10terminatoryypd_S2StF(v12, 32LL, -2233785415175766016LL, 10LL, -2233785415175766016LL);

  经过调试分析,可以知道String类大小为16字节,在函数传参中默认以值传递(X0/X1),而返回时也以值传递(X0/X1),可以得到如下结构。可以看到String结构在长度<=15时使用short方式存储,长度>=16时使用long方式存储。使用long方式存储时,还有存在偏移,不知道为何如此设计。从总体看形似std::string结构,但是更复杂。

struct Swift.StaticString {
    int64_t _addr; // 指向实际字符串
    int64_t _len;
};

union Swift.String {
    struct {
        char _buf[15];        // 实际字符串
        int _type : 4;        // short的type=0xe
        int _len : 4;          // 字符串长度
    } short,
    struct {
        int64_t _len : 60;  // 字符串长度
        int64_t _type : 4;  // long的type=0xd
        int64_t _addr;      // (_addr&0x7ffffffffffffffff)+0x20指向实际字符串,最高位固定为1
    } long
}
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-21 20:59 , Processed in 0.032840 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表