Création manuelle du fichier exécutable ELF

Bonjour classe, et bienvenue dans x86 Masochism 101. Ici, vous apprendrez comment utiliser directement les opcodes pour créer un exécutable sans jamais toucher le compilateur, l'assembleur ou l'éditeur de liens. Nous n'utiliserons qu'un éditeur capable de modifier les binaires (c'est-à-dire un éditeur hexadécimal) et «chmod» pour rendre le fichier exécutable.



Si cela ne vous excite pas, alors je ne sais même pas ...



Sérieusement, c'est une de ces choses que je trouve personnellement très intéressantes. Évidemment, vous n'allez pas l'utiliser pour écrire des programmes sérieux avec des millions de lignes. Cependant, vous pouvez avoir un immense plaisir à apprendre que vous comprenez vraiment comment ces choses fonctionnent vraiment à un bas niveau. C'est aussi formidable de pouvoir dire que vous avez écrit un exécutable sans même toucher le compilateur ou l'interpréteur. En outre, il existe des applications pour la programmation du noyau, la rétro-ingénierie et (sans surprise) la construction de compilateurs.



Tout d'abord, jetons un coup d'œil très rapide sur le fonctionnement réel d'un fichier ELF. De nombreux détails seront omis. Ce qui est important, c'est d'avoir une bonne idée de ce que fait votre ordinateur lorsque vous lui demandez d'exécuter le binaire ELF.





Lorsque vous dites à l'ordinateur d'exécuter un binaire ELF, la première chose qu'il recherchera est les en-têtes ELF correspondants. Ces en-têtes contiennent toutes sortes d'informations importantes sur l'architecture du processeur, les segments de fichier et les sections, etc. - nous en reparlerons plus tard. L'en-tête contient également des informations qui aident l'ordinateur à identifier le fichier comme ELF. Plus important encore, l'en-tête ELF contient des informations sur la table d'en-tête de programme dans le cas d'un fichier exécutable et l'adresse virtuelle à laquelle l'ordinateur transfère le contrôle lorsqu'il est exécuté.





, , . - , , «text» «data», . , , .





, , , ELF, .





, , , ELF x86. - Bless. Linux, ELF . Unix- , -, . , . Windows, . , x86 ( x86_64 ), .





ELF . (payload), . -, ELF program header table, . , , , .





: ELF . , , , , , . (: ) , « -» « », . !





, , . "Hello World!" , 93. , . ( ), ( «Hello World!» ). , :





(text segment)
mov ebx, 1
mov eax, 4
mov ecx, HWADDR
mov edx, HWLEN
int 0x80

mov eax, 1
mov ebx, 0x5D
int 0x80
      
      



, . 0x80 , EAX EBX , . .





. , -, . x86 , , :





0xBB 0x01 0x00 0x00 0x00
0xB8 0x04 0x00 0x00 0x00
0xB9 0x** 0x** 0x** 0x**
0xBA 0x0D 0x00 0x00 0x00
0xCD 0x80

0xB8 0x01 0x00 0x00 0x00
0xBB 0x5D 0x00 0x00 0x00 
0xCD 0x80
      
      



( . , )





, «Hello World!\n». ASCII ('man ascii'), , , :





(data segment)
0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64 0x21 0x0A
      
      



!





. , , , , - ELF . ELF , :





e_ident(16), e_type(2), e_machine(2), e_version(4), e_entry(4), e_phoff(4),
e_shoff(4), e_flags(4), e_ehsize(2), e_phentsize(2), e_phnum(2), e_shentsize(2)
e_shnum(2), e_shstrndx(2)
      
      



, , .





e_ident (16) - 16 , ELF. 0x7F, 'E', L ', F'. 0x01 32- little-endian. , 0x00, , 16 (= 0x10).





e_type (2) - 0x02 0x00. , , ELF.





e_machine (2) - 0x03 0x00, , ELF i386.





e_version (4) - 0x01 0x00 0x00 0x00.





e_entry (4) - . , 0x** 0x** 0x** 0x**.





e_phoff (4) - program header table. ELF, ELF : 0x34 0x00 0x00 0x00.





e_shoff (4) - . . 0x00 0x00 0x00 0x00.





e_flags (4) - . 0x00 0x00 0x00 0x00 .





e_ehsize (2) - ELF, 0x34 0x00.





e_phentsize (2) - . , , 0x20 0x00. , , .





e_phnum (2) - , . , 0x02 0x00.





e_shentsize (2), e_shnum (2), e_shstrndx (2) - , ( ), 0x00 0x00 0x00 0x00 0x00 0x00.





ELF! , , , :





0x7F 0x45 0x4C 0x46 0x01 0x01 0x01 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x10 0x02 0x00 0x03 0x00 0x01 0x00 0x00 0x00
0x** 0x** 0x** 0x** 0x34 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x34 0x00 0x20 0x00 0x02 0x00 0x00 0x00
0x00 0x00 0x00 0x00
      
      



. program header table. :





p_type(4), p_offset(4), p_vaddr(4), p_paddr(4), p_filesz(4), p_memsz(4),
p_flags(4), p_align(4)
      
      



, ( : , ) :





p_type (4) - . , PT_LOAD (= 0x01 0x00 0x00 0x00).





p_offset (4) - . , , . 0x** 0x** 0x** 0x**.





p_vaddr (4) - . 0x** 0x** 0x** 0x** 0x**, .





p_paddr (4) - , 0x00 0x00 0x00 0x00.





p_filesz (4) - , . , 0x** 0x** 0x** 0x**. .





p_memsz (4) - . , p_filesz, . 0x** 0x** 0x** 0x**, , , p_filesz.





p_flags (4) - , . , , READ - 0x04, WRITE - 0x02, EXEC - 0x01. READ + EXEC, 0x05 0x00 0x00 0x00, READ + WRITE + EXEC, 0x07 0x00 0x00 0x00.





p_align (4) - . 4 , 0x1000. , x86 little-endian, 0x00 0x10 0x00 0x00.





. , , . , ELF, . , (, , ELF - ?) :





0x01 0x00 0x00 0x00 0x** 0x** 0x** 0x** 0x** 0x** 0x** 0x**
0x00 0x00 0x00 0x00 0x** 0x** 0x** 0x** 0x** 0x** 0x** 0x**
0x05 0x00 0x00 0x00 0x00 0x10 0x00 0x00 
0x01 0x00 0x00 0x00 0x** 0x** 0x** 0x** 0x** 0x** 0x** 0x**
0x00 0x00 0x00 0x00 0x** 0x** 0x** 0x** 0x** 0x** 0x** 0x**
0x07 0x00 0x00 0x00 0x00 0x10 0x00 0x00
      
      



, . ELF , , , - , , . , .



-, , - . . ELF 116 + 2 , 116 = 0x74, 0x74. , 0x80. 0x74 0x7F 0x00, 0x80 .





34 = 0x22 , , 0x80 + 0x22 = 0xA2. 0xA4 0xA2 0xA3 0x00.





, , ELF, 0x00 0x73, 0x74 0x7F , 0x80 0xA1, 0xA2 0xA3 , 0xA4 0xB0. , , , .





, , . , , .





e_entry (4) - 0x80 0x80 0x04 0x08; 0x8048080 . , , , , , - , . ELF , , .





p_offset (4) - 0x80 0x00 0x00 0x00 , 0xA4 0x00 0x00 0x00 . - , .





p_vaddr (4) - 0x80 0x80 0x04 0x08 , 0xA4 0x80 0x04 0x08 . , , , .





p_filesz (4) - 0x24 0x00 0x00 0x00 , 0x20 0x00 0x00 0x00 . . p_memsz = p_filesz, .





, , :





7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 10 02 00 03 00
01 00 00 00 80 80 04 08 34 00 00 00 00 00 00 00 00 00 00 00
34 00 20 00 02 00 00 00 00 00 00 00 01 00 00 00 80 00 00 00
80 80 04 08 00 00 00 00 24 00 00 00 24 00 00 00 05 00 00 00
00 10 00 00 01 00 00 00 A4 00 00 00 A4 80 04 08 00 00 00 00
20 00 00 00 20 00 00 00 07 00 00 00 00 10 00 00 00 00 00 00
00 00 00 00 00 00 00 00 BB 01 00 00 00 B8 04 00 00 00 B9 A4
80 04 08 BA 0D 00 00 00 CD 80 B8 01 00 00 00 BB 2A 00 00 00
CD 80 00 00 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0A
      
      



C'est tout. Exécutez chmod + x sur ce binaire, puis exécutez-le. Bonjour tout le monde en 178 octets. J'espère que vous avez aimé écrire ceci. :-) Si vous trouvez ce HOWTO utile ou intéressant, faites le moi savoir! Je l'apprécie toujours. De plus, les conseils, commentaires et / ou critiques constructives sont toujours les bienvenus.








All Articles