DexPatcher: Menambal APK Android Menggunakan Java

DexPatcher memungkinkan pengembang untuk menambal APK menggunakan Java. Ini memiliki beberapa keuntungan, dan penggunaan DexPatcher jauh lebih mudah dibandingkan pendekatan Smali klasik.

Anda mungkin pernah melihat atau menginstal aplikasi yang dimodifikasi, baik itu dialer yang ditambal untuk resolusi Anda atau versi WhatsApp khusus dengan fitur tambahan. Namun, bagaimana cara pengembang melakukan hal tersebut? Sering kali, kode sumber aplikasi bahkan tidak tersedia, jadi bagaimana cara kerjanya? Kita akan melihatnya terlebih dahulu, lalu melihat alat baru yang bertujuan untuk membuat prosesnya lebih mudah, dan terakhir membandingkannya dengan kerangka Xpose yang populer untuk melihat perbedaannya.

Anda mungkin pernah mendengar tentang bagaimana APK biasanya dimodifikasi -- pengembang menghubungkan dirinya ke dalamnya matriks, mulailah melihat segala sesuatu di Smali, dan dapatkan kemampuan untuk memodifikasi berbagai hal menggunakan kekuatan Sumber. Panggilan telepon sudah cukup untuk membuat mereka keluar setelah selesai, dan pada saat itu mereka siap membagikan APK baru yang keren.

Lebih serius lagi… Mari kita mulai dari awal. Jika Anda belum familiar dengan modding aplikasi Android, Anda mungkin bertanya-tanya apa itu smali. Pengembang biasanya menggunakan bahasa pemrograman Java untuk mengkodekan aplikasi Android. Sebuah program (kompiler) kemudian "menerjemahkan" kode tersebut ke format lain yang sesuai untuk perangkat Anda, menghasilkan file .dex yang terdapat di dalam paket aplikasi (atau APK).

Pada saat itu, Anda tidak dapat lagi mengakses kode sumber aslinya (kecuali Anda adalah pengembangnya atau aplikasinya bersumber terbuka). Namun, yang Anda miliki hanyalah APK, karena itulah yang diinstal pada perangkat Anda. Dari sana, Anda bisa mendapatkan file dex (biasanya class.dex) dan kemudian mencoba menerjemahkannya kembali ke format yang Anda pahami. Di situlah smali berperan, sebagai terjemahan yang lebih mudah dibaca namun setia. Anda dapat melangkah lebih jauh dan menerjemahkannya kembali ke Java, meskipun prosesnya tidak cukup tepat -- Anda akan mendapatkan hasil yang dapat dimengerti, tetapi kemungkinan besar Anda tidak akan dapat menerjemahkannya lagi karena beberapa detail akan hilang sepanjang jalan. Dengan kata lain, modifikasi apa pun yang Anda lakukan akan sia-sia karena Anda tidak akan dapat mengubahnya kembali menjadi APK untuk menginstalnya di perangkat Anda… setidaknya bukan tanpa banyak usaha.

smali/baksmali sebenarnya adalah assembler/dissembler untuk format dex -- itulah arti harfiahnya dalam bahasa Islandia. Namun, kami biasanya mengacu pada format yang dipahami smali ketika kami mengucapkan 'Smali' (anggap saja sebagai instruksi mendefinisikan setiap detail kecil, meskipun tidak semuanya dibutuhkan oleh kita manusia -- oleh karena itu, hal ini lebih bertele-tele daripada Jawa). Perhatikan juga bahwa penjelasan di atas sedikit disederhanakan, tetapi harus berupa analogi yang mirip namun tetap mudah dipahami.

