diff options
| author | onelin <oscar@nelin.dk> | 2026-06-10 04:58:13 +0000 |
|---|---|---|
| committer | onelin <oscar@nelin.dk> | 2026-06-10 04:58:13 +0000 |
| commit | 7cc1a2e6ccc8f4a87e73c35672e7bb973e965470 (patch) | |
| tree | ce65f72b384f9d75d15cc68ed2f0225e2b21ae0b /write_elf.c | |
Initial commit
Diffstat (limited to 'write_elf.c')
| -rw-r--r-- | write_elf.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/write_elf.c b/write_elf.c new file mode 100644 index 0000000..62b6cd3 --- /dev/null +++ b/write_elf.c @@ -0,0 +1,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; +} |
