2012-11-02

Dekompilering av Android-appar

Först och främst skriver jag det här för att belysa den problematik som finns när det gäller apputveckling och hur lätt det är att kopiera appar och kringgå olika typer av skydd. Det är inte tänkt att vara en tutorial för hur man piratkopierar appar.
För att förhindra otillåten kopiering och användande av en app så går det att aktivera Google Play Licensing. Hur man implementerar det är upp till varje utvecklare, men lämpligt är att appen då och då kontrollerar mot Google Play om appen är installerad på korrekt sätt, dvs. genom Google Play och att eventuella avgifter är betalda. Om Google Play svarar att appen inte är licensierad så ber man användaren att köpa appen.

Problemet är att det ganska lätt går att dekompilera appen och ta bort licensieringskontrollen och sedan använda appen helt fritt.

Hur gör man det?
Skaffa först verktygen. Installera/packa upp på lämplig plats.
dex2jar: http://code.google.com/p/dex2jar/ - Läser dex-filer och skapar jar-filer.
JD-GUI: http://java.decompiler.free.fr/?q=jdgui - Grafiskt verktyg för att visa innehållet i .class-filer.

På Ubuntu kör jag följande kommando för att få ut en jar av en apk:
d2j-dex2jar.sh android-app.apk
Resultatet ut från den är filen android-app.jar

Starta JD-GUI och öppna android-app.jar.
Voila! All kod i klartext!

Härifrån är det lätt att ändra på det man behöver för att till exempel ta bort licensiering eller aktivera olika funktioner. Packa slutligen ihop appen och signera den. Sen är den klar att användas igen.

Hur gör man för att skydda sig från det här? Svaret heter obfuskering. Det gör koden väldigt mycket svårare att läsa eftersom de flesta namn översätts till enstaka bokstäver.
Här kan ni läsa om hur man obfuskerar med hjälp av ProGuard:
http://developer.android.com/tools/help/proguard.html

Obfuskering ger ett bra skydd, men ha ändå för vana att gå igenom den obfuskerade koden med JD-GUI och kontrollera känsliga punkter i koden och se till att det inte är för uppenbart vad som händer och hur man kan kringgå det. Alla klasser och metoder byter inte namn så det kan gå att luska ut hur det fungerar.
Det är viktigt att se till att loggning inte avslöjar vad som händer.
Ett enkelt och snabbt sätt är att låta ProGuard ta bort alla anrop till Log.d och Log.v med följande direktiv (observera att optimization måste vara påslagen):
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}



Slutsats
Om du vill skydda din app så lägg in Google Play Licensing och obfuskera sedan all kod. Det viktigaste skyddet är ändå att du är medveten om problematiken och hur enkelt det är att titta i din kod, så kolla själv innan någon annan gör det.