Advertisement
Guest User

Untitled

a guest
Aug 17th, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.12 KB | None | 0 0
  1.  
  2. /* Self extracting archives */
  3. /* Proof of concept, didn't try compiling or testing */
  4. /* Author: Krzysztof Szewczyk (a.k.a. Palaiologos) */
  5. /* Creation date: 08-17-2018*/
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <string.h>
  11. #include <sys/stat.h>
  12.  
  13. static int parseoct(const char *p, size_t n) {
  14.     int i = 0;
  15.  
  16.     while ((*p < '0' || *p > '7') && n > 0) {
  17.           ++p;
  18.         --n;
  19.       }
  20.       while (*p >= '0' && *p <= '7' && n > 0) {
  21.             i *= 8;
  22.             i += *p - '0';
  23.             ++p;
  24.             --n;
  25.       }
  26.     return i;
  27. }
  28.  
  29. static int is_end_of_archive(const char *p) {
  30.       int n;
  31.       for (n = 511; n >= 0; --n)
  32.             if (p[n] != '\0')
  33.                   return 0;
  34.         return (1);
  35. }
  36.  
  37. static void create_dir(char *pathname, int mode) {
  38.     char *p;
  39.     int r;
  40.       if (pathname[strlen(pathname) - 1] == '/')
  41.             pathname[strlen(pathname) - 1] = '\0';
  42.       r = mkdir(pathname, mode);
  43.       if (r != 0) {
  44.             p = strrchr(pathname, '/');
  45.             if (p != NULL) {
  46.                   *p = '\0';
  47.                   create_dir(pathname, 0755);
  48.                   *p = '/';
  49.                   r = mkdir(pathname, mode);
  50.             }
  51.       }
  52.       if (r != 0)
  53.             fprintf(stderr, "Could not create directory %s\n", pathname);
  54.     else printf("Created: %s", pathname);
  55. }
  56.  
  57. static FILE * create_file(char *pathname, int mode) {
  58.       FILE *f;
  59.       f = fopen(pathname, "wb+");
  60.       if (f == NULL) {
  61.             char *p = strrchr(pathname, '/');
  62.             if (p != NULL) {
  63.                   *p = '\0';
  64.                 create_dir(pathname, 0755);
  65.                   *p = '/';
  66.                   f = fopen(pathname, "wb+");
  67.             }
  68.       }
  69.       return f;
  70. }
  71.  
  72. static int verify_checksum(const char *p) {
  73.       int n, u = 0;
  74.       for (n = 0; n < 512; ++n) {
  75.             if (n < 148 || n > 155)
  76.                   u += ((unsigned char *)p)[n];
  77.             else
  78.                   u += 0x20;
  79.       }
  80.     return (u == parseoct(p + 148, 8));
  81. }
  82.  
  83. static void untar(FILE *a, const char *path) {
  84.       char buff[512];
  85.       FILE *f = NULL;
  86.       size_t bytes_read;
  87.       int filesize;
  88.  
  89.       printf("Extracting from %s\n", path);
  90.       for (;;) {
  91.             bytes_read = fread(buff, 1, 512, a);
  92.             if (bytes_read < 512) {
  93.                   fprintf(stderr, "Short read on %s: expected 512, got %d\n", path, (int)bytes_read);
  94.                   return;
  95.             }
  96.             if (is_end_of_archive(buff)) {
  97.                   printf("End of %s\n", path);
  98.                   return;
  99.             }
  100.             if (!verify_checksum(buff)) {
  101.                   fprintf(stderr, "Checksum failure\n");
  102.                   return;
  103.             }
  104.             filesize = parseoct(buff + 124, 12);
  105.             switch (buff[156]) {
  106.                 case '1':
  107.                       printf(" Ignoring hardlink %s\n", buff);
  108.                       break;
  109.                 case '2':
  110.                       printf(" Ignoring symlink %s\n", buff);
  111.                       break;
  112.                 case '3':
  113.                       printf(" Ignoring character device %s\n", buff);
  114.                         break;
  115.               case '4':
  116.                       printf(" Ignoring block device %s\n", buff);
  117.                       break;
  118.                 case '5':
  119.                       printf(" Extracting subdirectory %s\n", buff);
  120.                       create_dir(buff, parseoct(buff + 100, 8));
  121.                       filesize = 0;
  122.                       break;
  123.                 case '6':
  124.                       printf(" Ignoring FIFO %s\n", buff);
  125.                       break;
  126.                 default:
  127.                       printf(" Extracting file %s\n", buff);
  128.                       f = create_file(buff, parseoct(buff + 100, 8));
  129.                       break;
  130.             }
  131.             while (filesize > 0) {
  132.                    bytes_read = fread(buff, 1, 512, a);  
  133.              if (bytes_read < 512) {
  134.                          fprintf(stderr, "Short read on %s: Expected 512, got %d\n", path, (int)bytes_read);
  135.                          return;
  136.                    }
  137.                    if (filesize < 512)
  138.                         bytes_read = filesize;
  139.                     if (f != NULL) {
  140.                           if (fwrite(buff, 1, bytes_read, f) != bytes_read) {
  141.                                 fprintf(stderr, "Failed write\n");
  142.                                 fclose(f);
  143.                                 f = NULL;
  144.                           }
  145.                   }
  146.                     filesize -= bytes_read;
  147.             }
  148.             if (f != NULL) {
  149.                   fclose(f);
  150.                   f = NULL;
  151.             }
  152.       }
  153. }
  154.  
  155. int main(int argc, char **argv) {
  156.       char template[] = "/tmp/palapack.XXXXXX";
  157.     char dest[256];
  158.     char path[256];
  159.     char comment[512];
  160.     struct stat info;
  161.     FILE * self;
  162.     char *dir_name = mkdtemp(template);
  163.     pid_t pid = getpid();
  164.     if(dir_name == NULL) {
  165.         perror("mkdtemp");
  166.         return 0;
  167.     }
  168.     memset(dest,0,sizeof(dest));
  169.     sprintf(path, "/proc/%d/exe", pid);
  170.     if (readlink(path, dest, 256) == -1)
  171.         perror("readlink");
  172.     else {
  173.         printf("Exe path: %s\n", dest);
  174.         printf("Temp dir name: %s", dir_name);
  175.         self = fopen(dest, "rb");
  176.         if(self) {
  177.             fseek(self, 512, SEEK_SET); //TODO: SET TO EXECUTABLE SIZE!
  178.             untar(self, dir_name);
  179.             fclose(self);
  180.  
  181.             sprintf(comment, "%sstart.sh", dir_name);
  182.             if(access(comment, F_OK) != -1) {
  183.                 execl(comment,"start.sh",NULL);
  184.             } else {
  185.                 printf("No comment found, exiting.");
  186.             }
  187.  
  188.         } else {
  189.             perror("fopen");
  190.         }
  191.     }
  192.    
  193.     if(rmdir(dir_name) == -1) {
  194.         perror("rmdir");
  195.         return 0;
  196.     }
  197. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement