Πώς να δείτε μέσα σε δυαδικά αρχεία από τη γραμμή εντολών του Linux

Έχετε ένα αρχείο μυστηρίου; Η εντολή αρχείου Linux θα σας πει γρήγορα τι είδους αρχείο είναι. Αν είναι δυαδικό αρχείο, ωστόσο, μπορείτε να μάθετε περισσότερα για αυτό. αρχείο έχει μια ολόκληρη σειρά από σταθερούς που θα σας βοηθήσουν να το αναλύσετε. Θα σας δείξουμε πώς να χρησιμοποιήσετε μερικά από αυτά τα εργαλεία.

Προσδιορισμός τύπων αρχείων

Τα αρχεία συνήθως έχουν χαρακτηριστικά που επιτρέπουν στα πακέτα λογισμικού να προσδιορίζουν ποιος τύπος αρχείου είναι, καθώς και τι αντιπροσωπεύουν τα δεδομένα μέσα σε αυτό. Δεν θα είχε νόημα να προσπαθήσετε να ανοίξετε ένα αρχείο PNG σε μια συσκευή αναπαραγωγής μουσικής MP3, επομένως είναι χρήσιμο και ρεαλιστικό ένα αρχείο να φέρει μαζί του κάποια μορφή αναγνωριστικού.

Αυτά μπορεί να είναι μερικά byte υπογραφής στην αρχή του αρχείου. Αυτό επιτρέπει σε ένα αρχείο να είναι ξεκάθαρο σχετικά με τη μορφή και το περιεχόμενό του. Μερικές φορές, ο τύπος αρχείου συνάγεται από μια διακριτική πτυχή της εσωτερικής οργάνωσης των ίδιων των δεδομένων, γνωστή ως αρχιτεκτονική αρχείου.

Ορισμένα λειτουργικά συστήματα, όπως τα Windows, καθοδηγούνται πλήρως από την επέκταση ενός αρχείου. Μπορείτε να το ονομάσετε ευκολόπιστο ή αξιόπιστο, αλλά τα Windows υποθέτουν ότι οποιοδήποτε αρχείο με την επέκταση DOCX είναι πραγματικά ένα αρχείο επεξεργασίας κειμένου DOCX. Το Linux δεν είναι έτσι, όπως θα δείτε σύντομα. Θέλει αποδείξεις και ψάχνει μέσα στο αρχείο να το βρει.

Τα εργαλεία που περιγράφονται εδώ ήταν ήδη εγκατεστημένα στις διανομές Manjaro 20, Fedora 21 και Ubuntu 20.04 που χρησιμοποιήσαμε για την έρευνα αυτού του άρθρου. Ας ξεκινήσουμε την έρευνά μας χρησιμοποιώντας την εντολή αρχείου.

Χρησιμοποιώντας το αρχείο Command

Έχουμε μια συλλογή διαφορετικών τύπων αρχείων στον τρέχοντα κατάλογο μας. Είναι ένα μείγμα εγγράφων, πηγαίου κώδικα, εκτελέσιμων αρχείων και αρχείων κειμένου.

Η εντολή ls θα μας δείξει τι υπάρχει στον κατάλογο και η επιλογή -hl (μεγέθη αναγνώσιμα από τον άνθρωπο, μεγάλη λίστα) θα μας δείξει το μέγεθος κάθε αρχείου:

ls -hl

Ας δοκιμάσουμε να αρχειοθετήσουμε μερικά από αυτά και να δούμε τι παίρνουμε:

file build_instructions.odt
file build_instructions.pdf
file COBOL_Report_Apr60.djvu

Οι τρεις μορφές αρχείων προσδιορίζονται σωστά. Όπου είναι δυνατόν, το αρχείο μας δίνει περισσότερες πληροφορίες. Το αρχείο PDF αναφέρεται ότι βρίσκεται στο μορφή έκδοσης 1.5.

Ακόμα κι αν μετονομάσουμε το αρχείο ODT ώστε να έχει επέκταση με την αυθαίρετη τιμή XYZ, το αρχείο εξακολουθεί να αναγνωρίζεται σωστά, τόσο στο πρόγραμμα περιήγησης αρχείων Files όσο και στη γραμμή εντολών που χρησιμοποιεί το αρχείο.

Στο πρόγραμμα περιήγησης αρχείων Files, του δίνεται το σωστό εικονίδιο. Στη γραμμή εντολών, το αρχείο αγνοεί την επέκταση και αναζητά μέσα στο αρχείο για να προσδιορίσει τον τύπο του:

file build_instructions.xyz

Η χρήση αρχείου σε μέσα, όπως αρχεία εικόνας και μουσικής, συνήθως παρέχει πληροφορίες σχετικά με τη μορφή, την κωδικοποίηση, την ανάλυσή τους και ούτω καθεξής:

file screenshot.png
file screenshot.jpg
file Pachelbel_Canon_In_D.mp3

Είναι ενδιαφέρον ότι ακόμη και με αρχεία απλού κειμένου, το αρχείο δεν κρίνει το αρχείο από την επέκτασή του. Για παράδειγμα, εάν έχετε ένα αρχείο με την επέκταση “.c”, που περιέχει τυπικό απλό κείμενο αλλά όχι πηγαίο κώδικα, το αρχείο δεν το μπερδεύει με γνήσιο C αρχείο πηγαίου κώδικα:

file function+headers.h
file makefile
file hello.c

Το αρχείο προσδιορίζει σωστά το αρχείο κεφαλίδας (.h”) ως μέρος μιας συλλογής αρχείων πηγαίου κώδικα C και γνωρίζει ότι το αρχείο makefile είναι ένα σενάριο.

  Πώς να παρακολουθήσετε τα Twitch Streams χωρίς πρόγραμμα περιήγησης στο Linux

Χρήση αρχείου με δυαδικά αρχεία

Τα δυαδικά αρχεία είναι περισσότερο «μαύρο κουτί» από άλλα. Μπορούν να προβληθούν αρχεία εικόνας, να αναπαραχθούν αρχεία ήχου και να ανοίξουν αρχεία εγγράφων από το κατάλληλο πακέτο λογισμικού. Τα δυαδικά αρχεία, ωστόσο, είναι περισσότερο μια πρόκληση.

Για παράδειγμα, τα αρχεία “hello” και “wd” είναι δυαδικά εκτελέσιμα. Είναι προγράμματα. Το αρχείο που ονομάζεται “wd.o” είναι ένα αρχείο αντικειμένου. Όταν ο πηγαίος κώδικας μεταγλωττίζεται από έναν μεταγλωττιστή, δημιουργούνται ένα ή περισσότερα αρχεία αντικειμένων. Αυτά περιέχουν τον κωδικό μηχανής που θα εκτελέσει τελικά ο υπολογιστής όταν εκτελεστεί το ολοκληρωμένο πρόγραμμα, μαζί με πληροφορίες για το σύνδεσμο. Ο σύνδεσμος ελέγχει κάθε αρχείο αντικειμένου για κλήσεις συναρτήσεων σε βιβλιοθήκες. Τα συνδέει με οποιεσδήποτε βιβλιοθήκες χρησιμοποιεί το πρόγραμμα. Το αποτέλεσμα αυτής της διαδικασίας είναι ένα εκτελέσιμο αρχείο.

Το αρχείο “watch.exe” είναι ένα δυαδικό εκτελέσιμο αρχείο που έχει διασταυρωθεί για να εκτελεστεί στα Windows:

file wd
file wd.o
file hello
file watch.exe

Λαμβάνοντας πρώτα το τελευταίο, το αρχείο μας λέει ότι το αρχείο “watch.exe” είναι ένα εκτελέσιμο πρόγραμμα κονσόλας PE32+, για την οικογένεια επεξεργαστών x86 στα Microsoft Windows. Το PE σημαίνει φορητή εκτελέσιμη μορφή, που έχει εκδόσεις 32 και 64 bit. Το PE32 είναι η έκδοση 32-bit και το PE32+ είναι η έκδοση 64-bit.

Τα άλλα τρία αρχεία προσδιορίζονται όλα ως Μορφή εκτελέσιμη και συνδεόμενη αρχεία (ELF). Αυτό είναι ένα πρότυπο για εκτελέσιμα αρχεία και αρχεία κοινόχρηστων αντικειμένων, όπως βιβλιοθήκες. Θα ρίξουμε μια ματιά στη μορφή κεφαλίδας ELF σύντομα.

