Re: protecting program memory
- From: "Rod Pemberton" <do_not_have@xxxxxxxxxxx>
- Date: Mon, 9 Apr 2007 07:43:19 -0400
"tim" <tim.nicholson@xxxxxxxxxxxxxxxx> wrote in message
news:1174904445.122516.65450@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
<snip>
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.
It does not.I'm not seeing that. I'm using Win98SE (both Windows and v7.10 DOS) and
v2.03 of DJGPP. But, I changed your program slightly...
Any ideas?
Yes.
#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;
Casts of a function pointer to other types or objects are illegal in
standardized C. Use '-pedantic' to catch this. Change line to:
void (* ptr)(void);
extern char* _text asm(".text");
extern char* _etext asm("etext");
static char* __my_progstart = NULL;
static size_t __my_progsize = 0;
int status;
__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);
I'd separate the printf() and mprotect() calls, and exit() if not a valid
status. The mprotect() goes into prior to the printf(). So, the printf()
can cause a failure depending on PROT_NONE, PROT_READ, PROT_WRITE. Change
the printf() line to:
status = mprotect(__my_progstart, __my_progsize, PROT_WRITE);
printf("%d - %d\n",status, (int) __my_progsize);
if(status==-1)
{
printf("not all pages could be locked.\n");
return(0);
}
//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);
All is not well here... You can't legally cast function pointers in ANSI-C
(or ISO-C). A cast of a function pointer to a 'void *' or a pointer to an
object is allowed under pre-ANSI-C, though. You can legally assign function
pointer or zero to a another function pointer. Again, '-pedantic' will warn
about this. Change the memset() line to:
ptr = &a_function; /* legal in ANSI-C if ptr is a function pointer */
/* the 'void *' cast of a function pointer below isn't legal in ANSI-C
*/
/* conversion to 'void *' is valid in non-ANSI C */
memset ((unsigned char *)(((unsigned long)(void *)ptr) + 5), 0, 10);
I.e., the 'void *' is the only allowable cast for a function pointer (for
non-ANSI-C). The 'unsigned long' cast is to be able to perform arithmetic
since arithmetic isn't allowed on 'void *' types. The 'unsigned char *'
cast is to convert the resultant value to an address pointer, a byte in
size, for memset(). A standardized C byte is the minimal addressable group
of bits, not 8-bits as defined everywhere else.
//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);
}
Once, those changes are made. I get the following under DOS (v7.10 for
Win98SE, using CWSDPMI r5):
PROT_NONE causes PAGE_FAULT after mprotect()
PROT_READ causes PAGE_FAULT on memset()
PROT_WRITE causes SIG_SEGV on second call to a_function(), followed by
PAGE_FAULT
Of course, in a Win98SE command prompt (using Windows DPMI, not CWSDPMI), it
exits properly with the -1 return from mprotect() as "not all pages could be
locked."
Rod Pemberton
.
- Prev by Date: Weekly Mini-FAQ post for DJGPP
- Next by Date: ANNOUNCE: Update of GDB 6.4 uploaded
- Previous by thread: More readable format for gcc asm, mixed with c/cpp source code
- Next by thread: ANNOUNCE: Update of GDB 6.4 uploaded
- Index(es):
Relevant Pages
|