1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
#include "instructions.h"
#include "registers.h"
#include <elf.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char some_opcodes[] = {MOVDI(REG_EAX, 0x3c),
// 0xb8, 0x3c, 0x00, 0x00, 0x00,
MOVDI(REG_EDI, 0x41),
// 0xbf, 0x41, 0x00, 0x00, 0x00,
SYSCALL};
unsigned int some_opcodes_len = sizeof(some_opcodes) / sizeof(some_opcodes[0]);
int
write_elf(char* restrict file, size_t opcodes_len, char* restrict opcodes) {
int error = 0;
Elf64_Phdr header_program[] = {
//{
// .p_type = PT_LOAD,
// .p_flags = PF_R,
// .p_offset = 0, /* Segment file offset */
// .p_vaddr = 0x400000, /* Segment virtual address */
// .p_paddr = 0x400000, /* Segment physical address */
// .p_filesz = 0xb0, /* Segment size in file */
// .p_memsz = 0xb0, /* Segment size in memory */
// .p_align = 0x1000, /* Segment alignment */
//},
{
.p_type = PT_LOAD,
.p_flags = PF_X | PF_R,
.p_offset =
sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr), /* Segment file offset */
.p_vaddr = 0x400000 + sizeof(Elf64_Ehdr) +
sizeof(Elf64_Phdr), /* Segment virtual address */
.p_paddr = 0x400000 + sizeof(Elf64_Ehdr) +
sizeof(Elf64_Phdr), /* Segment physical address */
.p_filesz = opcodes_len, /* Segment size in file */
.p_memsz = opcodes_len, /* Segment size in memory */
.p_align = 0x1, /* Segment alignment */
},
};
Elf64_Shdr header_section[] = {
{
// .init
// Index in section header string table
.sh_name = 0,
.sh_type = 0,
.sh_flags = 0,
.sh_addr = 0,
.sh_offset = 0,
.sh_size = 0,
.sh_link = 0,
.sh_info = 0,
.sh_addralign = 0,
.sh_entsize = 0,
},
{
// .init
// Index in section header string table
.sh_name = 0,
.sh_type = SHT_PROGBITS,
.sh_flags = SHF_ALLOC | SHF_EXECINSTR,
.sh_addr = 0x401000,
.sh_offset = 0x1000,
.sh_size = opcodes_len,
/* todo: deps on type */
.sh_link = 0,
/* todo: deps on type */
.sh_info = 0,
.sh_addralign = 4,
.sh_entsize = 0,
},
{
// .shstrtab Section Header String Table
// Index in section header string table
.sh_name = 1,
.sh_type = SHT_STRTAB,
.sh_flags = 0,
.sh_addr = 0x100,
.sh_offset = 0x2000,
.sh_size = opcodes_len,
/* todo: deps on type */
.sh_link = 0,
/* todo: deps on type */
.sh_info = 0,
.sh_addralign = 1,
.sh_entsize = 0,
},
};
unsigned char string_header_table[] = {0, '.', 'i', 'n', 'i', 't', 0};
Elf64_Ehdr header = {
// memset(&header, 0, sizeof(Elf64_Ehdr));
.e_ident = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS64, ELFDATA2LSB,
EV_CURRENT, ELFOSABI_SYSV},
.e_type = ET_EXEC,
.e_machine = EM_X86_64,
.e_version = EV_CURRENT,
.e_entry = 0x400000 + sizeof(Elf64_Ehdr) +
sizeof(Elf64_Phdr), // point to VIRTUAL address of _start
.e_phoff = sizeof(Elf64_Ehdr) /* Program header table offset */,
.e_shoff = 0, // sizeof(Elf64_Ehdr) + sizeof(header_program) /* Section
// header table offset */,
.e_flags = 0,
.e_ehsize = sizeof(Elf64_Ehdr),
.e_phentsize = sizeof(Elf64_Phdr),
// If larger than PN_XNUM, then set to PN_XNUM and store real number in
// sh_info of first program header entry
.e_phnum = 1,
.e_shentsize = sizeof(header_section[0]),
// If larger than SHN_LORESERVE, then set to 0 and store real number in
// sh_size of first section header entry
.e_shnum = 0, // sizeof(header_section) / sizeof(header_section[0]),
// If larger than SHN_LORESERVE, then set to SHN_XINDEX and store real index
// in
// sh_link of first section header entry
.e_shstrndx = 0,
};
size_t bytes_written = 0;
FILE* fd = fopen(file, "w");
fwrite(&header, sizeof(Elf64_Ehdr), 1, fd);
fwrite(&header_program, sizeof(Elf64_Phdr),
sizeof(header_program) / sizeof(header_program[0]), fd);
// fseek(fd, 0x1000, SEEK_SET);
do {
bytes_written += fwrite(opcodes, sizeof(char), opcodes_len, fd);
} while (bytes_written != opcodes_len);
error = fclose(fd);
if (error) {
err(EXIT_FAILURE, "no way");
}
return 0;
}
|