Программы Андроид как защитить

В данной статье мы кратко расскажем о том, как можно защитить свою программу от взлома, не интегрируя стандартное решение от Google и предоставим пример рабочего кода. Интересно? Просим под кат!

В чём слабость Google Application Licensing?

Дело в том, что данный механизм хорошо известен разработчикам и его взлом не составляет большого труда. Всё что для этого нужно — скачать apktool, найти класс LicenseChecker и слегка подправить метод checkAccess.

Как реализовать свою собственную защиту?

Очевидно, что любую защиту можно сломать. Данный метод не является серебрянной пулей, но он имеет право на жизнь. Для проверки уникальности приложения есть смысл проверить сертификат, которым это приложение было подписано. Информацию о сертификате можно прочитать из PackageInfo:

PackageInfo info =getPackageManager().getPackageInfo(getPackageName(), 0); Signature[] signatures = info.signatures;

Нулевой элемент массива будет содержать необходимую информацию о ключе, которым было подписано приложение. Сохраните сам ключ, он вам понадобится совсем скоро.

Эти Простые Способы ПОМОГУТ Защитить твой Телефон от Взлома и Потери Всех Личных Данных !!!


Логично, что делать такую проверку в Java не имеет смысла, так как аналогичный приём с использованием apktool похоронит вашу защиту за несколько минут. Поэтому данную проверку стоит перенести на нейтив уровень.

const char* rsa = «PUT_YOUR_RSA_KEY_HERE»; jint verifyCertificate(JNIEnv *env, jobject obj, jobject cnt) < jclass cls = env->GetObjectClass(cnt); jmethodID mid = env->GetMethodID(cls, «getPackageManager», «()Landroid/content/pm/PackageManager;»); jmethodID pnid = env->GetMethodID(cls, «getPackageName», «()Ljava/lang/String;»); if (mid == 0 || pnid == 0) < return ERROR; >jobject pacMan_o = env->CallObjectMethod(cnt, mid); jclass pacMan = env->GetObjectClass(pacMan_o); jstring packName = (jstring) env->CallObjectMethod(cnt, pnid); /*flags = PackageManager.GET_SIGNATURES*/ int flags = 0x40; mid = env->GetMethodID(pacMan, «getPackageInfo», «(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;»); if (mid == 0) < return ERROR; >jobject pack_inf_o = (jobject) env->CallObjectMethod(pacMan_o, mid, packName, flags); jclass packinf = env->GetObjectClass(pack_inf_o); jfieldID fid; fid = env->GetFieldID(packinf, «signatures», «[Landroid/content/pm/Signature;»); jobjectArray signatures = (jobjectArray) env->GetObjectField(pack_inf_o, fid); jobject signature0 = env->GetObjectArrayElement(signatures, 0); mid = env->GetMethodID(env->GetObjectClass(signature0), «toByteArray», «()[B»); jbyteArray cert = (jbyteArray) env->CallObjectMethod(signature0, mid); if (cert == 0) < return ERROR; >jclass BAIS = env->FindClass(«java/io/ByteArrayInputStream»); if (BAIS == 0) < return ERROR; >mid = env->GetMethodID(BAIS, «», «([B)V»); if (mid == 0) < return ERROR; >jobject input = env->NewObject(BAIS, mid, cert); jclass CF = env->FindClass(«java/security/cert/CertificateFactory»); mid = env->GetStaticMethodID(CF, «getInstance», «(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;»); jstring X509 = env->NewStringUTF(«X509″); jobject cf = env->CallStaticObjectMethod(CF, mid, X509); if (cf == 0) < return ERROR; >//»java/security/cert/X509Certificate» mid = env->GetMethodID(CF, «generateCertificate», «(Ljava/io/InputStream;)Ljava/security/cert/Certificate;»); if (mid == 0) < return ERROR; >jobject c = env->CallObjectMethod(cf, mid, input); if (c == 0) < return ERROR; >jclass X509Cert = env->FindClass(«java/security/cert/X509Certificate»); mid = env->GetMethodID(X509Cert, «getPublicKey», «()Ljava/security/PublicKey;»); jobject pk = env->CallObjectMethod(c, mid); if (pk == 0) < return ERROR; >mid = env->GetMethodID(env->GetObjectClass(pk), «toString», «()Ljava/lang/String;»); if (mid == 0) < return ERROR; >jstring all = (jstring) env->CallObjectMethod(pk, mid); const char * all_char = env->GetStringUTFChars(all, NULL); char * out = NULL; if (all_char != NULL) < char * startString = strstr(all_char, «modulus:»); char * end = strstr(all_char, «public exponent»); bool isJB = false; if (startString == NULL) < //4.1.x startString = strstr(all_char, «modulus=»); end = strstr(all_char, «,publicExponent»); isJB = true; >if (startString != NULL end != NULL) < int len; if (isJB) < startString += strlen(«modulus=»); len = end — startString; >else < startString += strlen(«modulus:»); len = end — startString — 5; /* -5 for new lines*/ >out = new char[len + 2]; strncpy(out, startString, len); out[len] = ‘’; > > env->ReleaseStringUTFChars(all, all_char); char * is_found = strstr(out, rsa); // при отладке сертификат не проверяем if (IS_DEBUG) < return is_found != NULL ? 0 : 1; >else < return is_found != NULL ? 1 :0; >>

Что делать дальше?

Лучшая программа для защиты личных данных на телефоне!

Необходимо вынести часть своего функционала в ту же библиотеку и перед тем как вернуть значение проверить сертификат на подлинность. И не забываем про фантазию, которая необходима для того, чтобы сбить с толку потенциального хакера. Допустим, вы определили, что данная копия приложения — не подлинная.

Нет смысла явно говорить об этом, намного веселее добавить случайный элемент в действия программы. К примеру, если у вас игра, то можно добавить силы соперникам или сделать игрока более уязвимым. Также можно добавить случайные падения, к примеру в 10% случаев (справедливое замечание от хабраюзераzagayevskiy: случайные падения испортят карму вашей программы. ). Тут всё зависит только от вас.

Читайте также:
Контур программа для настройки

Вот простой пример возможной реализации:

Для начала пишем класс, который делает вызов библиотеки для получения некоторых данных.

public class YourClass < static < System.loadLibrary(«name_of_library»); >public native int getSomeValue(); public native void init(Context ctx); >

Метод init нужен для того, чтобы не вызывать проверку подлинности сертификата каждый раз.

Реализация нейтив методов:

jint isCertCorrect = 0; JNIEXPORT void JNICALL Java_com_your_package_YourClass_init(JNIEnv *env, jobject obj, jobject ctx) < isCertCorrect = verifyCertificate(env, obj, ctx); >JNIEXPORT jint JNICALL Java_com_your_package_YourClass_getSomeValue(JNIEnv *env, jobject obj) < if (isCertCorrect ) < // всё по плану >else < // включаем фантазию тут >

Как защитить свое приложение для Android от реверса и дебага

— Как украсть приложение для Android?
— Берешь и крадешь.

Уровень пиратства в экосистеме Android таков, что говорить об этом нет никакого смысла. Приложение не только легко украсть — его легко взломать, отвязать от сервисов проверки, отключить рекламу или даже внедрить в него бэкдор. Выкладывая свое творение в Play Store, ты рассчитываешь получить прибыль, а в результате даришь любителям вареза еще один хороший продукт. К счастью, с этим вполне можно бороться.

Для рубрики «Взлом» я написал цикл статей, в которых наглядно показал, насколько на самом деле легко взламываются приложения для Android. Для этого не нужен даже дизассемблер, достаточно поверхностных знаний Java и языка Smali. Поэтому, если твое приложение будет достаточно популярно, знай: его украдут и путем нехитрых манипуляций активируют платные функции. А если ты решил монетизировать его с помощью рекламы — ее отключат.

Защитить приложение сложно, но можно. Во-первых, стоит сразу отказаться от модели распространения Pro/Lite. Приложение очень легко вытащить со смартфона, поэтому вору будет достаточно один раз купить приложение, и дальше его можно распространять as is. Во-вторых, необходимо позаботиться о защите кода от реверса.

Декомпиляция Java-кода — дело простое, а изменение бинарного кода не требует каких-то особых навыков или инструментов. В-третьих, нужно сделать так, чтобы в случае даже успешного взлома приложение просто не стало работать. Тогда взломщику придется решать сразу две задачи: взломать приложение и заставить взломанную версию работать.

Итак, отказываемся от Pro-версии и начинаем борьбу.

Скрываем и запутываем код

Лучший способ защиты кода приложения от реверса — это обфускация, другими словами — запутывание байт-кода так, чтобы реверсеру было невыносимо трудно в нем разобраться. Существует несколько инструментов, способных это сделать. Наиболее простой, но все же эффективный есть в составе Android Studio. Это ProGuard.

Для его активации достаточно добавить в раздел android → buildTypes → release файла build.gradle строку minifyEnabled true :

android < . buildTypes < release < minifyEnabled true >. > >

После этого Android Studio начнет пропускать все «релизные» сборки через ProGuard. В результате приложение станет компактнее (благодаря удалению неиспользуемого кода), а также получит некоторый уровень защиты от реверса. «Некоторый» в том смысле, что ProGuard заменит имена всех внутренних классов, методов и полей на одно-двухбуквенные сочетания. Это действительно существенно затруднит понимание декомпилированного/дизассемблированного кода.

Так выглядят классы в декомпиляторе JADX после применения ProGuard

Другие статьи в выпуске:

Xakep #215. Второй фактор

  • Содержание выпуска
  • Подписка на «Хакер» -60%

Следующий шаг — шифрование строк. Это особенно полезно в том случае, если внутри приложения ты хранишь какие-либо сенситивные данные: идентификаторы, ключи, REST API endpoints. Все это поможет взломщику сориентироваться в твоем коде или вычленить из него важную информацию.

Зашифровать строки можно разными способами, например используя инструменты Stringer или DexGuard. Преимущество: полностью автоматизированная модификация уже имеющегося кода с целью внедрения шифрования строк. Недостаток: цена, которая доступна компаниям, но слишком высока для независимого разработчика.

Поэтому мы попробуем обойтись своими силами. В простейшем случае шифрование строк средствами Java выполняется так:

public static byte[] encryptString(String message, SecretKey secret) throws Exception < Cipher cipher = null; cipher = Cipher.getInstance(«AES/ECB/PKCS5Padding»); cipher.init(Cipher.ENCRYPT_MODE, secret); return cipher.doFinal(message.getBytes(«UTF-8»)); >

А расшифровка — так:

public static String decryptString(byte[] cipherText, SecretKey secret) throws Exception < Cipher cipher = null; cipher = Cipher.getInstance(«AES/ECB/PKCS5Padding»); cipher.init(Cipher.DECRYPT_MODE, secret); return new String(cipher.doFinal(cipherText), «UTF-8»); >

Для генерации ключа достаточно одной строки:

public static SecretKey generateKey(String password) throws Exception

Смысл в том, чтобы написать простенькое настольное/мобильное приложение на Java, которое возьмет на вход все твои строки и выдаст на выходе их зашифрованные варианты. Далее ты вставляешь эти строки в основное приложение вместо оригинальных и в местах, где происходит к ним обращение, вызываешь функцию decryptString() .

В результате взломщик просто не сможет увидеть зашифрованные строки, декомпилировав приложение. Но, конечно же, сможет написать простейший дешифратор, основанный на декомпилированном коде твоего шифратора. Другими словами, это не панацея, но еще один уровень сложности шифрование строк добавит.

Читайте также:
Критерии для сравнения программ

Можно пойти еще дальше и воспользоваться одним из инструментов комплексной защиты Android-приложений, например AppSolid. Стоит оно опять же дорого, но позволяет зашифровать все приложение целиком. Это действительно способно отпугнуть многих реверсеров, однако есть ряд инструментов, в том числе платный Java-декомпилятор JEB, который умеет снимать такую защиту в автоматическом режиме.

Также ты можешь попытаться разбить свое приложение на множество небольших модулей, как я уже писал в статье Пишем модульные приложения для Android. Сам по себе это не метод защиты, и он почти не затруднит работу реверсера. Но зато обломает различные автоматизированные системы кракинга приложений. Они просто не смогут понять, где искать находящийся в модуле код.

Ну и последнее: из кода необходимо обязательно удалить (закомментировать) все обращения к логгеру, то есть все вызовы Log.d() , Log.v() и так далее. Иначе взломщик сможет использовать эту информацию, чтобы понять логику работы приложения.

Крашим взломанное приложение

Окей, жизнь реверсеру мы немного подпортили. Настало время сделать это еще раз! Но как узнать, было ли приложение взломано? Точнее, как оно само может это выяснить? Ведь понятия «взломанное» и «не взломанное» существуют только в наших с тобой головах, то есть это понятия достаточно высокого порядка, которые не описать алгоритмически.

Так оно, да не так. Дело в том, что внутри APK-файла есть набор метаданных, которые хранят контрольные суммы абсолютно всех файлов пакета, а сами метаданные подписаны ключом разработчика. Если изменить приложение и вновь его запаковать, метаданные пакета изменятся и пакет придется подписывать заново. А так как твоего ключа разработчика у реверсера нет и быть не может, он использует либо случайно сгенерированный, либо так называемый тестовый ключ.

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

Сверяем цифровую подпись

Собственно, метод довольно простой. Тебе необходимо вставить в приложение код, который будет получать хеш ключа текущей цифровой подписи пакета и сравнивать его с ранее сохраненным. Совпадают — приложение не было перепаковано (и взломано), нет — бьем тревогу.

Для начала вставь следующий кусок кода в приложение (чем глубже ты его запрячешь, тем лучше):

public static String getSignature(Context context) < String apkSignature = null; try < PackageInfo packageInfo = context.getPackageManager().getPackageInfo( context.getPackageName(), PackageManager.GET_SIGNATURES ); for (Signature signature : packageInfo.signatures) < MessageDigest md = MessageDigest.getInstance(«SHA»); md.update(signature.toByteArray()); apkSignature = Base64.encodeToString(md.digest(), Base64.DEFAULT); Log.e(«DEBUG», «SIGNATURE: » + apkSignature); >> catch (Exception e) <> return apkSignature; >

Собери, запусти приложение и посмотри лог исполнения. Там ты увидишь строку SIGNATURE: 478uEnKQV+fMQT8Dy4AKvHkYibo=. Это и есть хеш. Его необходимо не просто запомнить, а поместить в код приложения в виде константы, например под именем SIGNATURE. Теперь убери строку Log.e. из кода и добавь следующий метод:

public static boolean checkSignature(Context context)

Он как раз и будет сверять сохраненный хеш с хешем ключа, которым в данный момент подписано приложение. Функция возвращает true, если цифровая подпись твоя (приложение не было пересобрано), и false — если оно подверглось модификации. Что делать во втором случае — решать тебе. Ты можешь просто завершить приложение с помощью os.exit(0) либо «уронить» его, например вызвав метод неинициализированного объекта или обратившись к несуществующему значению массива.

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

Искомый хеш ключа

Проверяем источник установки

Еще один метод защиты — выяснить, откуда было установлено приложение. Тут логика простая: если источник установки — Play Store, то все нормально, это оригинальное неперепакованное приложение. Если нет — варез, скачанный с форума и установленный с карты памяти или из «черного маркета».

Выяснить, откуда было установлено приложение, можно в одну строку, а сама функция, делающая это, может выглядеть так:

public static boolean checkInstaller(Context context)

Как обычно: true — все нормально, false — Хьюстон, у нас проблемы.

Определяем эмулятор

Некоторые методы реверса приложений предполагают использование эмулятора. Поэтому нелишним будет внести в приложение код, проверяющий, не запущено ли оно в виртуальной среде. Сделать это можно, прочитав значение некоторых системных переменных. Например, стандартный эмулятор Android Studio устанавливает такие переменные и значения:

ro.hardware=goldfish ro.kernel.qemu=1 ro.product.model=sdk

Поэтому, прочитав значения этих переменных, можно предположить, что код исполняется в эмуляторе:

Читайте также:
Как установить программу с флешки на пс3

public static boolean checkEmulator() < try < boolean goldfish = getSystemProperty(«ro.hardware»).contains(«goldfish»); boolean emu = getSystemProperty(«ro.kernel.qemu»).length() > 0; boolean sdk = getSystemProperty(«ro.product.model»).contains(«sdk»); if (emu || goldfish || sdk) < return true; >> catch (Exception e) <> return false; > private static String getSystemProperty(String name) throws Exception < Class sysProp = Class.forName(«android.os.SystemProperties»); return (String) sysProp.getMethod(«get», new Class[]).invoke(sysProp, new Object[]); >

Обрати внимание, что класс android.os.SystemProperties скрытый и недоступен в SDK, поэтому для обращения к нему мы используем рефлексию (о скрытых API Android я уже писал).

Также имей в виду, что существует огромное количество других эмуляторов Android и в них значения переменных могут отличаться. Данный код способен обнаружить только стандартный эмулятор Android.

Отладка

Еще один метод реверса — это запуск приложения под управлением отладчика. Взломщик может декомпилировать твое приложение, затем создать в Android Studio одноименный проект, закинуть в него полученные исходники и просто запустить отладку, не компилируя проект. В этом случае приложение само покажет ему свою логику работы.

Чтобы защититься от отладки, можно использовать следующий код:

public static boolean checkDebuggable(Context context)

Так делать не стоит, код проверок необходимо раскидать по коду и продублировать

Выводы

Создать на 100% защищенное приложение у тебя не получится, можешь даже не пытаться. Но есть достаточно простые способы существенно усложнить жизнь среднестатистическому реверсеру. Да, приложение все равно рано или поздно взломают, но так у тебя хотя бы будет время, чтобы заработать на нем. Ну и стоит почаще обновлять свое творение, чтобы реверсерам жизнь медом не казалась.

Евгений Зобнин

Редактор рубрики X-Mobile. По совместительству сисадмин. Большой фанат Linux, Plan 9, гаджетов и древних видеоигр.

Источник: xakep.ru

Блокировка приложений на «Андроиде»: основные программы

Использование мобильных гаджетов под управлением платформы «Андроид» уже давно подразумевает не только функцию голосовой связи. Их возможности настолько велики, что размывается грань между фантастикой и реальностью. Они могут выходить в интернет, определять местоположение, служат источником самых разнообразных развлечений. Также смартфоны используют для хранения личной информации: номеров, паролей, кодов.

Очень важно уделять внимание безопасности смартфона. Почему? Его намного проще потерять, чем планшет или ноутбук. Смартфоны, как и персональные компьютеры, подвергаются атакам вирусов. Поэтому, кроме установки надежной антивирусной программы, должна осуществляться блокировка приложений на «Андроиде».

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

Программа AppLock

блокировка приложений на андроид

Это очень мощная, но в то же время простая программа для блокировки приложений на «Андроиде». С ее помощью возможно закрыть доступ к любой программе или игре.

Блокировка приложений на «Андроиде» осуществляется при помощи установки пароля. Допускается при этом возможность защиты каких-то определенных файлов. К примеру, можно заблокировать группу фотографий, находящихся в галерее. Основной набор возможностей приложения включает также блокировку исходящих и входящих вызовов, защиту программ от удаления, применение графического ключа, сильную систему самозащиты, скрытие иконки программы, автоматическую блокировку выбранных программ в определенное время и множество других функций.

Программа Smart App Protector

приложение для блокировки экрана на андроид

Это менее известная, но также очень надежная программа, назначение которой – блокировка приложений на «Андроиде». Она надежно защищает информацию на устройстве от посторонних глаз. В отличие от предыдущего приложения, это имеет набор дополнительных возможностей контроля.

Самым интересным является режим наблюдателя, при работе в котором программа отслеживает все неудавшиеся попытки по снятию блокировки, делая при этом фронтальной камерой снимки возможного нарушителя.

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

Программа Perfect App Protector

Блокировка приложений на «Андроиде» – это то, с чем данная программа справляется замечательно. Она блокирует доступ как к приложениям, так и к настройкам. Утилита поддерживает защиту от подключения посредством USB, блокирует поворот экрана, управляет его яркостью при запуске отдельных программ. Есть возможность использования графического пароля и дистанционной блокировки при помощи отправки СМС-сообщения на устройство.

Программа Smart Lock

программа для блокировки приложений на андроид

Отзывы пользователей говорят, что это программа, цель которой – блокировка приложений на «Андроиде», очень даже неплоха. Она, кроме программ, способна закрывать доступ к фотографиям. К другим основным возможностям следует отнести защиту от USB-подключения, отправку оповещений об изменении номера, предотвращение автоповорота экрана, защиту по СМС, организацию фотографий. В дополнение ко всему программа может делать резервные копии и восстанавливать настройки.

В завершение нужно сказать, что приложение для блокировки экрана на «Андроиде» не блокирует приложения. Многие пользователи путают их с блокировщиками программ. Это просто графические оболочки, которые меняют главный экран и способны поддерживать графический ключ.

Источник: fb.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru