Copier le contenu d'un fichier exécutable Unix d'un fichier à l'autre

1

Je suis simplement en train d'expérimenter mais j'ai trouvé un phénomène que j'apprécierais beaucoup si quelqu'un pouvait essayer de l'expliquer.

J'écris un programme simple Hello World en C. gcc compiler ce programme dans un hello Unix Executable File, et peut l’exécuter en utilisant ./hello. Soigné.

J'ouvre cette hello file, pour voir une série de 4 segments de caractères (si quelqu'un veut ajouter une description technique de ce que je vois ici, je ne me plaindrais pas.).

Ma question est la suivante: comment se fait-il que je copie et colle tous ces segments hexadécimaux dans un fichier séparé, appelons test, et utilise chmod +x test, Je n'ai pas les mêmes résultats ./test comme je cours ./hello?

Voici mon programme C:

#include <stdio.h>

int main(void)
{
    int a;
    a = 5;

    printf("Memory address: %p\n", (void*) &a);
    return 0;
}

puis compilé en (20 premières lignes seulement ...)

cffa edfe 0700 0001 0300 0080 0200 0000
1000 0000 1005 0000 8500 2000 0000 0000
1900 0000 4800 0000 5f5f 5041 4745 5a45
524f 0000 0000 0000 0000 0000 0000 0000
0000 0000 0100 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 1900 0000 2802 0000
5f5f 5445 5854 0000 0000 0000 0000 0000
0000 0000 0100 0000 0010 0000 0000 0000
0000 0000 0000 0000 0010 0000 0000 0000
0700 0000 0500 0000 0600 0000 0000 0000
5f5f 7465 7874 0000 0000 0000 0000 0000
5f5f 5445 5854 0000 0000 0000 0000 0000
300f 0000 0100 0000 3800 0000 0000 0000
300f 0000 0400 0000 0000 0000 0000 0000
0004 0080 0000 0000 0000 0000 0000 0000
5f5f 7374 7562 7300 0000 0000 0000 0000
5f5f 5445 5854 0000 0000 0000 0000 0000
680f 0000 0100 0000 0600 0000 0000 0000
680f 0000 0100 0000 0000 0000 0000 0000

Je copie ce fichier exactement comme avec un éditeur de texte.

En regardant en utilisant diff, Je réalise qu'il y a une différence binaire?

fonctionnement ./test renvoie: (20 premières lignes à nouveau)

./test: line 1: cffa: command not found
./test: line 2: 1000: command not found
./test: line 3: 1900: command not found
./test: line 4: 524f: command not found
./test: line 5: 0000: command not found
./test: line 6: 0000: command not found
./test: line 7: 0000: command not found
./test: line 8: 5f5f: command not found
./test: line 9: 0000: command not found
./test: line 10: 0000: command not found
./test: line 11: 0700: command not found
./test: line 12: 5f5f: command not found
./test: line 13: 5f5f: command not found
./test: line 14: 300f: command not found
./test: line 15: 300f: command not found
./test: line 16: 0004: command not found
./test: line 17: 5f5f: command not found
./test: line 18: 5f5f: command not found
./test: line 19: 680f: command not found
./test: line 20: 680f: command not found
a_real_hero
la source
Comparez ces fichiers. Qu'avez-vous comme original et qu'avez-vous copié? (indice: si vous voyez 0x0D, c'est un moyen d'afficher la valeur 13. Vous devez copier cette valeur, et non la façon dont elle est représentée à l'écran).
Hennes
question originale modifiée pour aider à clarifier. Merci pour les réponses.
a_real_hero
La phrase clé est la suivante: "Je copie ce fichier exactement comme si je utilisais un éditeur de texte." ... ouais, ça ne va pas marcher. Maintenant, si vous avez utilisé un binaire rédacteur en chef, c’est tout à fait autre chose.
michael

Réponses:

3

Les codes hexadécimaux représentent des octets avec ces valeurs de caractère.

Ce qui suit montre les caractères réels (notez que tous ne sont pas des caractères imprimables à copier et coller):

cat ./hello

Ce qui suit va rediriger la sortie de ./hello à ./test

cat ./hello > ./test
chmod +x ./test
./test

Remarque: Ce qui suit copie explicitement l'exécutable:

cp ./hello ./test
Steven
la source
cela fonctionne et correspond essentiellement à ce que j'essayais de faire avec le processus de copier-coller. Pour approfondir ma question, qu'est-ce qu'imprimer exactement quand je cours un chat?
a_real_hero
Le compilateur gcc génère un code machine binaire (non lisible par l'homme). Votre éditeur hexadécimal affiche la valeur hexadécimale pour chaque octet. le cat La commande affiche le caractère représenté par la valeur de chaque octet.
Steven
2

Laissez-moi vous montrer la première partie du programme de travail.

Les 16 premières valeurs de votre programme de travail sont:

cffa edfe 0700 0001 0300 0080 0200 0000

cf est hexadécimal pour le nombre 207.
fa est hex pour le nombre 250

(Voir http://en.wikipedia.org/wiki/Hexadecimal pour plus d'informations).

Si vous ne faites que couper et coller cette ligne, vous en copiez une représentation et non les valeurs réelles.

Si vous les coupez et les collez dans un nouveau fichier, cela équivaut à avoir une flèche dans le code, ce qui le traduit en lettres. 'a r r o w' et copier la traduction. Au cours du processus, les informations sont modifiées et vous n’avez plus de programme opérationnel.

Ce que vous avez n’est rien d’autre qu’un fichier texte. Et apparemment, votre système essaie d’interpréter cela comme un script shell lorsque le bit exécutable est défini mais que ELFE en-tête ou case l'interprète est présent.

Hennes
la source
Il est intéressant de noter que les valeurs de ce nouveau fichier texte ne sont pas représentées de la même manière que celles de l’ancien fichier. Y aurait-il un moyen d'avoir ou de définir un en-tête ELF pour que ce fichier s'exécute?
a_real_hero
Ma principale confusion provient de ce qui se passe exactement avec ces nombres hexadécimaux. Je comprends que tout se résume finalement au binaire. l'assemblée est là quelque part. Avez-vous des lectures qui pourraient peut-être donner une vue d'ensemble de la façon dont tout cela s'emboîte à ce niveau inférieur? encore une fois, mes excuses. Je travaille dans le développement Web et j'essaie d'élargir mes horizons
a_real_hero
Pour continuer ma question, y a-t-il un moyen que j'aurais pu sortir ce programme en binaire, et le copier dans un autre fichier, et le lancer?
a_real_hero
Très simplifié: la CPU de votre ordinateur ne comprend que le code machine. Cela est écrit dans des modèles binaires. Ces modèles sont groupés (par exemple, chaque 8 bits sont regroupés dans un octet et peuvent avoir 256 valeurs différentes. 2 ^ 8. Les choses normales que nous lisons à l'écran sont bien inférieures à 256 (az, AZ, 0-9, etc. Donc, il est traduit lorsque vous essayez de le mettre sous une forme lisible par l'homme. Pour le copier (et le garder fonctionnel), ne le traduisez tout simplement pas sous une forme lisible par l'homme ou ne faites pas une danse compliquée pour le traduire en arrière.
Hennes
Intéressant! Je sais que cette question ne fait que prier, mais vous me dites que, dans l’ensemble, un processeur prend tout simplement 11010110 00101001 et ainsi de suite et peut déterminer quoi faire avec cela? (clarification latérale, 8bits = 1 octet?) Deuxièmement, je vais devoir lire dans les compilateurs, mais un compilateur prend ce programme helloworld.c et le transforme en assembly, et un compilateur d'assemblage le transforme en binaire? ou quel est le processus là-bas? à propos, MERCI
a_real_hero