Root Detection у мобилним апликацијама — суштина, методе откривања и принцип рада

Аутор: IT Sectr Објављено: 2026-04-03 Време читања: 9 мин

Root Detection — механизам заштите Android апликација од покретања на уређајима са привилегијама суперкорисника. Банкарске, платне и корпоративне апликације блокирају или ograničavaju функционалност на рутованим уређајима, јер роот приступ уклања ограничења Android пешчаника и отвара могућност пресретања саобраћаја, читања меморије процеса и замене података. Према OWASP Mobile Top 10 (2024), недостатак Root Detection спада у категорију M8 (Security Decisions via Untrusted Inputs). Root Detection се заснива на комбинацији статичких провера фајл система и динамичке анализе понашања у runtime-у.

Главно

  • Root Detection — провера Android уређаја на присуство роот приступа ради заштите апликације од покретања у компромитованом окружењу
  • Статичке методе проверавају фајл систем на присуство su бинарних фајлова, Superuser апликација и промена системских партиција
  • Динамичке методе анализирају runtime: провера Build.TAGS, покушај отварања /proc/self/maps са привилегованим процесима
  • Нативна имплементација у C/C++ преко JNI обезбеђује отпорност на заобилажење кроз Xposed и Frida на Java нивоу
  • Безбедност Root Detection захтева континуирану обфускацију и серверску верификацију ради спречавања замене резултата провере

Шта је Root Detection?

Root Detection — програмски механизам који утврђује присуство роот приступа на Android уређају. Роот приступ пружа потпуну контролу над оперативним системом, омогућавајући апликацијама и скриптама да извршавају команде са UID 0. На рутованом уређају губи се изолација апликација (Android Sandbox), што омогућава пресретање уноса са тастатуре, читање SQLite база података других апликација, убризгавање кода у процесе и замену SSL сертификата у поверљивом складишту.

За финансијске и корпоративне апликације рад на рутованом уређају представља неприхватљив ризик: нападач добија приступ токенима, сесијским кључевима и личним подацима. Регулатори, укључујући PCI Security Standards Council, захтевају од платних апликација откривање и реакцију на роот приступ. Као одговор на то, Android програмери уграђују Root Detection као део стратегије проактивне заштите.

Постоје два приступа откривању: статички, који анализира фајл систем и инсталиране пакете, и динамички, који врши провере у runtime-у. Комбиновани приступ се сматра најпоузданијим, јер покрива различите векторе заобилажења. Према истраживању NowSecure (2025), 76% банкарских апликација у топ 100 Google Play садржи неки облик Root Detection-а.

Статичке методе откривања роот-а

Статичке методе се извршавају при покретању апликације и проверавају знаке роот приступа које алати за рутовање остављају у фајл систему. Ове методе не захтевају извршавање привилегованих команди и раде у контексту обичне апликације.

Провера постојања su бинарног фајла

Главни знак роот приступа — присуство извршног фајла su у стандардним путањама: /system/bin/su, /system/xbin/su, /sbin/su, /su/bin/su. Апликација проверава постојање фајла кроз File.exists() или нативну имплементацију access() из libc-а. Додатно се може покушати извршавање su --version или su -c id и проверити излазни код.

Претрага роот менаџера

Типичне апликације за управљање роот приступом: Superuser, SuperSU, Magisk Manager, KingRoot. Њихово присуство се проверава кроз PackageManager.getPackageInfo() или читање /data/app/ директоријума. Пакети за проверу: com.topjohnwu.magisk, eu.chainfire.supersu, com.noshufou.android.su, com.thirdparty.superuser, com.koushikdutta.superuser, com.zacharee1.systemuituner.

Провера системских својстава

Android чува информације о стању система у системским својствима доступним кроз System.getProperty и Build.TAGS. Ако вредност Build.TAGS садржи test-keys уместо release-keys — то указује на прилагођени фирмвер, често са роот приступом. Додатно се проверавају ro.build.tags, ro.debuggable и ro.secure кроз читање /system/build.prop.

java
public class RootDetectionChecker {
    private static final String[] SU_PATHS = {
        "/system/bin/su",
        "/system/xbin/su",
        "/sbin/su",
        "/su/bin/su",
        "/system/sd/xbin/su"
    };

    public boolean checkRootByFiles() {
        for (String path : SU_PATHS) {
            if (new File(path).exists()) {
                return true;
            }
        }
        return false;
    }

    public boolean checkRootByPackages(Context ctx) {
        String[] packages = {
            "com.topjohnwu.magisk",
            "eu.chainfire.supersu",
            "com.noshufou.android.su",
            "com.koushikdutta.superuser"
        };
        for (String pkg : packages) {
            try {
                ctx.getPackageManager().getPackageInfo(pkg, 0);
                return true;
            } catch (PackageManager.NameNotFoundException e) {
                // paket nije pronađen
            }
        }
        return false;
    }
}