Lalu, apa yang perlu dilakukan pengembang untuk memodifikasi aplikasi (tanpa akses ke sumbernya? Prosesnya kurang lebih sebagai berikut:

  1. Dapatkan APK (dari web atau dari perangkat).
  2. Gunakan sesuatu seperti apktool untuk mendekompilasi APK ke Smali. (apktool menggunakan smali/baksmali, namun membuatnya lebih mudah untuk mendekompilasi dan membangun kembali APK, dan juga menangani decoding sumber daya seperti file XML.)
  3. Ekstrak class.dex dari APK, lalu gunakan dex2jar dan terakhir dekompiler Java untuk mendapatkan kode Java (tidak lengkap, sering rusak, tetapi sebagian besar dapat dimengerti). (Ini opsional, namun dapat membantu karena Smali jauh lebih sulit untuk dipahami.)
  4. Identifikasi apa yang harus dimodifikasi.
  5. Sebenarnya memodifikasinya dengan mengedit kode Smali secara langsung.
  6. Alternatifnya, tulis modifikasinya di Java, kompilasi, dekompilasi lagi ke Smali, lalu salin kode Smali yang dihasilkan.
  7. Setelah semuanya selesai, gunakan apktool lagi untuk membangun kembali APK.
  8. Menandatangani APK (untuk memverifikasi identitas penulis; semua paket harus ditandatangani) dan terakhir menginstalnya.

Penulisan kode Smali cukup sulit dan rawan kesalahan. Perubahan kecil dapat dilakukan di Smali, tetapi menambahkan fitur baru akan lebih menantang. Selain itu, Anda tidak akan mengalami kesalahan waktu kompilasi, sehingga kesalahan ketik pun hanya dapat terdeteksi saat runtime. Memperluas dan membagikan patch Smali juga bisa merepotkan, karena perbedaannya cenderung sangat spesifik untuk versi APK tertentu. Meskipun ada beberapa alat untuk mempermudah bagian proses yang dijelaskan di atas (Studio Sepuluh Berbudi Luhur terlintas dalam pikiran), ini masih bisa melelahkan.

DexPatcher oleh Anggota Senior XDA Lanchon bertujuan untuk memperbaiki masalah ini, dengan membuat prosesnya lebih sederhana dan memungkinkan pengembang menghindari berurusan dengan Smali. Sebaliknya, pengembang dapat menulis tambalan di Java saja dan meminta DexPatcher menangani semuanya.

Keuntungan utama dari hal ini adalah memiliki file patch yang mudah dibaca dan dikelola. Menambal APK juga menjadi lebih nyaman secara umum. Kita akan melihat contoh lengkap tentang cara menggunakan DexPatcher sebentar lagi, tapi inilah ikhtisar singkat tentang apa yang ditawarkannya terlebih dahulu:

  • Sumber terbuka.
  • Lintas platform: harus berjalan di Linux, Mac dan Windows.
  • File patch: modifikasi yang Anda buat terkandung dalam file patch Java yang dapat Anda bagikan secara mandiri.
  • Jawa: itu bukan Smali.

Anda juga mendapatkan keuntungan dari pemeriksaan kesalahan pada waktu build, sehingga bug muncul di awal siklus pengembangan. Java yang dikompilasi menyediakan pemeriksaan waktu kompilasi seperti biasanya (dengan akses ke simbol APK asli), dan DexPatcher menerapkannya kompatibilitas sumber dan patch saat melakukan patch, memberikan informasi bermanfaat dan memberikan peringatan ketika Anda sepertinya melakukan sesuatu legal tapi mencurigakan.

Selain itu, DexPatcher hadir dengan serangkaian skrip pembantu (hanya tersedia di Linux, meskipun dapat di-porting ke platform lain juga). Ini menangani pengaturan ruang kerja, mengekstraksi kelas dan sumber daya APK target, mendekompilasi kelas ke Java ( Dekompiler CFR Java digunakan untuk yang terakhir), dan terakhir membuat dan menandatangani APK yang telah dipatch setelah Anda selesai.

Mari kita lihat contohnya (di Linux):

Instal Skrip DexPatcher

$# 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.

Konfigurasikan Skrip DexPatcher

Membuka dxp.config di editor teks favorit Anda dan pastikan untuk mengubah variabel yang diperlukan agar sesuai dengan sistem Anda. Anda hanya perlu mengubah baris berikut untuk menunjuk ke lokasi instalasi Android SDK Anda:

dxp_android_sdk_dir=(~/android/sdk)

(DexPatcher akan secara otomatis memilih versi platform tertinggi yang tersedia. Selain itu, Anda juga dapat memodifikasi opsi konfigurasi lainnya agar menggunakan beberapa alat versi Anda sendiri, bukan default yang disertakan.)

Untuk kemudahan akses, kita dapat menambahkan pengirim direktori ke kami JALUR, atau bahkan menghubungkan yang berbeda dxp-* skrip ke lokasi yang sudah ada di Anda JALUR, seperti ~/tempat sampah:

export PATH=$PWD:$PATH

Memodifikasi Aplikasi

Untuk contoh ini, kami akan menggunakan aplikasi sederhana dan open source. Tentu saja, menambal kode sumber secara langsung dapat dilakukan dalam kasus khusus ini, tetapi itu tidak menyenangkan sama sekali!

Kami akan menggunakan aplikasi "Dapatkan ID" dari basil2style, sebuah aplikasi yang menunjukkan beberapa detail tentang perangkat Anda. Tujuan kami adalah mengubah tombol "Salin" untuk "ID Perangkat" dan menjadikannya membagikan ID ini:

  • Pertama, mari kita unduh APK yang akan kita modifikasi: Dapatkan ID.
  • Dekompilasi aplikasi.
  • Buat kunci penandatanganan yang nantinya akan kita gunakan untuk menandatangani APK.

Kita juga dapat melakukan semuanya melalui shell, menggunakan skrip pembantu:

$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".

Anda akan melihat beberapa direktori berbeda di sana:

  • membaca sandi: Anda akan menemukan sumber daya dan Smali di sini, seperti yang diterjemahkan oleh apktool.
  • src: Direktori kosong. Di sinilah kami akan menempatkan file patch kami.
  • src-cfr: di sinilah cfr mendekompilasi aplikasi (bersama dengan kesalahan). Tempat yang bagus untuk mencari tahu guna memutuskan apa yang harus diubah (Anda mungkin juga memerlukan sumber daya dan ID-nya dari direktori dekode di atas, tetapi tidak untuk contoh khusus ini).
  • src-cfr-nodecode: sama seperti di atas, tetapi hanya berisi stub kosong (tanpa kode, hanya kerangka). Anda dapat menggunakan file-file ini sebagai dasar untuk patch Anda seperti yang akan kita lihat sebentar lagi.

Seperti yang telah kami sebutkan sebelumnya, kami ingin mengubah tombol "Salin" ID Perangkat untuk membagikan teks ID. Jika kita melihat kode sumbernya, kita akan melihat tombol Salin ID Perangkat (perangkat_salinan) diKlik acara ditangani oleh kelas anonim di src-cfr/makeinfo/com/getid/MainActivity.java. Meskipun kita dapat memodifikasinya di sini, biasanya lebih baik mencari cara alternatif untuk melakukannya karena kelas anonim memiliki nama numerik (NamaKelas Utama$NomorBeberapa, mis. Aktivitas Utama$3) yang mungkin berubah secara tidak terduga antar versi.

Sebagai gantinya, kita akan mendaftarkan kelas kita sendiri untuk acara tersebut dengan memodifikasi Aktifitas utama kelas. Pertama, mari kita salin versi "kerangka" dari src-cfr-nocode/makeinfo/com/getid/MainActivity.java ke src/makeinfo/com/getid/MainActivity.java (ingat itu src adalah tempat patch kita akan berada). (Anda juga dapat menyalin versi dengan kode lengkap jika Anda mau, ini murni masalah selera.)

Sekarang kita dapat mengeditnya sebagai berikut:

  • Tambahkan impor yang diperlukan untuk anotasi DexPatcher:
importlanchon.dexpatcher.annotation.*;
  • Tambahkan tag untuk menunjukkan bahwa kita sedang mengedit kelas. Kami juga menetapkan tindakan default untuk anggota kelas patch MENGABAIKAN, yang berarti bahwa anggota ada untuk direferensikan oleh kode kita selama kompilasi Java, namun akan diabaikan oleh DexPatcher.
@DexEdit(defaultAction=DexAction.IGNORE)

publicclassMainActivity

// The reference to ActionBarActivity will be satisfied by symbols

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

extendsActionBarActivity{

  • Selain itu, tambahkan badan kosong ke konstruktor dan diBuat metode tersebut, serta semua metode lain yang ingin kami gunakan (ingat bahwa metode tersebut akan diabaikan ketika patch kami benar-benar diterapkan -- kami hanya menambahkannya sehingga kami dapat merujuknya di sini jika diperlukan). Anda juga bisa menambahkan warga asli kata kunci sebagai gantinya.
  • Kami sudah dapat membuat patchnya saat ini, jika Anda penasaran:
    $ dxp-make # Output: `patched.apk`.
    Cukup sederhana, bukan? Namun, mari kita lanjutkan -- kita masih belum selesai.
  • Mari kita edit diBuat sekarang untuk berangkat sendiri OnClickListener sehingga kami dapat membagikan ID perangkat alih-alih menyalinnya ke clipboard:
    // 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();}}}
  • Sepertinya kita sudah selesai sekarang! Patch lengkapnya akan terlihat seperti ini ini. Sekarang kita dapat membuat APK yang telah dipatch dan menginstalnya:
    $ dxp-make$ adb install patched.apk
  • Mari kita lihat hasilnya:

(Terima kasih kepada Lanchon karena telah membantu dengan kode contoh!)

Xpose sangat populer, dan untuk alasan yang bagus -- membuat pembuatan, berbagi, dan pemasangan mod menjadi lebih mudah bagi pengembang dan pengguna. Ada beberapa perbedaan antara DexPatcher dan Xpose yang mungkin membuat beberapa orang lebih memilih salah satu dari yang lain:

  1. Xpose melakukan keajaibannya dengan mengaitkan metode saat runtime dan memungkinkan pengembang melakukan sesuatu sebelum, sesudah, atau sebagai pengganti metode apa pun. DexPatcher, di sisi lain, memodifikasi semuanya sebelum runtime dan menghasilkan APK mandiri yang dimodifikasi -- menjalankan kode sebelum, sesudah, atau sebagai pengganti metode masih dapat dilakukan, dan Anda sebenarnya memiliki beberapa tambahan kebebasan.
  2. Memproduksi APK mandiri berarti tidak bergantung pada kerangka kerja eksternal apa pun. Ini juga berarti root tidak diperlukan untuk memodifikasi aplikasi pengguna.
  3. Karena Anda membuat APK baru dengan DexPatcher, APK tersebut akan ditandatangani secara berbeda. Ini berarti pengguna tidak dapat menerima pembaruan resmi dari pembuat aslinya, dan dapat menyebabkan beberapa masalah dengan aplikasi seperti Google Apps jika tanda tangan dicentang.
  4. Kode sumber modul dan patch DexPatcher dapat dengan mudah didistribusikan dan dimodifikasi. Mereka juga memiliki banyak kesamaan jika Anda sedikit mengenalnya.

Kita sudah cukup banyak berbicara tentang DexPatcher. Sekarang giliran Anda untuk mencobanya sekarang, jadi pergilah ke Utas Forum DexPatcher untuk segera memulai!