Android alkalmazások visszafejtése 101

  1. Bevezetés
  2. Android alkalmazások alapjai
  3. Kezdő lépések az Android alkalmazások visszafejtésével
    • gyakorlat 1
  4. Android alkalmazások visszafejtése… DEX Bytecode
    • gyakorlat 2
    • gyakorlat 3
    • gyakorlat 4
  5. Reverse Engineering Android Apps – Natív könyvtárak
    • gyakorlat 5
    • gyakorlat 6
  6. Reverse Engineering Android Apps – Obfuscation
    • Exercise 7
  7. Conclusion

Build an App

Az egyik legnagyobb javaslatom azoknak, akik reverse engineeringet szeretnének végezni, bármi legyen is az, hogy próbálják megépíteni azt, amit vissza akarnak fordítani. Az Android esetében szerencsés vagy, mert nagyon sok ingyenes forrás áll rendelkezésre az első alkalmazásod elkészítéséhez. Ha még soha nem készítettél Android-alkalmazást, azt javaslom, hogy ott kezdd. Válassza ki az elérhető oktatóanyagok és videók közül bármelyiket, amely felkeltette az érdeklődését, és kezdjen hozzá az építéshez. Ha megérted, hogy egy fejlesztő hogyan épít valamit, akkor sokkal könnyebb lesz megérteni, hogyan kell azt visszafejteni.

Fundamentals Review

Nagyszerű! Építettél egy alkalmazást, vagy megtanultad az Android alkalmazásfejlesztés alapelveit. Íme néhány fontos pont áttekintése. Ez az “Alkalmazás alapjai” oldal az Android fejlesztők dokumentumaiban egy nagyszerű áttekintés.

  • Az Android alkalmazások APK fájlformátumban vannak. Az APK alapvetően egy ZIP fájl. (A fájlkiterjesztést átnevezheti .zip-re, és az unzip segítségével megnyithatja és megtekintheti a tartalmát.)
  • APK tartalom (A teljesség igénye nélkül)
    • AndroidManifest.xml
    • META-INF/
      • A tanúsítvány itt lakik!
    • classes.dex
      • Dalvik bytecode az alkalmazáshoz DEX fájlformátumban. Ez az a Java (vagy Kotlin) kód, amit az alkalmazás alapértelmezés szerint futtatni fog.
    • lib/
      • Az alkalmazás natív könyvtárai alapértelmezés szerint itt élnek! A lib/ könyvtár alatt találhatók a cpu-specifikus könyvtárak. Pl: armeabi, mips,
    • assets/
      • Minden más fájl, amire az alkalmazásnak szüksége lehet.
      • Kiegészítő natív könyvtárak vagy DEX fájlok ide kerülhetnek. Ez különösen akkor fordulhat elő, ha a rosszindulatú programok szerzői úgy akarják megpróbálni “elrejteni” a további, natív vagy Dalvik kódot, hogy nem az alapértelmezett helyeken helyezik el.

Dalvik & Smali

A legtöbb Android alkalmazás Java nyelven íródott. A Kotlin is támogatott és interoperábilis a Javával. Az egyszerűség kedvéért a workshop további részében, amikor “Java”-ra hivatkozom, feltételezheti, hogy “Java vagy Kotlin” alatt értem. Ahelyett, hogy a Java kódot az asztali alkalmazásokhoz hasonlóan a Java Virtual Machine (JVM) futtatná, az Androidban a Java a Dalvik Executable (DEX) bytecode formátumba van fordítva. Az Android korábbi verziói esetében a bytecode-ot a Dalvik virtuális gép fordította le. Az Android újabb verzióinál az Android Runtime-ot (ART) használják.
Ha a fejlesztők, Java-ban írnak, és a kódot DEX bytecode-ba fordítják, a visszafejtéshez az ellenkező irányba dolgozunk.

A smali a Dalvik bytecode ember által olvasható változata. Technikailag a Smali és a baksmali az eszközök neve (assembler, illetve disassembler), de az Androidban gyakran használjuk a “Smali” kifejezést az utasításokra. Ha végeztél már fordított mérnöki vagy számítógép-építészeti munkát lefordított C/C++ kódon. A SMALI olyan, mint az assembly nyelv: a magasabb szintű forráskód és a bytecode között.

A következő Hello World Java kódhoz:

public static void printHelloWorld() {System.out.println("Hello World")}

A Smali kód a következő lenne:

.method public static printHelloWorld()V.registers 2sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;const-string v1, "Hello World"invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)Vreturn-void.end method

