Introduction to x64
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Εισαγωγή στο x64
x64, γνωστό και ως x86-64, είναι μια αρχιτεκτονική επεξεργαστή 64-bit που χρησιμοποιείται κυρίως σε υπολογιστές και διακομιστές. Προέρχεται από την αρχιτεκτονική x86 που παράγεται από την Intel και αργότερα υιοθετήθηκε από την AMD με την ονομασία AMD64, είναι η κυρίαρχη αρχιτεκτονική στους προσωπικούς υπολογιστές και τους διακομιστές σήμερα.
Καταχωρητές
x64 επεκτείνει την αρχιτεκτονική x86, διαθέτοντας 16 γενικούς καταχωρητές που φέρουν τις ετικέτες rax
, rbx
, rcx
, rdx
, rbp
, rsp
, rsi
, rdi
, και r8
έως r15
. Κάθε ένας από αυτούς μπορεί να αποθηκεύσει μια 64-bit (8-byte) τιμή. Αυτοί οι καταχωρητές διαθέτουν επίσης υποκαταχωρητές 32-bit, 16-bit και 8-bit για συμβατότητα και συγκεκριμένες εργασίες.
rax
- Παραδοσιακά χρησιμοποιείται για τιμές επιστροφής από συναρτήσεις.rbx
- Συχνά χρησιμοποιείται ως βασικός καταχωρητής για λειτουργίες μνήμης.rcx
- Συνήθως χρησιμοποιείται για μετρητές βρόχων.rdx
- Χρησιμοποιείται σε διάφορους ρόλους, συμπεριλαμβανομένων των επεκτεινόμενων αριθμητικών λειτουργιών.rbp
- Βασικός δείκτης για το πλαίσιο της στοίβας.rsp
- Δείκτης στοίβας, παρακολουθεί την κορυφή της στοίβας.rsi
καιrdi
- Χρησιμοποιούνται για δείκτες πηγής και προορισμού σε λειτουργίες συμβολοσειρών/μνήμης.r8
έωςr15
- Πρόσθετοι γενικοί καταχωρητές που εισήχθησαν στο x64.
Σύμβαση Κλήσης
Η σύμβαση κλήσης x64 διαφέρει μεταξύ των λειτουργικών συστημάτων. Για παράδειγμα:
Windows: Οι πρώτες τέσσερις παράμετροι μεταφέρονται στους καταχωρητές
rcx
,rdx
,r8
, καιr9
. Οι περαιτέρω παράμετροι τοποθετούνται στη στοίβα. Η τιμή επιστροφής είναι στονrax
.System V (συνήθως χρησιμοποιούμενη σε συστήματα τύπου UNIX): Οι πρώτες έξι παραμέτρους ακέραιων ή δεικτών μεταφέρονται στους καταχωρητές
rdi
,rsi
,rdx
,rcx
,r8
, καιr9
. Η τιμή επιστροφής είναι επίσης στονrax
.
Εάν η συνάρτηση έχει περισσότερες από έξι εισόδους, οι υπόλοιπες θα μεταφερθούν στη στοίβα. RSP, ο δείκτης στοίβας, πρέπει να είναι ευθυγραμμισμένος στα 16 bytes, που σημαίνει ότι η διεύθυνση στην οποία δείχνει πρέπει να είναι διαιρετή του 16 πριν από οποιαδήποτε κλήση. Αυτό σημαίνει ότι κανονικά θα πρέπει να διασφαλίσουμε ότι το RSP είναι σωστά ευθυγραμμισμένο στον κώδικα μας πριν κάνουμε μια κλήση συνάρτησης. Ωστόσο, στην πράξη, οι κλήσεις συστήματος λειτουργούν πολλές φορές ακόμη και αν αυτή η απαίτηση δεν πληρούται.
Σύμβαση Κλήσης στο Swift
Το Swift έχει τη δική του σύμβαση κλήσης που μπορεί να βρεθεί στο https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#x86-64
Κοινές Εντολές
Οι εντολές x64 διαθέτουν ένα πλούσιο σύνολο, διατηρώντας τη συμβατότητα με τις προηγούμενες εντολές x86 και εισάγοντας νέες.
mov
: Μεταφορά μιας τιμής από έναν καταχωρητή ή θέση μνήμης σε άλλη.Παράδειγμα:
mov rax, rbx
— Μεταφέρει την τιμή απόrbx
στοrax
.push
καιpop
: Πιέστε ή αφαιρέστε τιμές από/στην στοίβα.Παράδειγμα:
push rax
— Πιέζει την τιμή στοrax
στη στοίβα.Παράδειγμα:
pop rax
— Αφαιρεί την κορυφαία τιμή από τη στοίβα στοrax
.add
καιsub
: Λειτουργίες πρόσθεσης και αφαίρεσης.Παράδειγμα:
add rax, rcx
— Προσθέτει τις τιμές στοrax
καιrcx
, αποθηκεύοντας το αποτέλεσμα στοrax
.mul
καιdiv
: Λειτουργίες πολλαπλασιασμού και διαίρεσης. Σημείωση: αυτές έχουν συγκεκριμένες συμπεριφορές σχετικά με τη χρήση των τελεστών.call
καιret
: Χρησιμοποιούνται για κλήση και επιστροφή από συναρτήσεις.int
: Χρησιμοποιείται για να προκαλέσει μια διακοπή λογισμικού. Π.χ.,int 0x80
χρησιμοποιήθηκε για κλήσεις συστήματος σε 32-bit x86 Linux.cmp
: Συγκρίνει δύο τιμές και ρυθμίζει τις σημαίες της CPU με βάση το αποτέλεσμα.Παράδειγμα:
cmp rax, rdx
— Συγκρίνει τοrax
με τοrdx
.je
,jne
,jl
,jge
, ...: Συνθήκες άλματος που αλλάζουν τη ροή ελέγχου με βάση τα αποτελέσματα μιας προηγούμενης εντολήςcmp
ή test.Παράδειγμα: Μετά από μια εντολή
cmp rax, rdx
,je label
— Πηδάει στοlabel
αν τοrax
είναι ίσο με τοrdx
.syscall
: Χρησιμοποιείται για κλήσεις συστήματος σε ορισμένα συστήματα x64 (όπως οι σύγχρονες Unix).sysenter
: Μια βελτιστοποιημένη εντολή κλήσης συστήματος σε ορισμένες πλατφόρμες.
Πρόλογος Συνάρτησης
Πιέστε τον παλιό βασικό δείκτη:
push rbp
(αποθηκεύει τον βασικό δείκτη του καλούντος)Μεταφέρετε τον τρέχοντα δείκτη στοίβας στον βασικό δείκτη:
mov rbp, rsp
(ρυθμίζει τον νέο βασικό δείκτη για την τρέχουσα συνάρτηση)Δημιουργήστε χώρο στη στοίβα για τοπικές μεταβλητές:
sub rsp, <size>
(όπου<size>
είναι ο αριθμός των bytes που χρειάζονται)
Επίλογος Συνάρτησης
Μεταφέρετε τον τρέχοντα βασικό δείκτη στον δείκτη στοίβας:
mov rsp, rbp
(απελευθερώνει τις τοπικές μεταβλητές)Αφαιρέστε τον παλιό βασικό δείκτη από τη στοίβα:
pop rbp
(αποκαθιστά τον βασικό δείκτη του καλούντος)Επιστροφή:
ret
(επιστρέφει τον έλεγχο στον καλούντα)
macOS
syscalls
Υπάρχουν διαφορετικές κατηγορίες syscalls, μπορείτε να τις βρείτε εδώ:
Τότε, μπορείτε να βρείτε κάθε αριθμό syscall σε αυτή τη διεύθυνση:
Έτσι, για να καλέσετε το open
syscall (5) από την Unix/BSD class πρέπει να το προσθέσετε: 0x2000000
Έτσι, ο αριθμός syscall για να καλέσετε το open θα ήταν 0x2000005
Shellcodes
Για να το μεταγλωττίσετε:
Για να εξαγάγετε τα bytes:
Last updated