macOS Dyld Process
Βασικές Πληροφορίες
Το πραγματικό σημείο εισόδου ενός δυαδικού Mach-o είναι το δυναμικά συνδεδεμένο, που ορίζεται στο LC_LOAD_DYLINKER
και συνήθως είναι /usr/lib/dyld
.
Αυτός ο συνδέστης θα πρέπει να εντοπίσει όλες τις βιβλιοθήκες εκτελέσιμων αρχείων, να τις χαρτογραφήσει στη μνήμη και να συνδέσει όλες τις μη-τεμπέλικες βιβλιοθήκες. Μόνο μετά από αυτήν τη διαδικασία, θα εκτελεστεί το σημείο εισόδου του δυαδικού.
Φυσικά, το dyld
δεν έχει καμία εξάρτηση (χρησιμοποιεί κλήσεις συστήματος και αποσπάσματα libSystem).
Αν αυτός ο συνδέστης περιέχει κάποια ευπάθεια, καθώς εκτελείται πριν από την εκτέλεση οποιουδήποτε δυαδικού (ακόμα και υψηλά προνομιούχων), θα ήταν δυνατή η ανάδειξη προνομίων.
Ροή
Το Dyld θα φορτωθεί από το dyldboostrap::start
, το οποίο θα φορτώσει επίσης πράγματα όπως το stack canary. Αυτό συμβαίνει επειδή αυτή η λειτουργία θα λάβει στο διάνυσμά της apple
αυτή και άλλες ευαίσθητες τιμές.
Το dyls::_main()
είναι το σημείο εισόδου του dyld και η πρώτη του εργασία είναι να εκτελέσει το configureProcessRestrictions()
, το οποίο συνήθως περιορίζει τις DYLD_*
μεταβλητές περιβάλλοντος που εξηγούνται στο:
Στη συνέχεια, χαρτογραφεί την κοινόχρηστη προσωρινή μνήμη dyld που προ-συνδέει όλες τις σημαντικές βιβλιοθήκες συστήματος και στη συνέχεια χαρτογραφεί τις βιβλιοθήκες στις οποίες εξαρτάται το δυαδικό και συνεχίζει αναδρομικά μέχρι να φορτωθούν όλες οι απαιτούμενες βιβλιοθήκες. Συνεπώς:
ξεκινά τη φόρτωση εισαγόμενων βιβλιοθηκών με το
DYLD_INSERT_LIBRARIES
(εάν επιτρέπεται)Στη συνέχεια οι κοινόχρηστες προσωρινές μνήμες
Στη συνέχεια οι εισαγόμενες
Στη συνέχεια συνεχίζει την εισαγωγή βιβλιοθηκών αναδρομικά
Μόλις φορτωθούν όλα, εκτελούνται οι αρχικοποιητές αυτών των βιβλιοθηκών. Αυτοί κωδικοποιούνται χρησιμοποιώντας το __attribute__((constructor))
που ορίζεται στο LC_ROUTINES[_64]
(πλέον αποσυρμένο) ή με δείκτη σε ενότητα με σημαία S_MOD_INIT_FUNC_POINTERS
(συνήθως: __DATA.__MOD_INIT_FUNC
).
Οι τερματοφόροι κωδικοποιούνται με __attribute__((destructor))
και βρίσκονται σε μια ενότητα με σημαία S_MOD_TERM_FUNC_POINTERS
(__DATA.__mod_term_func
).
Αντικείμενα
Όλα τα δυαδικά στο macOS είναι δυναμικά συνδεδεμένα. Συνεπώς, περιέχουν ορισμένες ενότητες stubs που βοηθούν το δυαδικό να μεταβεί στον σωστό κώδικα σε διαφορετικές μηχανές και πλαίσια. Είναι το dyld όταν εκτελείται το δυαδικό το μυαλό που πρέπει να επιλύσει αυτές τις διευθύνσεις (τουλάχιστον τις μη-τεμπέλικες).
Ορισμένες ενότητες stubs στο δυαδικό:
__TEXT.__[auth_]stubs
: Δείκτες από ενότητες__DATA
__TEXT.__stub_helper
: Μικρός κώδικας που καλεί δυναμική σύνδεση με πληροφορίες για τη συνάρτηση προς κλήση__DATA.__[auth_]got
: Πίνακας Παγίων Τιμών (διευθύνσεις σε εισαγόμενες συναρτήσεις, όταν επιλυθούν, (δεσμευμένες κατά τη φόρτωση καθώς είναι σημειωμένες με τη σημαίαS_NON_LAZY_SYMBOL_POINTERS
)__DATA.__nl_symbol_ptr
: Δείκτες μη-τεμπέλικων συμβόλων (δεσμευμένοι κατά τη φόρτωση καθώς είναι σημειωμένοι με τη σημαίαS_NON_LAZY_SYMBOL_POINTERS
)__DATA.__la_symbol_ptr
: Δείκτες τεμπέλικων συμβόλων (δεσμευμένοι κατά την πρώτη πρόσβαση)
Σημειώστε ότι οι δείκτες με το πρόθεμα "auth_" χρησιμοποιούν ένα κλειδί κρυπτογράφησης σε διαδικασία για προστασία (PAC). Επιπλέον, είναι δυνατόν να χρησιμοποιηθεί η εντολή arm64 BLRA[A/B]
για να επαληθευτεί ο δείκτης πριν ακολουθηθεί. Και το RETA[A/B] μπορεί να χρησιμοποιηθεί αντί για μια διεύθυνση RET.
Πράγματι, ο κώδικας στο __TEXT.__auth_stubs
θα χρησιμοποιήσει braa
αντί για bl
για να καλέσει την απαιτούμενη συνάρτηση για την επαλήθευση του δείκτη.
Επίσης, σημειώστε ότι οι τρέχουσες εκδόσεις dyld φορτώνουν όλα ως μη-τεμπέλικα.
Εύρεση τεμπέλικων συμβόλων
Ενδιαφέρουσα μεταφρασμένη μερίδα:
Είναι δυνατόν να δούμε ότι το άλμα προς το κάλεσμα της printf πηγαίνει στο __TEXT.__stubs
:
Στην αποσυναρμολόγηση της ενότητας __stubs
:
Μπορείτε να δείτε ότι αλλάζουμε στη διεύθυνση του GOT, η οποία σε αυτήν την περίπτωση επιλύεται μη-τεμπέλικα και θα περιέχει τη διεύθυνση της συνάρτησης printf.
Σε άλλες καταστάσεις αντί να αλλάξει απευθείας στο GOT, θα μπορούσε να αλλάξει στο __DATA.__la_symbol_ptr
το οποίο θα φορτώσει μια τιμή που αντιπροσωπεύει τη συνάρτηση που προσπαθεί να φορτώσει, στη συνέχεια θα αλλάξει στο __TEXT.__stub_helper
το οποίο αλλάζει το __DATA.__nl_symbol_ptr
που περιέχει τη διεύθυνση του dyld_stub_binder
το οποίο παίρνει ως παραμέτρους τον αριθμό της συνάρτησης και μια διεύθυνση.
Αυτή η τελευταία συνάρτηση, μετά τον εντοπισμό της διεύθυνσης της αναζητούμενης συνάρτησης, τη γράφει στην αντίστοιχη θέση στο __TEXT.__stub_helper
για να αποφευχθούν μελλοντικές αναζητήσεις.
Ωστόσο, παρατηρήστε ότι οι τρέχουσες εκδόσεις dyld φορτώνουν όλα τα πράγματα ως μη-τεμπέλικα.
Οδηγίες Dyld
Τέλος, το dyld_stub_binder
χρειάζεται να βρει την υποδειγμένη συνάρτηση και να τη γράψει στη σωστή διεύθυνση για να μην την αναζητήσει ξανά. Για να το κάνει αυτό χρησιμοποιεί οδηγίες (ένα πεπερασμένο αυτόματο κατάστασης) μέσα στο dyld.
apple[] argument vector
Στο macOS η κύρια συνάρτηση λαμβάνει πραγματικά 4 ορίσματα αντί για 3. Το τέταρτο ονομάζεται apple και κάθε καταχώρηση είναι στη μορφή key=value
. Για παράδειγμα:
Μέχρι τη στιγμή που αυτές οι τιμές φτάνουν στην κύρια συνάρτηση, έχει ήδη αφαιρεθεί από αυτές ευαίσθητη πληροφορία ή θα μπορούσε να οδηγήσει σε διαρροή δεδομένων.
είναι δυνατόν να δείτε όλες αυτές τις ενδιαφέρουσες τιμές αποσφαλματώντας πριν μπείτε στην κύρια με:
dyld_all_image_infos
Αυτή είναι μια δομή που εξάγεται από το dyld με πληροφορίες σχετικά με την κατάσταση του dyld που μπορεί να βρεθεί στο source code με πληροφορίες όπως η έκδοση, δείκτης προς τον πίνακα dyld_image_info, προς τον dyld_image_notifier, αν η διαδικασία έχει αποσυνδεθεί από την κοινόχρηστη μνήμη, αν έχει κληθεί ο αρχικοποιητής του libSystem, δείκτης προς τη δική Mach κεφαλίδα του dyld, δείκτης προς τη συμβολοσειρά έκδοσης του dyld...
dyld μεταβλητές περιβάλλοντος
αποσφαλμάτωση dyld
Ενδιαφέρουσες μεταβλητές περιβάλλοντος που βοηθούν στην κατανόηση του τι κάνει το dyld:
DYLD_PRINT_LIBRARIES
Ελέγξτε κάθε βιβλιοθήκη που φορτώνεται:
DYLD_PRINT_SEGMENTS
Ελέγξτε πώς φορτώνεται κάθε βιβλιοθήκη:
DYLD_PRINT_INITIALIZERS
Εκτύπωση όταν εκτελείται κάθε αρχικοποιητής βιβλιοθήκης:
Άλλα
DYLD_BIND_AT_LAUNCH
: Οι lazy δεσμεύσεις επιλύονται με μη-αδράDYLD_DISABLE_PREFETCH
: Απενεργοποίηση προ-φόρτωσης περιεχομένων __DATA και __LINKEDITDYLD_FORCE_FLAT_NAMESPACE
: Δεσμεύσεις μονού επιπέδουDYLD_[FRAMEWORK/LIBRARY]_PATH | DYLD_FALLBACK_[FRAMEWORK/LIBRARY]_PATH | DYLD_VERSIONED_[FRAMEWORK/LIBRARY]_PATH
: Διαδρομές ανάλυσηςDYLD_INSERT_LIBRARIES
: Φόρτωση μιας συγκεκριμένης βιβλιοθήκηςDYLD_PRINT_TO_FILE
: Εγγραφή αποσφαλμάτωσης dyld σε ένα αρχείοDYLD_PRINT_APIS
: Εκτύπωση κλήσεων API libdyldDYLD_PRINT_APIS_APP
: Εκτύπωση κλήσεων API libdyld που πραγματοποιούνται από το mainDYLD_PRINT_BINDINGS
: Εκτύπωση συμβόλων όταν δεσμεύονταιDYLD_WEAK_BINDINGS
: Εκτύπωση μόνο αδύναμων συμβόλων όταν δεσμεύονταιDYLD_PRINT_CODE_SIGNATURES
: Εκτύπωση λειτουργιών εγγραφής υπογραφής κώδικαDYLD_PRINT_DOFS
: Εκτύπωση τμημάτων μορφής αντικειμένου D-Trace όπως φορτώνονταιDYLD_PRINT_ENV
: Εκτύπωση περιβάλλοντος που βλέπει το dyldDYLD_PRINT_INTERPOSTING
: Εκτύπωση λειτουργιών ενδιάθεσηςDYLD_PRINT_LIBRARIES
: Εκτύπωση φορτωμένων βιβλιοθηκώνDYLD_PRINT_OPTS
: Εκτύπωση επιλογών φόρτωσηςDYLD_REBASING
: Εκτύπωση λειτουργιών επαντοποίησης συμβόλωνDYLD_RPATHS
: Εκτύπωση επεκτάσεων @rpathDYLD_PRINT_SEGMENTS
: Εκτύπωση αντιστοιχίσεων τμημάτων Mach-ODYLD_PRINT_STATISTICS
: Εκτύπωση στατιστικών χρονομέτρησηςDYLD_PRINT_STATISTICS_DETAILS
: Εκτύπωση λεπτομερών στατιστικών χρονομέτρησηςDYLD_PRINT_WARNINGS
: Εκτύπωση μηνυμάτων προειδοποίησηςDYLD_SHARED_CACHE_DIR
: Διαδρομή για χρήση κοινής βιβλιοθήκης cacheDYLD_SHARED_REGION
: "χρήση", "ιδιωτικό", "αποφυγή"DYLD_USE_CLOSURES
: Ενεργοποίηση κλεισιμάτων
Είναι δυνατόν να βρείτε περισσότερα με κάτι σαν:
Ή κατεβάστε το έργο dyld από https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz και εκτελέστε μέσα στον φάκελο:
Αναφορές
Last updated