A Smali utasításkészlet itt érhető el.

Az Android alkalmazások visszafejtésekor leggyakrabban nem kell Smali nyelven dolgozni. A legtöbb alkalmazás még magasabb szintre, dekompilált Java-ra emelhető. Mint minden eszköznek, a Java dekompilátoroknak is lehetnek hibái. Azt javaslom neked, hogy amikor a dekompilált Java kimenet megkérdőjelezhetőnek tűnik, nézd meg a Smali kimenetet. Dolgozzon sorról sorra az utasításhivatkozással, hogy rájöjjön, mit csinál a kód.

A Smali DEX-ből való kinyeréséhez használhatja a https://github.com/JesusFreke/smali/wiki címen elérhető baksmali eszközt (disassembler). A smali eszköz lehetővé teszi a smali visszaszerelését a DEX-be.

Az alkalmazás belépési pontjai

A reverse engineering egyik legfontosabb pontja, hogy tudjuk, hol kezdjük az elemzést, és ennek fontos részét képezik a kódvégrehajtás belépési pontjai.

Launcher Activity

A launcher activity az, amire a legtöbb ember úgy gondol, mint az Android alkalmazás belépési pontjára. Az indító tevékenység az a tevékenység, amely akkor indul el, amikor a felhasználó rákattint az alkalmazás ikonjára. Az indító tevékenységet az alkalmazás manifesztjének megtekintésével határozhatja meg. A launcher-aktivitás a következő MAIN és LAUNCHER intenteket tartalmazza.

Ne feledjük, hogy nem minden alkalmazásnak lesz launcher-aktivitása, különösen a felhasználói felület nélküli alkalmazásoknak. A felhasználói felület (és így indító aktivitás) nélküli alkalmazások példái az előre telepített alkalmazások, amelyek a háttérben szolgáltatásokat végeznek, mint például a hangposta.

<activity android:name=".LauncherActivity"><intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter></activity>

Services

A szolgáltatások a háttérben futnak felhasználói felület nélkül. Számtalan módon indíthatók, és így belépési pontot jelentenek az alkalmazások számára. Alapértelmezett módon egy szolgáltatás egy alkalmazás belépési pontjaként indítható az Intenteken keresztül.

Amikor a startService API-t meghívjuk egy szolgáltatás indításához, a szolgáltatásban lévő onStart metódus végrehajtódik.

Broadcast Receivers

A broadcastokat egy üzenetküldő rendszernek lehet elképzelni, a broadcast vevők pedig a hallgatók. Ha egy alkalmazás regisztrált egy vevőt egy adott broadcasthoz, akkor a rendszer a broadcast küldésekor végrehajtja az adott vevőben lévő kódot. Egy alkalmazás 2 módon regisztrálhat vevőt: az alkalmazás manifesztjében vagy dinamikusan regisztrálva az alkalmazás kódjában a registerReceiver() API hívás segítségével.

A vevők regisztrálásához mindkét esetben be kell állítani a vevőkészülék szándékszűrőit. Ezek a szándékszűrők azok az adások, amelyeknek be kell indítaniuk a vevőt.

Az adott adások küldésekor, amelyekre a vevő regisztrálva van, a BroadcastReceiver osztályban a onReceive végrehajtásra kerül.

Exportált komponensek (szolgáltatások & tevékenységek)

A szolgáltatások és tevékenységek “exportálhatók” is, ami lehetővé teszi, hogy az eszközön más folyamatok elindítsák a szolgáltatást vagy elindítsák a tevékenységet. A komponensek exportálása egy elem beállításával történik a manifesztben az alábbiak szerint. Alapértelmezés szerint android:exported="false" kivéve, ha ez az elem a manifesztben igazra van állítva, vagy a tevékenységhez vagy szolgáltatáshoz szándékszűrők vannak definiálva.

<service android:name=".ExampleExportedService" android:exported="true"/><activity android:name=".ExampleExportedActivity" android:exported="true"/>

Application Subclass

Az androidos alkalmazások meghatározhatják az Application alosztályát. Az alkalmazások definiálhatják, de nem kell, hogy definiálják az Application saját alosztályát. Ha egy Android alkalmazás definiál egy Application alosztályt, akkor ez az osztály az alkalmazás bármely más osztálya előtt instanciálódik.

Ha az Application alosztályban definiáljuk a attachBaseContext metódust, akkor azt hívjuk meg először, a onCreate metódus előtt.

NEXT > 3. Kezdő lépések az Android alkalmazások visszafordításával

.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.