Когда задумываешься о защите приложения от реверса, в первую очередь на ум приходят такие слова, как обфускация и шифрование. Но это только часть решения проблемы. Вторая половина — это детект и защита от самих инструментов реверса: отладчиков, эмуляторов, Frida и так далее. В этой статье мы рассмотрим техники, которые мобильный софт и зловреды используют, чтобы спрятаться от этих инструментов.
Не стоит воспринимать приведенную в статье информацию как рецепт абсолютной защиты. Такого рецепта нет. Мы всего лишь даем себе отсрочку, затормаживаем исследование, но не делаем его невозможным. Все это — бесконечная игра в кошки‑мышки, когда исследователь взламывает очередную защиту, а разработчик придумывает ей более изощренную замену.
Важный момент: я приведу множество разных техник защиты, и у тебя может возникнуть соблазн запихнуть их все в один класс (или нативную библиотеку) и с удобством для себя запускать один раз при старте приложения. Так делать не стоит, механизмы защиты должны быть разбросаны по приложению и стартовать в разное время. Так ты существенно усложнишь жизнь взломщику, который в противном случае мог бы определить назначение класса/библиотеки и целиком заменить его на одну большую заглушку.
Права root — один из главных инструментов реверсера. Root позволяет запускать Frida без патчинга приложений, использовать модули Xposed для изменения поведения приложения и трейсинга приложений, менять низкоуровневые параметры системы. В целом наличие root четко говорит о том, что окружению исполнения доверять нельзя. Но как его обнаружить?
Самый простой вариант — поискать исполняемый файл su в одном из системных каталогов:
Бинарник su всегда присутствует на рутованном устройстве, ведь именно с его помощью приложения получают права root. Найти его можно с помощью примитивного кода на Java:
private static boolean findSu() { String[] paths = { "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su", "/data/local/su" }; for (String path : paths) { if (new File(path).exists()) return true; } return false;}
Либо использовать такую функцию, позаимствованную из приложения rootinspector:
jboolean Java_com_example_statfile(JNIEnv * env, jobject this, jstring filepath) { jboolean fileExists = 0; jboolean isCopy; const char * path = (*env)->GetStringUTFChars(env, filepath, &isCopy); struct stat fileattrib; if (stat(path, &fileattrib) < 0) { __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NATIVE: stat error: [%s]", strerror(errno)); } else { __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NATIVE: stat success, access perms: [%d]", fileattrib.st_mode); return 1; } return 0;}
Еще один вариант — попробовать не просто найти, а запустить бинарник su:
try { Runtime.getRuntime().exec("su");} catch (IOException e) { // Телефон не рутован}
Если его нет, система выдаст IOException. Но здесь нужно быть осторожным: если устройство все‑таки имеет права root, пользователь увидит на экране запрос этих самых прав.
Еще один вариант — найти среди установленных на устройство приложений менеджер прав root. Он как раз и отвечает за диалог предоставления прав:
Для поиска можно использовать такой метод:
private static boolean isPackageInstalled(String packagename, Context context) { PackageManager pm = context.getPackageManager(); try { pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES); return true; } catch (NameNotFoundException e) { return false; }}
Искать можно и по косвенным признакам. Например, SuperSU, некогда популярное решение для получения прав root, имеет несколько файлов в файловой системе:
Еще один косвенный признак — прошивка, подписанная тестовыми ключами. Это не всегда подтверждает наличие root, но точно говорит о том, что на устройстве установлен кастом:
private boolean isTestKeyBuild() { String buildTags = android.os.Build.TAGS; return buildTags != null && buildTags.contains("test-keys");}
Все эти методы детекта root отлично работают до тех пор, пока ты не столкнешься с устройством, рутованным с помощью Magisk. Это так называемый systemless-метод рутинга, когда вместо размещения компонентов для root-доступа в файловой системе поверх нее подключают другую файловую систему (оверлей), содержащую эти компоненты.
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
1 год7690 р. |
1 месяц720 р. |
Я уже участник «Xakep.ru»
Читайте также
Последние новости