/* ELF extractor ** ** Extract ELF files from a bigger file ** -- subdub */ #include #include #include #include #include #include #include #include #define ELF_MAGIC "\x7F\x45\x4C\x46" #define END_ELF "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" unsigned char *mapfile(const char *path, unsigned long *size) { int fd; struct stat s; unsigned char *ret; if ((fd = open(path, O_RDONLY, 0400)) < 0) { fprintf(stderr, "[X] %s : %s\n", path, strerror(errno)); return NULL; } if (fstat(fd, &s) < 0) { perror("[X] fstat"); return NULL; } *size = (unsigned long) s.st_size; if ((ret = (unsigned char *) mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0)) == NULL) { perror("[X] mmap"); return NULL; } printf("[*] File %s mapped at %p, %ld bytes\n", path, ret, *size); return ret; } int saveelf(unsigned char *map, unsigned char *begin, unsigned char *end, int n) { unsigned long size = (unsigned long) end - (unsigned long) begin; char path[256]; int fd; snprintf(path, 255, "xelf-%d.elf", n); if ((fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) { fprintf(stderr, "\n[X] %s : %s\n", path, strerror(errno)); return 0; } if (write(fd, begin, size) != size) { perror("\n[X] write"); return 0; } printf("saved as : %s\n", path); return 1; } int extractelf(unsigned char *map, unsigned long size) { unsigned char *cur_map; unsigned char *begin, *end; unsigned int i; unsigned long cur_size; for (cur_map = map, cur_size = size, i = 0; cur_size > 1; i++) { if ((begin = (unsigned char *) memmem(cur_map, cur_size, ELF_MAGIC, 4)) == NULL) break; cur_size -= (unsigned long) begin - (unsigned long) cur_map; cur_map = begin; if ((end = (unsigned char *) memmem(cur_map, cur_size, END_ELF, 16)) == NULL) break; cur_size -= (unsigned long) end - (unsigned long) cur_map; cur_map = end; printf("\t-> ELF file #%d at : begin=%p end=%p size=%lu ", i, begin, end, (unsigned long) end - (unsigned long) begin); if (!saveelf(map, begin, end, i)) return 1; } printf("\n[*] All OK.\n"); return 0; } int main(int argc, const char **argv) { unsigned char *mapped; unsigned long size; if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } if ((mapped = mapfile(argv[1], &size)) == NULL) return 1; return extractelf(mapped, size); }