【问题标题】:objective-C variable layoutObjective-C 变量布局
【发布时间】:2018-11-19 20:07:04
【问题描述】:

我正在尝试调查我在代码中访问函数 strlen 中的地址 0 时触发的恐慌消息,该代码基本上是 C++ 并结合了 Objective-C 变量。

产生恐慌的方法不是直接访问strlen,而是从ARC引擎访问,我试图弄清楚strlen是用来作为自动释放变量的一部分的。

根据从反汇编程序复制的下一个块,[rax UTF8String] 的输出似乎产生了 null 而不是有效字符串,这最终导致了崩溃。也许任何人都可以告诉我在 autoreleasing 变量之后需要检查的 Objective-C 的内部布局是什么。

*(int8_t *)(r15 + rbx) = 0x0;
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator=(r13 + 0x198, &var_60);
rax = [var_98 orgName];
rax = [rax retain];
rax = objc_retainAutorelease(rax);
var_70 = rax;
r14 = [rax UTF8String];
var_90 = intrinsic_movaps(var_90, 0x0);
var_80 = 0x0;
r15 = strlen(r14);
if (r15 >= 0xfffffffffffffff0) goto loc_10001267b;
if (r15 < 0x17) {
        r12 = &var_8F;
        *(int8_t *)(r12 - 0x1) = r15 + r15;
        if (r15 != 0x0) {
                memcpy(r12, r14, r15);
        }
}
else {
        r12 = operator new(r15 + 0x10 & 0xfffffffffffffff0);
        var_80 = r12;
        var_90 = r15 + 0x10 & 0xfffffffffffffff0 | 0x1;
        memcpy(r12, r14, r15);
}

【问题讨论】:

  • 问题是什么?你不明白这里的哪条指令?原始源代码在哪里?
  • 嗨,我不明白为什么 ARC 将方法 objc_retainAutorelease 的返回值转换为 UTF8String,使用 strlen 检查它的长度并将这个值与constand 0x17.. 我希望 ARC 只是释放变量,仅此而已..
  • 你没有来源?在代码的开头,var_98、var_90、var_8F 中存储了什么?我怀疑 ARC 是否执行 UTF8String/strlen。 ARC 可能会插入 objc_retainAutorelease,但其余部分对我来说似乎是程序逻辑的一部分。

标签: c++ objective-c macos layout reverse-engineering


【解决方案1】:

ARC 只插入retain/release/autorelease 指令。它不会插入像UTF8Stringstrlen 这样的东西。

objc_retainAutoreleaseretain + autorelease 的组合。 autorelease 操作不是释放值,而是将对象放入当前的“自动释放池”中(就像标记对象以备将来销毁一样)。

在这段代码中,我假设orgName 将一个NSString 返回到rax,然后它使用UTF8String 将这个NSString 转换为一个C 字符串并放入r14。出于某种原因,这段代码的作者决定(很奇怪)不使用orgName.length,而是使用strlen。那么这个字符串orgName的长度就放到r15中了。

如果orgName.length(在r15)小于0x17,它将C字符串复制到var_8F。 否则它会分配一个新的缓冲区r12 并在那里复制orgName C 字符串。

*(int8_t *)(r12 - 0x1) = r15 + r15; 行很奇怪。就好像 var_8F 在 var_8F 之前有一个字节大小的字段,它把字符串长度的两倍放在那里(长度很小,所以很合适,但为什么要加倍呢?)。

【讨论】:

  • 很好的分析,但程序集有点陌生,它先是 retain,然后是 retainAutorelease(第 4 行和第 5 行),这是一个双重保留...if (r15 &gt;= 0xfffffffffffffff0) 是使用new 保护缓冲区分配,使用r15 + 0x10 &amp; 0xfffffffffffffff0 将大小四舍五入到下一个16 字节边界(假设严格的从左到右操作,就像顺序指令中发生的那样)。
  • 我注意到双重保留 - 确实很奇怪,但认为这对于理解这件作品无关紧要。感谢 0xfffffffffffffff0 的解释,现在说得通了,因为我看到先计算“+”,如 (r15 + 0x10) &amp; 0xfffffffffffffff0
猜你喜欢
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多