Динамичке методе провере

Динамичке методе се извршавају током рада апликације и анализирају окружење извршавања. За разлику од статичких, могу открити рутовање сакривено кроз Magisk Hide или Zygisk, јер проверавају понашање система, а не само структуру фајлова.

Провера mount тачака

При роот приступу, неке системске партиције се монтирају са rw (read-write) заставицом уместо ro (read-only). Апликација чита /proc/mounts и проверава да ли је /system монтиран као ro. Ако је /system монтиран као rw — то је знак модификованог система. Додатно се проверава присуство монтирања /su кроз Magisk.

Тест безбедног режима

Android Safe Mode искључује апликације трећих страна, укључујући роот менаџере. Исправна имплементација Root Detection-а може проверити да ли уређај ради у безбедном режиму. Ако апликација открије да роот менаџери нису видљиви, али su бинарни фајл постоји — то је знак Magisk Hide-а.

Провера извршавања команди

Покушај извршавања su -c id кроз ProcessBuilder или Runtime.exec — директан тест роот приступа. Међутим, Magisk може пресрести овај позив. Поузданија опција — провера кроз нативни код: отварање /proc/1/limits или /proc/self/maps и анализа UID-а покренутих процеса. Ако апликација може добити UID 0 или читати фајлове доступне само роот-у — уређај је компромитован.

java
public boolean checkRootDynamically() {
    // Provera flagova kompilacije
    String buildTags = Build.TAGS;
    if (buildTags != null && buildTags.contains("test-keys")) {
        return true;
    }

    // Provera montiranja /system
    try {
        BufferedReader reader = new BufferedReader(
            new InputStreamReader(new FileInputStream("/proc/mounts"))
        );
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.contains("/system")
                && line.contains("rw")) {
                reader.close();
                return true;
            }
        }
        reader.close();
    } catch (IOException e) {
        // greška pri čitanju mount-a
    }

    return false;
}

Нативна имплементација Root Detection у C++

Root Detection имплементиран у Java-и се лако заобилази кроз Xposed модуле или Frida, који пресрећу Java методе и замењују повратне вредности. Нативна имплементација у C++ кроз JNI је знатно отпорнија: алати за динамичку анализу који раде на Java нивоу не виде нативне позиве libc-а, попут stat, access, popen и dlopen.

cpp
#include <unistd.h>
#include <sys/stat.h>
#include <cstring>
#include <vector>

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_example_checker_RootCheck_nativeCheck(
    JNIEnv* env, jobject instance) {

    std::vector<const char*> paths = {
        "/system/bin/su",
        "/system/xbin/su",
        "/sbin/su",
        "/data/local/su"
    };

    struct stat st;
    for (const char* path : paths) {
        if (stat(path, &st) == 0) {
            return JNI_TRUE;
        }
    }
    return JNI_FALSE;
}

Нативна провера не користи Java API, што је чини невидљивом за алате за заобилажење који раде на Dalvik/ART нивоу. За додатну заштиту препоручује се чување константи (листа путања) не у read-only секцији, већ њихово израчунавање кроз једноставне реверзибилне функције. Stat позив из libc-а директно се обраћа језгру Linux-а, заобилазећи Java омоте, и не може се пресрести кроз Xposed.

Методе заобилажења Root Detection

Програмерима заштите је неопходно да разумеју постојеће методе заобилажења како би изградили отпоран систем откривања. Свака метода заобилажења захтева противмеру на одговарајућем нивоу.

Заобилажење кроз Magisk Hide и Zygisk

Magisk — најпопуларнији алат за рутовање на Android 9–14. Magisk Hide скрива присуство su-а из /proc-а и замењује резултате провере путања. Magisk ради на нивоу језгра и пресреће stat() и access() пре него што их апликација види. Противмера: провера присуства самог Magisk-а кроз постојање /sbin/.magisk или провера кроз читање сопствених maps — Magisk уграђује своју библиотеку у сваки процес.

Заобилажење кроз Frida

Frida — алат за динамичку инструментацију који може пресретати нативне функције кроз Ptrace или Dobby. Frida замењује повратну вредност сваке провере, замењујући резултат stat-а са ENOENT. Противмера: провера интегритета нативних функција кроз израчунавање checksum-а инструкција у меморији и откривање Frida-е кроз анализу /proc/self/maps на присуство frida-agent.so или frida-helper.

Заобилажење кроз патч APK-а

