Home > Business > Помощь хакера

Помощь хакера

Added: (Fri Aug 26 2022)

Pressbox (Press Release) - В связи с последними событиями хочется затронуть тему Помощь хакера!
Взлом и внедрение своего кода в чужое iOS-приложение.
В жизни хакеры не так всесильны и эффектны, как в голливудских фильмах. Но это не значит, что iOS-разработчик может вообще не думать о безопасности своего приложения. Пусть оно и не хранит тайны Пентагона, взломать его всё равно могут хотя бы для того, чтобы получить платные функции бесплатно.
На нашей конференции Mobius разработчик Мурад Татаев рассказывал о взломе iOS-приложений — и о том, что разработчики могут делать для защиты от него. А теперь мы расшифровали этот доклад (видеозапись также прилагаем). Далее повествование идёт от лица спикера.
Мы не будем говорить о защите сетевого слоя — о SSL Pinning и тому подобном, а рассмотрим только взлом приложения. Будет теоретическая часть, где мы разберемся с некоторыми понятиями, и практическая, где применим полученные знания.
Начнем с теории.
Взлом.
В моем понимании взлом — это изменение поведения приложения в интересах хакера. То есть приложение работает не так, как изначально задумывал программист. В основном поведение меняется в тех частях, что связаны с получением чего-то, обычно за деньги — хакер хочет получить это бесплатно.
Относительная безопасность.
Относительная безопасность означает, что затраты на атаку превышают полученную в результате выгоду. Допустим, у вас есть погодное приложение, в котором нет внутренних покупок. Вы пользуетесь открытым API, вам нет смысла париться о безопасности. ?? в результате взлома вы ничего не потеряете.
Но если вдруг у вас что-то серьезнее, например, фоторедактор, в котором через встроенные покупки можно открыть дополнительные фильтры, то стоит задуматься о безопасности.
Нужно понимать, что абсолютной безопасности вы не добьетесь. Вы можете добиться некоторой «лучшей обезопашенности» по сравнению с тем, что было раньше.
Почему важно защищать приложение?
Чтобы это понять, нужно увидеть в этом смысл. ?? он в основном экономический, реже — репутационный.
Для примера возьмем YouTube Tools — твик для отключения рекламы в приложении YouTube. В чем проблема: из-за того, что вы не смотрите рекламу, YouTube недополучает денег. Разработчики YouTube знают об этом и часто борются с различными твиками.
Другой пример — получение платного бесплатно, как в игре Plague Inc. со взломанными покупками. В интернете лежит уже взломанный .ipa-файл, и из-за хакеров ребята теряют много денег, не уделяя достаточного внимания безопасности.
Еще один пример — обход платного скачивания Minecraft. В этом случае особенно не защитишься, потому что пользователь скачает приложение, расшифрует его, выложит файл, и его скачают другие.
Но в двух предыдущих вариантах (YouTube и Plague Inc.) есть способы бороться с хакерами, причем их довольно много.
Как защищаться?
Это главный вопрос. Есть несколько вариантов, которые я знаю:
Проверка на джейлбрейк Проверка на дебаггер Обфускация кода (security through obscurity) Strip Swift Symbols — настройка в Xcode Валидация покупок на сервере Silent Push и Background Updates Написание кода на Swift и минимальное использование objc и dynamic.
Совет : проверяйте, нет ли в интернете вашего взломанного приложения.
Проверка на джейлбрейк.
Плюсы : легко и дешево использовать (достаточно скопировать и вставить код).
Минусы : во-первых, это очень легко пропатчить.
Во-вторых, страдают некоторые мирные пользователи, которые могли поставить джейлбрейк не чтобы получить что-то ваше бесплатно, а чтобы пользоваться различными другими твиками.
Есть и обратная сторона — джейлбрейк используется все реже, но есть и те, кто по-прежнему ставят его.
Проверка на дебаггер.
Плюсы : легко использовать, сложнее патчить.
Это хорошо работает с отложенными ошибками . Если вы узнали, что пользователь запустил ваше приложение с подключенным дебаггером или у него джейлбрейк и так далее, вы можете конкретно в каких-то критичных местах не давать ему проходить дальше. Такую ошибку нужно показывать не сразу, а делать это позже, чтобы код проверки не был в очевидном месте.
Минусы : это тоже патчится.
Примерный код проверки выглядит так:
Мы создаем структуру для информации о процессе, задаем размер этой структуры и с помощью утилиты systemctl пытаемся запросить флаги для текущего процесса. Если у нас получилось запросить их — идем дальше и проверяем, активен ли флаг P_TRACED. При помощи этого флага производится дебаггинг в iOS.
Если флаг стоит не в null, то нас дебажат.
Обфускация кода.
Есть различные обфускаторы, один из популярных, насколько я понял по GitHub — это SwiftShield.
Плюсы : код превращается в лабиринт, в нем вообще не разберешься. Особенно классные обфускаторы создают дополнительные методы, мусор, чтобы запутать хакера. Насчет Swift не уверен, но в C#, Java и Kotlin есть такие.
Минусы : иногда этот лабиринт сказывается и на вас. ?? еще крэш-логи приходится каждый раз расшифровывать.
На скриншоте — крэш-лог одного из приложений.
Над зеленой полосой — крэш-лог до расшифровки, ниже — расшифрованный крэш-лог. Крэш-лог нужно расшифровывать через утилиту, которая идет вместе со SwiftShield. Это можно автоматизировать: засунуть в CI дополнительный job, чтобы подтягивать все крэш-логи, прогонять их через утилиту и что-то делать с ними дальше. Но это дополнительная работа.
Еще один большой минус — нет готовых решений, годных для энтерпрайза. Они опенсорсные. Это не плохо, но нужно быть осторожным, подтягивая что-то опенсорсное в ваш проект, особенно если он связан с безопасностью и обфускацией.
Я за свою практику не сталкивался с тем, чтобы кто-то в iOS пользовался обфускатором кода, поэтому это очень редкая практика.
Strip Swift Symbols.
Плюсы : легко и дешево использовать, удаляется часть информации о Swift-классах. ?? это включено по умолчанию, то есть Xcode думает о вашей безопасности.
Минусы : информацию о классе можно найти другим способом.
Зачем нужно включать Strip Swift Symbols?
Допустим, у нас есть стандартный класс ViewController, label, viewDidLoad и так далее. Прошу обратить особенное внимание на статичную функцию buildScreen, о ней мы еще поговорим.
Если вы оставили Swift Symbols и после этого прогнали бинарник вашего приложения через специальную утилиту dsdump, вот что появится в логе:
Ниже можно увидеть, что есть некоторые свифтовые методы, и по названиям методов и переменных вы можете примерно понять, что здесь происходит и важен ли для вас этот класс. Что самое интересное, здесь нет статического метода buildScreen. Статические методы находятся в другом месте.
Вот что будет, если включить эту функцию: как вы видите, данных о свифтовых методах просто нет. Есть все, что связано с Objective-C и бриджингом для Objective-C.
Валидация покупок на сервере.
Это очень хорошая практика, которой придерживаются не все. Среди топ-100 приложений я находил немало тех, у которых валидация все еще производится на девайсе, и при помощи одного твика можно обойти валидацию (подмена ответа сервера).
Плюсы : безопасность.
Минусы : вам придется покупать хостинг.
А если вы будете валидировать на клиенте?
Плюс : вам не нужен сервер.
Минус : потенциальная потеря денег. Твик LocaliAPStore будет вашим худшим врагом.
В качестве примера могу привести одно приложение, связанное с фоторедактированием. Название я, к сожалению, не могу сказать. Это приложение как раз не использует валидацию покупок на сервере. Приложение классное, но при помощи одного твика вы можете получить всё бесплатно.
Еще есть одна RPG-игра, она тоже находится в топах, там тоже валидация покупок на девайсе. Даже у известного раннера про подземки и бег с поездами такая же проблема — валидация идет на девайсе.
??нструменты — чем я пользуюсь каждый день.
Filza — файловый менеджер, в котором скрыто очень много функций. С его помощью вы можете поднять сервер, FileDAV и обмениваться файлами с компьютером.
Unc0ver — это джейлбрейк, которым я пользуюсь. Он поддерживает версии вплоть до iOS 13.5.
Но с iOS 13.5 я бы посоветовал быть осторожней, потому что встроенный браузер в приложении, Safari View Controller, работает плохо. Лично у меня, когда я открываю ссылки, появляется окно внутреннего браузера (Safari View Controller), которое абсолютно пустое и ничего не грузит.
Cydia — это менеджер пакетов для взломанных устройств.
Наверное, некоторые из вас слышали, что Cydia — всё, закрыта, но нет, она поддерживается и вполне живет. Здесь есть куча разных твиков. Мы будем использовать Cydia в основном для того, чтобы устанавливать различные инструменты на устройство. С Cydia вы можете скачать ту же самую Filza.
NewTerm — это мобильный терминал. Он тоже доступен из Cydia и тоже полезная штука.
FLEXing — твик для поверхностного анализа приложения на устройстве. При помощи него можно посмотреть интернет-трафик, ваши файлы и тому подобное. Снифер трафика обходит SSL Pinning.
Я так проверял трафик в Instagram, а там есть SSL Pinning,
Можно посмотреть объекты в куче, которые есть сейчас, и вызвать различные методы в этих объектах. Есть общий список классов для приложения, можно поверхностно посмотреть, что там есть. Можно посмотреть UserDefaults и, неожиданно, Keychain.
Keychain — это, грубо говоря, тот же самый UserDefaults, только зашифрованный вашим паролем, то есть пин-кодом от вашего устройства. Если вы введете пин-код, Keychain разблокируется, и все, что там лежит, можно посмотреть. Так что я бы вам советовал не хранить ничего незашифрованного в Keychain, потому что до этого можно добраться и что-то поменять.
Как делать не надо.
В AppDelegate есть строка isUnlocked:
То есть разработчик добавил в AppDelegate переменную, с помощью которой он смотрит, куплено приложение или нет.
Естественно, эта переменная легко меняется: вы жмете кнопку i, дергаете свитч, нажимаете «ОК». Поменяли переменную, закрыли меню флексинга, и у вас полностью «купленное» приложение.
Ghidra.
Классная штука, дизассемблер от АНБ США, здесь можно вставить шутку про слежку от спецслужб.
Бесплатный Умеет в arm64, что нам как раз и нужно Умеет в псевдокод — вы можете посмотреть интерпретацию кода и понять, что ничего не поломали Позволяет бесплатно редактировать и экспортировать бинарники.
Переходим к практике.
Мы будем практиковаться на тестовом проекте.
Как достать расшифрованное приложение?
Необходимо клонировать репозиторий Установить на девайс Frida Tools, используя Cydia Запустить проект MobiusStep1 в режиме Release на взломанном устройстве Установить утилиту iProxy Запустить терминал, ввести код iproxy 2222 22 Поставить Frida на компьютер, например, через Homebrew Ввести freeda-ps -Uai Если всё сделано правильно, то в терминале отобразится общий набор приложений на устройстве и в топе будут находиться включенные приложения. Будет написан их PID и так далее. Скачать скрипт frida-ios-dump для скачивания взломанных приложений Перейти в папку с этим скриптом (телефон подключен при помощи кабеля, iProxy запущен) Ввести ./dump.py “имя вашего приложения”
Есть ограничения — не дампятся extensions. Но за все время, что я этим пользовался, мне extensions и не были нужны.
Обход проверки на джейлбрейк.
Патчим бинарник. Тот проект, что вы скачали ранее, выглядит так: простой белый экран, на нем — label с текстом: либо Hacked, либо Safe and sound в зависимости от того, джейлбрейкнуто устройство или нет.
Достаем .ipa-файл, о котором говорили выше (он будет в папке со скриптом, по сути это .zip-архив) Разархивируем и переходим в папку Payload, далее — в .app-контейнер Копируем бинарник и содержимое папки Frameworks в отдельную папку. Тогда Ghidra подтянет все зависимости, ссылки и так далее. Это очень удобно, если вы проверяете многомодульное приложение: один метод находится в другом модуле, часть этого модуля — в третьем модуле и так далее. Можно разом все импортировать в Ghidra. Запускаем Ghidra, создаем новый проект и добавляем ранее скопированные файлы.
Если все сделали правильно, это будет выглядеть примерно так:
Как найти необходимый участок кода?
Так как у нас код не обфусцирован, нужно либо вручную, не давая методам слишком очевидные имена, либо утилитами обфусцировать код.
При помощи поиска ищем слово jail в настройках. Найдется пара методов. ?? если вы нажмете на один из них, как можно увидеть чуть выше, курсор прыгнет в нужную область памяти.
Патчим инструкцию.
Здесь вы видите инструкцию bl (branch with link) — это по сути прыжок на функцию, которая ожидает, что из этой функции что-то вернется в регистре w0. Если мы знаем, в какой регистр вернется значение, мы можем выполнить команду mov (присваивание).
То есть в регистр w0 записывается как раз то, что возвращается с метода. Мы записываем 0 (то есть false), экспортируем бинарник. Так как мы не трогали остальные фреймворки, нам нужен только бинарник.
Скорее всего, он будет экспортирован с припиской bin, ее нужно удалить и оставить только MobiusStep1. После этого открываем папку, откуда мы брали бинарник, то есть папку с приложением, папку с .app-контейнером, заменяем старый бинарник на новый.
После этого все подписываем, собираем и устанавливаем на устройство.
Готово — вы пропатчили приложение.
Подпись и установка приложения.
Необходимые предварительные требования:
Профиль разработчика. Можно воспользоваться бесплатным — на одно устройство и на неделю, но это намного проблемнее. Проще купить профиль и воспользоваться AdHoc provisioning profile , то есть создать AdHoc-профайл на портале разработчика. libimobiledevice — набор утилит, одна из которых — установка .ipa-файла на устройство через консоль вне зависимости от того, взломан телефон или нет (brew install libmobiledevice). Приложение, которое хотите установить Терпение и усидчивость — потому что все может пойти не по плану именно в этой части.
Копируем необходимые файлы.
Создаем Adhoc Provisioning Profile и копируем его в папку с приложением. Дальше выполняем код:
В итоге мы получим entitlements.plist, который нам нужен. Profile.plist уже не нужен. Система безопасности iOS построена вокруг этих entitlements.
security — утилита macOS, с помощью которой можно работать с сертификатами, паролями, keychains и всем, что связано с безопасностью.
После этого копируем Adhoc Provisioning Profile в контейнер приложения (папку Payload/*.app) и переименовываем его в embedded.mobileprovision. Это обязательно!
Находим ключ для подписи.
security find-identity -v -p codesigning.
Этот код ищет сертификат, при помощи которого можно подписать приложение. В моем случае я выбрал iPhone Distribution, можно выбрать Developer, разницы я не заметил. Она может возникнуть, когда вы будете пытаться залить это все в App Store. Но в локальном тесте разницы нет.
Подписываем файлы.
Это самое интересное. Вводим codesign, не забываем подписывать фреймворки. В моем случае там лежали только dylib, если лежат еще и фреймворки — обговорим этот кейс позже.
Не забывайте сначала подписать основной бинарник, а потом все приложение. В таком порядке у меня все работало отлично.
zip -qr resigned.ipa Payload.
?? устанавливаем. Не забывайте, чтобы устройство было подключенным через кабель, иначе работать не будет.
ideviceinstaller -i resigned.ipa.
Cтавим через ideviceinstaller, а не Xcode — ideviceinstaller пишет логи в консоль, и вы сможете понять, на каком шаге допустили ошибку. Это довольно сильно облегчает дебаг.
??нъекция фреймворков и подмена реализации методов.
Дальше начинается самое интересное, то есть настоящий взлом. Необходимые инструменты:
otool (он поставляется из Xcode, вам ничего не нужно качать) dsdump (есть в интернете, можно найти) фреймворк, который нужно будет вставить в ваше приложение и в котором будет ваш дополнительный код.
Потренируемся!
Советую всем начинать с простого и только потом бежать взламывать пентагоны.
Приложение называется Mobius Conf. У вас есть 300 монет, можно добавить монеты, то есть их купить, но мы так делать не будем, либо можно что-то купить внутри приложения за 200 монет.
Создайте проект, добавьте в него новый таргет, в меню выберите фреймворк. Во фреймворк добавьте новый ObjC-класс, дайте название по вкусу. В имплементационный файл MobiusStep2/MOBFramework/Injector.m добавьте код:
Скорее всего, большинству из вас код будет непонятен. Метод вызывается в момент. когда загружается ваш фреймворк. Стоит учитывать, что именно в этот момент приложения еще нет, оно только грузится.
Здесь нельзя сразу пытаться что-то менять. ??менно поэтому здесь прописан dispatch_after. Через три секунды на экране появится алерт с текстом вроде «Вы это сделали, классно». Если вы скопировали, вставили, все заработало — прекрасно, это первый шаг в сторону взлома.
Поиграем с кодом.
Склонируйте Substrate и скопируйте фреймворк Substrate на рабочий стол. Во фреймворк MOBFramework добавьте фреймворк Substrate (переносится через drag and drop). ??мпортируйте заголовок “CydiaSubstrate/CydiaSubstrate.h”.
Cydia Substrate — это такой фреймворк для подмены реализации методов, другими словами, для хукания методов. Есть метод с изначальной реализацией, которую задумал программист, и есть ваш метод. Вы берете и подменяете эти методы. На этом фреймворке держатся все твики, которые лежат в Cydia.
Попробуем вызвать какую-нибудь функцию.
В навигаторе Xcode откройте папку Products. Вы можете открыть файл MobiusStep2.app в Finder, перейти в папку app через терминал, войти в app-контейнер и с помощью утилиты dsdump принтануть все символы, которые есть в приложении. Все статичные методы в приложении тоже реализованы в виде символов.
dsdump -c MobiusStep2 | grep viewDidLoad.
Вводите ViewDidLoad или то, что вам интересно. Здесь есть два метода, я выбрал второй, вы можете выбрать первый — по сути, это одно и то же.
Копируете всю строку, в Xcode удаляете весь предыдущий код и вводите команду MSFindSymbol.
Что такое MS? ??значально CydiaSubstate называлась MobileSubstate, и MS — дань уважения этому. MSFindSymbol делает то же, что и dsdump — идет поиск символа, копируется отступ по памяти, дополнительные данные. Всё это нужно для того, чтобы позже можно было что-то менять по этому символу.
Можно что-то вызвать по этому символу:
Но имейте в виду, что в этом методе могут вызываться различные переменные, которые еще не инициализированы. ?? возможно, приложение будет просто крашиться. Поэтому будьте осторожны, и лучше всего через Ghidra заранее проверять метод, который вы хотите вызвать: посмотреть в интерпретаторе, не идут ли вызовы в какие-то локальные переменные, которые еще не инициализированы, и так далее.
Если вы так вызовете символ в этом проекте, вы увидите, что принтанется viewDidLoad. ??з-за того, что вы сами вызвали viewDidLoad, и после этого вызвался «натуральный» метод, у вас в консоли продублируется текст viewDidLoad.
Давайте вызовем свой код после viewDidLoad.
Это уже что-то более боевое и интересное. ??з предыдущего кода остается MSFindSymbol, но только вызов MSFindSymbol заменяется на MSHookFunction. Здесь оригинальный метод заменяется на засвизленный, то есть на наш.
В нашем методе мы сначала вызываем оригинальную имплементацию в виде Load, и после него идет наш код. Ничего оригинального не стал придумывать, просто через 2 секунды отображаю алерт.
Как насчет бесконечности денег?
Если вы будете бродить по символам, найдете интересный символ PurchaseManager spend. ??з названия понятно, что этот метод будет вызван, если что-то нужно потратить, например, деньги. ?? этот метод можно захукать.
С помощью Ghidra можно понять и проверить, что этот метод на входе принимает аргумент в виде количества денег, и просто подменить оригинальную реализацию своей.
Разница в том, что мы не учитываем количество денег, которое потратил пользователь, — всегда передаем 1. Каждый раз, когда вы нажимаете кнопку покупки, единичка будет уходить. Можно передавать 0, и тогда у вас будет бесконечное количество денег (они не будут тратиться).
Потренировались? Будем инжектить в реальное приложение.
Ранее созданный фреймворк копируем на рабочий стол или в отдельную папку. Его можно будет найти в папке Products. Собираем проект в режиме Release, предварительно удалив ранее созданный фреймворк из проекта. Так мы почистим следы вмешательства. Запускаем на устройстве, копируем .ipa-файл и разархивируем его. Копируем MOBFramework.framework в папку Frameworks (Payload/MobiusStep2.app/Frameworks)
Дальше добавим загрузку своего фреймворка. В консоли переходим в MobiusStep2.app, и при помощи otool -L MobiusStep2 проверяем, какие фреймворки и библиотеки добавлены на загрузку.
Здесь есть Foundation, Objective-C, UIKit, SwiftCore и так далее.
При помощи optool можно добавить свою дополнительную строку. Вводим код:
optool install -c load -p “@rpath/MOBFramework.framework/MOBFramework” -t MobiusStep2.
Добавится новая строка. Это можно проверить, вызвав команду:
otool -L MobiusStep2.
Вы увидите, что в конце добавлена новая строка на загрузку нового фреймворка. Обязательно после фреймворка написать / и путь до бинарника, иначе ничего не подгрузится и не будет работать.
Не забудьте подписать фреймворк!
codesign -f -s "identity” Payload/*.app/Frameworks/*.framework.
Не забудьте скопировать фреймворк в папку с фреймворками — та строка, что мы писали, магическим образом не будет искать по всему проекту — только в папке Frameworks.
Можно объединить все в один shell-файл, чтобы не вводить каждый раз несколько команд. Можно добавить еще одну команду для подписи сразу всех фреймворков.
Вы заинжектили свой фреймворк и свой код в чужое приложение.
Но! Хукать свифтовые методы можно только на взломанном устройстве.
Если хотите хукать не только на взломанных устройствах и карма смотрит на вас лицом, то вам повезет, и то приложение, которое вы будете исследовать, будет на Objective-C.
Это еще одна причина, почему я говорил, что писать надо на Swift. Вы сейчас увидите, почему не следует писать на Objective-С что-то безопасное.
Это приложение MobiusStep3. Здесь кнопка добавления денег пропала, есть только кнопка «Потратить». Наша цель — иметь бесконечное количество монет. В этом нам поможет Objective-C Runtime и тот же свизлинг методов.
Подготовка проекта.
Клонируем проект MobiusStep3 Собираем (билдим) проект Переходим в папку с приложением, открываем его бандл (.app)
Запускаем терминал в этой папке.
??спользуя команду dsdump --objc MobiusStep3 -vvv , можно посмотреть, какие методы есть в приложении.
??х немного, и если присмотреться, можно заметить уязвимый метод spend. Мы его взламывали ранее, и он может принести потенциальные проблемы.
Будем свизлить как раз-таки его, здесь классический свизлинг методов. Находим класс по имени, находим селектор по имени и подменяем реализацию оригинального метода на неоригинальный.
Не забываем сохранять ссылку на предыдущую (оригинальную) реализацию. Можно заметить строку с переменной originalImplementation, так мы держим ссылку на оригинальную имплементацию. IMP — это сишная структура, просто так IMP-структуры не вызвать, приходится их кастить.
Внизу видно, как мы их закастили через swizzled_spend. id, SEL — это обязательно. Наконец, вы можете увидеть int в коде, который кастим. На следующей строке вызываем этот метод и передаем 0 или 1. Единица удобна для дебага.
Все работает без мам, пап, кредитов и Cydia Substrate. Причина — особенность гипердинамичного Objective-C Runtime, где связывание с методами происходит как можно позже.
Резюмируем.
Проверяйте на джейлбрейк и на дебаггер, потому что это дешево и просто. Не используйте Objective-C, либо используйте его по минимуму и не забывайте отрезать Swift Symbols. Обфускация в целом классная идея, но используется редко и приносит неудобства с крэш-логами. Привязывайтесь к хардварным особенностям системы. Если у вас есть какие-то токены, которые необходимо обновлять, то лучше всего построить логику обновления так. Через Silent Push к вам приходит некоторое уведомление, вы на него реагируете и запрашиваете обновленный токен заново с сервера. После того, как пришел Silent Push, у вас есть где-то 30 секунд на то, чтобы запросить новый токен, записать его и опять уйти в сон. Реализовать это не так сложно, зато в такой системе хакеру будет очень тяжело получать токены. Храните данные на сервере, потому что локальные хранилища (UserDefaults, Keychain, LokalDB) очень ненадежны. Даже локальные базы данных можно просмотреть при помощи Filza. Валидируйте покупки на сервере, а не на девайсе.
?? помните — абсолютной безопасности не существует. Но можно сделать безопаснее, чем было раньше.
об ARM о хукании методов на Medium о том, как заинжектить iOS-код в .ipa-файлы , которая пригодится, если вы хотите подписать приложение бесплатным сертификатом Немного об macOS Security Utility.
Если вам захочется обсудить с Мурадом его доклад, напишите ему:
Telegram и Хабр: spartanrasul Email: spartanrasul@gmail.com.
Если вы дочитали досюда и вы не злонамеренный хакер (фу таким быть) — тогда, скорее всего, вы мобильный разработчик. Тогда обращаем ваше внимание, что следующий Mobius пройдет 22-25 ноября, и там будет много новых докладов. Хакерский колорит в их случае не обещаем, а вот актуальность для мобильных разработчиков — вполне.

Хакерские программы

Submitted by:DavidIsolo
Disclaimer: Pressbox disclaims any inaccuracies in the content contained in these releases. If you would like a release removed please send an email to remove@pressbox.com together with the url of the release.