├── .gitignore ├── screenshot.png ├── Makefile ├── README.md └── ELFappend.c /.gitignore: -------------------------------------------------------------------------------- 1 | ELFappend 2 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droberson/ELFappend/HEAD/screenshot.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -o ELFappend ELFappend.c 3 | 4 | clean: 5 | rm -rf ELFappend 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ELFappend 2 | 3 | This is a quick demonstration to show how one would append and extract 4 | data to an ELF binary. 5 | 6 | This would be useful for appending the source code to a binary for 7 | future reference, including supplementary stuff with an ELF, or a 8 | number of other scenarios. 9 | 10 | ## Usage 11 | 12 | ![Screenshot](https://github.com/droberson/ELFappend/blob/master/screenshot.png) 13 | -------------------------------------------------------------------------------- /ELFappend.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | /* get_file_size() -- returns size of file in bytes 14 | */ 15 | size_t get_file_size(const char *filename) { 16 | struct stat s; 17 | 18 | if (stat(filename, &s) == -1) { 19 | fprintf(stderr, "Failed to stat file %s: %s\n", filename, strerror(errno)); 20 | return -1; 21 | } 22 | 23 | return s.st_size; 24 | } 25 | 26 | 27 | /* get_elf_size() -- returns length of ELF data for a file. 28 | * 29 | * TODO: validate ELF file 30 | * figure out actual header size of ELF (malloc) 31 | */ 32 | size_t get_elf_size(const char *progname) { 33 | int fd; 34 | void *ELFheaderdata; 35 | Elf64_Ehdr *ELFheader; 36 | size_t elfsize; 37 | 38 | 39 | ELFheaderdata = malloc(64); 40 | 41 | fd = open(progname, O_RDONLY); 42 | if (fd == -1) { 43 | fprintf(stderr, "Failed to open input file %s: %s\n", 44 | progname, 45 | strerror(errno)); 46 | fprintf(stderr, "Exiting.\n"); 47 | 48 | exit(EXIT_FAILURE); 49 | } 50 | 51 | read(fd, ELFheaderdata, 64); 52 | ELFheader = (Elf64_Ehdr *)ELFheaderdata; 53 | 54 | 55 | elfsize = ELFheader->e_shoff + (ELFheader->e_shnum * ELFheader->e_shentsize); 56 | 57 | close(fd); 58 | free(ELFheaderdata); 59 | 60 | return elfsize; 61 | } 62 | 63 | int main(int argc, char *argv[]) { 64 | char ch; 65 | FILE *fp; 66 | char progname[PATH_MAX]; 67 | size_t filesize; 68 | size_t elfsize; 69 | 70 | realpath("/proc/self/exe", progname); 71 | printf("Hello there! I am %s\n", progname); 72 | 73 | filesize = get_file_size(progname); 74 | printf("I am %ld bytes long\n", filesize); 75 | 76 | elfsize = get_elf_size(progname); 77 | printf("%ld bytes is valid ELF data.\n", elfsize); 78 | 79 | printf("This means that there are %ld extra bytes at the end of this file\n", 80 | filesize - elfsize); 81 | 82 | if (filesize - elfsize > 0) { 83 | printf("dumping data....\n"); 84 | 85 | fp = fopen(progname, "rb"); 86 | if (fp == NULL) { 87 | printf("Unable to open %s for reading: %s", progname, strerror(errno)); 88 | exit(EXIT_FAILURE); 89 | } 90 | 91 | fseek(fp, elfsize, SEEK_SET); 92 | 93 | while (fread(&ch, 1, 1, fp)) 94 | fprintf(stderr, "%c", ch); 95 | 96 | fclose(fp); 97 | } 98 | } 99 | --------------------------------------------------------------------------------