Αυτό που μπορεί να τραβήξει την προσοχή σας είναι ότι τα δύο εκτελέσιμα (“wd” και “hello”) προσδιορίζονται ως Τυπική βάση Linux (LSB) κοινόχρηστα αντικείμενα και το αρχείο αντικειμένου “wd.o” προσδιορίζεται ως LSB με δυνατότητα μετεγκατάστασης. Η λέξη εκτελέσιμο είναι προφανής ερήμην της.

Τα αρχεία αντικειμένων μπορούν να μετακινηθούν, πράγμα που σημαίνει ότι ο κώδικας μέσα σε αυτά μπορεί να φορτωθεί στη μνήμη σε οποιαδήποτε τοποθεσία. Τα εκτελέσιμα παρατίθενται ως κοινόχρηστα αντικείμενα επειδή έχουν δημιουργηθεί από τον σύνδεσμο από τα αρχεία αντικειμένων με τέτοιο τρόπο ώστε να κληρονομούν αυτή τη δυνατότητα.

Αυτό επιτρέπει την Τυχαιοποίηση διάταξης χώρου διεύθυνσης (ASMR) σύστημα για τη φόρτωση των εκτελέσιμων στη μνήμη στις διευθύνσεις της επιλογής του. Τα τυπικά εκτελέσιμα έχουν μια διεύθυνση φόρτωσης κωδικοποιημένη στις κεφαλίδες τους, η οποία υπαγορεύει πού θα φορτωθούν στη μνήμη.

Το ASMR είναι μια τεχνική ασφάλειας. Η φόρτωση εκτελέσιμων στη μνήμη σε προβλέψιμες διευθύνσεις τα καθιστά επιρρεπή σε επιθέσεις. Αυτό συμβαίνει επειδή τα σημεία εισόδου τους και οι θέσεις των λειτουργιών τους θα είναι πάντα γνωστά στους επιτιθέμενους. Θέση Ανεξάρτητων Εκτελεστών Το (PIE) τοποθετημένο σε τυχαία διεύθυνση ξεπερνά αυτή την ευαισθησία.

  Πώς να δοκιμάσετε την εναλλακτική λύση Firefox ανοιχτού κώδικα LibreWolf σε Linux

Αν εμείς να συντάξουμε το πρόγραμμά μας με τον μεταγλωττιστή gcc και παρέχοντας την επιλογή -no-pie, θα δημιουργήσουμε ένα συμβατικό εκτελέσιμο αρχείο.

Η επιλογή -o (αρχείο εξόδου) μας επιτρέπει να παρέχουμε ένα όνομα για το εκτελέσιμο αρχείο μας:

gcc -o hello -no-pie hello.c

Θα χρησιμοποιήσουμε το αρχείο στο νέο εκτελέσιμο αρχείο και θα δούμε τι έχει αλλάξει:

file hello

Το μέγεθος του εκτελέσιμου αρχείου είναι το ίδιο με πριν (17 KB):

ls -hl hello

Το δυαδικό αρχείο αναγνωρίζεται πλέον ως τυπικό εκτελέσιμο αρχείο. Το κάνουμε αυτό μόνο για λόγους επίδειξης. Εάν μεταγλωττίσετε εφαρμογές με αυτόν τον τρόπο, θα χάσετε όλα τα πλεονεκτήματα του ASMR.

Γιατί ένα εκτελέσιμο αρχείο είναι τόσο μεγάλο;

Το παράδειγμά μας hello είναι 17 KB, οπότε δύσκολα θα μπορούσε να ονομαστεί μεγάλο, αλλά τότε όλα είναι σχετικά. Ο πηγαίος κώδικας είναι 120 byte:

cat hello.c

Τι διογκώνει το δυαδικό αρχείο εάν το μόνο που κάνει είναι να εκτυπώσει μια συμβολοσειρά στο παράθυρο τερματικού; Γνωρίζουμε ότι υπάρχει μια κεφαλίδα ELF, αλλά έχει μήκος μόνο 64 byte για ένα δυαδικό αρχείο 64 bit. Προφανώς, πρέπει να είναι κάτι άλλο:

ls -hl hello

Ας σαρώστε το δυαδικό με το Η εντολή strings είναι ένα απλό πρώτο βήμα για να ανακαλύψετε τι υπάρχει μέσα της. Θα το βάλουμε σε λιγότερα:

