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ő:
- Szerezze be az APK-t (az internetről vagy az eszközről).
- 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.)
- 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.)
- Határozza meg, hogy mit kell módosítani.
- Valójában módosítsa a Smali kód közvetlen szerkesztésével.
- 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.
- Ha mindennek vége, használja apktool ismét az APK újraépítéséhez.
- 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 vö 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:
- 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.
- 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.
- 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.
- 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!