All pastes #477510 Raw Edit

Someone

public c v1 · immutable
·published 2007-05-08 18:08 UTC
rendered paste body
/* ELF extractor                                                                                                                                            **                                                                                                                                                          ** Extract ELF files from a bigger file                                                                                                                     ** -- subdub                                                                                                                                                */                                                                                                                                                                                                                                                                                                                      #include <sys/mman.h>                                                                                                                                       #include <sys/stat.h>                                                                                                                                       #include <stdio.h>                                                                                                                                          #include <stdlib.h>                                                                                                                                         #include <unistd.h>                                                                                                                                         #include <errno.h>                                                                                                                                          #include <fcntl.h>                                                                                                                                          #include <string.h>                                                                                                                                                                                                                                                                                                     #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 <file>\n", argv[0]);                                                                                                             return 1;                                                                                                                                                 }                                                                                                                                                         if ((mapped = mapfile(argv[1], &size)) == NULL)                                                                                                               return 1;                                                                                                                                                 return extractelf(mapped, size);                                                                                                                          }