Как Apple узнает, что вы используете частный API?

109

Я отправил в Apple двоичный файл без исходного кода.

Помимо ручной проверки исходного кода, как Apple узнает, что использовалось и какие API вы вызывали?

Таттат
источник
изменен заголовок - я полагаю, вы имели в виду «Откуда Apple знает ..»
Анураг

Ответы:

173

Я знаю 3 способа. Это всего лишь предположения, так как я не работаю в группе обзора Apple.

1. otool -L

В нем будут перечислены все библиотеки, с которыми связано приложение. То, что вам явно не следует использовать, например, IOKit и WebKit, могут быть обнаружены этим.

2. nm -u

Это список всех связанных символов. Это может обнаружить

  • Недокументированные функции C, такие как _UIImageWithName;
  • Классы Objective-C, такие как UIProgressHUD
  • Ivars, например UITouch._phase(который может быть причиной отказа от приложений на базе Three20 в последние несколько месяцев).

3. Перечислить селекторы Objective-C, или strings

Селекторы Objective-C хранятся в специальной области двоичного файла, поэтому Apple может извлечь оттуда контент и проверить, не использовали ли вы какие-либо недокументированные методы Objective-C, например -[UIDevice setOrientation:].

Поскольку селекторы не зависят от класса, о котором вы сообщаете, даже если ваш собственный класс определяет -setOrientation:не относящийся к UIDevice, существует вероятность того, что он будет отклонен.


Вы можете использовать APIKit Эрики Садун для обнаружения потенциального отказа из-за (ложных срабатываний) частных API.


(Если вы действительно действительно хотите обойти эти проверки, вы можете использовать функции времени выполнения, такие как

  • длопен, длсым
  • objc_getClass, sel_registerName, objc_msgSend
  • -valueForKey:; object_getInstanceVariable, object_getIvar и т. д.

чтобы получить эти частные библиотеки, классы, методы и ivars. )

kennytm
источник
Отличный ответ. Я просто добавлю, что если ваше приложение делает что-то, что чрезвычайно трудно сделать без использования частного API, я уверен, что ваше приложение подвергнется дополнительной проверке.
Мэтью Фредерик,
Мне любопытно, как можно обойтись при вызове частных методов. Я думаю, что компилятор сгенерирует вызов objc_msgSend (foo, @selector (privateMethod)) для [foo privateMethod], поэтому, если Apple может обнаружить прямой вызов privateMethod, они также могут обнаружить косвенный вызов через objc_msgSend (или performSelector :).
an0
Мне интересно, почему вы говорите, что не должны ссылаться на IOKit и WebKit?
hjaltij
2
На чем вы выполняете otool? Файл .app?
Роб
1
@Eric, они могли бы , хотя такая инструментальная версия, вероятно, повлияла бы на производительность. Несмотря на это, когда частные API постоянно поступают в App Store, становится ясно, что они этого не делают или, по крайней мере, не делают это все время.
Nate
26

Вы можете перечислить селекторы в программе Mach-O, используя следующую однострочную строку в Терминале:

otool -s __TEXT __objc_methname "$1" |expand -8 | cut -c17- | sed -n '3,$p' | perl -n -e 'print join("\n",split(/\x00/,scalar reverse (reverse unpack("(a4)*",pack("(H8)*",split(/\s/,$_))))))'
Роберт Даймонд
источник
+1, @ Роберт Даймонд, Можете еще описать по тому же. Мне нужно проверить, использует ли Google Analytics вызов UDID или нет. Спасибо
Mangesh
13

Допустим, вы хотите использовать частный API; цель C позволяет вам построить любой SEL из строки:

   SEL my_sel = NSSelectorFromString([NSString stringWithFormat:\
@"%@%@%@", "se","tOr","ientation:"]);
    [UIDevice performSelector:my_sel ...];

Как робот или сканирование библиотеки могли это обнаружить? Им придется уловить это с помощью какого-нибудь инструмента, который отслеживает частный доступ во время выполнения. Даже если они построили такой инструмент времени выполнения, его трудно поймать, потому что этот вызов может быть скрыт на каком-то редко используемом пути.

Крис МакЛувин
источник
user1203764 комментирует, что такие звонки действительно могут быть обнаружены
Rup
@Rup хотите высказать свое мнение по моему вопросу об использовании valueForKey, пожалуйста? stackoverflow.com/questions/11923597/…
Дэн Розенстарк
1
@Yar интересный вопрос! Но я недостаточно эксперт, чтобы прокомментировать, извините. То, что сказал Фаркаллер, кажется мне разумным
Руп
Спасибо @Rup, очевидно, никого не хватает эксперта в этой области :)
Дэн Розенстарк
Кто-то, кого я знаю, сказал, что ему только что позвонили в App Store.
bugloaf
7

Я предполагаю, что они смотрят на все символы, которые пытается импортировать ваш двоичный файл (информация, без сомнения, легко доступна для них в соответствующей таблице символов), и предупреждают вас, если какой-либо из этих символов находится в их «частном списке API». На самом деле, довольно легко автоматизировать.

Алекс Мартелли
источник
1
На самом деле, я могу с уверенностью сказать, что это не так (по крайней мере, это не все, что они делают), основываясь на использовании частного API, которое, как я знаю, прошло. Если это все , что нужно, частное использование API не проскользнуть через. Мой опыт подсказывает, что ответ Кенни почти наверняка верен. Это область, в которой Objective-C принципиально отличается от других языков, таких как C.
Нейт
1

Исполняемый файл - это не совсем черный ящик. Если вы обратитесь в библиотеку, ее легко найти. Вот почему я оплакиваю потерю языков ассемблера в современном образовании CS. =] Такие инструменты, как ldd, расскажут, на что вы ссылались, хотя я не помню, какое воплощение ldd вошло в комплект разработчика Mac для iPhone.

Sniggerfardimungus
источник
1
Я часто задавался вопросом: если бы вы написали свой двоичный файл для самомодификации, генерируя код для импорта частного API только после выполнения некоторых критериев (например, после даты публикации вашего приложения), поймает ли Apple его. Они, безусловно, сообщают нам интересную статистику, например, количество наших игр, запущенных на взломанных телефонах.
Sniggerfardimungus
@ user30997, к привилегированному коду, наверное, можно получить доступ только через системный вызов; выполняющийся поток переключается на более высокую привилегию и проверяет, имеет ли предыдущая привилегия разрешения на выполнение кода или нет. Это всего лишь пример, есть и другие способы сделать это, но я очень сомневаюсь, что разработчики были достаточно наивны, чтобы не упомянуть базовый механизм проверки привилегий во время выполнения, такой как этот, он определенно был бы опубликован к настоящему времени.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
1

помимо исследования символов ...

Apple может очень легко иметь версию sdk, которая проверяет каждый из стеков частных методов при вызове, чтобы убедиться, что он вводится одним из назначенных методов.

Grady Player
источник
Этого будет недостаточно, потому что программа может вызывать этот частный вызов только в произвольное время в будущем, в зависимости от другой логики. Чтобы провести такую ​​проверку, Apple должна фактически полностью заблокировать частные API-интерфейсы или заставить фреймворки автоматически сообщать Apple о частных вызовах API, что значительно снижает производительность.
Мотти Шнеор
0

Даже если вы статически связываетесь, в худшем случае они могут взять образцы кода из частных API-интерфейсов в своем списке и выполнить поиск вашего двоичного файла по ним (также относительно легко автоматизировать).

Зная Apple, я готов поспорить, что у них есть комплексная автоматизированная система, и любая неопределенность, вероятно, либо отрицается, либо проверяется вручную.

В конце концов, я думаю, что попытки обмануть Apple не стоит.

мыть
источник
4
Знание Apple о процессе проверки при возникновении какой-либо неопределенности включает в себя набор игральных костей для максимальной прихоти.
ТОЛЬКО МОЕ ПРАВИЛЬНОЕ МНЕНИЕ
0

Это настольное приложение, App Scanner , может сканировать файлы .app на предмет использования частного API, извлекая двоичный файл Mach-O. Если может, то сможет и Apple!

Андрей
источник
0

Существует множество инструментов для реверс-инжиниринга, позволяющих проверять код.

  • nm - перечисляет символы из объектных файлов
  • objdump - отображать информацию из объектных файлов.
  • otool- просмотреть содержание Mach-O [О программе] исполняемых файлов
  • strings - это даст вам все ниточки.

Вы можете найти примеры / представление использования этих команд в сущности для Objective-C и Swift.

yoAlex5
источник