#include <stdio.h>
#include <stddef.h>
#include <elf.h>
#include <string.h>
#include <stdlib.h>



#define LOAD_ADDRESS 0x8048000

struct Binary {
    Elf64_Ehdr ehdr;
    Elf64_Phdr phdr;
  char code[];
};


struct Binary binary = {
    /* ELF HEADER */
    .ehdr = {
      /* general */
      .e_ident   = {
        ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
        ELFCLASS64,
        ELFDATA2LSB,
        EV_CURRENT,
        ELFOSABI_LINUX,
      },
      .e_type    = ET_EXEC,
      .e_machine = EM_X86_64,
      .e_version = EV_CURRENT,
      .e_entry   = LOAD_ADDRESS + (offsetof (struct Binary, code)),
      .e_phoff   = offsetof (struct Binary, phdr),
      .e_shoff   = 0,
      .e_flags   = 0,
      .e_ehsize   = sizeof (Elf64_Ehdr),
      /* program header */
      .e_phentsize = sizeof (Elf64_Phdr),
      .e_phnum     = 1,
      /* section header */
      .e_shentsize = sizeof (Elf64_Shdr),
      .e_shnum     = 0,
      .e_shstrndx  = 0
    },

    /* PROGRAM HEADER */
    .phdr = {
      .p_type   = PT_LOAD,
      .p_offset = 0,
      .p_vaddr = LOAD_ADDRESS,
      .p_paddr = LOAD_ADDRESS,
      .p_filesz = 0,
      .p_memsz = 0,
      .p_flags = PF_R | PF_X,
      .p_align = 0x1000
    }
  };

#define MAX_BUF_SIZE 4096
char code[MAX_BUF_SIZE];
size_t code_size = 0;

int main (int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("usage: %s [input file] [output file]\n", argv[0]);
        return -1;
    }
    FILE* input = fopen(argv[1], "rb");
    FILE* output = fopen(argv[2], "wb");

    if (input && output)
    {
        code_size = fread(code, 1, MAX_BUF_SIZE, input);
        if (code_size > 0)
        {
            /* fix program header */
            binary.phdr.p_filesz = sizeof (struct Binary) + code_size;
            binary.phdr.p_memsz = sizeof (struct Binary) + code_size;
            fwrite (&binary, sizeof (struct Binary), 1, output);
            fwrite (code, 1, code_size, output);
        }
    }

    if (input)
    {
        fclose(input);
    }
    if (output)
    {
        fclose(output);
    }


//  0000000000000000 <_start>:
//     0:   b8 01 00 00 00          mov    $0x1,%eax
//     5:   b3 2a                   mov    $0x2a,%bl
//     7:   cd 80                   int    $0x80


  return 0;
}
