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
|
#include <elf.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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 = 0x1000, /* Segment file offset */
.p_vaddr = 0x400000 + 0x1000, /* Segment virtual address */
.p_paddr = 0x400000 + 0x1000, /* Segment physical address */
.p_filesz = opcodes_len, /* Segment size in file */
.p_memsz = opcodes_len, /* Segment size in memory */
.p_align = 0x1, /* Segment alignment */
},
};
unsigned char string_header_table[] = {0, '.', 'i', 'n', 'i', 't',
0, '.', 's', 'h', 's', 't',
'r', 't', 'a', 'b', 0};
Elf64_Shdr header_section[] = {
{0}, // NULL
{
// .init
// Index in section header string table
.sh_name = 1,
.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 = 7,
.sh_type = SHT_STRTAB,
.sh_flags = 0,
.sh_addr = 0x0,
.sh_offset = 0x2000,
.sh_size = sizeof(string_header_table) / sizeof(string_header_table[0]),
/* todo: deps on type */
.sh_link = 0,
/* todo: deps on type */
.sh_info = 0,
.sh_addralign = 1,
.sh_entsize = 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,
// point to VIRTUAL address of _start
.e_entry = 0x400000 + 0x1000,
// Program header table offset
.e_phoff = sizeof(Elf64_Ehdr),
// Section header table offset
.e_shoff = sizeof(Elf64_Ehdr) + sizeof(header_program),
.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 = 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
// "Section Header string-table-index
.e_shstrndx = 2,
};
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);
fwrite(&header_section, sizeof(Elf64_Shdr),
sizeof(header_section) / sizeof(header_section[0]), fd);
fseek(fd, 0x1000, SEEK_SET);
do {
bytes_written += fwrite(opcodes, sizeof(char), opcodes_len, fd);
} while (bytes_written != opcodes_len);
fseek(fd, 0x2000, SEEK_SET);
fwrite(string_header_table, sizeof(char),
sizeof(string_header_table) / sizeof(string_header_table[0]), fd);
error = fclose(fd);
if (error) {
err(EXIT_FAILURE, "no way");
}
return 0;
}
|