Marking a Page of Memory Executable

P

Pie Squared

I'm not completely sure that this is the right place to ask, but I'm
doing it in C, so I'm asking, but if I'm wrong, then please don't
hesitate to correct me and tell me where to post this.

What I want to do is get an executable and writable page of memory, so
that I can (say) write machine code to it and then switch %eip (the
instruction pointer on x86) to that page so that it will execute that
code, or something similar.

I'm attempting to figure out how JIT's manage to run code made during
run-time without writing to an executable file, so if anyone knows
that or has some suggestions I'd like to hear those too.

I'm using Ubuntu Hardy Heron, by the way, in case that matters. I
tried looking in comp.os.linux, but that seems to be archived, so I
can't post this there.

Thanks, and sorry if this is mis-posted.

--Piesquared
 
D

dj3vande

I'm not completely sure that this is the right place to ask, but I'm
doing it in C, so I'm asking, but if I'm wrong, then please don't
hesitate to correct me and tell me where to post this.

This isn't the right place; what you're trying to do goes beyond the C
language, which puts it outside the scope of comp.lang.c.

What I want to do is get an executable and writable page of memory, so
that I can (say) write machine code to it and then switch %eip (the
instruction pointer on x86) to that page so that it will execute that
code, or something similar.

Since you seem to be using x86, the x86 assembly language newsgroup
(comp.lang.asm.x86 if I'm remembering the name correctly) would be a
good first stop.

But, you'll probably need to do something OS-specific to mark the page
executable, so:
I'm using Ubuntu Hardy Heron, by the way, in case that matters. I
tried looking in comp.os.linux, but that seems to be archived, so I
can't post this there.

Something under comp.os.linux.development is probably a good place to
look for that.
If you can't find something there, the people in comp.unix.programmer
may be able to give you a better redirection than I can.

I'm attempting to figure out how JIT's manage to run code made during
run-time without writing to an executable file, so if anyone knows
that or has some suggestions I'd like to hear those too.

comp.compilers (moderated) is the first place that comes to mind for
discussing JIT.


In addition to all of those, comp.programming is a pretty good first
stop for any programming problem you don't know which other newsgroup
to post to about.


dave
 
T

Tomás Ó hÉilidhe

What I want to do is get an executable and writable page of memory, so
that I can (say) write machine code to it and then switch %eip (the
instruction pointer on x86) to that page so that it will execute that
code, or something similar.


I'm not sure if I'm barking up the right tree, but how about this:

Within your program, have a function that consists of a hell of a lot
of instructions so that it takes up a sizeable piece of memory. Then
in your program, just use the function's address to alter it:

void Func(void)
{
int volatile i;

i = 5;
i = 6;
i = 7;
i = 8;
}

int main(void)
{
char my_machine_code[] = {65,43,24,233,1,43,211,13,21};

memcpy( (void*)Func,
my_machine_code,
sizeof my_machine_code );

Func();
}


Of course, the C Standard doesn't guarantee this will work, but maybe
it'll work... ?
 
J

jacob navia

Pie said:
I'm not completely sure that this is the right place to ask, but I'm
doing it in C, so I'm asking, but if I'm wrong, then please don't
hesitate to correct me and tell me where to post this.

What I want to do is get an executable and writable page of memory, so
that I can (say) write machine code to it and then switch %eip (the
instruction pointer on x86) to that page so that it will execute that
code, or something similar.

I'm attempting to figure out how JIT's manage to run code made during
run-time without writing to an executable file, so if anyone knows
that or has some suggestions I'd like to hear those too.

I'm using Ubuntu Hardy Heron, by the way, in case that matters. I
tried looking in comp.os.linux, but that seems to be archived, so I
can't post this there.

Thanks, and sorry if this is mis-posted.

--Piesquared

Hi Piesquared (pipi for friends I suppose :)

% man mmap

MMAP(2) Linux Programmer's Manual MMAP(2)

NAME
mmap, munmap - map or unmap files or devices into memory

SYNOPSIS
#include <unistd.h>
#include <sys/mman.h>

#ifdef _POSIX_MAPPED_FILES

void * mmap(void *start, size_t length, int prot , int
flags, int fd, off_t offset);

int munmap(void *start, size_t length);

#endif

DESCRIPTION
The mmap function asks to map length bytes starting at
offset offset from the file (or other object) specified by
the file descriptor fd into memory, preferably at address
start. This latter address is a hint only, and is usually
specified as 0. The actual place where the object is
mapped is returned by mmap, and is never 0.

The prot argument describes the desired memory protection
(and must not conflict with the open mode of the file). It
is either PROT_NONE or is the bitwise OR of one or more of
the other PROT_* flags.

PROT_EXEC Pages may be executed.

etc, did not copy the rest
 
P

Pie Squared

Hi Piesquared (pipi for friends I suppose :)

% man mmap

MMAP(2)             Linux Programmer's Manual             MMAP(2)

NAME
        mmap, munmap - map or unmap files or devices into memory

SYNOPSIS
        #include <unistd.h>
        #include <sys/mman.h>

        #ifdef _POSIX_MAPPED_FILES

        void  *  mmap(void  *start,  size_t length, int prot , int
        flags, int fd, off_t offset);

        int munmap(void *start, size_t length);

        #endif

DESCRIPTION
        The mmap function asks to map  length  bytes  starting  at
        offset offset from the file (or other object) specified by
        the file descriptor fd into memory, preferably at  address
        start.  This latter address is a hint only, and is usually
        specified as 0.  The actual  place  where  the  object  is
        mapped is returned by mmap, and is never 0.

        The  prot argument describes the desired memory protection
        (and must not conflict with the open mode of the file). It
        is either PROT_NONE or is the bitwise OR of one or more of
        the other PROT_* flags.

        PROT_EXEC  Pages may be executed.

etc, did not copy the rest

Thanks, all! That was immensely useful.

Thanks, Dave, for that info. I'll keep that in mind from now on
whenever I post here (I'm sort-of new to USENET). Thanks for helping a
newbie in need. :)

Also, so _that's_ what the infamous mmap does...

And now let this topic sink into obscurity before my mispost angers
anyone. ;-)
 
P

Pie Squared

Hi Piesquared (pipi for friends I suppose :)

% man mmap

MMAP(2)             Linux Programmer's Manual             MMAP(2)

NAME
        mmap, munmap - map or unmap files or devices into memory

SYNOPSIS
        #include <unistd.h>
        #include <sys/mman.h>

        #ifdef _POSIX_MAPPED_FILES

        void  *  mmap(void  *start,  size_t length, int prot , int
        flags, int fd, off_t offset);

        int munmap(void *start, size_t length);

        #endif

DESCRIPTION
        The mmap function asks to map  length  bytes  starting  at
        offset offset from the file (or other object) specified by
        the file descriptor fd into memory, preferably at  address
        start.  This latter address is a hint only, and is usually
        specified as 0.  The actual  place  where  the  object  is
        mapped is returned by mmap, and is never 0.

        The  prot argument describes the desired memory protection
        (and must not conflict with the open mode of the file). It
        is either PROT_NONE or is the bitwise OR of one or more of
        the other PROT_* flags.

        PROT_EXEC  Pages may be executed.

etc, did not copy the rest

Thanks, all! That was immensely useful.

Thanks, Dave, for that info. I'll keep that in mind from now on
whenever I post here (I'm sort-of new to USENET). Thanks for helping a
newbie in need. :)

Also, so _that's_ what the infamous mmap does...

And now let this topic sink into obscurity before my mispost angers
anyone. ;-)
 
B

Bartc

Pie Squared said:
I'm not completely sure that this is the right place to ask, but I'm
doing it in C, so I'm asking, but if I'm wrong, then please don't
hesitate to correct me and tell me where to post this.

What I want to do is get an executable and writable page of memory, so
that I can (say) write machine code to it and then switch %eip (the
instruction pointer on x86) to that page so that it will execute that
code, or something similar.

This sounds like a problem peculiar to your system. Under WinXP I don't have
a problem executing code created in my data:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int testfn(int a,int b) {return a*b;}

int main(void){
int (*newfn)(int,int);
int i;

newfn=malloc(100); /* assumed to work */
memcpy(newfn,&testfn,100); /* assumes testfn has <=100 bytes */

i=(*newfn)(10,20);

printf("I=%d\n",i);
}

This copies the instructions opcodes from function testfn() to heap memory
pointed to by newfn. Then executes the code at newfn.

And it works for this example although crashes if testfn is changed, maybe
because some x86 code is not relocatable.
 
R

Richard Tobin

What I want to do is get an executable and writable page of memory, so
that I can (say) write machine code to it and then switch %eip (the
instruction pointer on x86) to that page so that it will execute that
code, or something similar.
[/QUOTE]
This sounds like a problem peculiar to your system. Under WinXP I don't have
a problem executing code created in my data:

Just because something isn't the same as Windows XP doesn't mean it's
"peculiar to your system". For decades processors and operating
systems have distinguished between executable and non-executable
memory, just as between writable and read-only memory.

(It's one of the deficiencies of the x86 architecture that it has
not generally been possible to make the stack non-executable, making
possible most of the buffer-overflow exploits that are so popular.)

Most operating systems have functions for controlling this, assuming
the processor supports it. In unix mmap() allows permissions to
be set on allocated memory, and mprotect() allows them to be changed.
int testfn(int a,int b) {return a*b;}

