Thread: Help with mprotect and writing on code section

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    19

    Help with mprotect and writing on code section

    hi,
    I am trying to write on the code section of an executing C program. I tried using mprotect to get PROT_WRITE access to a section in memory and tried to write bytecode on it. It doesnt seem to write on that section. The code is:
    Code:
    #ifndef PAGESIZE
    #define PAGESIZE 4096
    #endif
    unsigned char buffer[1024];
    
    int blank();
    int main()
    {
     unsigned  long *p;
     unsigned char c;
     unsigned long *d;
     int i;
     p = ␣
    
    p = (unsigned long *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));
     if (mprotect(p,12,PROT_WRITE))
      {
       perror("Could not mprotect");
       exit(errno);
      }
      p[0] = 0xccccc3c9; // basically I was trying to make it return without executing
      p[1] = 0x08a14097;
    d= ␣
    printf(" written values %x %x",p[0],p[1]);
    printf(" written values %x %x",d[0],d[1]);
    .....
    return 0; 
    } 
    
    int blank()
    {
      int index=0;
      int i;
      unsigned char *p;
      p = &main;
      printf("here"); 
     for (i=0;i<=203;i++)
      buffer[index++] = p[i];
      buffer[index]='\0';
      return 0;
    }
    The first print returns: ccccc3c9 8a14097.
    The second print returns: 83e58955 45c718ec // these are the values in blank() on objdump of the binary.

    Can someone help me on this, or is there any easier way to make a running program write byte code onto itself?
    Regards,
    Raghu

  2. #2
    Registered User
    Join Date
    Jun 2008
    Posts
    19
    I figured a small portion of the problem. p starts pointing to a different location after the alignment.
    so I did the following:

    Code:
    #ifndef PAGESIZE
    #define PAGESIZE 4096
    #endif
    unsigned char buffer[1024];
    int blank();
    
    int main()
    {
     unsigned  long *p;
     unsigned char c;
     unsigned long *d;
     int i;
     p = &blank;
     d  = (unsigned long *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));
    
     if (mprotect(d,1024,PROT_WRITE))
      {
       perror("Could not mprotect");
       exit(errno);
      }
      printf("before");
      printf("address contained in p %x add cotained in d %x", p, d);
     fflush(NULL);
     p[0] = 0xcc;
       printf("after");
     fflush(NULL);
     return 0;
     }
    int blank()
    {
    }
    This results in
    p = 8048590
    d = 8049000
    Can someone tell me how to align d such that it does not come from one page after p?
    Thanks

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    And what exactly are you hoping to learn from this?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Assuming you are modifying x86 machine code [with 0xcc being int3, I expect that you are], perhaps you should use unsigned char *, instead of unsigned long?

    Also, you may want to add some more parenthesis to your alignment calculation [assuming you are insisting on using unsigned long *], so that when you add 1024, you are not actually adding 1024 * sizeof(unsigned long).

    I too ponder what you are actually wanting to achieve by doing this...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed