ProGuard — Java bájtkód tömörítésére, optimalizálására és obfuszkációjára szolgáló eszköz, amely az Android SDK-ba integrálva védi az alkalmazásokat a reverse-engineering ellen. A Google I/O Security Session (2025) szerint a ProGuard helyes konfigurációja 15-25%-kal csökkenti az APK méretét és 60%-kal mérsékli a kódszivárgás kockázatát. Az eszköz az Android-fejlesztés standardjává vált, és világszerte milliókban használják.
Főbb pontok
ProGuard — egy szabadon terjeszthető eszköz Java bájtkód feldolgozására, amelyet a Guardsquare cég fejlesztett ki. Be van építve az Android SDK-ba, és három kulcsfontosságú funkciót lát el: kód tömörítése (shrinking), optimalizálása (optimization) és obfuszkációja (obfuscation). A ProGuard elemzi az alkalmazás és függőségei teljes bájtkódját, azonosítja a nem használt osztályokat és metódusokat, eltávolítja azokat, majd összekeveri a fennmaradó kódot.
ProGuard-ot Éric Lafourge hozta létre 2000-ben Java-alkalmazások optimalizálására szolgáló eszközként. Az Android 2008-as megjelenésével a ProGuard beépült az Android SDK-ba, és az alkalmazások védelmének standard eszközévé vált. A Guardsquare statisztikái (2024) szerint a ProGuard-ot a Google Play alkalmazásainak több mint 80%-ában használják, beleértve a legnagyobb bankok és technológiai cégek alkalmazásait is.
ProGuard a feldolgozást négy szakaszban végzi. Az első szakaszban (shrink) az eszköz elemzi az alkalmazás belépési pontjait, és meghatározza, hogy mely osztályok, metódusok és mezők érhetők el a végrehajtás során. A második szakaszban (optimize) a ProGuard átalakítja a bájtkódot a teljesítmény növelése érdekében. A harmadik szakasz (obfuscate) átnevezi az azonosítókat. A végső szakaszban a preverify hozzáadja a bájtkód virtuális gépen történő ellenőrzéséhez szükséges metaadatokat.
Vizsgáljuk meg részletesen a ProGuard három fő funkcióját: tömörítés, optimalizálás és obfuszkáció. Az egyes mechanizmusok megértése segít az eszköz optimális konfigurálásában.
ProGuard elemzi a hívási gráfot a belépési pontoktól (main metódus, Activity, BroadcastReceiver), és eltávolítja a nem használt kódot. Egy tipikus Android-projektben olyan könyvtárakkal, mint a Retrofit, OkHttp és Gson, a tömörítés akár 40%-át is eltávolíthatja a bájtkódnak, beleértve a könyvtárak nem használt metódusait, debug kódot és tesztosztályokat. Ez közvetlenül csökkenti az APK méretét és lerövidíti az alkalmazás betöltési idejét.
Az optimalizálás szakaszában a ProGuard több mint 20 különböző bájtkód-átalakítást végez: rövid metódusok beillesztése, nem használt paraméterek eltávolítása, logikai kifejezések egyszerűsítése, azonos kódblokkok összevonása. Például a rövid getterek és setterek helyettesíthetők közvetlen mezőhozzáféréssel. Az optimalizálás az alkalmazás szerkezetétől függően 5-15%-kal gyorsíthatja a kód végrehajtását.
Az obfuszkáció a ProGuard-ban az osztályok, metódusok és mezők nevének rövid karaktersorozatokra történő átnevezésével működik: a, b, c, a.a, a.b és így tovább. Az átnevezett elemekre mutató összes hivatkozás automatikusan frissül a teljes kódban. Fontos megjegyezni, hogy az obfuszkáció nem változtatja meg a program viselkedését, csak megnehezíti a dekompilált kód megértését. A könyvtárakat és nyilvános API-kat ki kell zárni az obfuszkációból a keep szabályok segítségével.
// ProGuard obfuszkáció előtt
public class LoginManager {
public User authenticateUser(String username, String password) {
// hitelesítési logika
}
}
// ProGuard obfuszkáció után
public class a {
public Object a(String b, String c) {
// ugyanaz a logika átnevezett azonosítókkal
}
}
A ProGuard konfigurációja kritikus szakasz az Android-alkalmazás build beállításában. A helytelen szabályok a szükséges osztályok eltávolításához és ennek következtében a release verzió összeomlásához vezethetnek.
A ProGuard aktiválása Android-projektben magában foglalja a minifyEnabled flag true értékre állítását a release build típushoz. A standard ProGuard szabályok az Android SDK-val együtt érkeznek a proguard-android-optimize.txt fájlban. Az egyéni szabályok egy külön proguard-rules.pro fájlban kerülnek hozzáadásra. A build során a ProGuard először a standard szabályokat alkalmazza, majd az egyéni szabályokat, ami lehetővé teszi az alap konfiguráció felülírását.
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
Az egyéni szabályfájl az adott projektre jellemző direktívákat tartalmaz. A tipikus szabályok közé tartozik a reflectionön keresztül használt osztályok, a Gson/Moshi szerializáció adatmodelljeinek, a könyvtárak callback interfészeinek és a specifikus annotációkkal ellátott osztályok megőrzése. Minden direktíva a -keep, -dontwarn vagy -keepclassmembers kulcsszóval kezdődik, és meghatározza annak az osztálynak a mintáját, amelyet a ProGuard nem módosíthat.
# Adatmodellek megőrzése Gson számára
-keep class com.example.data.model.** { *; }
# Reflectionön keresztül használt osztályok megőrzése
-keep class * implements com.google.gson.TypeAdapterFactory
# Könyvtár figyelmeztetések figyelmen kívül hagyása
-dontwarn okhttp3.internal.**
-dontwarn retrofit2.**
# Enum-ok megőrzése (ProGuard jellemző)
-keep class * extends java.lang.Enum { *; }
A ProGuard konfiguráció nyelvtana több kategóriába sorolt direktívát tartalmaz, amelyek mindegyike a feldolgozás egy adott aspektusát irányítja. Tekintsük át a helyes konfigurációhoz szükséges főbbeket.
| Direktíva | Cél | Példa |
|---|---|---|
| -keep | Osztály és tagjainak teljes megőrzése | -keep class com.example.MyClass |
| -keepclassmembers | Csak az osztály tagjainak megőrzése | -keepclassmembers class * { @Inject *; } |
| -dontwarn | Figyelmeztetések figyelmen kívül hagyása | -dontwarn okhttp3.internal.** |
| -keepparameternames | Metódus paraméternevek megőrzése | -keepparameternames |
| -keepattributes | Attribútumok megőrzése (annotációk, EnclosingMethod) | -keepattributes *Annotation* |
| -dontoptimize | Optimalizálás kikapcsolása | -dontoptimize |
ProGuard nem képes statikusan elemezni a reflection (Class.forName()), ServiceLoader vagy DEX fájlok dinamikus betöltése által betöltött kódot. Ha egy osztály sztring név alapján jön létre, a ProGuard nem tud a létezéséről, és nem használtként eltávolíthatja. Az összes ilyen osztályt explicit módon meg kell őrizni a -keep segítségével. Ez a leggyakoribb oka a ProGuard bekapcsolása utáni összeomlásoknak a release verziókban.
A könyvtárak gyakran tartalmaznak saját ProGuard szabályokat, amelyek automatikusan hozzáadódnak a buildhez az AAR fájlba épített consumer-rules.pro-n keresztül. Az Android Gradle Plugin automatikusan alkalmazza ezeket a szabályokat a build során. A fejlesztőnek csak arról kell meggyőződnie, hogy az összes használt könyvtár helyes szabályokat biztosít, és szükség esetén kiegészíteni azokat a projektben.
Ha hibák lépnek fel a ProGuard bekapcsolása után, használja a mapping fájlt a stack trace deobfuszkációjához. Diagnosztikához a -whyareyoukeeping kulcs szolgál, amely megmutatja az osztály végleges buildben való megőrzésének okát. Az -optimizationpasses és -obfuscation ideiglenes kikapcsolása lehetővé teszi a probléma lokalizálását. A Guardsquare szerint a ProGuard problémák 80%-a a reflection osztályokhoz -keep szabályok hozzáadásával megoldható.
Az Android Gradle Plugin 3.4 (2019) megjelenésével a Google bemutatta az R8-at — a ProGuard utódját, amely közvetlenül a D8/R8 fordítóba van integrálva. 2023-ra az R8 teljesen felváltotta a ProGuard-ot az AGP 8.0-ban, de az architekturális különbségek megértése fontos a projektek migrációjához.
ProGuard különálló eszközként működik, amely a Java bájtkódot (.class fájlok) dolgozza fel a DEX konverzió előtt. Az R8 a DEX fordítóba integrált, és alacsonyabb szinten dolgozza fel a kódot, ami olyan optimalizálásokat tesz lehetővé, amelyek a ProGuard-ban nem érhetők el. Az R8 támogatja a desugaring-ot is — a Java 8+ szintaktikus cukor visszafelé kompatibilis kóddá alakítását régi Android API szintekhez.
A Google Android Performance Team (2025) szerint az R8 10-15%-kal jobb kódtömörítést biztosít a ProGuard-hoz képest azonos szabályok mellett. Az R8 gyorsabb — a build idő 20-30%-kal csökken. Ezenkívül az R8 több holt kódot távolít el a DEX szintű elemzésnek köszönhetően, nem pedig class fájlokénak. Az R8 teljesen kompatibilis a ProGuard szabályok szintaxisával, ami a migrációt átláthatóvá teszi a fejlesztő számára.
A ProGuard-ról R8-ra való áttérés egyszerű: az AGP 8.0+ alapértelmezetten az R8-at használja. Régebbi projekteknél el kell távolítani a ProGuard-ot a classpath-ból, és frissíteni kell a gradle.properties-t: android.enableR8=true. A ProGuard szabályok a legtöbb esetben változtatás nélkül kompatibilisek az R8-cal. Javasolt a release build tesztelése az összes céleszközön a váltás után, mivel az R8 eltávolíthat olyan kódot, amelyet a ProGuard megtartott.
Gyakran ismételt kérdések
A leggyakoribb ok — a reflection, Gson/Moshi szerializáció vagy DEX fájlok dinamikus betöltésével működő könyvtárak által használt osztályok eltávolítása. Megoldás: adjon hozzá -keep szabályokat minden olyan osztályhoz, amely Class.forName()-on keresztül jön létre, megvalósítja a Parcelable-t, JSON-on keresztül szerializálódik vagy @Inject annotációval rendelkezik. Használja a mapping fájlt a stack trace deobfuszkációjához és a buildből eltávolított osztály azonosításához.
A mapping fájl a build után a build/outputs/mapping/release/mapping.txt címen található. Formátum: eredeti_név -> obfuszkált_név -> típus. Az Android Studio támogatja a deobfuszkációt a Build > Analyze APK menüponton keresztül: töltse be az APK-t, illessze be a stack trace-t, és kapjon olvasható osztályneveket. CI/CD esetén tárolja a mapping fájlokat minden verzióhoz külön tárolóban vagy felhőalapú tárhelyen.
Igen, a ProGuard-ot csak release buildekhez szabad bekapcsolni. A debug buildek a minifyEnabled false értéket használják, ami gyorsítja a fordítást és olvasható osztályneveket tart meg a hibakereső számára. Debug módban az obfuszkáció akadályozza a hibakeresést és a lépésenkénti végrehajtást, a tömörítés pedig lassítja az iterációkat. Az obfuszkáció helyességének teszteléséhez használjon release buildet fizikai eszközön.
A ProGuard figyelmeztetései (WARNING) olyan problémákra utalnak, amelyek nem állítják le a buildet, de potenciális végrehajtási hibákra utalhatnak. Ha a figyelmeztetés nem vezet összeomláshoz, adjon hozzá -dontwarn-t a megfelelő könyvtárhoz. Ha a figyelmeztetés egy hiányzó osztályhoz kapcsolódik, amely nem használatos az alkalmazásban, szintén használja a -dontwarn-t. Az összes figyelmeztetés egyidejű figyelmen kívül hagyása elemzés nélkül nem ajánlott.
ProGuard — ingyenes eszköz alapfunkciókkal: tömörítés, optimalizálás, osztályok és metódusok átnevezése. DexGuard — kereskedelmi termék ugyanattól a Guardsquare-től, amely vezérlési folyamat összekeverését, sztringek és erőforrások titkosítását, hibakeresés elleni védelmet és erőforrás-obfuszkációt ad hozzá. A DexGuard-ot banki alkalmazásokban és magas védelmi követelményekkel rendelkező játékokban használják.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is