Hai un file misterioso?? El Linux file
Il comando ti dirà rapidamente che tipo di file è. Nonostante questo, se è un file binario, puoi avere maggiori informazioni a riguardo. file
ha tutta una serie di compagni di scuderia che ti aiuteranno ad analizzarlo. Ti mostreremo come utilizzare alcuni di questi strumenti.
Identificazione dei tipi di file
I file hanno spesso caratteristiche che consentono ai pacchetti software di identificare il tipo di file., così come ciò che i dati che contiene rappresentano. Non avrebbe senso provare ad aprire un file PNG in un lettore musicale MP3., quindi è utile e pragmatico che un file contenga un qualche tipo di identificazione.
Questi possono essere alcuni byte della firma all'inizio del file. Ciò consente a un file di essere esplicito sul suo formato e contenuto. Qualche volta, il tipo di file è desunto da un aspetto distintivo dell'organizzazione interna dei dati stessi, noto come architettura di file.
Alcuni sistemi operativi, come Windows, sono assolutamente guidati dall'estensione di un file. Puoi chiamarlo credulone o fiducioso, ma Windows presuppone che qualsiasi file con estensione DOCX sia veramente un file di elaborazione testi DOCX. Linux non è così, appena vedrai. Vuoi una prova e guarda all'interno dell'archivio per trovarla.
Gli strumenti qui descritti erano già installati nelle distribuzioni Manjaro 20, Fedora 21 e Ubuntu 20.04 Cosa usiamo per ricercare questo post?. Iniziamo la nostra indagine usando il file
comando.
Usando il comando file
Abbiamo una raccolta di diversi tipi di file nella nostra directory corrente. Sono un mix di documenti, codice sorgente, eseguibili e file di testo.
il ls
il comando ci mostrerà cosa c'è nella directory, e il -hl
L'opzione (dimensioni leggibili dall'uomo, lunga lista) ci mostrerà la dimensione di ogni file:
ls -hl
Proviamo file
su alcuni di questi e vediamo cosa otteniamo:
file build_instructions.odt
file build_instructions.pdf
file COBOL_Report_Apr60.djvu
Tutti e tre i formati di file sono identificati correttamente. Dove fattibile, file
ci dà qualche informazione in più. Il file PDF è segnalato per essere in formato della versione 1.5.
Anche se cambiamo il nome del file ODT in modo che abbia un'estensione con il valore arbitrario di XYZ, il file è ancora correttamente identificato, sia all'interno del Files
file explorer e sulla riga di comando usando file
.
Entro Files
Navigatore di file, viene assegnata l'icona corretta. Sulla riga di comando, file
ignora l'estensione e guarda all'interno del file per impostarne il tipo:
file build_instructions.xyz
Usando file
nei media, come immagini e file musicali, generalmente fornisce informazioni sul suo formato, codifica, risoluzione, eccetera.
file screenshot.png
file screenshot.jpg
file Pachelbel_Canon_In_D.mp3
curiosamente, anche con file di testo normale, file
non giudica il file dalla sua estensione. Come esempio, si tiene un archivo con la extensión “.C”, contenente testo normale standard ma senza codice sorgente, file
non confonderlo con un vero C file del codice sorgente:
file function+headers.h
file makefile
file ciao.c
file
identifica correttamente il file di intestazione (“.h”) come parte di una raccolta di file di codice sorgente C, e sai che il makefile è uno script.
Utilizzo dell'archivio con file binari
Los archivos binarios son más una “caja negra” que otros. I file di immagine possono essere visualizzati, i file audio possono essere riprodotti e i file di documenti possono essere aperti con il pacchetto software appropriato. Nonostante questo, i binari sono una sfida più grande.
Come esempio, i file “Ciao” e “wd” son ejecutables binarios. Sono programmi. El archivo llamado “wd.o” es un archivo de objeto. Quando un compilatore compila il codice sorgente, vengono creati uno o più file oggetto. Estos contienen el código de máquina que la computadora eventualmente ejecutará cuando se ejecute el programa terminado, junto con información para el enlazador. El vinculador comprueba cada archivo de objeto en busca de llamadas a funciones a las bibliotecas. Los vincula a las bibliotecas que utiliza el programa. El resultado de este procedimiento es un archivo ejecutable.
Il file “watch.exe” es un ejecutable binario que ha sido compilado de forma cruzada para ejecutarse en Windows:
file wd
file wd.o
file hello
file watch.exe
Tomando el último primero file
nos dice que el archivo “watch.exe” es un programa de consola ejecutable PE32 + para la familia de procesadores x86 en Microsoft Windows. PE significa formato ejecutable portátil, que tiene versiones de 32 e 64 bit. El PE32 es la versión de 32 bits y el PE32 + es la versión de 64 bit.
Los otros tres archivos están todos identificados como Formato ejecutable y enlazable (ELF) record. Este es un estándar para archivos ejecutables y archivos de objetos compartidos, como bibliotecas. Vedremo a breve il formato dell'intestazione ELF.
Ciò che potrebbe attirare la tua attenzione è che i due eseguibili (“wd” e “Ciao”) sono identificati come Base standard Linux (LSB) oggetti condivisi, y el archivo de objeto “wd.o” se identifica como un LSB reubicable. La parola eseguibile è ovvia in sua assenza.
I file oggetto sono rilocabili, il che significa che il codice che contengono può essere caricato in memoria in qualsiasi posizione. Gli eseguibili sono elencati come oggetti condivisi perché sono stati creati dal linker dai file oggetto in modo tale da ereditare questa capacità.
Ciò consente Casualizzazione del layout dello spazio degli indirizzi (ASMR) per caricare gli eseguibili in memoria agli indirizzi di tua scelta. Gli eseguibili standard hanno un indirizzo di carico utile codificato nelle loro intestazioni, che determina dove vengono caricati in memoria.
ASMR è una tecnica di sicurezza. Il caricamento di eseguibili in memoria a indirizzi prevedibili li rende suscettibili agli attacchi. Questo perché gli aggressori conosceranno sempre i loro punti di ingresso e la posizione delle loro funzioni.. Eseguibili indipendenti dalla posizione (TORTA) posizionato in una direzione casuale supera questa suscettibilità.
Se noi compila il nostro programma con il gcc
compilatore e fornire il -no-pie
opzione, genereremo un eseguibile convenzionale.
il -o
L'opzione (file di uscita) ci consente di fornire un nome per il nostro eseguibile:
gcc -o ciao -no-pie ciao.c
noi useremo file
nel nuovo eseguibile e vedere cosa è cambiato:
file hello
La dimensione dell'eseguibile è la stessa di prima (17 KB):
ls -hl ciao
Il binario è ora identificato come eseguibile standard. Lo stiamo facendo solo a scopo dimostrativo. Se compili le app in questo modo, perderai tutti i vantaggi di ASMR.
Perché un eseguibile è così grande??
Il nostro esempio hello
Il programma ha 17 KB, quindi difficilmente potrebbe essere definito fantastico, ma tutto è relativo. Il codice sorgente è da 120 byte:
gatto ciao.c
Cosa aumenta il volume del binario se tutto ciò che fa è stampare una stringa nella finestra del terminale?? Sappiamo che esiste un'intestazione ELF, ma ha solo 64 byte lunghi per un binario di 64 bit. Chiaramente, Deve essere qualcos'altro:
ls -hl ciao
Andiamo scansiona il binario con il strings
comando come semplice primo passo per scoprire cosa contiene. Lo canalizzeremo in less
:
stringhe ciao | meno
Ci sono molte stringhe all'interno del binario, al mismo tiempo del “Ciao, mondo geek!” de nuestro código fuente. La maggior parte sono etichette per le regioni all'interno del binario e i nomi e le informazioni sui collegamenti degli oggetti condivisi. Questi includono le librerie e le funzioni all'interno di quelle librerie, da cui dipende il binario.
il ldd
comando ci mostra le dipendenze degli oggetti condivisi di un binario:
ldd ciao
Ci sono tre voci nell'output e due di esse includono un percorso di directory (il primo no):
- linux-vdso.so: Oggetto condiviso dinamico virtuale (VDSO) è un meccanismo del kernel che consente a un binario dello spazio utente di accedere a un insieme di routine dello spazio del kernel. Questo evitare di sovraccaricare un cambio di contesto dalla modalità kernel utente. Gli oggetti condivisi VDSO aderiscono al formato del formato associabile ed eseguibile (ELF), che consente loro di legarsi dinamicamente al binario in fase di esecuzione. VDSO è assegnato dinamicamente e sfrutta ASMR. La funzionalità VDSO è fornita dallo standard Libreria GNU C se il kernel supporta lo schema ASMR.
- libc.so.6: il Libreria GNU C oggetto condiviso.
- /lib64/ld-linux-x86-64.so.2: Questo è il linker dinamico che il binario vuole usare. Il linker dinamico interrogare il binario per scoprire quali dipendenze ha. Getta quegli oggetti condivisi nella memoria. Preparare il binario per essere eseguito e per essere in grado di trovare e inserire le dipendenze in memoria. Dopo, avvia il programma.
L'intestazione ELF
Noi possiamo esaminare e decodificare l'intestazione ELF usando il readelf
utilità e -h
(intestazione del file) opzione:
readelf -h ciao
L'intestazione è interpretata per noi.
Il primo byte di tutti i binari ELF è impostato sul valore esadecimale 0x7F. I successivi tre byte sono impostati su 0x45, 0x4C e 0x46. Il primo byte è un flag che identifica il file come binario ELF. Per essere molto chiaro, los siguientes tres bytes deletrean “ELF” Su ASCII:
- Classe: Indica se il binario è un eseguibile da 32 oh 64 bit (1 = 32, 2 = 64).
- Dati: Indica il endianità In uso. La codifica Endian imposta il modo in cui vengono memorizzati i numeri multibyte. Nella codifica big-endian, un numero viene memorizzato con i suoi bit più significativi per primi. Nella codifica little-endian, il numero viene memorizzato con i bit meno significativi per primi.
- Versione: La versione ELF (A quest'ora, è 1).
- TU / AIUTO: Rappresenta il tipo di interfaccia binaria dell'applicazione In uso. Questo stabilisce l'interfaccia tra due moduli binari, come programma e libreria condivisi.
- Versione ABI: La versione ABI.
- scrive: Il tipo binario ELF. I valori comuni sono
ET_REL
per una risorsa trasferibile (come file oggetto),ET_EXEC
per un eseguibile compilato con il-no-pie
bandiera, eET_DYN
per un eseguibile conforme ad ASMR. - Macchina: il set di istruzioni per l'architettura. Questo indica la piattaforma di destinazione per la quale è stato creato il binario.
- Versione: Sempre impostato su 1, per questa versione di ELF.
- Indirizzo del punto di ingresso: L'indirizzo di memoria all'interno del binario in cui inizia l'esecuzione.
Gli altri post sono le dimensioni e il numero di regioni e sezioni all'interno del binario in modo che le loro posizioni possano essere calcolate.
Una rapida occhiata ai primi otto byte del binario insieme a hexdump
mostrará el byte de firma y la cadena “ELF” en los primeros cuatro bytes del archivo. il -C
(canonico) ci dà la rappresentazione ASCII dei byte insieme ai loro valori esadecimali, e il -n
L'opzione (numero) ci permette di specificare quanti byte vogliamo vedere:
dump esadecimale -C -n 8 Ciao
objdump e la vista granulare
Se vuoi vedere il nocciolo della questione, puoi usare il objdump
comando con il -d
(smontare) opzione:
objdump -d ciao | meno
Questo disassembla il codice macchina eseguibile e lo visualizza in byte esadecimali insieme al linguaggio assembly come. La posizione dell'indirizzo del primo bye in ogni riga è mostrata all'estrema sinistra.
Questo è utile solo se sai leggere il linguaggio assembly o se sei curioso di sapere cosa succede dietro le quinte. Ci sono molti risultati, quindi lo canalizziamo su less
.
Compila e collega
Ci sono molte alternative alla compilazione di un binario. Come esempio, lo sviluppatore sceglie se includere le informazioni di debug. Il modo in cui il binario è collegato influenza anche il suo contenuto e le sue dimensioni. Se i riferimenti binari condividono oggetti come dipendenze esterne, sarà più piccolo di quello a cui le dipendenze sono legate staticamente.
La maggior parte degli sviluppatori ha già familiarità con i comandi che abbiamo trattato qui. Per gli altri, nonostante questo, offrono alcuni modi semplici per curiosare e vedere cosa c'è dentro la scatola nera binaria.