Kod obfuskasiyası (Code Obfuscation) — icra olunan kodu analiz və reverse engineering üçün çətin formaya çevirmə prosesidir, tətbiqin tam funksionallığı saxlanılmaqla. Obfuskasiya metodlarına sinif və metodların adlarının mənasız identifikatorlarla dəyişdirilməsi, idarəetmə axınının qarışdırılması və sətir sabitlərinin şifrələnməsi daxildir. Android Developers (2025) məlumatına görə, obfuskasiya istehsal versiyalarının qurulmasının standart mərhələsidir. Code Obfuscation əqli mülkiyyətin oğurlanmasını və tətbiqdə zəifliklərin aşkarlanmasını çətinləşdirir.
Əsas məqamlar
Kod obfuskasiyası (lat. obfuscare — qaraltmaq, qarışdırmaq) — mənbə və ya aralıq tətbiq kodunun insan və ya avtomatik dekompilasiya alətləri tərəfindən analizini maksimum dərəcədə çətinləşdirən formaya məqsədyönlü çevrilməsidir. Obfuskasiyaya əsas tələb: çevrilmədən sonra proqram orijinal versiya ilə tam funksional ekvivalentliyi saxlamalıdır.
Obfuskasiyaya ehtiyac aralıq təmsil dillərinin (JVM bayt kodu, .NET IL, JavaScript) populyarlaşması ilə yarandı. Bu dillər maşın koduna deyil, aralıq bayt koduna kompilə olunur ki, bu da asanlıqla geri oxuna bilən mənbə koduna dekompilə olunur. Məsələn, Java bayt kodu JD-GUI və ya CFR alətləri ilə praktiki olaraq məlumat itkisi olmadan dekompilə olunur ki, bu da əqli mülkiyyəti həssas edir.
Mobil inkişafda obfuskasiya istehsal versiyalarının qurulmasının məcburi mərhələsinə çevrilib. Android Java/Kotlin kodu üçün ProGuard və R8, iOS — optimallaşdırmalarla LLVM kompilatoru və SwiftShield kimi əlavə alətlərdən istifadə edir. Hətta Flutter tətbiqləri qurma zamanı --obfuscate bayrağı vasitəsilə obfuska edilə bilər ki, bu da Dart identifikatorlarını təsadüfi simvollara dəyişir.
Bir neçə kateqoriyaya bölünən çoxsaylı obfuskasiya metodları mövcuddur. Leksik obfuskasiya — sinif, metod və sahə adlarının qısa mənasız adlarla dəyişdirilməsi (a, b, c). Struktur obfuskasiya — idarəetmə axınının dəyişdirilməsi, ölü kodun əlavə edilməsi, miras iyerarxiyasının şişirdilməsi. Məlumatların qorunması — sətir sabitlərinin şifrələnməsi, ədədi literalların obfuskasiyası, massivlərin bölünməsi.
Ən geniş yayılmış obfuskasiya metodu — sinif, metod və sahələrin mənalı adlarının qısa identifikatorlarla əvəz edilməsidir. Nəticədə UserAuthenticationService sinifi a sinfinə, validateLoginCredentials metodu a(Bundle) metoduna çevrilir. Bu proqramın davranışını dəyişmir, lakin dekompilə olunmuş kodu praktiki olaraq oxunmaz edir. 1000 sinifli layihə bir neçə yüz simvol ümumi identifikatora sıxıla bilər.
Vacib məhdudiyyət: adlandırma ictimai API — reflection, Binding (DataBinding, ViewBinding), serializasiya (Gson, Kotlinx Serialization) və JNI funksiyaları vasitəsilə çağrılan metodlara təsir etməməlidir. Bu hallarda ProGuard-da müəyyən sinif və metodların adlandırılmasını qadağan edən -keep qaydaları istifadə olunur.
Control Flow Obfuscation (CFO) — proqramın strukturunu nəticəni dəyişmədən dəyişən metoddur. Kompilator həmişə eyni şəkildə icra olunan uydurma şərti keçidlər əlavə edir, eyni semantikaya malik kod bloklarını təkrarlayır, xətti çağırış ardıcıllıqlarını rekursiv və ya dövri konstruksiyalara çevirir. Bu kodun statik analizini xeyli çətinləşdirir.
Obfuscator-LLVM kimi bəzi alətlər LLVM IR aralıq təmsili səviyyəsində qabaqcıl CFO həyata keçirir. Onlar əsas blokları kiçik fraqmentlərə bölür, qarışdırır və şərtsiz keçidlər (goto) vasitəsilə birləşdirir. Nəticədə idarəetmə axını qrafiki labirintə bənzəyir ki, onu kod icra edilmədən bərpa etmək mümkün deyil.
Sətir sabitləri dekompilə olunmuş kodun ən informativ elementidir. API URL-ləri, API açarları, SQL sorğuları, xəta mesajları — bunların hamısı bayt kodunda açıq formada mövcuddur. Sətirlərin şifrələnməsi bütün sətir sabitlərini şifrələnmiş ardıcıllıqlarla əvəz edir ki, onlar ilk müraciətdə runtime zamanı deşifrə olunur.
// Obfuskasiyadan əvvəl mənbə kodu
String apiUrl = "https://api.example.com/v2/users";
String apiKey = "sk_live_abc123def456";
// Sətirlərin obfuskasiyasından sonra (dekompilə edilmiş görünüş)
String apiUrl = decrypt("x9K2pQ7mR4");
String apiKey = decrypt("z3F8nL1tV6");
// Decrypt metodu runtime-da sətri deşifrə edir
String decrypt(String encoded) {
return new String(xorDecode(base64Decode(encoded)), StandardCharsets.UTF_8);
}
ProGuard — Android SDK-ya inteqrasiya olunmuş Java/Kotlin bayt kodunun sıxılması, optimallaşdırılması və obfuskasiyası üçün klassik alətdir. 2018-ci ildən Google eyni funksiyaları daha sürətli və daha yaxşı optimallaşdırma ilə yerinə yetirən daha məhsuldar R8 istifadəsini tövsiyə edir. R8 3.4.0 versiyasından Android Gradle Plugin-də standart olaraq aktivdir.
Obfuskasiya konfiqurasiyası ProGuard Rules — qaydalar dəsti olan mətn faylı vasitəsilə təyin edilir. Qaydalar hansı sinif və metodların saxlanmalı (-keep), hansıların adlandırıla biləcəyini (-obfuscate) və hansıların silinməli olduğunu (-dontwarn) müəyyən edir. proguard-rules.pro — Android layihəsində qaydalar faylının standart yerləşməsidir.
// proguard-rules.pro — Android üçün əsas qaydalar
// Reflection vasitəsilə istifadə olunan sinifləri saxla
-keep class com.example.models.** { *; }
// Gson vasitəsilə serializasiya olunan sinifləri saxla
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.google.gson.** { *; }
// JNI metodlarını obfuska etmə
-keepclasseswithmembernames class * {
native <methods>;
}
// Activity-ni saxla (giriş nöqtələri)
-keep class * extends android.app.Activity
minifyEnabled və obfuskasiya arasındakı fərqi başa düşmək vacibdir. minifyEnabled true bayrağı build.gradle-də sıxılmanı (istifadə olunmayan kodun silinməsi) aktivləşdirir. proguardFiles bayrağı qaydalar faylını göstərir. Obfuskasiyanı aktivləşdirmək üçün əlavə olaraq useProguard true göstərilir və ya R8 istifadə olunur, burada obfuskasiya minifyEnabled ilə standart olaraq aktivdir.
Obfuskasiya zamanı R8/ProGuard mapping.txt — obfuska edilmiş və orijinal adlar arasında uyğunluq faylı yaradır. Bu fayl crash loqlarının analizi üçün kritik əhəmiyyətlidir: onsuz stack trace yalnız a.b.c() kimi adları ehtiva edir ki, bu da oxunmazdır. Mapping faylı hər bir release qurulması üçün saxlanmalı və Google Play Console və ya Sentry-ə yüklənməlidir.
// build.gradle — Android üçün obfuskasiya konfiqurasiyası
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
iOS ekosistemində obfuskasiya Android-dən daha az yayılmışdır, çünki Swift və Objective-C üçün LLVM kompilatoru qismən reverse engineering-i çətinləşdirən bir sıra optimallaşdırmalar həyata keçirir. Lakin iOS tətbiqlərinin tam obfuskasiyası da mümkündür. SwiftShield — qurma mərhələsində Swift və Objective-C simvollarını təsadüfi sətirlərə dəyişən məşhur alətdir.
SwiftShield post-kompilasiya aləti kimi işləyir: Mach-O ikili faylını analiz edir və tətbiqin bütün simvollarını (siniflər, protokollar, metodlar) obfuska edilmiş adlarla əvəz edir. Vacibdir ki, SwiftShield sistem kitabxanalarının və ictimai API-nin simvollarına toxunmur, App Store ilə uyğunluğu saxlayır. Objective-C üçün əlavə obfuskasiya bayraqları ilə LLVM kompilatorundan istifadə mümkündür.
Obfuscator-LLVM — əlavə obfuskasiya keçidləri olan LLVM kompilatorunun forkudur: idarəetmə axınının qarışdırılması, sətirlərin şifrələnməsi və ölü kodun əlavə edilməsi. C, C++, Objective-C və Swift-i dəstəkləyir, lakin kompilatorun öz versiyasının qurulmasını tələb edir. Bu yanaşma ən effektivdir, lakin konfiqurasiya və CI/CD pipeline ilə inteqrasiya baxımından çətindir.
Flutter SDK release versiyasının qurulması zamanı --obfuscate bayrağı vasitəsilə obfuskasiya üçün daxili dəstək təmin edir. Bu bayraq ProGuard-a bənzər şəkildə Dart kodunun identifikatorlarını təsadüfi simvollardan istifadə edərək dəyişir. Əlavə qorunma üçün Flutter obfuskasiyasını R8 (Android) və ya SwiftShield (iOS) vasitəsilə native kod obfuskasiyası ilə birləşdirmək olar.
React Native tətbiqləri JavaScript bundle səviyyəsində obfuska edilir. javascript-obfuscator (və ya JScrambler) aləti JS kodunu çevirir: dəyişən adlarını dəyişir, sətirləri şifrələyir, uydurma kod əlavə edir. Obfuskasiyadan sonra bundle ölçüsü 50–100% artır, lakin kod analizi əhəmiyyətli dərəcədə çətinləşir. Native örtük səviyyəsində də Android və iOS-un standart alətləri tətbiq olunur.
Obfuskasiya əqli mülkiyyətin qorunmasını təmin edir — alqoritmlərin və biznes məntiqinin surətinin çıxarılması deobfuskasiyaya sərf olunan vaxta görə iqtisadi cəhətdən sərfəli olmur. Bu, qeyri-rəsmi mağazalarda tətbiq klonlarının yaranma riskini azaldır və şəkillərin işlənməsi, tövsiyə sistemləri və ya kriptovalyuta pulqabları kimi unikal alqoritmləri qoruyur.
Vacib üstünlük — avtomatik analizdən qorunma. Təcavüzkarların zəiflikləri axtarmaq üçün istifadə etdiyi statik analiz alətlərinin çoxu (DB qoşulma sətirləri, API açarları, gizli endpointlər) obfuskasiyadan sonra effektivliyini itirir. Alətlər kodu icra etməli (dinamik analiz) olur ki, bu da statik analizdən qat-qat çətindir.
Birinci məhdudiyyət — obfuskasiya şifrələmə deyil. Kod prosessor üçün oxunaqlı qalır və debuggerlər (LLDB, Frida) və tracerlər vasitəsilə runtime zamanı analiz edilə bilər. Obfuskasiya yalnız reverse engineering-i çətinləşdirir, lakin kifayət qədər vaxt və resurs olduqda onu qeyri-mümkün etmir.
İkinci məhdudiyyət — performansa təsir. Bəzi obfuskasiya metodları (idarəetmə axınının qarışdırılması, sətirlərin şifrələnməsi) runtime zamanı əlavə yük yaradır. Aqressiv obfuskasiya başlatma vaxtını 10–30% və ikili faylın ölçüsünü 50–200% artıra bilər. Buna görə metodların seçimi balanslaşdırılmış olmalıdır: qorunma tətbiqi qəbuledilməz dərəcədə yavaş etməməlidir.
Üçüncü məhdudiyyət — alət dəsti ilə uyğunluq. Obfuskasiya mapping faylları konfiqurasiya edilmədikdə crash-reporting sistemlərinin (Firebase Crashlytics, Sentry) işini poza bilər. Reflection əsaslı kitabxanalar (Dagger/Hilt, Retrofit, Gson) açıq saxlama qaydaları tələb edir. R8 və ProGuard mütəmadi olaraq yenilənir, lakin konfiqurasiyadakı səhvlər istifadə olunan kodun silinməsinə səbəb ola bilər.
Tez-tez verilən suallar
Obfuskasiya — oxunaqlı kodun qarışıq formaya çevrilməsidir, eyni işləyir, lakin analiz etmək çətindir. Sinif və metodların adları mənasız simvol dəstləri ilə əvəz olunur.
build.gradle faylında minifyEnabled true təyin edin və release qurulması üçün proguardFiles göstərin. R8 standart olaraq aktivdir və avtomatik olaraq sıxılma, optimallaşdırma və obfuskasiya həyata keçirir.
R8 — Google-dan ProGuard-ın daha müasir və sürətli əvəzedicisidir. R8 eyni funksiyaları (sıxılma, optimallaşdırma, obfuskasiya) yerinə yetirir, lakin Android Gradle Plugin-ə daha dərin inteqrasiya olunub və daha səmərəli işləyir.
Mapping.txt — obfuska edilmiş və orijinal sinif və metod adları arasında uyğunluq faylı. Crash loqlarının deobfuskasiyası və release qurulmalarının analizi üçün zəruridir.
-obfuscate-strings bayrağı ilə ProGuard/R8 (Android) və ya qurma mərhələsində sətir şifrələmə alətlərindən istifadə edin. iOS üçün SwiftShield və ya sabitlərin şifrələmə keçidi ilə Obfuscator-LLVM tətbiq edin.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun