DexPatcher: Javítsa meg az Android APK-kat Java használatával

A DexPatcher lehetővé teszi a fejlesztők számára, hogy Java segítségével javítsák az APK-kat. Ennek számos előnye van, és a DexPatcher használata sokkal egyszerűbb, mint a klasszikus Smali megközelítés.

Valószínűleg már látott vagy telepített módosított alkalmazásokat, legyen az az Ön felbontásának megfelelő javított tárcsázó, vagy egy egyedi WhatsApp verzió hozzáadott funkciókkal. De hogyan csinálják ezt a fejlesztők? Sokszor az alkalmazások forráskódja sem érhető el, így hogyan működik mindez? Először ezt nézzük meg, aztán vessünk egy pillantást egy új eszközre, amelynek célja a folyamat sokkal könnyebbé tétele, végül pedig hasonlítsuk össze a népszerű Xposed keretrendszerrel, hogy lássuk, miben különböznek egymástól.

Lehet, hogy hallott már arról, hogy az APK-kat általában hogyan módosítják – a fejlesztők bekapcsolják magukat a mátrix, kezdj el mindent látni szmali nyelven, és szerezd meg a képességet a dolgok módosítására a Forrás. Egy telefonhívás elegendő ahhoz, hogy kiszabadítsák őket, miután ez megtörtént, és készen állnak a csillogó új APK-k megosztására.

Komolyabban… Kezdjük az elején. Ha nem ismeri az Android-alkalmazások módosítását, felmerülhet a kérdés, mi az a smali. A fejlesztők általában a Java programozási nyelvet használják az Android-alkalmazások kódolásához. Egy program (a fordító) ezután „lefordítja” ezt a kódot egy másik, az Ön eszközének megfelelő formátumba, ami az alkalmazáscsomagban (vagy APK-ban) található .dex-fájlokat eredményez.

Ekkor már nem férhet hozzá az eredeti forráskódhoz (hacsak nem Ön a fejlesztő, vagy ha az alkalmazás nyílt forráskódú). Azonban, amivel rendelkezel, az az APK, mivel ez az, ami telepítve van az eszközödre. Ebből beszerezheti a dex fájlokat (általában classes.dex), majd megpróbálhatja visszafordítani egy érthető formátumba. Itt jön be a smali, olvashatóbb, de hűséges fordításként. Egy lépéssel tovább léphet, és visszafordíthatja Java nyelvre, bár ez a folyamat nem elég hűséges – kapsz egy érthető eredmény, de valószínű, hogy nem fogja tudni újra fordítani, mert néhány részlet elveszik az út mentén. Más szóval, az esetleges módosítások hiábavalók, mivel nem tudod újra APK-vá alakítani, hogy telepítsd az eszközödre… legalábbis nem sok erőfeszítés nélkül.

A smali/baksmali valójában egy assembler/dissembler a dex formátumhoz -- szó szerint ezt jelenti izlandi nyelven. Általában azonban arra a formátumra hivatkozunk, amelyet a smali megért, amikor azt mondjuk, hogy „Smali” (gondolja ezt utasításnak minden apró részletet meghatároz, még akkor is, ha nekünk, embereknek nem mindenre van szükségünk – ezért bőbeszédűbb, mint Jáva). Vegye figyelembe azt is, hogy a fenti magyarázat kissé leegyszerűsített, de közeli analógiának kell lennie, miközben továbbra is könnyen érthető.

Mit kell tennie egy fejlesztőnek egy alkalmazás módosításához (a forráshoz való hozzáférés nélkül)? A folyamat többé-kevésbé a következő:

  1. Szerezze be az APK-t (az internetről vagy az eszközről).
  2. Használj valami hasonlót apktool hogy visszafejtse az APK-t Smalira. (apktool használja a smali/baksmali-t, de sokkal könnyebbé teszi az APK-k visszafejtését és újraépítését, valamint gondoskodik az erőforrások, például az XML-fájlok dekódolásáról.)
  3. Bontsa ki a classes.dex fájlt az APK-ból, majd használja dex2jar és végül egy Java decompiler (hiányos, gyakran törött, de többnyire érthető) Java kód beszerzéséhez. (Ez nem kötelező, de hasznos lehet, mivel a Smali nyelvet sokkal nehezebb megérteni.)
  4. Határozza meg, hogy mit kell módosítani.
  5. Valójában módosítsa a Smali kód közvetlen szerkesztésével.
  6. Alternatív megoldásként írja le a módosítást Java nyelven, fordítsa le, dekomponálja újra Smalira, majd másolja át a kapott Smali kódot.
  7. Ha mindennek vége, használja apktool ismét az APK újraépítéséhez.
  8. Aláírja az APK-t (a szerző azonosításának ellenőrzéséhez; minden csomagot alá kell írni), és végül telepíteni kell.

A Smali kód írása meglehetősen nehéz és hibás. Kisebb változtatásokat lehet végrehajtani a Smaliban, de új funkciók hozzáadása nagyobb kihívást jelent. Ezenkívül nem lesznek fordítási időbeli hibák, így előfordulhat, hogy a gépelési hibákat is csak futás közben észleljük. A Smali javítások bővítése és megosztása szintén problémás lehet, mivel a különbségek általában nagyon specifikusak egy adott APK-verzióra. Bár léteznek olyan eszközök, amelyek megkönnyítik a fent ismertetett folyamat egyes részeit (Virtuous Ten Stúdió jut eszembe), még mindig fárasztó lehet.

DexPatcher az XDA vezető tagjától Lanchon célja ezeknek a problémáknak a megoldása azáltal, hogy egyszerűbbé teszi a folyamatot, és lehetővé teszi a fejlesztők számára, hogy teljesen elkerüljék a Smalival való foglalkozást. Ehelyett a fejlesztők csak Java-ban írhatnak javításokat, és a DexPatcher kezelheti az összes többit.

Ennek az a fő előnye, hogy könnyen olvasható és kezelhető javítási fájljai vannak. Az APK-k javítása általában is kényelmesebbé válik. Rövidesen látni fogunk egy teljes példát a DexPatcher használatára, de itt egy gyors áttekintés arról, hogy mit kínál először:

  • Nyílt forráskód.
  • Többplatformos: Linuxon, Macen és Windowson kell futnia.
  • Javítófájlok: az Ön által végzett módosítások a Java javítófájlokban találhatók, amelyeket önállóan is megoszthat.
  • Java: ez nem Smali.

A felépítési idejű hibaellenőrzés előnyeit is élvezheti, így a hibák a fejlesztési ciklus elején jelennek meg. A lefordított Java biztosítja a szokásos fordítási idő ellenőrzését (az eredeti APK szimbólumokhoz való hozzáféréssel), és a DexPatcher kényszeríti a forrás és a javítás kompatibilitása javításkor, hasznos információk biztosítása és figyelmeztetések, ha úgy tűnik, hogy csinál valamit legális, de halvány.

Ezen kívül a DexPatcherhez tartozik egy sor segítő szkriptek (csak Linuxon érhető el, bár más platformokra is átvihetők). Ezek gondoskodnak a munkaterület beállításáról, a cél APK osztályainak és erőforrásainak kinyeréséről, az osztályok Java-ra történő visszafordításáról (a CFR Java decompiler az utóbbihoz használják), és végül a javított APK felépítése és aláírása, ha végzett.

Nézzünk egy példát (Linuxon):

Telepítse a DexPatcher szkripteket

$# Make a directory where we can test stuff out and enter it. 

$ mkdir xda-test

$cd xda-test

$ git clone https://github.com/Lanchon/DexPatcher-scripts.git dexpatcher # Clone the DexPatcher helper scripts repo.

$cd dexpatcher

$ chmod +x dxp-* # Not necessary, but for clarity: we need to make sure the files we'll call later are executable.

Konfigurálja a DexPatcher szkripteket

Nyisd ki dxp.config kedvenc szövegszerkesztőjében, és ügyeljen arra, hogy módosítsa a szükséges változókat a rendszerének megfelelően. Csak a következő sort kell módosítania, hogy az Android SDK telepítési helyére mutasson:

dxp_android_sdk_dir=(~/android/sdk)

(A DexPatcher automatikusan kiválasztja az elérhető legmagasabb platformverziót. Ezenkívül más konfigurációs beállításokat is módosíthat, hogy az egyes eszközök saját verzióit használja a csomagban szereplő alapértelmezett beállítások helyett.)

