165 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Smali - Decompiling/\[Modifying]/Compiling
{{#include ../../banners/hacktricks-training.md}}
Μερικές φορές είναι ενδιαφέρον να τροποποιήσετε τον κώδικα της εφαρμογής για να αποκτήσετε πρόσβαση σε κρυφές πληροφορίες (ίσως καλά κρυμμένους κωδικούς ή σημαίες). Τότε, θα μπορούσε να είναι ενδιαφέρον να αποσυμπιέσετε το apk, να τροποποιήσετε τον κώδικα και να τον ξανασυμπιέσετε.
**Opcodes reference:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html)
## Fast Way
Χρησιμοποιώντας το **Visual Studio Code** και την επέκταση [APKLab](https://github.com/APKLab/APKLab), μπορείτε να **αποσυμπιέσετε αυτόματα**, να τροποποιήσετε, **να ξανασυμπιέσετε**, να υπογράψετε και να εγκαταστήσετε την εφαρμογή χωρίς να εκτελέσετε καμία εντολή.
Ένα άλλο **script** που διευκολύνει πολύ αυτή την εργασία είναι [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)
## Decompile the APK
Χρησιμοποιώντας το APKTool μπορείτε να αποκτήσετε πρόσβαση στον **κώδικα smali και τους πόρους**:
```bash
apktool d APP.apk
```
Αν το **apktool** σας δώσει κάποιο σφάλμα, προσπαθήστε να [εγκαταστήσετε την **τελευταία έκδοση**](https://ibotpeaches.github.io/Apktool/install/)
Ορισμένα **ενδιαφέροντα αρχεία που θα πρέπει να εξετάσετε είναι**:
- _res/values/strings.xml_ (και όλα τα xml μέσα στο res/values/\*)
- _AndroidManifest.xml_
- Οποιοδήποτε αρχείο με κατάληξη _.sqlite_ ή _.db_
Αν το `apktool` έχει **προβλήματα στην αποκωδικοποίηση της εφαρμογής**, ρίξτε μια ματιά στο [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) ή προσπαθήστε να χρησιμοποιήσετε το επιχείρημα **`-r`** (Μην αποκωδικοποιείτε τους πόρους). Στη συνέχεια, αν το πρόβλημα ήταν σε έναν πόρο και όχι στον πηγαίο κώδικα, δεν θα έχετε το πρόβλημα (δεν θα αποκωδικοποιήσετε επίσης τους πόρους).
## Αλλαγή κώδικα smali
Μπορείτε να **αλλάξετε** **εντολές**, να αλλάξετε την **τιμή** ορισμένων μεταβλητών ή να **προσθέσετε** νέες εντολές. Αλλάζω τον κώδικα Smali χρησιμοποιώντας [**VS Code**](https://code.visualstudio.com), στη συνέχεια εγκαθιστάτε την **επέκταση smalise** και ο επεξεργαστής θα σας πει αν κάποια **εντολή είναι λανθασμένη**.\
Ορισμένα **παραδείγματα** μπορούν να βρεθούν εδώ:
- [Παραδείγματα αλλαγών Smali](smali-changes.md)
- [Google CTF 2018 - Shall We Play a Game?](google-ctf-2018-shall-we-play-a-game.md)
Ή μπορείτε να [**ελέγξετε παρακάτω μερικές εξηγήσεις αλλαγών Smali**](smali-changes.md#modifying-smali).
## Ανακατασκευή του APK
Αφού τροποποιήσετε τον κώδικα, μπορείτε να **ανακατασκευάσετε** τον κώδικα χρησιμοποιώντας:
```bash
apktool b . #In the folder generated when you decompiled the application
```
Θα **συγκεντρώσει** το νέο APK **μέσα** στον _**φάκελο dist**_.
Αν το **apktool** ρίξει ένα **σφάλμα**, δοκιμάστε[ να εγκαταστήσετε την **τελευταία έκδοση**](https://ibotpeaches.github.io/Apktool/install/)
### **Υπογράψτε το νέο APK**
Στη συνέχεια, πρέπει να **δημιουργήσετε ένα κλειδί** (θα σας ζητηθεί ένας κωδικός πρόσβασης και κάποιες πληροφορίες που μπορείτε να συμπληρώσετε τυχαία):
```bash
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
```
Τέλος, **υπογράψτε** το νέο APK:
```bash
jarsigner -keystore key.jks path/to/dist/* <your-alias>
```
### Βελτιστοποίηση νέας εφαρμογής
**zipalign** είναι ένα εργαλείο ευθυγράμμισης αρχείων που παρέχει σημαντική βελτιστοποίηση στα αρχεία εφαρμογών Android (APK). [More information here](https://developer.android.com/studio/command-line/zipalign).
```bash
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk
```
### **Υπογράψτε το νέο APK (ξανά;)**
Αν **προτιμάτε** να χρησιμοποιήσετε [**apksigner**](https://developer.android.com/studio/command-line/) αντί για jarsigner, **πρέπει να υπογράψετε το apk** μετά την εφαρμογή **της βελτιστοποίησης με** zipalign. ΑΛΛΑ ΠΡΟΣΟΧΗ ΟΤΙ ΠΡΕΠΕΙ ΝΑ **ΥΠΟΓΡΑΨΕΤΕ ΤΗΝ ΕΦΑΡΜΟΓΗ ΜΙΑ ΦΟΡΑ ΜΟΝΟ** ΜΕ jarsigner (πριν το zipalign) Ή ΜΕ aspsigner (μετά το zipalign).
```bash
apksigner sign --ks key.jks ./dist/mycompiled.apk
```
## Τροποποίηση Smali
Για τον παρακάτω κώδικα Hello World Java:
```java
public static void printHelloWorld() {
System.out.println("Hello World")
}
```
Ο κώδικας Smali θα είναι:
```java
.method public static printHelloWorld()V
.registers 2
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World"
invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void
.end method
```
Το σύνολο εντολών Smali είναι διαθέσιμο [εδώ](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions).
### Ελαφρές Αλλαγές
### Τροποποίηση αρχικών τιμών μιας μεταβλητής μέσα σε μια συνάρτηση
Ορισμένες μεταβλητές ορίζονται στην αρχή της συνάρτησης χρησιμοποιώντας την εντολή _const_, μπορείτε να τροποποιήσετε τις τιμές τους ή να ορίσετε νέες:
```bash
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"
```
### Βασικές Λειτουργίες
```bash
#Math
add-int/lit8 v0, v2, 0x1 #v2 + 0x1 and save it in v0
mul-int v0,v2,0x2 #v2*0x2 and save in v0
#Move the value of one object into another
move v1,v2
#Condtions
if-ge #Greater or equals
if-le #Less or equals
if-eq #Equals
#Get/Save attributes of an object
iget v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save this.o inside v0
iput v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save v0 inside this.o
#goto
:goto_6 #Declare this where you want to start a loop
if-ne v0, v9, :goto_6 #If not equals, go to: :goto_6
goto :goto_6 #Always go to: :goto_6
```
### Μεγαλύτερες Αλλαγές
### Καταγραφή
```bash
#Log win: <number>
iget v5, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Get this.o inside v5
invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; #Transform number to String
move-result-object v1 #Move to v1
const-string v5, "wins" #Save "win" inside v5
invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #Logging "Wins: <num>"
```
Συστάσεις:
- Αν πρόκειται να χρησιμοποιήσετε δηλωμένες μεταβλητές μέσα στη συνάρτηση (δηλωμένες v0,v1,v2...) τοποθετήστε αυτές τις γραμμές μεταξύ του _.local \<number>_ και των δηλώσεων των μεταβλητών (_const v0, 0x1_)
- Αν θέλετε να τοποθετήσετε τον κώδικα καταγραφής στη μέση του κώδικα μιας συνάρτησης:
- Προσθέστε 2 στον αριθμό των δηλωμένων μεταβλητών: Π.χ.: από _.locals 10_ σε _.locals 12_
- Οι νέες μεταβλητές θα πρέπει να είναι οι επόμενοι αριθμοί των ήδη δηλωμένων μεταβλητών (σε αυτό το παράδειγμα θα πρέπει να είναι _v10_ και _v11_, θυμηθείτε ότι ξεκινά από v0).
- Αλλάξτε τον κώδικα της συνάρτησης καταγραφής και χρησιμοποιήστε _v10_ και _v11_ αντί για _v5_ και _v1_.
### Toasting
Θυμηθείτε να προσθέσετε 3 στον αριθμό των _.locals_ στην αρχή της συνάρτησης.
Αυτός ο κώδικας είναι έτοιμος να εισαχθεί στη **μέση μιας συνάρτησης** (**αλλάξτε** τον αριθμό των **μεταβλητών** όπως απαιτείται). Θα πάρει την **τιμή του this.o**, θα την **μετατρέψει** σε **String** και στη συνέχεια θα **δημιουργήσει** ένα **toast** με την τιμή του.
```bash
const/4 v10, 0x1
const/4 v11, 0x1
const/4 v12, 0x1
iget v10, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I
invoke-static {v10}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v11
invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v12
invoke-virtual {v12}, Landroid/widget/Toast;->show()V
```
{{#include ../../banners/hacktricks-training.md}}