Tipo di conversione del codice utilizzato nei file eseguibili Linux


13

Voglio chiedere che tipo di codifica viene utilizzata per creare file eseguibili di Linux, ad es. Esadecemali, binari o altro. come viene convertito? C'è un modo per recuperare il codice originale da questo file eseguibile?

Ecco un po 'di codice che ho:

ELF���������>�����%|�����@�������������������@�8��@���������������������@�������@�����7<�����7<������� ������������������f�����f���������������������� ������[�UPX!L
h�h�8����������?�E�h=��ڊ̓�N�    4���9ISloB�q�w�]ȉ.��,ς��Q䝦����#e��-�N����/�b,���d<��'��-E��6E�s�/�U���ly�V�Y2]"a��S�.�hU�|�S�J�I�2���X}
�G0�;���5d�$���.)

cosa vuol dire?


Sebbene non ti aiuti a recuperare gran parte di qualcosa, vale la pena notare che il stringsprogramma di filtro può essere molto utile per identificare ciò che un determinato programma binario è o fa perché stampa tutte le stringhe di testo incorporate più lunghe di una lunghezza specificata in un file binario e guardare i messaggi in un programma a volte ti dice molto su cosa è e cosa fa.
Joe,

Risposte:


29

È binario. Il codice sorgente è stato compilato. Puoi visualizzarlo in un editor (un editor esadecimale come blesspotrebbe apportare modifiche più raffinate) ma devi davvero sapere cosa stai facendo. Probabilmente è utile solo per apportare modifiche alle stringhe.

Per qualcosa di più hardcore, puoi iniziare a decodificare il file binario in codice assembly . Questo è spesso considerato come il linguaggio di computer analizzabile più basso livello umano.

objdump -d helloworld | less

Ma includerà anche molte assurdità del compilatore. Ad esempio, se compili il più semplicehelloworld.cpp con G ++ e poi objdump, finisci con 226 righe (208 stripped) di yuck. Potresti scrivere un "ciao mondo" in sole 15 righe di assemblaggio , compilarlo e objdumplo stesso ma che sboccia ancora in 166 righe (spogliate).

Se sei abbastanza bravo con il montaggio, questo potrebbe darti abbastanza accesso per capire cosa sta succedendo e persino permetterti di cambiarlo ... Ma per rispondere alla tua domanda originale:

Non è possibile ripristinare il codice compilato nel codice sorgente originale .

Scusa. È una trasformazione unidirezionale che perde informazioni (commenti, formattazione, concetti di algoritmi leggibili, ecc.), È staticamente collegata ad altre cose ed è generalmente ottimizzata in modo tale da renderla incomprensibile a tutto tranne che ai programmatori migliori e più esperti.

Per darti un'idea della portata del problema, l'intera idea del software di reverse engineering ha il suo sito Stack Exchange .


Puoi dirmi come faccio a decodificare e recuperare la massima quantità di codice perché ho perso la fonte
redchief

7
Vedi la mia modifica recente. Non si può tornare alla fonte originale. Con un sacco di apprendimento e molto tempo, potresti essere in grado di riscrivere il codice sorgente in base al codice assembly smontato, ma nella maggior parte dei casi sarebbe più economico (a meno che il tempo non sia inutile) e più semplice riscriverlo da zero.
Oli

1
Il modo per recuperare la massima quantità di codice è ripristinare il backup più recente. Questo è anche, per inciso, l' unico modo per ottenere in modo affidabile qualcosa di simile al codice sorgente originale.
un CVn

1
Non in disaccordo con l'ultimo paragrafo, solo una nota a margine: alcuni decompilatori IME fanno un ottimo lavoro nel ripristinare l'esatta struttura del codice (a parte ovviamente come hai detto commenti, formattazione, nomi dei simboli ...). Se non hai scritto il programma al primo posto, il codice sorgente recuperato potrebbe essere ancora incomprensibile, tuttavia penso che sia un'ottima opzione per recuperare (almeno parzialmente) un codice sorgente perso / un codice sorgente sconosciuto (con almeno parti di esso effettivamente comprensibile, a seconda del codice specifico e anche se sei fortunato)
kos

1
Questo è ciò che tutti quegli EULA nel mondo del software proprietario dicono che non ti è permesso fare - reverse engineering / disassemblaggio. Includono clausole come questa perché è possibile farlo - ma certamente non è facile! Ma come dice @ MichaelKjörling, l'unico buon modo per recuperare le cose è da più livelli di backup per tutto ciò che ti interessa.
Joe,

7

Non ho abbastanza punti reputazione per un commento, quindi è una risposta:

No, non è possibile convertirlo "indietro". Hai citato il packer upx, hai mai letto il manuale di upx?

Se hai perso la fonte o non hai accesso al codice di qualcun altro non importa qui, semplicemente non è possibile.

L'eseguibile binario è stato prodotto con un compilatore, non credete a nulla dichiarato in questo sito, basta leggere il manuale di esattamente quel compilatore. Quindi, puoi aggiungere qui, in quale lingua è stato scritto il codice originale, quale compilatore è stato utilizzato e quindi potresti notare che questi passaggi (preelaborazione, compilazione, collegamento, forse impacchettamento) non sono invertiti nel loro insieme, ma potrebbero solo essere analizzato ciò che l'autore originale avrebbe potuto intendere e scritto.



3

Come Oli ha già sottolineato nella sua risposta, non è possibile ottenere il codice sorgente molto originale di un eseguibile.

Durante la compilazione di un codice sorgente (compilazione intesa come nella sua più ampia accettazione tipica, quindi come l'intero processo che "trasforma" un codice sorgente in un eseguibile), molte informazioni vengono perse.

Il preprocessore C, per esempio, farà quanto segue (tra le altre cose):

  • Interpretazione, esecuzione e rimozione delle direttive ( #dichiarazioni) del preprocessore
  • Rimuovi commenti
  • Rimuovi gli spazi bianchi non necessari

D'altra parte, ciò che non viene perso durante la compilazione del codice sorgente è tecnicamente riverificabile in un codice sorgente funzionalmente equivalente.

Questo è perché:

  • Le istruzioni binarie hanno una corrispondenza 1: 1 con le istruzioni di assemblaggio; l'assemblaggio di un codice sorgente di assembly è solo una semplice conversione delle istruzioni di assemblaggio in istruzioni binarie basate su una tabella di corrispondenze; una singola istruzione binaria è sempre identificabile e riverificabile in una singola istruzione di assemblaggio ;
  • Le istruzioni di montaggio non hanno una corrispondenza 1: 1 con le istruzioni C; la compilazione di un codice sorgente C di solito non è solo una semplice conversione delle istruzioni C in istruzioni di assemblaggio basate su una tabella di corrispondenze, in realtà è spesso il contrario; di solito un'istruzione C viene convertita in istruzioni di assemblaggio multiple (spesso diverse in base al compilatore); tuttavia, i modelli di più istruzioni di assemblaggio sono generalmente identificabili e riverificabili in una singola istruzione C ;

Esistono strumenti chiamati decompilatori il cui scopo è tentare di ripristinare un eseguibile in un codice sorgente funzionalmente equivalente; tuttavia il risultato è di solito qualcosa di lontano dal codice sorgente molto originale (e di solito anche non compilabile);

Considera questo programma:

#include <stdio.h>

#define MESSAGE "Literal strings will be recovered" // This preprocessor directive won't be recovered

/*

This comment and the comment above won't be recovered

*/

int main(int argc, char* argv[]) {
    printf(MESSAGE);
    return 0;
}

Compilandolo in un eseguibile e decompilandolo nuovamente in un codice sorgente, questo è più o meno ciò che di solito si ottiene (in questo caso specifico ho usato gcc/ Boomerang ):

// address: 0x80483fb
int main(int argc, char **argv, char **envp) {
    printf("Literal strings will be recovered");
    return 0;
}

Come previsto:

  • Mancano le direttive del preprocessore
  • Mancano commenti (a parte // address: 0x80483fb, che è stato aggiunto dal decompilatore)
  • Spazio bianco non necessario mancante (a parte le nuove righe e tabulazioni, che sono state aggiunte dal decompilatore)

Anche questo è un risultato abbastanza buono; non è raro ottenere istruzioni di assemblaggio in linea nel codice:

asm("assembly_instruction");
__asm__("assembly_instruction");

La linea di fondo è (come già sottolineato nelle altre risposte): non è possibile ottenere la fonte molto originale di un eseguibile *.

* Tuttavia, a seconda dell'eseguibile e della fortuna, potresti essere in grado di ottenere qualcosa usando un decompilatore.


2

Gli eseguibili sono generalmente binari se si parla di programmi compilati. Puoi trovare maggiori informazioni usando file path/to/executable. Puoi visualizzare gli eseguibili binari in esadecimali usando ad es. hexdump -C path/to/executable | less(Qualunque cosa ti possa fare bene). Se vuoi "riconvertirlo nella sua forma originale" dovresti usare un decompilatore appropriato , se questo è quello che ti serve. vedi questo post, ad esempio , anche se questo ti darebbe un codice illeggibile non l'originale da cui è stato compilato. Se non è un file binario compilato sarebbe una sorta di script eseguibile, che dovrebbe essere facilmente leggibile in qualsiasi editor di testo. Quello che ci hai mostrato qui è probabilmente un eseguibile compilato. ELF significa "formato eseguibile e di collegamento" che è un formato binario comune su sistemi Linux / Unix. Là'strings path/to/executable


Ho provato a decodificarlo con upx packer ma non ha funzionato e anche con il post che hai suggerito. Quindi per favore dimmi se c'è un altro modo.
redchief

Molto dispiaciuto, ma non posso dirti altro oltre a ciò che è scritto nell'eccellente post di @ Oli.
Hinz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.