Root Detection имплементиран у Java-и се уклања за 2–3 минута: APK се распакује кроз apktool, у smali коду се мења повратна вредност метода на false, APK се поново саставља и потписује. Противмера: премештање критичне логике у нативни код и провера дигиталног потписа апликације у runtime-у кроз Signature API или поређење хеша APK-а са еталоном на серверу.

Препоруке за поуздану заштиту

Ефикасан Root Detection се заснива на вишеслојној архитектури. Ниједна метода појединачно не обезбеђује довољан ниво заштите. Комбинација статичких и динамичких провера, нативног кода и серверске верификације даје максималну отпорност.

Серверска верификација

Не ослањајте се само на client-side проверу. Шаљите на сервер резултате Root Detection-а заједно са једнократним токеном сесије. Сервер доноси одлуку о блокирању или ограничавању функционалности. Ово спречава нападе на API нивоу, где клијентска апликација може бити модификована, а сервер остаје поверљива страна.

Обфускација кода провере

Код Root Detection-а мора бити обфускован. Ако нападач види у jadx-у јасну секвенцу провера su путања — заобилажење ће трајати минуте. Користите ProGuard или DexGuard за замршавање тока контроле и шифровање стрингова. Обфускација повећава време анализе кода заштите са неколико минута на неколико сати.

Редовно ажурирање сигнатура

Листа проверених путања, пакета и индикатора мора се ажурирати са сваким издањем апликације. Нови алати за рутовање и заобилажење појављују се месечно. Статичка листа која се није мењала годину дана не открива модерне методе. Препоручује се учитавање актуелних сигнатура са сервера при покретању апликације пре извршавања провера.

Често постављана питања

Зашто апликацијама треба Root Detection?

Root Detection штити од покретања апликације на уређају где је Android пешчаник искључен. На рутованом уређају, свака апликација може читати податке других апликација. Банкарске и платне апликације су обавезне да блокирају рад на рутованим уређајима према захтевима PCI DSS и препорукама OWASP Mobile Security.

Како ради Magisk Hide?

Magisk Hide користи механизам монтирања именских простора (mount namespace). За сваки процес наведен у листи изузетака, Magisk креира изоловани именски простор где је su бинарни фајл невидљив. Системски позиви stat, access и open у овом именском простору не виде Magisk фајлове. Magisk се може открити кроз проверу присуства /proc/self/maps и претрагу magisk дампа.

Може ли се Root Detection заобићи без роот-а?

Да, ако апликација не проверава интегритет свог кода. Кроз Frida се може пресрести Java метод провере и принудно вратити false. Противмера — нативна имплементација критичне логике у C++ и провера интегритета кроз хеш DEX фајла. Без обфускације, било који Root Detection у Java-и се заобилази за 5–10 минута.

Шта су safety net и attestation?

SafetyNet (застарео) и Play Integrity API — то су серверске провере од Google-а које потврђују интегритет уређаја. Оне укључују проверу bootloader-а, системског потписа и роот статуса. Play Integrity API — препоручена замена за SafetyNet, која даје три нивоа: BASIC, DEVICE и STRONG. Root Detection на клијенту допуњује серверску атестацију.

Како проверити Root Detection у својој апликацији?

Инсталирајте апликацију на стварни рутовани уређај (нпр. Pixel са Magisk-ом). Проверите да ли се блокирање активира. Затим покушајте сакрити роот кроз Magisk Hide за вашу апликацију и поновите тест. За детаљну проверу користите Frida за пресретање циљних метода и уверите се да нативна заштита не подлеже заобилажењу.

Закључци

  • Root Detection — обавезна безбедносна компонента за банкарске, платне и корпоративне Android апликације, која ради на комбинацији статичких и динамичких провера
  • Статичке методе укључују претрагу su бинарног фајла у стандардним путањама, проверу инсталираних роот менаџера и анализу системских својстава Build.TAGS
  • Динамичке методе анализирају монтирање /system у rw режиму, проверавају интегритет /proc/mounts и врше тестове извршавања привилегованих команди
  • Нативна имплементација у C++ кроз JNI чини провере невидљивим за Xposed и Frida који раде на Java нивоу и захтева заобилажење кроз Dobby или Ptrace
  • Magisk Hide — главни алат за заобилажење Root Detection-а кроз mount namespaces, открива се кроз анализу /proc/self/maps на присуство magisk библиотека
  • Препоручена архитектура: нативне провере + обфускација кода + серверска верификација резултата + редовно ажурирање сигнатура
  • Play Integrity API од Google-а допуњује Root Detection на клијенту серверском атестацијом уређаја, обезбеђујући комплексну заштиту

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође