Hallo Klasse, und willkommen bei x86 Masochism 101. Hier erfahren Sie, wie Sie mit Opcodes direkt eine ausführbare Datei erstellen, ohne jemals den Compiler, Assembler oder Linker zu berühren. Wir werden nur einen Editor verwenden, der Binärdateien ändern kann (dh einen Hex-Editor) und "chmod", um die Datei ausführbar zu machen.
Wenn dich das nicht anmacht, dann weiß ich nicht mal ...
Im Ernst, dies ist eines der Dinge, die ich persönlich sehr interessant finde. Offensichtlich werden Sie dies nicht verwenden, um ernsthafte Programme mit Millionen von Zeilen zu schreiben. Es kann Ihnen jedoch eine große Freude sein zu lernen, dass Sie wirklich verstehen, wie diese Dinge auf niedrigem Niveau wirklich funktionieren. Es ist auch großartig zu erkennen, dass Sie eine ausführbare Datei geschrieben haben, ohne den Compiler oder Interpreter zu berühren. Darüber hinaus gibt es Anwendungen für die Kernel-Programmierung, das Reverse Engineering und (nicht überraschend) das Erstellen von Compilern.
Lassen Sie uns zunächst einen kurzen Blick darauf werfen, wie die Ausführung einer ELF-Datei tatsächlich funktioniert. Viele Details werden weggelassen. Wichtig ist, dass Sie eine gute Vorstellung davon bekommen, was Ihr Computer tut, wenn Sie ihn anweisen, die ELF-Binärdatei auszuführen.
Wenn Sie den Computer anweisen, eine ELF-Binärdatei auszuführen, sucht er zuerst nach den entsprechenden ELF-Headern. Diese Header enthalten alle möglichen wichtigen Informationen zur Prozessorarchitektur, zu Dateisegmenten und -abschnitten und mehr - darüber werden wir später sprechen. Der Header enthält auch Informationen, mit denen der Computer die Datei als ELF identifizieren kann. Am wichtigsten ist, dass der ELF-Header Informationen über die Programmheadertabelle bei einer ausführbaren Datei und die virtuelle Adresse enthält, an die der Computer bei der Ausführung die Steuerung überträgt.
, , . - , , «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
Das ist alles. Führen Sie chmod + x für diese Binärdatei aus und führen Sie sie dann aus. Hallo Welt in 178 Bytes. Ich hoffe, es hat Ihnen Spaß gemacht, dies zu schreiben. :-) Wenn Sie dieses HOWTO nützlich oder interessant finden, lassen Sie es mich wissen! Ich schätze es immer. Auch Ratschläge, Kommentare und / oder konstruktive Kritik sind immer willkommen.