int main(void){
int (*newfn)(int,int);
int i;

newfn=malloc(100); /* assumed to work */
memcpy(newfn,&testfn,100); /* assumes testfn has <=100 bytes */
And it works for this example although crashes if testfn is changed, maybe
because some x86 code is not relocatable.

There's also no guarantee that all the code for testfn immediately
follows the address of testfn.

-- Richard
 
B

Bartc

This sounds like a problem peculiar to your system. Under WinXP I don't
have
a problem executing code created in my data:

Just because something isn't the same as Windows XP doesn't mean it's
"peculiar to your system". For decades processors and operating
systems have distinguished between executable and non-executable
memory, just as between writable and read-only memory.[/QUOTE]

I had some idea that on x86-32 this was controlled by the kind of segments
used (code, data, etc) rather than set per page. In that case the behaviour
wouldn't depend so much on the OS. Clearly I was wrong.
There's also no guarantee that all the code for testfn immediately
follows the address of testfn.

No, that wasn't meant to be recommended C programming practice. Just to
establish that I could actually execute data.
 
R

Richard Tobin

Bartc said:
I had some idea that on x86-32 this was controlled by the kind of segments
used (code, data, etc) rather than set per page. In that case the behaviour
wouldn't depend so much on the OS. Clearly I was wrong.

Yes.

How segments and pages are used for protection depends on the
operating system. For example, on most unix-like operating systems
for x86 the segments for data, code and stack all have the same
mappings, but this is not the only possibility. Within a segment

-- Richard
 
K

Kenny McCormack

This sounds like a problem peculiar to your system. Under WinXP I don't have
a problem executing code created in my data:

Just because something isn't the same as Windows XP doesn't mean it's
"peculiar to your system". For decades processors and operating
systems have distinguished between executable and non-executable
memory, just as between writable and read-only memory.[/QUOTE]

Come on, get with the program.

It is standard practice for standards jockeys (including the clc regs)
to use the term "system specific" (or, equivalently, "peculiar to your
system") to refer to things that aren't 100% portable. Even though the
thing before so referred to may work on 98% of all systems. I.e., the
fact that there might exist a system on which it doesn't work gets
translated into calling it "system specific".
 
A

Antoninus Twink

Thanks, all! That was immensely useful.

And now let this topic sink into obscurity before my mispost angers
anyone. ;-)

clc is a cranky place. Almost any post will anger most of the regulars
here, because they usually read posts specifically looking for something
they can become angry about. But there are some posters (Jacob, as
you've seen, my humble self and some others) who are happy to answer
questions about real-world C, so don't be put off asking them by a few
crotchety old grumps.
 
A

Antoninus Twink

This sounds like a problem peculiar to your system. Under WinXP I don't have
a problem executing code created in my data:
[snip]

I find this pretty surprising. I know Windows isn't built for security -
quite the opposite - but I thought this sort of problem would have been
patched up in XP and Vista.

On doing some poking around, there's an interesting Wikipedia article,
<http://en.wikipedia.org/wiki/Executable_space_protection#Windows>,
which explains the situation. Apparently, since XP Service Pack 2, it
will indeed mark memory non-executable where there's hardware support,
but (if my reading of the article is correct) only for kernel memory
pages.
 
R

Richard

I posted a "real-world C" question, but somehow neither Paul nor
Jacob nor you answered it.

http://groups.google.ca/group/comp...._frm/thread/d49136e360fe880d/b013d937ee3e71ee

I'm not sure what you mean with this. Is it trying to be funny? You seem
to rambling on about a car and temperature or something. How this is in
any way related to real world programmers issues with the common C
language implementations is quite beyond me. You seem intent in
elevating yourself to the same heady heights (depths) of anal
retentiveness as Falconer and Heathfield. Don't. It really is not a
position where people look up to you.
 
A

Antoninus Twink

I'm not sure what you mean with this. Is it trying to be funny?

For a while, Walter took to providing helpful advice to posters asking
about things outside the strict limits of ANSI C. Then he got slapped
down by Jack "The Psycho" Klein, so presumably now he feels he needs to
be a topicality bore on order to try to re-ingratiate himself with The
Clique.
 
R

Richard

Antoninus Twink said:
For a while, Walter took to providing helpful advice to posters asking
about things outside the strict limits of ANSI C. Then he got slapped
down by Jack "The Psycho" Klein, so presumably now he feels he needs to
be a topicality bore on order to try to re-ingratiate himself with The
Clique.

I had noticed. I also noticed after a break away that Santosh seems to
be the new corridor prefect. Some of the others have loosened up a bit
which is only a positive for this group. Falconer has, if anything, got
worse.
 
W

Walter Roberson

(e-mail address removed)-cnrc.gc.ca (Walter Roberson) writes:
I'm not sure what you mean with this. Is it trying to be funny? You seem
to rambling on about a car and temperature or something. How this is in
any way related to real world programmers issues with the common C
language implementations is quite beyond me.

Richard, by your own posted philosophy: if you don't have an answer
for the question, just ignore the question and let the *real* C programmers
answer it.

The question was about a real-world situation faced in the course of C
programming. Questions about marking pages executable or about mutexes
are not about issues with "the common C language implementations", as
memory protection and mutexes are part of the operating system or of
additional system-dependant libraries rather than part of C. Thus if
those topics are deemed to be germaine to the newsgroups by Mr. Twink,
Mr. Hsieh, or Mr. Navia, we must conclude that the topicality boundary
for them must simply be that C plays a role in the question, rather
than that the question is about C.
 
R

rahul

This sounds like a problem peculiar to your system. Under WinXP I don't have
a problem executing code created in my data:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int testfn(int a,int b) {return a*b;}

int main(void){
int (*newfn)(int,int);
int i;

newfn=malloc(100); /* assumed to work */
memcpy(newfn,&testfn,100); /* assumes testfn has <=100 bytes */

i=(*newfn)(10,20);

printf("I=%d\n",i);

}

This copies the instructions opcodes from function testfn() to heap memory
pointed to by newfn. Then executes the code at newfn.

And it works for this example although crashes if testfn is changed, maybe
because some x86 code is not relocatable.
Execution of data triggers trap on most platforms. Its surprising it
still works on XP as it may lead to possible buffer-overflow attacks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top