strings hello | less

Υπάρχουν πολλές συμβολοσειρές μέσα στο δυαδικό αρχείο, εκτός από το “Hello, Geek world!” από τον πηγαίο κώδικα μας. Τα περισσότερα από αυτά είναι ετικέτες για περιοχές εντός του δυαδικού αρχείου και τα ονόματα και οι πληροφορίες σύνδεσης των κοινόχρηστων αντικειμένων. Αυτές περιλαμβάνουν τις βιβλιοθήκες και τις λειτουργίες μέσα σε αυτές τις βιβλιοθήκες, από τις οποίες εξαρτάται το δυαδικό.

ο εντολή ldd μας δείχνει τις κοινόχρηστες εξαρτήσεις αντικειμένων ενός δυαδικού:

ldd hello

Υπάρχουν τρεις εγγραφές στην έξοδο και δύο από αυτές περιλαμβάνουν μια διαδρομή καταλόγου (η πρώτη όχι):

linux-vdso.so: Εικονικό δυναμικό κοινόχρηστο αντικείμενο (VDSO) είναι ένας μηχανισμός πυρήνα που επιτρέπει την πρόσβαση σε ένα σύνολο ρουτινών kernel-space από ένα δυαδικό χώρο χρήστη. Αυτό αποφεύγει την επιβάρυνση ενός διακόπτη περιβάλλοντος από τη λειτουργία πυρήνα χρήστη. Τα κοινόχρηστα αντικείμενα VDSO προσκολλώνται στη μορφή εκτελέσιμη και συνδεόμενη μορφή (ELF), επιτρέποντάς τους να συνδέονται δυναμικά με το δυαδικό αρχείο κατά το χρόνο εκτέλεσης. Το VDSO εκχωρείται δυναμικά και εκμεταλλεύεται το ASMR. Η δυνατότητα VDSO παρέχεται από το πρότυπο Βιβλιοθήκη GNU C εάν ο πυρήνας υποστηρίζει το σχήμα ASMR.
libc.so.6: Το Βιβλιοθήκη GNU C κοινόχρηστο αντικείμενο.
/lib64/ld-linux-x86-64.so.2: Αυτός είναι ο δυναμικός σύνδεσμος που θέλει να χρησιμοποιήσει το δυαδικό. Ο δυναμικός σύνδεσμος ανακρίνει το δυαδικό για να ανακαλύψει τι εξαρτήσεις έχει. Εκκινεί αυτά τα κοινόχρηστα αντικείμενα στη μνήμη. Προετοιμάζει το δυαδικό να τρέξει και να μπορέσει να βρει και να αποκτήσει πρόσβαση στις εξαρτήσεις στη μνήμη. Στη συνέχεια, εκκινεί το πρόγραμμα.

Η κεφαλίδα ELF

Μπορούμε εξετάστε και αποκωδικοποιήστε την κεφαλίδα ELF χρησιμοποιώντας το βοηθητικό πρόγραμμα readelf και την επιλογή -h (κεφαλίδα αρχείου):

readelf -h hello

Η κεφαλίδα ερμηνεύεται για εμάς.

  Πώς να προσθέσετε και να αλλάξετε χρήστες στο υποσύστημα Windows για Linux

Το πρώτο byte όλων των δυαδικών αρχείων ELF έχει οριστεί σε δεκαεξαδική τιμή 0x7F. Τα επόμενα τρία byte ορίζονται σε 0x45, 0x4C και 0x46. Το πρώτο byte είναι μια σημαία που προσδιορίζει το αρχείο ως δυαδικό ELF. Για να γίνει αυτό πεντακάθαρο, τα επόμενα τρία byte γράφουν το “ELF”. ASCII:

Κλάση: Υποδεικνύει εάν το δυαδικό αρχείο είναι εκτελέσιμο 32 ή 64 bit (1=32, 2=64).
Δεδομένα: Υποδεικνύει το endianness σε χρήση. Η κωδικοποίηση Endian καθορίζει τον τρόπο με τον οποίο αποθηκεύονται οι αριθμοί πολλών byte. Στην κωδικοποίηση big-endian, ένας αριθμός αποθηκεύεται με πρώτα τα πιο σημαντικά bits του. Στην κωδικοποίηση μικρού endian, ο αριθμός αποθηκεύεται πρώτα με τα λιγότερο σημαντικά bits του.
Έκδοση: Η έκδοση του ELF (προς το παρόν είναι 1).
OS/ABI: Αντιπροσωπεύει τον τύπο του δυαδική διεπαφή εφαρμογής σε χρήση. Αυτό καθορίζει τη διεπαφή μεταξύ δύο δυαδικών μονάδων, όπως ένα πρόγραμμα και μια κοινόχρηστη βιβλιοθήκη.
Έκδοση ABI: Η έκδοση του ABI.
Τύπος: Ο τύπος του δυαδικού ELF. Οι κοινές τιμές είναι ET_REL για έναν πόρο με δυνατότητα επανατοποθέτησης (όπως ένα αρχείο αντικειμένου), ET_EXEC για ένα εκτελέσιμο μεταγλωττισμένο με τη σημαία -no-pie και ET_DYN για ένα εκτελέσιμο αρχείο ASMR-aware.
Μηχανή: Το αρχιτεκτονική συνόλου εντολών. Αυτό υποδεικνύει την πλατφόρμα στόχο για την οποία δημιουργήθηκε το δυαδικό αρχείο.
Έκδοση: Ρυθμίζεται πάντα σε 1, για αυτήν την έκδοση του ELF.
Διεύθυνση Σημείου Εισόδου: Η διεύθυνση μνήμης εντός του δυαδικού αρχείου από την οποία ξεκινά η εκτέλεση.

Οι άλλες εγγραφές είναι μεγέθη και αριθμοί περιοχών και τμημάτων εντός του δυαδικού αρχείου, ώστε να μπορούν να υπολογιστούν οι τοποθεσίες τους.

Μια γρήγορη ματιά στα πρώτα οκτώ byte του δυαδικού αρχείου με hexdump θα εμφανίσει το byte υπογραφής και τη συμβολοσειρά “ELF” στα πρώτα τέσσερα byte του αρχείου. Η επιλογή -C (κανονική) μας δίνει την αναπαράσταση ASCII των byte μαζί με τις δεκαεξαδικές τιμές τους και η επιλογή -n (αριθμός) μας επιτρέπει να καθορίσουμε πόσα byte θέλουμε να δούμε:

hexdump -C -n 8 hello

το objdump και η Granular View

Εάν θέλετε να δείτε τη λεπτομέρεια με λεπτομέρεια, μπορείτε να χρησιμοποιήσετε την εντολή objdump με την επιλογή -d (disassemble):

objdump -d hello | less

Αυτό αποσυναρμολογεί τον κώδικα του εκτελέσιμου μηχανήματος και τον εμφανίζει σε δεκαεξαδικά byte μαζί με το ισοδύναμο γλώσσας συγκρότησης. Η τοποθεσία της διεύθυνσης του πρώτου αντίο σε κάθε γραμμή εμφανίζεται στην άκρη αριστερά.

Αυτό είναι χρήσιμο μόνο εάν μπορείτε να διαβάσετε τη γλώσσα συναρμολόγησης ή αν είστε περίεργοι τι συμβαίνει πίσω από την κουρτίνα. Υπάρχει πολλή έξοδος, γι’ αυτό το διοχετεύσαμε σε λιγότερα.

Μεταγλώττιση και Σύνδεση

Υπάρχουν πολλοί τρόποι μεταγλώττισης ενός δυαδικού αρχείου. Για παράδειγμα, ο προγραμματιστής επιλέγει αν θα συμπεριλάβει πληροφορίες εντοπισμού σφαλμάτων. Ο τρόπος με τον οποίο συνδέεται το δυαδικό αρχείο παίζει επίσης ρόλο στο περιεχόμενό του και στο μέγεθός του. Εάν οι δυαδικές αναφορές μοιράζονται αντικείμενα ως εξωτερικές εξαρτήσεις, θα είναι μικρότερο από ένα με το οποίο συνδέονται στατικά οι εξαρτήσεις.

Οι περισσότεροι προγραμματιστές γνωρίζουν ήδη τις εντολές που έχουμε καλύψει εδώ. Για άλλους, ωστόσο, προσφέρουν μερικούς εύκολους τρόπους για να ψάξετε και να δείτε τι βρίσκεται μέσα στο δυαδικό μαύρο κουτί.