Type de conversion de code utilisé dans les fichiers exécutables Linux

13

Je veux demander quel type d'encodage est utilisé pour créer des fichiers exécutables linux, par exemple hexadécémal, binaire ou autre. comment est-il converti? Existe-t-il un moyen de récupérer le code d'origine à partir de ce fichier exécutable?

Voici un peu de code que j'ai:

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�$���.)

qu'est-ce que cela signifie?

foulard
la source
Bien que cela ne vous aidera pas à récupérer beaucoup de choses, il convient de noter que le stringsprogramme de filtrage peut être très utile pour identifier ce qu'est ou fait un programme binaire particulier car il imprimera toutes les chaînes de texte incorporées plus longtemps qu'une longueur spécifiée dans un fichier binaire et en regardant les messages dans un programme vous en dit parfois beaucoup sur ce qu'il est et ce qu'il fait.
Joe

Réponses:

29

C'est binaire. Le code source a été compilé. Vous pouvez le visualiser dans un éditeur (un éditeur hexadécimal comme celui-ci blesspourrait apporter des modifications plus raffinées) mais vous devez vraiment savoir ce que vous faites. C'est probablement seulement bon pour faire des changements de chaîne.

Pour quelque chose de plus hardcore, vous pouvez commencer à inverser l'ingénierie du binaire en code assembleur . Ceci est souvent considéré comme le langage informatique analysable par l'homme le plus bas niveau.

objdump -d helloworld | less

Mais cela comprendra également beaucoup de bêtises du compilateur. Par exemple, si vous compilez le plus simplehelloworld.cpp avec G ++ et ensuite objdump, vous vous retrouvez avec 226 lignes (208 supprimées) de beurk. Vous pouvez écrire un "bonjour le monde" en seulement 15 lignes d'assemblage , le compiler et objdumpcela mais qui s'épanouit toujours en 166 lignes (dépouillé).

Si vous êtes assez bon en assemblage, cela peut vous donner un accès suffisant pour comprendre ce qui se passe, et même vous laisser le changer ... Mais pour répondre à votre question d'origine:

Vous ne pouvez pas reconvertir le code compilé en code source d' origine .

Pardon. C'est une transformation à sens unique qui perd des informations (commentaires, formatage, concepts d'algorithmes lisibles, etc.), est liée statiquement à d'autres choses et est généralement optimisée de manière à la rendre inintelligible pour tout sauf les meilleurs et les plus expérimentés programmeurs.

Pour vous donner une idée de l'ampleur du problème, toute l'idée d'un logiciel d'ingénierie inverse a son propre site Stack Exchange .

