Hello! I can't build an ELF executable using the libelf library for

Linux ws-3 4.10.0-38-generic #42~16.04.1-Ubuntu SMP Tue Oct 10 16:32:20 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 

When executing the generated executable file crashes

 $ ./test bash: ./test: cannot execute binary file: Exec format error 

Please tell me what errors you see in the example code and how to correct them correctly.

  1. Code
 #include <err.h> #include <fcntl.h> #include <libelf.h> #include <stdio.h> #include <stdlib.h> #include <sysexits.h> #include <unistd.h> unsigned char code[] = { 0xB8, 0x3C, 0x00, 0x00, 0x00, // mov rax, 60 0xBF, 0x00, 0x00, 0x00, 0x00, // mov rdi, 0 0x0F, 0x05 // syscall }; #define LOADADDR 0x08048000 int main(int argc, char const *argv[]) { int fd; Elf *e; Elf_Scn *scn; Elf_Data *data; Elf64_Ehdr *ehdr; Elf64_Phdr *phdr; Elf64_Shdr *shdr; if (argc != 2) { errx(EX_USAGE, "usage: %s filename\n", argv[0]); } if (elf_version(EV_CURRENT) == EV_NONE) { errx(EX_SOFTWARE, "elf_version is ev_none, wtf? %s\n", elf_errmsg(-1)); } if ((fd = open(argv[1], O_WRONLY | O_CREAT, 0777)) < 0) { errx(EX_OSERR, "open failed: %s\n", elf_errmsg(-1)); } if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) { errx(EX_SOFTWARE, "elf_begin failed: %s\n", elf_errmsg(-1)); } if ((ehdr = elf64_newehdr(e)) == NULL) { errx(EX_SOFTWARE, "elf64_newehdr failed: %s\n", elf_errmsg(-1)); } ehdr->e_ident[EI_DATA] = ELFDATA2MSB; ehdr->e_ident[EI_CLASS] = ELFCLASS32; ehdr->e_machine = EM_X86_64; ehdr->e_type = ET_EXEC; size_t ehdrsz = elf64_fsize(ELF_T_EHDR, 1, EV_CURRENT); size_t phdrsz = elf64_fsize(ELF_T_PHDR, 1, EV_CURRENT); ehdr->e_entry = LOADADDR + ehdrsz + phdrsz; if ((phdr = elf64_newphdr(e, 1)) == NULL) { errx(EX_SOFTWARE, "elf64_newphdr failed: %s\n", elf_errmsg(-1)); } if ((scn = elf_newscn(e)) == NULL) { errx(EX_SOFTWARE, "elf_newscn failed: %s\n", elf_errmsg(-1)); } if ((data = elf_newdata(scn)) == NULL) { errx(EX_SOFTWARE, "elf64_newdata failed: %s\n", elf_errmsg(-1)); } data->d_align = 1; data->d_off = 0LL; data->d_buf = code; data->d_type = ELF_T_BYTE; data->d_size = sizeof(code); data->d_version = EV_CURRENT; if ((shdr = elf64_getshdr(scn)) == NULL) { errx(EX_SOFTWARE, "elf64_getshdr %s\n", elf_errmsg(-1)); } shdr->sh_name = 1; shdr->sh_type = SHT_PROGBITS; shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC; shdr->sh_addr = LOADADDR + ehdrsz + phdrsz; if (elf_update(e, ELF_C_NULL) < 0) { errx(EX_SOFTWARE, "elf_update failed: %s\n", elf_errmsg(-1)); } phdr->p_type = PT_LOAD; phdr->p_offset = 0; phdr->p_filesz = ehdrsz + phdrsz + sizeof(code); phdr->p_memsz = phdr->p_filesz; phdr->p_vaddr = LOADADDR; phdr->p_paddr = phdr->p_vaddr; phdr->p_align = 4; phdr->p_flags = PF_X | PF_R; elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); if (elf_update(e, ELF_C_WRITE) < 0) { errx(EX_SOFTWARE, "elf_update failed: %s\n", elf_errmsg(-1)); } elf_end(e); close(fd); return 0; } 
  1. Copying

    cc ex3.c -o ex3 -g -lelf

  2. Performance

    ./ex3 test

  3. objdump -D test

 test: file format elf64-big objdump: can't disassemble for architecture UNKNOWN! 
  1. hexdump -C test
 00000000 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 00 02 00 3e 00 00 00 01 00 00 00 00 08 04 80 78 |...>...........x| 00000020 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 88 |.......@........| 00000030 00 00 00 00 00 40 00 38 00 01 00 40 00 02 00 00 |.....@.8...@....| 00000040 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 08 04 80 00 00 00 00 00 08 04 80 00 |................| 00000060 00 00 00 00 00 00 00 84 00 00 00 00 00 00 00 84 |................| 00000070 00 00 00 00 00 00 00 04 b8 3c 00 00 00 bf 00 00 |.........<......| 00000080 00 00 0f 05 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000000c0 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 |................| 000000d0 00 00 00 00 00 00 00 06 00 00 00 00 08 04 80 78 |...............x| 000000e0 00 00 00 00 00 00 00 78 00 00 00 00 00 00 00 0c |.......x........| 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 |................| * 00000108 
  1. ELF execution
 $ ./test bash: ./test: cannot execute binary file: Exec format error 

    1 answer 1

    The code began to work correctly after reducing the fields to the following form:

      ehdr->e_ident[EI_DATA] = ELFDATA2LSB; ehdr->e_ident[EI_CLASS] = ELFCLASS64; ehdr->e_machine = EM_X86_64;