#include "instructions.h" #include "registers.h" #include #include #include #include #include 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; }