Oli
la source
Pouvez-vous me dire comment je fais de l'ingénierie inverse et que je récupère la quantité maximale de code parce que j'ai perdu la source
redchief
7
Voir ma récente modification. Il n'y a pas de retour à la source d'origine. Avec beaucoup d'apprentissage et beaucoup de temps, vous pourriez être en mesure de réécrire la source sur la base du code d'assemblage démonté, mais dans la plupart des cas, cela serait moins cher (à moins que votre temps ne vaille rien) et plus facile à simplement réécrire à partir de zéro.
Oli
1
La façon de récupérer la quantité maximale de code est de restaurer la sauvegarde la plus récente. C'est aussi, incidemment, le seul moyen de récupérer de manière fiable quelque chose qui ressemble au code source d'origine.
un CVn le
1
Pas du tout en désaccord avec le dernier paragraphe, juste une remarque: certains décompilateurs IME font un excellent travail pour restaurer la structure de code exacte (à part bien sûr comme vous l'avez dit les commentaires, la mise en forme, les noms des symboles ...). Si vous n'avez pas écrit le programme en premier lieu, le code source récupéré pourrait être encore inintelligible, mais je pense que c'est une excellente option pour récupérer (au moins partiellement) un code source perdu / un code source inconnu (avec au moins une partie de celui-ci effectivement intelligible, selon le code spécifique et selon que vous avez de la chance également)
kos
1
C'est ce que tous ces CLUF dans le monde des logiciels propriétaires disent que vous n'êtes pas autorisé à faire - l'ingénierie inverse / le démontage. Ils incluent des clauses comme celle-ci car il est possible de le faire - mais certainement pas facile! Mais comme le dit @ MichaelKjörling, le seul bon moyen de récupérer les choses consiste à utiliser plusieurs niveaux de sauvegarde pour tout ce qui vous intéresse.
Joe
7

Je n'ai pas assez de points de réputation pour un commentaire c'est donc une réponse:

Non, il n'est pas possible de le reconvertir "en arrière". Vous mentionnez upx packer, avez-vous déjà lu le manuel d'upx?

Si vous avez perdu la source ou n'avez pas accès au code de quelqu'un d'autre, cela n'a pas d'importance ici, ce n'est tout simplement pas possible.

L'exécutable binaire a été produit avec un compilateur, ne croyez rien de ce qui est indiqué sur ce site, lisez simplement le manuel de ce compilateur. Ensuite, vous pouvez ajouter ici, dans quelle langue le code d'origine a été écrit, quel compilateur a été utilisé, puis vous pouvez vous-même noter que ces étapes (prétraitement, compilation, liaison, peut-être emballage) ne sont pas inversées dans leur ensemble, mais ne peuvent que être analysé ce que l'auteur original aurait pu vouloir, et écrit.

justabot
la source
3

Comme Oli l'a déjà souligné dans sa réponse, vous ne pouvez pas obtenir le code source très original d'un exécutable.

Pendant la compilation d'un code source (compilation conçue comme dans son acceptation plus large typique, donc comme tout le processus qui "transforme" un code source en un exécutable), beaucoup d'informations sont perdues.

Le préprocesseur C, pour sa part, fera ce qui suit (entre autres):

  • Interpréter, exécuter et supprimer des directives de préprocesseur ( #instructions)
  • Supprimer les commentaires
  • Supprimer les espaces inutiles

D'un autre côté, ce qui n'est pas perdu lors de la compilation du code source est techniquement réversible en un code source fonctionnellement équivalent.

Ceci est dû au fait:

  • Les instructions binaires ont une correspondance 1: 1 avec les instructions de montage; l'assemblage d'un code source d'assemblage n'est qu'une simple conversion des instructions d'assemblage en instructions binaires sur la base d'un tableau de correspondance; une seule instruction binaire est toujours identifiable et convertible en une seule instruction d'assemblage ;
  • Les instructions de montage n'ont pas de correspondance 1: 1 avec les instructions C; la compilation d'un code source C n'est généralement pas seulement une simple conversion des instructions C en instructions d'assemblage basées sur un tableau de correspondance, en fait c'est souvent le contraire; généralement une instruction C est convertie en plusieurs instructions d'assemblage (souvent différentes selon le compilateur); cependant, les modèles d'instructions d'assemblage multiples sont généralement identifiables et convertibles en une seule instruction C ;

Il existe des outils appelés décompilateurs dont le but est d'essayer de rétablir un exécutable en un code source fonctionnellement équivalent; cependant le résultat est généralement quelque chose de loin du code source très original (et généralement aussi incompilable);

Considérez ce programme:

#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;
}

En le compilant dans un exécutable et en le décompilant à nouveau dans un code source, c'est plus ou moins ce que vous récupérez habituellement (dans ce cas spécifique, j'ai utilisé gcc/ Boomerang ):

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

Comme prédit:

  • Les directives du préprocesseur sont manquantes
  • Les commentaires sont manquants (à part // address: 0x80483fb, qui a été ajouté par le décompilateur)
  • Espace vide inutile manquant (à part les nouvelles lignes et les tabulations, qui ont été ajoutées par le décompilateur)

C'est aussi un très bon résultat; il n'est pas rare d'obtenir des instructions d'assemblage en ligne dans le code:

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

L'essentiel est (comme déjà souligné dans les autres réponses): vous ne pouvez pas obtenir la source très originale d'un exécutable *.

* Cependant, selon l'exécutable et votre chance, vous pourrez peut- être obtenir quelque chose en utilisant un décompilateur.

kos
la source
2

Les exécutables sont généralement binaires si vous parlez de programmes compilés. Vous pouvez trouver plus d'informations en utilisant file path/to/executable. Vous pouvez afficher les exécutables binaires en hexadécimal en utilisant par exemple hexdump -C path/to/executable | less(tout ce qui vous ferait du bien). Si vous voulez "le reconvertir à sa forme originale", vous devrez utiliser un décompilateur approprié, voir ce post, par exemple , bien que cela vous donnerait un code assez illisible et non l'original à partir duquel il a été compilé. S'il ne s'agit pas d'un binaire compilé, ce serait une sorte de script exécutable, qui devrait être facilement lisible dans n'importe quel éditeur de texte. Ce que vous nous avez montré ici est probablement un exécutable compilé. ELF signifie "format exécutable et de liaison" qui est un format binaire commun sur les systèmes Linux / Unix. Là'strings path/to/executable, si c'est ce dont vous avez besoin.

Hinz
la source
J'ai essayé de le désosser avec upx packer mais cela n'a pas fonctionné et aussi avec le post que vous avez suggéré. Alors s'il vous plaît, dites-moi s'il y a un autre moyen.
redchief
Très désolé, mais je ne peux rien vous dire de plus que ce qui est écrit dans l'excellent article de @ Oli.
Hinz