переменная layout-C - PullRequest
       51

переменная layout-C

0 голосов
/ 10 июня 2018

Я пытаюсь исследовать паническое сообщение, которое я получил, вызванное доступом к адресу 0 в функции strlen в моем коде, который в основном является C ++ с объединенными с переменными target-C.

Метод, который вызывает панику, не обращается напрямую к strlen, а из ARC-движка, и я пытаюсь выяснить, для чего используется strlen как часть автоматического высвобождения переменной.

Согласно следующему блоку, скопированному из дизассемблера, похоже, что вывод [rax UTF8String] выдал пустую строку вместо допустимой строки, и это в конечном итоге привело к падению.Возможно, кто-нибудь может сказать мне, каково внутреннее расположение объекта C, для которого требуется эта проверка после autoreleasing переменной.

*(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);
}

1 Ответ

0 голосов
/ 10 июня 2018

ARC только вставляет retain/release/autorelease инструкции.Он не вставит ничего типа UTF8String или strlen.

objc_retainAutorelease представляет собой комбинацию retain + autorelease. autorelease операция не освобождает значение, она помещает объект в текущий «пул autorelease» (это похоже на пометку объекта для будущего удаления).

В этом коде я предполагаю, что orgName возвращает строку NSString в rax, затем преобразует этот NSString в строку C с помощью UTF8String и помещает в r14.По какой-то причине автор этого кода решил (как ни странно) не использовать orgName.length, а вместо этого использовать strlen.Таким образом, длина этой строки orgName помещается в r15.

Если orgName.lengthr15) меньше 0x17, она копирует строку C в var_8F.В противном случае он выделяет новый буфер r12 и копирует туда строку orgName C.

Строка *(int8_t *)(r12 - 0x1) = r15 + r15; странно.Это как если бы у var_8F было поле байтового размера непосредственно перед var_8F, и оно помещает туда двойную длину строки (длина мала, поэтому она подходит, но почему удваивается?).

...