Το DexPatcher επιτρέπει στους προγραμματιστές να επιδιορθώνουν τα APK χρησιμοποιώντας Java. Αυτό έχει πολλά πλεονεκτήματα και η χρήση του DexPatcher είναι πολύ πιο εύκολη από την κλασική προσέγγιση Smali.
Πιθανότατα έχετε δει ή εγκαταστήσει τροποποιημένες εφαρμογές, είτε πρόκειται για διορθωμένο πρόγραμμα κλήσης για την ανάλυσή σας είτε για προσαρμοσμένη έκδοση WhatsApp με πρόσθετες λειτουργίες. Πώς το κάνουν αυτό όμως οι προγραμματιστές; Πολλές φορές, ο πηγαίος κώδικας των εφαρμογών δεν είναι καν διαθέσιμος, οπότε πώς λειτουργούν όλα; Θα το δούμε πρώτα αυτό, μετά θα ρίξουμε μια ματιά σε ένα νέο εργαλείο που στοχεύει να κάνει τη διαδικασία πολύ πιο εύκολη και, τέλος, θα το συγκρίνουμε με το δημοφιλές πλαίσιο Xposed για να δούμε πώς διαφέρουν.
Ίσως έχετε ακούσει για τον τρόπο με τον οποίο συνήθως τροποποιούνται τα APK -- οι προγραμματιστές συνδέονται σε αυτό matrix, αρχίστε να βλέπετε τα πάντα στο Smali και αποκτήστε τη δυνατότητα να τροποποιήσετε πράγματα χρησιμοποιώντας τη δύναμη του Πηγή. Αρκεί ένα τηλεφώνημα για να τους βγάλετε μόλις ολοκληρωθεί, οπότε είναι έτοιμοι να μοιραστούν τα λαμπερά νέα APK.
Πιο σοβαρά… Ας πάρουμε τα πράγματα από την αρχή. Εάν δεν είστε εξοικειωμένοι με την τροποποίηση εφαρμογών Android, ίσως αναρωτιέστε τι είναι το smali. Οι προγραμματιστές χρησιμοποιούν συνήθως τη γλώσσα προγραμματισμού Java για την κωδικοποίηση εφαρμογών Android. Στη συνέχεια, ένα πρόγραμμα (ο μεταγλωττιστής) "μεταφράζει" αυτόν τον κώδικα σε άλλη μορφή κατάλληλη για τη συσκευή σας, με αποτέλεσμα αρχεία .dex που περιέχονται μέσα στο πακέτο εφαρμογής (ή APK).
Σε εκείνο το σημείο, δεν μπορείτε πλέον να έχετε πρόσβαση στον αρχικό πηγαίο κώδικα (εκτός εάν είστε ο προγραμματιστής ή η εφαρμογή είναι ανοιχτού κώδικα). Ωστόσο, αυτό που έχετε είναι το APK, καθώς είναι αυτό που είναι εγκατεστημένο στη συσκευή σας. Από αυτό, μπορείτε να λάβετε τα αρχεία dex (συνήθως classes.dex) και στη συνέχεια να προσπαθήσετε να τα μεταφράσετε σε μια μορφή που μπορείτε να κατανοήσετε. Εκεί μπαίνει το smali, ως μια πιο ευανάγνωστη αλλά πιστή μετάφραση. Μπορείτε να προχωρήσετε ένα βήμα παραπέρα και να το μεταφράσετε ξανά σε Java, αν και αυτή η διαδικασία δεν είναι αρκετά πιστή -- θα λάβετε κατανοητό αποτέλεσμα, αλλά το πιθανότερο είναι ότι δεν θα μπορείτε να το μεταφράσετε ξανά αντίστροφα καθώς κάποιες λεπτομέρειες θα χαθούν στην πορεία. Με άλλα λόγια, οποιεσδήποτε τροποποιήσεις μπορεί να κάνετε θα είναι μάταιες, καθώς δεν θα μπορείτε να το μετατρέψετε ξανά σε APK για να το εγκαταστήσετε στη συσκευή σας… τουλάχιστον όχι χωρίς πολλή προσπάθεια.
Το smali/baksmali είναι στην πραγματικότητα ένας assembler/dissembler για τη μορφή dex -- αυτό σημαίνει κυριολεκτικά στα ισλανδικά. Ωστόσο, συνήθως αναφερόμαστε στη μορφή που καταλαβαίνει το smali όταν λέμε "Smali" (σκεφτείτε το ως οδηγίες ορίζοντας κάθε μικρή λεπτομέρεια, ακόμα κι αν δεν είναι όλα απαραίτητα σε εμάς τους ανθρώπους -- είναι επομένως πιο ρητό από Ιάβα). Σημειώστε επίσης ότι η παραπάνω εξήγηση είναι λίγο απλοποιημένη, αλλά θα πρέπει να είναι μια στενή αναλογία ενώ εξακολουθεί να είναι εύκολη στην κατανόηση.
Τι θα πρέπει να κάνει ένας προγραμματιστής για να τροποποιήσει μια εφαρμογή (χωρίς πρόσβαση στην πηγή), τότε; Η διαδικασία είναι λίγο πολύ ως εξής:
- Λάβετε το APK (από τον ιστό ή από τη συσκευή).
- Χρησιμοποιήστε κάτι σαν apktool για να απομεταγλωττίσετε το APK στο Smali. (apktool κάνει χρήση του smali/baksmali, αλλά διευκολύνει πολύ την αποσυμπίληση και την ανακατασκευή των APK και φροντίζει επίσης για την αποκωδικοποίηση πόρων όπως τα αρχεία XML.)
- Εξαγάγετε το classes.dex από το APK και, στη συνέχεια, χρησιμοποιήστε το dex2jar και τέλος ένα Java decompiler για λήψη (ελλιπούς, συχνά σπασμένου, αλλά κυρίως κατανοητού) κώδικα Java. (Αυτό είναι προαιρετικό, αλλά μπορεί να είναι χρήσιμο καθώς το Smali είναι πολύ πιο δύσκολο να κατανοηθεί.)
- Προσδιορίστε τι να τροποποιήσετε.
- Στην πραγματικότητα, τροποποιήστε το επεξεργαζόμενοι απευθείας τον κώδικα Smali.
- Εναλλακτικά, γράψτε την τροποποίηση σε Java, μεταγλωττίστε την, απομεταγλωττίστε την ξανά σε Smali και μετά αντιγράψτε τον κώδικα Smali που προκύπτει.
- Μόλις τελειώσουν όλα, χρησιμοποιήστε apktool ξανά για να ξαναχτίσετε το APK.
- Υπογράψτε το APK (για να επαληθεύσετε την ταυτότητα του συγγραφέα. όλα τα πακέτα πρέπει να είναι υπογεγραμμένα) και τελικά να το εγκαταστήσετε.
Η σύνταξη κώδικα Smali είναι αρκετά δύσκολη και επιρρεπής σε σφάλματα. Μικρότερες αλλαγές μπορούν να γίνουν στο Smali, αλλά η προσθήκη νέων χαρακτηριστικών με αυτό είναι πιο δύσκολη. Επιπλέον, δεν θα έχετε σφάλματα χρόνου μεταγλώττισης, επομένως ακόμη και τυπογραφικά λάθη μπορεί να εντοπιστούν μόνο κατά το χρόνο εκτέλεσης. Η επέκταση και η κοινή χρήση ενημερώσεων κώδικα Smali μπορεί επίσης να είναι ενοχλητική, καθώς οι διαφορές τείνουν να είναι πολύ συγκεκριμένες για μια συγκεκριμένη έκδοση APK. Παρόλο που υπάρχουν ορισμένα εργαλεία για να διευκολύνουν τα μέρη της διαδικασίας που εξηγήθηκαν παραπάνω (Virtuous Ten Studio έρχεται στο μυαλό), μπορεί να γίνει ακόμα κουραστικό.
DexPatcher από XDA Senior Member Lanchon στοχεύει να διορθώσει αυτά τα ζητήματα, κάνοντας τη διαδικασία πιο απλή και επιτρέποντας στους προγραμματιστές να αποφύγουν εντελώς την ενασχόληση με το Smali. Αντίθετα, οι προγραμματιστές μπορούν να γράφουν ενημερώσεις κώδικα μόνο σε Java και να έχουν το DexPatcher να χειρίζεται οτιδήποτε άλλο.
Αυτό έχει το κύριο πλεονέκτημα ότι διαθέτει εύκολα αναγνώσιμα και διαχειρίσιμα αρχεία ενημέρωσης κώδικα. Η ενημέρωση κώδικα APK γίνεται επίσης πιο βολική γενικά. Θα δούμε ένα πλήρες παράδειγμα για το πώς να χρησιμοποιήσετε το DexPatcher σε λίγο, αλλά εδώ είναι μια γρήγορη επισκόπηση του τι προσφέρει πρώτα:
- Ανοιχτή πηγή.
- Cross-platform: θα πρέπει να τρέχει σε Linux, Mac και Windows.
- Αρχεία ενημέρωσης κώδικα: οι τροποποιήσεις που κάνετε περιέχονται σε αρχεία ενημέρωσης κώδικα Java που μπορείτε να μοιραστείτε ανεξάρτητα.
- Java: δεν είναι Smali.
Αποκτάτε επίσης το πλεονέκτημα του ελέγχου σφαλμάτων στο χρόνο κατασκευής, έτσι τα σφάλματα εμφανίζονται νωρίς στον κύκλο ανάπτυξης. Το μεταγλωττισμένο Java παρέχει τον συνήθη έλεγχο του χρόνου μεταγλώττισης (με πρόσβαση στα αρχικά σύμβολα APK) και το DexPatcher επιβάλλει συμβατότητα πηγής και ενημέρωσης κώδικα κατά την επιδιόρθωση, παροχή χρήσιμων πληροφοριών και προειδοποιήσεις όταν φαίνεται να κάνετε κάτι νόμιμη αλλά ψαρωμένη.
Επιπλέον, το DexPatcher έρχεται με ένα σύνολο βοηθητικά σενάρια (διατίθεται μόνο σε Linux, αν και θα μπορούσαν να μεταφερθούν και σε άλλες πλατφόρμες). Αυτά φροντίζουν για τη ρύθμιση του χώρου εργασίας, την εξαγωγή των κλάσεων και των πόρων του APK στόχου, την αποσυμπίληση των κλάσεων σε Java (το CFR Java decompiler χρησιμοποιείται για το τελευταίο) και τέλος δημιουργία και υπογραφή του επιδιορθωμένου APK μόλις τελειώσετε.
Ας ρίξουμε μια ματιά σε ένα παράδειγμα (σε Linux):
Εγκαταστήστε τα σενάρια 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.
Διαμορφώστε τα σενάρια DexPatcher
Ανοιξε dxp.config στον αγαπημένο σας επεξεργαστή κειμένου και φροντίστε να αλλάξετε τις απαραίτητες μεταβλητές ώστε να ταιριάζουν στο σύστημά σας. Χρειάζεται μόνο να αλλάξετε την ακόλουθη γραμμή για να δείχνει τη θέση εγκατάστασης του Android SDK σας:
dxp_android_sdk_dir=(~/android/sdk)
(Το DexPatcher θα επιλέξει αυτόματα την υψηλότερη διαθέσιμη έκδοση πλατφόρμας. Επιπλέον, μπορείτε επίσης να τροποποιήσετε άλλες επιλογές διαμόρφωσης ώστε να χρησιμοποιεί τις δικές σας εκδόσεις ορισμένων εργαλείων αντί για τις προεπιλεγμένες ομαδοποιημένες.)
Για ευκολία πρόσβασης, μπορούμε να προσθέσουμε το αποστολέας κατάλογο στο δικό μας ΜΟΝΟΠΑΤΙ, ή ακόμα και να συνδυάσουν το διαφορετικό dxp-* σενάρια σε μια τοποθεσία που βρίσκεται ήδη στη δική σας ΜΟΝΟΠΑΤΙ, όπως ~/bin:
export PATH=$PWD:$PATH
Τροποποίηση μιας Εφαρμογής
Για αυτό το παράδειγμα, θα χρησιμοποιήσουμε μια απλή και ανοιχτού κώδικα εφαρμογή. Φυσικά, η άμεση επιδιόρθωση του πηγαίου κώδικα θα ήταν δυνατή στη συγκεκριμένη περίπτωση, αλλά αυτό δεν είναι καθόλου διασκεδαστικό!
Θα πάρουμε την εφαρμογή "Get ID" από το basil2style, μια εφαρμογή που σας δείχνει ορισμένες λεπτομέρειες σχετικά με τη συσκευή σας. Στόχος μας είναι να τροποποιήσουμε το κουμπί "Αντιγραφή" για το "Αναγνωριστικό συσκευής" και να μοιράζεται αυτό το αναγνωριστικό:
- Αρχικά, ας κατεβάσουμε το APK που πρόκειται να τροποποιήσουμε: Λάβετε ταυτότητα.
- Απομεταγλωττίστε την εφαρμογή.
- Δημιουργήστε το κλειδί υπογραφής που θα χρησιμοποιήσουμε αργότερα για να υπογράψουμε το APK.
Μπορούμε επίσης να τα κάνουμε όλα μέσω του κελύφους, χρησιμοποιώντας τα βοηθητικά σενάρια:
$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".
Θα παρατηρήσετε μερικούς διαφορετικούς καταλόγους εκεί:
- αποκρυπτογραφώ: θα βρείτε τους πόρους και το Smali εδώ, όπως αποκωδικοποιήθηκαν από apktool.
- src: Κενός κατάλογος. Εδώ θα τοποθετήσουμε τα αρχεία ενημέρωσης κώδικα.
- src-cfr: εδώ είναι που βλ απομεταγλώττιση της εφαρμογής (μαζί με σφάλματα). Είναι καλό να κοιτάξετε για να αποφασίσετε τι να αλλάξετε (ενδέχεται επίσης να χρειάζεστε πόρους και τα αναγνωριστικά τους από τον παραπάνω κατάλογο αποκωδικοποίησης, αλλά όχι για αυτό το συγκεκριμένο παράδειγμα).
- src-cfr-κόμβος: ίδιο με το παραπάνω, αλλά περιέχει μόνο κενά στελέχη (χωρίς κωδικό, μόνο σκελετούς). Μπορείτε να χρησιμοποιήσετε αυτά τα αρχεία ως βάση για την ενημερωμένη έκδοση κώδικα, όπως θα δούμε σε λίγο.
Όπως έχουμε αναφέρει προηγουμένως, θέλουμε να αλλάξουμε το κουμπί "Αντιγραφή" του Αναγνωριστικού Συσκευής για κοινή χρήση του κειμένου αναγνωριστικού. Αν κοιτάξουμε γύρω από τον πηγαίο κώδικα, θα παρατηρήσουμε ότι το κουμπί Αντιγραφή αναγνωριστικού συσκευής (συσκευή_αντίγραφο) στο κλικ Το συμβάν διεκπεραιώνεται από ανώνυμη τάξη στο src-cfr/makeinfo/com/getid/MainActivity.java. Ενώ θα μπορούσαμε να το τροποποιήσουμε εδώ, είναι συνήθως καλύτερο να βρούμε έναν εναλλακτικό τρόπο για να το κάνουμε, καθώς οι ανώνυμες τάξεις έχουν αριθμητικά ονόματα (MainClassName$SomeNumber, π.χ. MainActivity$3) που ενδέχεται να αλλάξουν απρόβλεπτα μεταξύ των εκδόσεων.
Αντίθετα, θα καταχωρήσουμε τη δική μας τάξη για το συμβάν τροποποιώντας το Κύρια δραστηριότητα τάξη. Αρχικά, ας αντιγράψουμε την έκδοση "σκελετός" από src-cfr-nocode/makeinfo/com/getid/MainActivity.java προς την src/makeinfo/com/getid/MainActivity.java (να θυμάστε ότι src είναι όπου θα ζήσει το μπάλωμα μας). (Μπορείτε επίσης να αντιγράψετε την έκδοση με τον πλήρη κωδικό αν προτιμάτε, αυτό είναι καθαρά θέμα γούστου.)
Μπορούμε τώρα να το επεξεργαστούμε ως εξής:
- Προσθέστε την απαραίτητη εισαγωγή για τον σχολιασμό DexPatcher:
importlanchon.dexpatcher.annotation.*;
- Προσθέστε μια ετικέτα για να υποδείξετε ότι επεξεργαζόμαστε την τάξη. Ορίσαμε επίσης την προεπιλεγμένη ενέργεια για τα μέλη της κατηγορίας ενημέρωσης κώδικα ΑΓΝΟΩ, πράγμα που σημαίνει ότι τα μέλη είναι εκεί για να αναφέρονται από τον κώδικά μας κατά τη μεταγλώττιση Java, αλλά θα αγνοηθούν από το 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{
- Επιπλέον, προσθέστε κενά σώματα στον κατασκευαστή και onCreate μέθοδο, καθώς και όλες τις άλλες μεθόδους που σκοπεύουμε να χρησιμοποιήσουμε (θυμηθείτε ότι θα αγνοηθούν όταν εφαρμοστεί πραγματικά η ενημερωμένη έκδοση κώδικα -- απλώς τις προσθέτουμε για να μπορούμε να τις ανατρέξουμε εδώ αν χρειαστεί). Μπορείτε επίσης απλώς να προσθέσετε το ντόπιος λέξη-κλειδί αντί.
- Μπορούμε ήδη να δημιουργήσουμε το patch σε αυτό το σημείο, αν είστε περίεργοι:
$ dxp-make # Output: `patched.apk`.
Πολύ απλό, σωστά; Ας συνεχίσουμε, όμως -- δεν έχουμε τελειώσει ακόμα. - Ας επεξεργαστούμε onCreate τώρα για να ξεκινήσετε τη δική σας OnClickListener ώστε να μπορούμε να μοιραστούμε το αναγνωριστικό της συσκευής αντί να το αντιγράψουμε στο πρόχειρο:
// 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();}}}
- Φαίνεται ότι τελειώσαμε τώρα! Το πλήρες έμπλαστρο θα πρέπει να μοιάζει Αυτό. Μπορούμε τώρα να δημιουργήσουμε το διορθωμένο APK και να το εγκαταστήσουμε:
$ dxp-make$ adb install patched.apk
- Ας ρίξουμε μια ματιά στο αποτέλεσμα:
(Ευχαριστούμε τη Lanchon που βοήθησε με το δείγμα κώδικα!)
Το Xposed είναι εξαιρετικά δημοφιλές και για έναν καλό λόγο -- κάνει τη δημιουργία, την κοινή χρήση και την εγκατάσταση mods πολύ πιο απλή τόσο για προγραμματιστές όσο και για χρήστες. Υπάρχουν μερικές διαφορές μεταξύ του DexPatcher και του Xposed που μπορεί να κάνουν κάποιους να προτιμούν το ένα έναντι του άλλου:
- Το Xposed κάνει τα μαγικά του συνδέοντας μεθόδους κατά το χρόνο εκτέλεσης και επιτρέποντας στους προγραμματιστές να κάνουν κάτι πριν, μετά ή αντί για οποιαδήποτε μέθοδο. Το DexPatcher, από την άλλη πλευρά, τροποποιεί τα πάντα πριν από το χρόνο εκτέλεσης και παράγει ένα αυτόνομο, τροποποιημένο APK -- Η εκτέλεση κώδικα πριν, μετά ή αντί των μεθόδων είναι ακόμα δυνατή και στην πραγματικότητα έχετε κάποια επιπλέον ελευθερία.
- Η δημιουργία ενός αυτόνομου APK σημαίνει ότι δεν εξαρτάται από κανένα εξωτερικό πλαίσιο. Αυτό σημαίνει επίσης ότι δεν απαιτείται root για την τροποποίηση εφαρμογών χρηστών.
- Εφόσον δημιουργήσατε ένα νέο APK με το DexPatcher, θα υπογραφεί διαφορετικά. Αυτό σημαίνει ότι οι χρήστες δεν μπορούν να λάβουν επίσημες ενημερώσεις από τον αρχικό συντάκτη και ενδέχεται να προκληθούν ορισμένα προβλήματα με εφαρμογές όπως το Google Apps, εάν ελεγχθούν οι υπογραφές.
- Ο πηγαίος κώδικας και των δύο μονάδων και των ενημερώσεων κώδικα του DexPatcher μπορεί εύκολα να διανεμηθεί και να τροποποιηθεί. Μοιράζονται επίσης πολλές ομοιότητες, αν εξοικειωθείτε λίγο με το καθένα.
Έχουμε μιλήσει αρκετά για το DexPatcher. Είναι η σειρά σας να το δοκιμάσετε τώρα, οπότε κατευθυνθείτε προς το Νήμα φόρουμ DexPatcher για να ξεκινήσετε αμέσως!