A könnyebb hozzáférés érdekében hozzáadhatjuk a dexpatcher címtárunkba PÁLYA, vagy akár szimbolizálja a különbözőt dxp-* szkripteket egy olyan helyre, amely már benne van PÁLYA, mint például ~/bin:

export PATH=$PWD:$PATH

Alkalmazás módosítása

Ebben a példában egy egyszerű és nyílt forráskódú alkalmazást fogunk használni. Természetesen ebben az esetben a forráskód közvetlen javítása lehetséges lenne, de ez egyáltalán nem szórakoztató!

Elfogadjuk a basil2style „Identitás megszerzése” alkalmazását, egy olyan alkalmazást, amely megmutat néhány részletet az eszközről. Célunk, hogy módosítsuk az „Eszközazonosító” „Másolás” gombját, és ossza meg ezt az azonosítót:

  • Először is töltsük le a módosítani kívánt APK-t: Szerezzen azonosítót.
  • Dekomponálja az alkalmazást.
  • Hozd létre az aláíró kulcsot, amelyet később az APK aláírására használunk.

Mindezt a shell-en keresztül is megtehetjük, a segédszkriptek segítségével:

$cd dexpatcher # Go to our working directory. 

$ curl -O https://f-droid.org/repo/makeinfo.com.getid_1.apk # Download the APK.

$ dxp-setup-for-apk makeinfo.com.getid_1.apk # Unpack and decompile the APK.

$cd makeinfo.com.getid_1 # Go to the newly created directory where everything is unpacked/decompiled to.

$ dxp-create-keystore # Create the APK signing key. Press 6 times (or fill out the info), then "yes".

Néhány különböző könyvtárat fog látni benne:

  • dekódolni: itt találja a forrásokat és a Smali-t, ahogyan dekódolta apktool.
  • src: Üres könyvtár. Ide fogjuk elhelyezni a javítási fájljainkat.
  • src-cfr: ez az, ahol visszafordította az alkalmazást (a hibákkal együtt). Jó hely, ahol érdemes megnézni, hogy mit kell módosítani (lehet, hogy a fenti dekódolási könyvtár forrásaira és azonosítóira is szüksége lesz, de nem ebben a konkrét példában).
  • src-cfr-nodecode: ugyanaz, mint fent, de csak üres csonkokat tartalmaz (nincs kód, csak csontvázak). Ezeket a fájlokat használhatja a javítás alapjaként, amint azt hamarosan látni fogjuk.

Amint azt korábban említettük, az Eszközazonosító „Másolás” gombját szeretnénk megváltoztatni, hogy helyette az azonosító szövegét ossza meg. Ha körülnézünk a forráskódban, észrevesszük, hogy a Device ID Copy gomb (device_copy) kattintásra Az eseményt anonim osztály kezeli src-cfr/makeinfo/com/getid/MainActivity.java. Bár itt módosíthatjuk, általában jobb, ha más módszert találunk erre, mivel az anonim osztályoknak numerikus neveik vannak (MainClassName$SomeNumber, például. Főtevékenység $3), amelyek a verziók között kiszámíthatatlanul változhatnak.

Ehelyett saját osztályunkat regisztráljuk az eseményre a Fő tevékenység osztály. Először másoljuk át a "csontváz" verziót innen src-cfr-nocode/makeinfo/com/getid/MainActivity.java nak nek src/makeinfo/com/getid/MainActivity.java (Emlékezz arra src ott fog élni a tapaszunk). (Ha úgy tetszik, a teljes kódot tartalmazó verziót is lemásolhatja, ez pusztán ízlés kérdése.)

Most a következőképpen szerkeszthetjük:

  • Adja hozzá a szükséges importálást a DexPatcher megjegyzéshez:
importlanchon.dexpatcher.annotation.*;
  • Adjon hozzá egy címkét, amely jelzi, hogy szerkesztjük az osztályt. A javítási osztály tagjainak alapértelmezett műveletét is a következőre állítottuk FIGYELMEN KÍVÜL HAGYNI, ami azt jelenti, hogy a tagokra azért van, hogy a kódunk hivatkozzon rájuk a Java fordítás során, de a DexPatcher figyelmen kívül hagyja őket.
@DexEdit(defaultAction=DexAction.IGNORE)

publicclassMainActivity

// The reference to ActionBarActivity will be satisfied by symbols

// extracted from the app when we build the patch.

extendsActionBarActivity{

  • Ezenkívül adjon hozzá üres testeket a konstruktorhoz és onCreate metódussal, valamint az összes többi módszerrel, amelyet használni tervezünk (ne feledje, hogy ezeket figyelmen kívül hagyja, amikor a javítást ténylegesen alkalmazzuk – mi csak hozzáadjuk őket, hogy szükség esetén hivatkozhassunk rájuk). Azt is csak hozzáadhatja a anyanyelvi kulcsszó helyett.
  • Ezen a ponton már elkészíthetjük a javítást, ha kíváncsi vagy:
    $ dxp-make # Output: `patched.apk`.
    Elég egyszerű, igaz? Folytassuk azonban – még mindig nem végeztünk.
  • Szerkesszük onCreate most indulni a saját OnClickListener hogy a vágólapra másolás helyett megoszthassuk az eszközazonosítót:
    // Rename the target method so that we can still call it (the original)// if needed.@DexEdit(target="onCreate")protectedvoidsource_onCreate(Bundlevar1){}// Add our new custom method.@Override@DexAddprotectedvoidonCreate(Bundlevar1){// Call the original method:source_onCreate(var1);// Replace the text and handler:device_copy.setText("Share");device_copy.setOnClickListener(newDeviceCopyOnClick());}// Note that we don't use an anonymous class to avoid nameclashing with// MainActivity$1, which already exists.// We also could've defined a nested MainActivity.Patch class and used// an anonymous class in MainActivity.Patch.onCreate(), and then called// MainActivity.Patch.onCreate() from MainActivity.onCreate().@DexAddclassDeviceCopyOnClickimplementsView.OnClickListener{@OverridepublicvoidonClick(Viewobject){if(MainActivity.this.val){Intentintent=newIntent(Intent.ACTION_SEND);intent.setType("text/plain");intent.putExtra(Intent.EXTRA_SUBJECT,"Device ID");intent.putExtra(Intent.EXTRA_TEXT,device.getText().toString());startActivity(Intent.createChooser(intent,"Share Device ID"));}else{Toast.makeText(MainActivity.this.getApplicationContext(),"Nothing to Share",0).show();}}}
  • Úgy tűnik, most végeztünk! A teljes foltnak így kell kinéznie ez. Most már elkészíthetjük a javított APK-t és telepíthetjük:
    $ dxp-make$ adb install patched.apk
  • Nézzük az eredményt:

(Köszönjük Lanchonnak, hogy segített a mintakóddal!)

Az Xposed rendkívül népszerű, és ennek jó oka van – sokkal egyszerűbbé teszi a modok létrehozását, megosztását és telepítését a fejlesztők és a felhasználók számára egyaránt. Van néhány különbség a DexPatcher és az Xposed között, amelyek miatt egyesek előnyben részesíthetik egyiket a másikkal szemben:

  1. Az Xposed megteszi a varázslatot azáltal, hogy futás közben metódusokat kapcsol be, és lehetővé teszi a fejlesztők számára, hogy bármilyen módszer előtt, után vagy helyett tegyenek valamit. A DexPatcher viszont mindent a futásidő előtt módosít, és önálló, módosított APK-t készít -- kód futtatása a metódusok előtt, után vagy helyett továbbra is lehetséges, és valójában van némi extra szabadság.
  2. Az önálló APK létrehozása azt jelenti, hogy nem függ semmilyen külső keretrendszertől. Ez azt is jelenti, hogy a root nem szükséges a felhasználói alkalmazások módosításához.
  3. Mivel új APK-t hozott létre a DexPatcherrel, az másként lesz aláírva. Ez azt jelenti, hogy a felhasználók nem kaphatnak hivatalos frissítéseket az eredeti szerzőtől, és az aláírások ellenőrzése esetén problémákat okozhat az olyan alkalmazásokban, mint a Google Apps.
  4. Mind a modulok, mind a DexPatcher javítások forráskódja könnyen terjeszthető és módosítható. Sok hasonlóság is van bennük, ha kicsit ismerkedsz velük.

Eleget beszéltünk a DexPatcherről. Most rajtad a sor, hogy megpróbáld, úgyhogy irány a DexPatcher fórum téma hogy azonnal kezdjem!