Root Detection — مکانیزم محافظت از برنامههای Android در برابر اجرا روی دستگاههایی با امتیازات superuser. برنامههای بانکی، پرداخت و شرکتی عملکرد را روی دستگاههای روت شده مسدود یا محدود میکنند، زیرا دسترسی root محدودیتهای sandbox Android را برمیدارد و امکان رهگیری ترافیک، خواندن حافظه فرآیندها و جعل دادهها را فراهم میکند. بر اساس OWASP Mobile Top 10 (2024)، نبود Root Detection متعلق به دسته M8 (Security Decisions via Untrusted Inputs) است. Root Detection بر ترکیبی از بررسیهای ایستای فایلسیستم و تحلیل پویای رفتار runtime ساخته شده است.
مهمترین نکات
Root Detection — مکانیزم نرمافزاری که وجود دسترسی root را در دستگاه Android تعیین میکند. دسترسی root کنترل کامل بر سیستم عامل را فراهم میکند و به برنامهها و اسکریپتها اجازه میدهد دستورات را با UID 0 اجرا کنند. در دستگاه روت شده، ایزولاسیون برنامهها (Android Sandbox) از بین میرود که رهگیری ورودی صفحه کلید، خواندن پایگاههای داده SQLite سایر برنامهها، تزریق کد به فرآیندها و جعل گواهیهای SSL در فروشگاه معتمد را ممکن میسازد.
برای برنامههای مالی و شرکتی، کار روی دستگاه روت شده یک ریسک غیرقابل قبول است: مهاجم به توکنها، کلیدهای جلسه و دادههای شخصی دسترسی پیدا میکند. نهادهای نظارتی، از جمله PCI Security Standards Council، از برنامههای پرداخت میخواهند دسترسی root را شناسایی و به آن واکنش نشان دهند. در پاسخ به این، توسعهدهندگان Android Root Detection را به عنوان بخشی از استراتژی حفاظت proactive پیادهسازی میکنند.
دو رویکرد برای تشخیص وجود دارد: ایستا، که فایلسیستم و بستههای نصب شده را تحلیل میکند، و پویا، که بررسیها را در runtime انجام میدهد. رویکرد ترکیبی قابل اعتمادترین محسوب میشود، زیرا بردارهای مختلف دور زدن را پوشش میدهد. بر اساس تحقیق NowSecure (2025)، 76٪ از برنامههای بانکی در 100 برنامه برتر Google Play حاوی نوعی Root Detection هستند.
روشهای ایستا هنگام راهاندازی برنامه اجرا میشوند و نشانههای دسترسی root را که ابزارهای روت در فایلسیستم بر جای میگذارند، بررسی میکنند. این روشها نیازی به اجرای دستورات ممتاز ندارند و در بافت یک برنامه معمولی کار میکنند.
نشانه اصلی دسترسی root — وجود فایل اجرایی su در مسیرهای استاندارد: /system/bin/su، /system/xbin/su، /sbin/su، /su/bin/su. برنامه وجود فایل را از طریق File.exists() یا پیادهسازی بومی access() از libc بررسی میکند. علاوه بر این، میتوان su --version یا su -c id را اجرا کرده و کد خروج را بررسی کرد.
برنامههای معمول برای مدیریت دسترسی root: 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 — این نشاندهنده سیستمعامل سفارشی است که اغلب با دسترسی root همراه است. علاوه بر این، ro.build.tags، ro.debuggable و ro.secure از طریق خواندن /system/build.prop بررسی میشوند.
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) {
// پکیج پیدا نشد
}
}
return false;
}
}
روشهای پویا در طول اجرای برنامه انجام میشوند و محیط اجرا را تحلیل میکنند. برخلاف روشهای ایستا، میتوانند روت مخفی شده از طریق Magisk Hide یا Zygisk را تشخیص دهند، زیرا رفتار سیستم را بررسی میکنند، نه فقط ساختار فایل را.
هنگام دسترسی root، برخی پارتیشنهای سیستم با پرچم rw (read-write) به جای ro (read-only) mount میشوند. برنامه /proc/mounts را میخواند و بررسی میکند که /system به صورت ro mount شده است. اگر /system به صورت rw mount شده باشد — این نشانه یک سیستم تغییر یافته است. علاوه بر این، وجود mount /su از طریق Magisk بررسی میشود.
Android Safe Mode برنامههای شخص ثالث، از جمله مدیرهای root را غیرفعال میکند. پیادهسازی صحیح Root Detection میتواند بررسی کند که آیا دستگاه در حالت امن کار میکند. اگر برنامه تشخیص دهد که مدیرهای root قابل مشاهده نیستند، اما باینری su وجود دارد — این نشانه Magisk Hide است.
تلاش برای اجرای su -c id از طریق ProcessBuilder یا Runtime.exec — یک تست مستقیم دسترسی root است. با این حال، Magisk میتواند این فراخوانی را رهگیری کند. گزینه قابل اعتمادتر — بررسی از طریق کد بومی: باز کردن /proc/1/limits یا /proc/self/maps و تحلیل UID فرآیندهای در حال اجرا. اگر برنامه بتواند UID 0 را به دست آورد یا فایلهای قابل دسترسی فقط برای root را بخواند — دستگاه به خطر افتاده است.
public boolean checkRootDynamically() {
// بررسی فلاگهای ساخت
String buildTags = Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys")) {
return true;
}
// بررسی مونت /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) {
// خطا در خواندن مونت
}
return false;
}
Root Detection پیادهسازی شده در Java به راحتی از طریق ماژولهای Xposed یا Frida که متدهای Java را رهگیری کرده و مقادیر بازگشتی را جعل میکنند، دور زده میشود. پیادهسازی بومی در C++ از طریق JNI به طور قابل توجهی مقاومتر است: ابزارهای تحلیل پویا که در سطح Java کار میکنند، فراخوانیهای بومی libc مانند stat، access، popen و dlopen را نمیبینند.
#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 مراجعه میکند و wrapperهای Java را دور میزند و نمیتوان آن را از طریق Xposed رهگیری کرد.
توسعهدهندگان حفاظت باید روشهای موجود دور زدن را درک کنند تا یک سیستم تشخیص مقاوم بسازند. هر روش دور زدن نیاز به اقدام متقابل در سطح مربوطه دارد.
Magisk — محبوبترین ابزار روت در Android 9–14. Magisk Hide وجود su را از /proc پنهان میکند و نتایج بررسی مسیرها را جعل میکند. Magisk در سطح هسته کار میکند و stat() و access() را قبل از دیده شدن توسط برنامه رهگیری میکند. اقدام متقابل: بررسی وجود خود Magisk از طریق وجود /sbin/.magisk یا بررسی از طریق خواندن maps خود برنامه — Magisk کتابخانه خود را در هر فرآیند جاسازی میکند.
Frida — ابزار instrumentation پویا که میتواند توابع بومی را از طریق Ptrace یا Dobby رهگیری کند. Frida مقدار بازگشتی هر بررسی را جایگزین کرده و نتیجه stat را با ENOENT جعل میکند. اقدام متقابل: بررسی یکپارچگی توابع بومی از طریق محاسبه checksum دستورالعملها در حافظه و تشخیص Frida از طریق تحلیل /proc/self/maps برای وجود frida-agent.so یا frida-helper.
Root Detection پیادهسازی شده در Java در 2–3 دقیقه حذف میشود: APK با apktool باز میشود، در کد smali مقدار بازگشتی متد به false تغییر مییابد، APK دوباره ساخته و امضا میشود. اقدام متقابل: انتقال منطق بحرانی به کد بومی و بررسی امضای دیجیتال برنامه در runtime از طریق Signature API یا مقایسه hash APK با الگو روی سرور.
Root Detection مؤثر بر معماری چندلایه ساخته شده است. هیچ روشی به تنهایی سطح حفاظت کافی را فراهم نمیکند. ترکیب بررسیهای ایستا و پویا، کد بومی و تأیید سمت سرور حداکثر مقاومت را میدهد.
فقط به بررسی سمت کلient اعتماد نکنید. نتایج Root Detection را همراه با یک token یکبار مصرف جلسه به سرور ارسال کنید. سرور درباره مسدودسازی یا محدود کردن عملکرد تصمیم میگیرد. این کار از حملات در سطح API جلوگیری میکند، جایی که برنامه کلient ممکن است تغییر یافته باشد، اما سرور طرف معتمد باقی میماند.
کد Root Detection باید obfuscated شود. اگر مهاجم در jadx توالی واضحی از بررسی مسیرهای su ببیند — دور زدن دقیقهها طول میکشد. از ProGuard یا DexGuard برای پیچیده کردن جریان کنترل و رمزگذاری رشتهها استفاده کنید. Obfuscation زمان تحلیل کد حفاظت را از چند دقیقه به چند ساعت افزایش میدهد.
لیست مسیرها، بستهها و شاخصهای قابل بررسی باید با هر نسخه از برنامه بهروز شود. ابزارهای جدید روت و دور زدن ماهانه ظاهر میشوند. یک لیست ایستا که یک سال تغییر نکرده است، روشهای مدرن را تشخیص نمیدهد. توصیه میشود امضاهای بهروز را از سرور هنگام راهاندازی برنامه قبل از انجام بررسیها بارگیری کنید.
سوالات متداول
Root Detection از اجرای برنامه روی دستگاهی که sandbox Android در آن غیرفعال است محافظت میکند. در دستگاه روت شده، هر برنامهای میتواند دادههای سایر برنامهها را بخواند. برنامههای بانکی و پرداخت موظفند کار روی دستگاههای روت شده را طبق الزامات PCI DSS و توصیههای OWASP Mobile Security مسدود کنند.
Magisk Hide از مکانیزم mount namespace استفاده میکند. برای هر فرآیند مشخص شده در لیست استثناها، Magisk یک namespace ایزوله ایجاد میکند که در آن باینری su نامرئی است. فراخوانیهای سیستمی stat، access و open در این namespace فایلهای Magisk را نمیبینند. Magisk را میتوان از طریق بررسی وجود /proc/self/maps و جستجوی dump magisk تشخیص داد.
بله، اگر برنامه یکپارچگی کد خود را بررسی نکند. از طریق Frida میتوان متد Java بررسی را رهگیری کرده و به اجبار false返回 کرد. اقدام متقابل — پیادهسازی بومی منطق بحرانی در C++ و بررسی یکپارچگی از طریق hash فایل DEX. بدون obfuscation هر Root Detection در Java در 5–10 دقیقه دور زده میشود.
SafetyNet (منسوخ) و Play Integrity API — بررسیهای سمت سرور Google هستند که یکپارچگی دستگاه را تأیید میکنند. آنها شامل بررسی bootloader، امضای سیستم و وضعیت root هستند. Play Integrity API — جایگزین توصیه شده SafetyNet که سه سطح ارائه میدهد: BASIC، DEVICE و STRONG. Root Detection سمت کلient، attestation سرور را تکمیل میکند.
برنامه را روی یک دستگاه واقعی روت شده (مثلاً Pixel با Magisk) نصب کنید. بررسی کنید که آیا مسدودسازی فعال میشود. سپس سعی کنید root را از طریق Magisk Hide برای برنامه خود پنهان کرده و تست را تکرار کنید. برای بررسی عمیق از Frida برای رهگیری متدهای هدف استفاده کنید و مطمئن شوید که حفاظت بومی قابل دور زدن نیست.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید