delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2007/03/26/05:30:54

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: "tim" <tim DOT nicholson AT skyforcekent DOT com>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: protecting program memory
Date: 26 Mar 2007 03:20:45 -0700
Organization: http://groups.google.com
Lines: 130
Message-ID: <1174904445.122516.65450@l75g2000hse.googlegroups.com>
References: <OF8FAF1ED8 DOT 483B1086-ON872572A7 DOT 0078F978-872572A7 DOT 007C4A14 AT seagate DOT com>
<46074baf DOT sandmann AT clio DOT rice DOT edu>
NNTP-Posting-Host: 217.155.149.201
Mime-Version: 1.0
X-Trace: posting.google.com 1174904446 1880 127.0.0.1 (26 Mar 2007 10:20:46 GMT)
X-Complaints-To: groups-abuse AT google DOT com
NNTP-Posting-Date: Mon, 26 Mar 2007 10:20:46 +0000 (UTC)
In-Reply-To: <46074baf.sandmann@clio.rice.edu>
User-Agent: G2/1.0
X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20060601 Firefox/2.0.0.2 (Ubuntu-edgy),gzip(gfe),gzip(gfe)
X-HTTP-Via: 1.1 localhost:8080 (squid/2.5.STABLE9)
Complaints-To: groups-abuse AT google DOT com
Injection-Info: l75g2000hse.googlegroups.com; posting-host=217.155.149.201;
posting-account=lGMSoA0AAAAj3K6TdfxB2w_vj0YEAdck
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Mar 26, 5:27 am, Charles Sandmann <sandm DOT  DOT  DOT  AT clio DOT rice DOT edu> wrote:
> > # Is there an easy way to protect the memory used to store the
> > # program op codes from a rogue memory write from within the
> > # application? I have a large (100,000+ line) DJGPP
> > # application which sometimes crashes with SIGILL - It would
> > # seem the program is cannibalizing itself! In order
> > # to find how this is happening, I would like to protect the
> > # entire block of memory that contains the application code
> > # so that an exception occurs at the point the corruption occurs
> > # rather than the point that the corrupted code is executed.
> > # I guest I need to make the memory block read only, but I am
> > # not sure how to do that.
> > Not without DPMI 1.0, you can't.
>
> Correct.  But CWSDPMI implements enough of the DPMI 1.0 specification
> that you can make pages readonly.  This is the same API which is used
> to make the "null" page non-mapped to catch all references to null pointers.
>
> > You can get a pointer to the beginning of code and its size
> > by applying some mild abuse of GCC and the linker map:
> >    extern char*               _text  asm(".text");
> >    extern char*               _etext asm("etext");
> >    static char*               __my_progstart   = NULL;
> >    static size_t              __my_progsize    = 0;
> >    __my_progstart = (char*) &_text;
> >    __my_progsize = (&_etext - &_text) - sizeof(void*);
>
> There are some non-clean parts of the libc which have writeable code
> sections, so you will need to identify those and keep them as writeable.
> If I remember correctly they are in the exception handling code and
> maybe the stub itself.
>
> I don't remember completely, but you should check <sys/mman.h> for the
> mprotect() function.
>
> It's been a long time, but I remember supporting a memory allocation
> package which protected it's control structures and fencing it's allocated
> memory using these routines.


Thanks

Maybe I have misunderstood something, but I tried the following and it
did not do what I expected. If I understand correctly, this code
should fall over with a protection fault when it attempts to execute
the memset() function. It does not. It fails with a SIGSEGV when it
attempts to execute the corrupted function. The mprotect() function is
returning a zero suggesting that the memory was protected, but it is
not preventing the write.

I compile with no optimization

djgpp -g test.c

This is all running under normal DOS (Win 98 DOS without Windows
running at all). The DPMI is provided by CWSDPMI ("CWSDPMI V0.90+ (r5)
Copyright (C) 2000 CW Sandmann ABSOLUTELY NO WARRANTY") - It is called
by the stub in default mode, in other words, I do not all CWSDPMI
explicitly.

If I run CWSDPMI with -x  the mprotect() function returns -1 - Which I
expected as it only uses DPMI 0.9 calls

As a matter of interest, why do I need to subtract size of (void*)
from the program size?

I did try page aligning both the start and the size variables, but it
made no difference.

Any ideas?

#include <stdio.h>
#include <string.h>
#include <pc.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <keys.h>

void a_function(void);

int main (void)
{
char *ptr = (char*) a_function;

extern char*               _text  asm(".text");
extern char*               _etext asm("etext");
static char*               __my_progstart   = NULL;
static size_t              __my_progsize    = 0;

  __my_progstart = (char*) &_text;
  __my_progsize = (&_etext - &_text) - sizeof(void*);


  //protect the application memory and print the result of the
mprotect function.
  printf("%d - %d\n", mprotect(__my_progstart, __my_progsize,
PROT_READ) , (int) __my_progsize);

  //wait for a key press.
  getkey();

  //call a_function - This should work fine.
  a_function();

  //corrupt the function, If all is well the program should crash here
with a protection fault.
  memset ((char*) ptr + 5, 0, 10);

  //If the protection worked, this line should not get printed!
  printf ("The function is now broken!\n");

  //try calling the function again, It will crash because if it
corrupt
  a_function();

  return (0);
}


void a_function(void)
{
int a = 10;
int b = 20;
int c = 30;
int d = 40;


   printf ("a=%d; b=%d, c=%d, d=%d\n",a,b,c,d);
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019