DexPatcher, geliştiricilerin Java kullanarak APK'lara yama yapmasına olanak tanır. Bunun birçok avantajı vardır ve DexPatcher'ı kullanmak klasik Smali yaklaşımından çok daha kolaydır.
Çözünürlüğünüz için yamalı bir çevirici veya ek özelliklere sahip özel bir WhatsApp sürümü olsun, muhtemelen değiştirilmiş uygulamaları görmüş veya yüklemişsinizdir. Peki geliştiriciler bunu nasıl yapıyor? Çoğu zaman uygulamaların kaynak kodu bile mevcut değildir, peki nasıl çalışıyor? Önce bunu göreceğiz, ardından süreci daha kolay hale getirmeyi amaçlayan yeni bir araca göz atacağız ve son olarak onu popüler Xposed çerçevesiyle karşılaştırarak ne kadar farklı olduklarını göreceğiz.
APK'ların genellikle nasıl değiştirildiğini duymuş olabilirsiniz; geliştiriciler kendilerini APK'lara bağlarlar. matrisi, her şeyi Smali'de görmeye başlayın ve Smali'nin gücünü kullanarak şeyleri değiştirme yeteneği kazanın. Kaynak. Bu işlem tamamlandıktan sonra onları dışarı çıkarmak için bir telefon görüşmesi yeterlidir; bu noktada yeni ve parlak APK'ları paylaşmaya hazır olurlar.
Daha ciddisi… En baştan başlayalım. Android uygulamalarını modlamaya aşina değilseniz, smali'nin ne olduğunu merak ediyor olabilirsiniz. Geliştiriciler genellikle Android uygulamalarını kodlamak için Java programlama dilini kullanır. Daha sonra bir program (derleyici) bu kodu cihazınız için uygun başka bir formata "çevirir" ve sonuçta uygulama paketinin (veya APK'nin) içinde .dex dosyaları bulunur.
Bu noktada artık orijinal kaynak koduna erişemezsiniz (geliştirici değilseniz veya uygulama açık kaynak değilse). Ancak cihazınızda yüklü olduğu için sahip olduğunuz APK'dır. Buradan dex dosyalarını (genellikle class.dex) alabilir ve ardından onu anlayabileceğiniz bir formata çevirmeyi deneyebilirsiniz. Daha okunaklı ama aslına sadık bir çeviri olarak smali'nin devreye girdiği yer burasıdır. Bir adım daha ileri giderek onu tekrar Java'ya çevirebilirsiniz, ancak bu süreç yeterince sadık değildir. anlaşılabilir bir sonuç, ancak bazı ayrıntılar kaybolacağından büyük olasılıkla bunu tam tersi şekilde çeviremeyeceksiniz yol boyunca. Başka bir deyişle, cihazınıza yüklemek için tekrar APK'ya dönüştüremeyeceğiniz için yapacağınız herhangi bir değişiklik boşa gidecektir… en azından çok fazla çaba harcamadan.
smali/baksmali aslında dex formatı için bir birleştirici/çözücüdür - İzlandaca'da kelimenin tam anlamıyla bu anlama gelir. Ancak, 'Smali' dediğimizde genellikle Smali'nin anladığı formata atıfta bulunuruz (bunu talimatlar olarak düşünün). biz insanların ihtiyaç duyduğu her şey olmasa bile her küçük ayrıntıyı tanımlamak - bu nedenle bundan daha ayrıntılıdır Java). Ayrıca yukarıdaki açıklamanın biraz basitleştirilmiş olduğunu ancak anlaşılması kolay olmakla birlikte yakın bir benzetme olması gerektiğini de unutmayın.
O halde bir geliştiricinin bir uygulamayı değiştirmek için (kaynağa erişimi olmadan) ne yapması gerekir? Süreç aşağı yukarı şu şekildedir:
- APK'yı edinin (web'den veya cihazdan).
- Gibi bir şey kullanın apktool APK'yı Smali'ye derlemek için. (apktool smali/baksmali'yi kullanır, ancak APK'ları kaynak koda dönüştürmeyi ve yeniden oluşturmayı çok daha kolaylaştırır ve ayrıca XML dosyaları gibi kaynakların kodunu çözmeyle de ilgilenir.)
- Class.dex'i APK'dan çıkarın ve kullanın dex2jar ve son olarak (eksik, çoğunlukla bozuk, ancak çoğunlukla anlaşılabilir) Java kodunu almak için bir Java derleyicisi. (Bu isteğe bağlıdır ancak Smali'nin anlaşılması çok daha zor olduğundan faydalı olabilir.)
- Neyin değiştirileceğini belirleyin.
- Aslında doğrudan Smali kodunu düzenleyerek değiştirin.
- Alternatif olarak, değişikliği Java'da yazın, derleyin, tekrar Smali'ye kaynak koda dönüştürün ve ardından ortaya çıkan Smali kodunu kopyalayın.
- Her şey bittiğinde, kullanın apktool APK'yı yeniden oluşturmak için tekrar.
- APK'yı imzalayın (yazarın kimliğini doğrulamak için; tüm paketlerin imzalanması gerekir) ve son olarak yükleyin.
Smali kodunu yazmak oldukça zordur ve hataya açıktır. Smali'de daha küçük değişiklikler yapılabilir ancak ona yeni özellikler eklemek daha zordur. Ayrıca herhangi bir derleme zamanı hatası yaşamazsınız, dolayısıyla yazım hataları bile yalnızca çalışma zamanında tespit edilebilir. Farklılıklar belirli bir APK sürümüne çok özel olma eğiliminde olduğundan Smali yamalarını genişletmek ve paylaşmak da zahmetli olabilir. Yukarıda açıklanan sürecin bölümlerini kolaylaştırmak için bazı araçlar mevcut olsa da (Erdemli On Stüdyo aklıma geliyor), yine de yorucu olabiliyor.
XDA Kıdemli Üyesi tarafından DexPatcher Lanchon süreci basitleştirerek ve geliştiricilerin Smali ile uğraşmaktan tamamen kaçınmasına olanak tanıyarak bu sorunları çözmeyi amaçlıyor. Bunun yerine geliştiriciler yamaları yalnızca Java'da yazabilir ve DexPatcher'ın geri kalan her şeyi halletmesini sağlayabilir.
Bunun ana avantajı, kolayca okunabilir ve yönetilebilir yama dosyalarına sahip olmaktır. APK'lara yama eklemek de genel olarak daha kullanışlı hale geliyor. Birazdan DexPatcher'ın nasıl kullanılacağına dair tam bir örnek göreceğiz, ancak öncelikle sunduklarına kısa bir genel bakış:
- Açık kaynak.
- Çapraz platform: Linux, Mac ve Windows'ta çalışmalıdır.
- Yama dosyaları: Yaptığınız değişiklikler, bağımsız olarak paylaşabileceğiniz Java yama dosyalarında bulunur.
- Java: Smali değil.
Ayrıca derleme zamanı hata denetimi avantajından da yararlanırsınız, böylece hatalar geliştirme döngüsünün erken safhalarında ortaya çıkar. Derlenen Java, olağan derleme zamanı kontrolünü sağlar (orijinal APK simgelerine erişimle birlikte) ve DexPatcher, Yama yaparken kaynak ve yama uyumluluğu, yararlı bilgiler sağlama ve bir şey yapıyormuş gibi göründüğünüzde uyarı verme yasal ama kuşkulu.
Buna ek olarak DexPatcher bir takım özelliklerle birlikte gelir: yardımcı komut dosyaları (yalnızca Linux'ta mevcuttur, ancak diğer platformlara da taşınabilirler). Bunlar çalışma alanının ayarlanması, hedef APK'nın sınıflarının ve kaynaklarının çıkarılması, sınıfların Java'ya derlenmesi ( CFR Java kod çözücü ikincisi için kullanılır) ve işiniz bittiğinde son olarak yamalı APK'yi oluşturup imzalamak.
Bir örneğe bakalım (Linux'ta):
DexPatcher Komut Dosyalarını Yükleyin
$# 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.
DexPatcher Komut Dosyalarını Yapılandırma
Açık dxp.config favori metin düzenleyicinizde ve gerekli değişkenleri sisteminize uyacak şekilde değiştirdiğinizden emin olun. Bunun yerine Android SDK'nızın kurulum konumunu işaret edecek şekilde aşağıdaki satırı değiştirmeniz yeterlidir:
dxp_android_sdk_dir=(~/android/sdk)
(DexPatcher otomatik olarak mevcut en yüksek platform sürümünü seçecektir. Ayrıca, paketteki varsayılanlar yerine bazı araçların kendi sürümlerinizi kullanmasını sağlamak için diğer yapılandırma seçeneklerini de değiştirebilirsiniz.)
Erişim kolaylığı için şunu ekleyebiliriz: dexpatcher bizim dizin YOL, hatta farklı olanı sembolik olarak bağlayın dxp-* zaten bulunduğunuz bir konuma komut dosyaları YOL, örneğin ~/bin:
export PATH=$PWD:$PATH
Bir Uygulamayı Değiştirme
Bu örnek için basit ve açık kaynaklı bir uygulama kullanacağız. Elbette bu özel durumda kaynak kodunu doğrudan yamalamak mümkün olabilir, ancak bu hiç de eğlenceli değil!
Cihazınızla ilgili bazı ayrıntıları gösteren bir uygulama olan basil2style'ın "Kimlik Al" uygulamasını ele alacağız. Amacımız "Cihaz Kimliği" için "Kopyala" düğmesini değiştirmek ve bunun yerine bu kimliği paylaşmasını sağlamaktır:
- Öncelikle değiştireceğimiz APK'yı indirelim: Kimlik al.
- Uygulamayı kaynak koda dönüştürün.
- Daha sonra APK'yı imzalamak için kullanacağımız imzalama anahtarını oluşturun.
Yardımcı komut dosyalarını kullanarak tüm bunları kabuk aracılığıyla da yapabiliriz:
$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".
Orada birkaç farklı dizin göreceksiniz:
- şifreyi çözmek: Kaynakları ve Smali'yi burada kodu çözülmüş olarak bulacaksınız. apktool.
- kaynak: Boş dizin. Yama dosyalarımızı buraya yerleştireceğiz.
- kaynak-cfr: burası cfr uygulamayı kaynak koda dönüştürdü (hatalarla birlikte). Neyi değiştireceğinize karar vermek için bakılacak iyi bir yer (yukarıdaki kod çözme dizinindeki kaynaklara ve bunların kimliklerine de ihtiyacınız olabilir, ancak bu özel örnek için değil).
- src-cfr-düğüm kodu: yukarıdakiyle aynı, ancak yalnızca boş taslaklar içeriyor (kod yok, yalnızca iskeletler). Birazdan göreceğimiz gibi bu dosyaları yamanız için temel olarak kullanabilirsiniz.
Daha önce de belirttiğimiz gibi Cihaz Kimliğini "Kopyala" butonunu değiştirerek bunun yerine kimlik metnini paylaşmak istiyoruz. Kaynak koduna bakarsak, Cihaz Kimliğini Kopyala düğmesinin (cihaz_kopyası) tıklamada olay anonim sınıf tarafından ele alınır src-cfr/makeinfo/com/getid/MainActivity.java. Burada değişiklik yapabiliriz ancak anonim sınıfların sayısal adları olduğundan bunu yapmanın alternatif bir yolunu bulmak genellikle daha iyidir (MainClassName$SomeNumber, Örneğin. Ana Faaliyet$3) sürümler arasında tahmin edilemeyecek şekilde değişebilir.
Bunun yerine, olay için kendi sınıfımızı değiştirerek kaydedeceğiz. Ana aktivite sınıf. Öncelikle "iskelet" versiyonunu kopyalayalım. src-cfr-nocode/makeinfo/com/getid/MainActivity.java ile src/makeinfo/com/getid/MainActivity.java (bunu hatırla kaynak yamamızın yaşayacağı yer burasıdır). (İsterseniz tam kodlu versiyonu da kopyalayabilirsiniz, bu tamamen zevk meselesidir.)
Artık aşağıdaki gibi düzenleyebiliriz:
- DexPatcher ek açıklaması için gerekli içe aktarmayı ekleyin:
importlanchon.dexpatcher.annotation.*;
- Sınıfı düzenlediğimizi belirtmek için bir etiket ekleyin. Ayrıca yama sınıfının üyeleri için varsayılan eylemi de şu şekilde ayarladık: GÖRMEZDEN GELMEKBu, üyelerin Java derlemesi sırasında kodumuz tarafından referans alınacağı, ancak DexPatcher tarafından göz ardı edileceği anlamına gelir.
@DexEdit(defaultAction=DexAction.IGNORE)publicclassMainActivity
// The reference to ActionBarActivity will be satisfied by symbols
// extracted from the app when we build the patch.
extendsActionBarActivity{
- Ek olarak, yapıcıya boş gövdeler ekleyin ve onCreate yöntemini ve kullanmayı planladığımız diğer tüm yöntemleri (yamayı gerçekten uyguladığımızda bunların göz ardı edileceğini unutmayın; yalnızca ihtiyaç duymamız halinde burada başvurabilmemiz için bunları ekliyoruz). Ayrıca şunları da ekleyebilirsiniz: yerli bunun yerine anahtar kelime.
- Merak ediyorsanız yamayı bu noktada zaten oluşturabiliriz:
$ dxp-make # Output: `patched.apk`.
Oldukça basit, değil mi? Yine de devam edelim; henüz işimiz bitmedi. - Hadi düzenleyelim onCreate şimdi kendi yola çıkmak için OnClickListener böylece cihaz kimliğini panoya kopyalamak yerine paylaşabiliriz:
// 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();}}}
- Artık işimiz bitti gibi görünüyor! Tam yama şöyle görünmeli Bu. Artık yamalı APK'yı oluşturup yükleyebiliriz:
$ dxp-make$ adb install patched.apk
- Gelin sonuca bir göz atalım:
(Örnek kod konusunda yardımcı olduğu için Lanchon'a teşekkürler!)
Xposed son derece popüler ve bunun iyi bir nedeni var; modların oluşturulmasını, paylaşılmasını ve kurulmasını hem geliştiriciler hem de kullanıcılar için çok daha kolay hale getiriyor. DexPatcher ve Xposed arasında bazılarının birini diğerine tercih etmesine neden olabilecek birkaç fark vardır:
- Xposed, çalışma zamanındaki yöntemleri bağlayarak ve geliştiricilerin herhangi bir yöntemden önce, sonra veya bunun yerine bir şeyler yapmasına izin vererek sihrini yapar. Öte yandan DexPatcher, her şeyi çalışma zamanından önce değiştirir ve bağımsız, değiştirilmiş bir APK üretir -- yöntemlerin öncesinde, sonrasında veya yerine kod çalıştırmak hala mümkündür ve aslında bazı ekstralarınız da vardır. özgürlük.
- Bağımsız bir APK üretmek, herhangi bir harici çerçeveye bağlı olmadığı anlamına gelir. Bu aynı zamanda kullanıcı uygulamalarını değiştirmek için root'un gerekli olmadığı anlamına da gelir.
- DexPatcher ile yeni bir APK oluşturduğunuz için farklı şekilde imzalanacaktır. Bu, kullanıcıların orijinal yazardan resmi güncellemeleri alamayacağı ve imzaların kontrol edilmesi durumunda Google Apps gibi uygulamalarda bazı sorunlara neden olabileceği anlamına gelir.
- Hem modüllerin hem de DexPatcher yamalarının kaynak kodları kolaylıkla dağıtılabilir ve değiştirilebilir. Ayrıca her birine biraz aşina olursanız, pek çok benzerlik paylaşıyorlar.
DexPatcher hakkında yeterince konuştuk. Şimdi deneme sırası sizde, o yüzden şuraya gidin: DexPatcher Forum Konusu hemen başlamak için!