Passing execution to a memory address

P

polas

Hi everyone - I have a question. I am just playing around with C (I
realise there are better ways to do what I want, but I would like to
do it this way to increase my understanding of C) and would like to
read an executable file in to a portion of memory and then pass
execution to this and execute the file. However, I can not get it
working and my efforts have resulted in a Seg Fault.

Below is the code I have got

#include "stdio.h"
void (*p) ();
int main()
{
FILE *reader;
reader=fopen("sample", "r"); /* Open in TEXT mode */

void *x=malloc(8000);
int j=fread(x, 1, 8000,reader);

printf ("Read %d\n",j);
fclose(reader);
funcp=(fctype)x;
printf("%d\n",x);
p=x;
printf("%d\n",p);

p();
}

Where sample is a tested small executable file (compiled from c, just
to display a message.) It seems that the file is being read ok (as it
reports reading the correct number of bytes.)

I would appreciate any help on this - it seems to me that I need some
sort of equivalent jump instruction as in assembly, (instead of
function pointers) but I can not find one.

Thanks,
Nick
 
C

Chris Dollin

polas said:
Hi everyone - I have a question. I am just playing around with C (I
realise there are better ways to do what I want, but I would like to
do it this way to increase my understanding of C) and would like to
read an executable file in to a portion of memory and then pass
execution to this and execute the file. However, I can not get it
working and my efforts have resulted in a Seg Fault.

Below is the code I have got

#include "stdio.h"
void (*p) ();
int main()
{
FILE *reader;
reader=fopen("sample", "r"); /* Open in TEXT mode */

void *x=malloc(8000);
int j=fread(x, 1, 8000,reader);

printf ("Read %d\n",j);
fclose(reader);
funcp=(fctype)x;
printf("%d\n",x);
p=x;
printf("%d\n",p);

p();
}

This is of course wildly unportable: there's nothing in the
Standard about it. Typically the implementation will not let
you execute code from the data areas of your program, because
it's often (a) a mistake or (b) an attack (buffer overflow!
run away! run away!). So you need to give your code execute
permission in an implementation-specific way.

On an apropriate system, you might want to use dlopen instead.
 
N

Nelu

polas said:
Hi everyone - I have a question. I am just playing around with C (I
realise there are better ways to do what I want, but I would like to
do it this way to increase my understanding of C) and would like to
read an executable file in to a portion of memory and then pass
execution to this and execute the file. However, I can not get it
working and my efforts have resulted in a Seg Fault.

Below is the code I have got

#include "stdio.h"

it's:
#include <stdio.h>

also, you are using malloc a little later so you need stdlib.h
#include said:
void (*p) ();
int main()

preferable to use int main(void)
{
FILE *reader;
reader=fopen("sample", "r"); /* Open in TEXT mode */

you should make sure that fopen succeeded.
void *x=malloc(8000);

you should make sure that malloc succeeded.
int j=fread(x, 1, 8000,reader);

fread returns size_t. It shouldn't be a problem in your case but
it's a good thing to remember if you want values higher than 8000.
printf ("Read %d\n",j);
fclose(reader);
funcp=(fctype)x;

what is fctype?
printf("%d\n",x);

x is a pointer to void. You are not allowed to print it with %d.
If you want to print it's address use: printf("%p\n",x);

That's not good. You can't assign a void pointer to a function
pointer. They're not the same thing.
printf("%d\n",p);

You can't print it like that. Not even sure you can print that.

p is not pointing to a function so what is it supposed to do?
}

Where sample is a tested small executable file (compiled from c, just
to display a message.) It seems that the file is being read ok (as it
reports reading the correct number of bytes.)

Suppose we don't see the other mistakes. If sample is executable
and you open it as a text file then you're not going to read the
file properly.
I would appreciate any help on this - it seems to me that I need some
sort of equivalent jump instruction as in assembly, (instead of
function pointers) but I can not find one.

Try to use the system function. Anything else is both highly
system dependent and OT here.
 
R

Richard Bos

polas said:
Hi everyone - I have a question. I am just playing around with C (I
realise there are better ways to do what I want, but I would like to
do it this way to increase my understanding of C) and would like to
read an executable file in to a portion of memory and then pass
execution to this and execute the file.

It's not portably possible, and any attempt you might make in ISO C is
incredibly hairy. And still not portable. Quoth the FAQ:
Below is the code I have got

#include "stdio.h"
void (*p) ();
int main()
{
FILE *reader;
reader=fopen("sample", "r"); /* Open in TEXT mode */

Well, that's fundamentally wrong to begin with, and judging from the
comment you know it. So why do so? Open it binary.
void *x=malloc(8000);
int j=fread(x, 1, 8000,reader);

Wooo! Wooo! Magic number alert!

At the very least, #define OBJECT_FILE_SIZE 8000, and use that. Better,
allocate memory dynamically while reading the file.
printf ("Read %d\n",j);
fclose(reader);
funcp=(fctype)x;

This line doth not belong. You have not declared either funcp or fctype.
Are you _sure_ that this is the very same program you compiled?
printf("%d\n",x);

This is the wrong way to printf() a pointer. Use %p instead. Pointers of
other types need to be cast to void *, but x already is one.

This isn't possible in ISO C. Function pointers and object pointers
cannot be assigned to one another. The only thing which can be assigned
to both object and function pointers is a null pointer _constant_. Even
an object pointer which happens to have null value cannot be portably
converted to a function pointer type, nor v.v.
printf("%d\n",p);

And for the same reason, this is not possible, not even if you use %p.
(Not possible, because, as above, you need to cast p to void *; but as
also above, you cannot convert a function pointer to void *.)
I would appreciate any help on this - it seems to me that I need some
sort of equivalent jump instruction as in assembly, (instead of
function pointers) but I can not find one.

As the FAQ writes, this is not only non-portable but also highly
complicated. Use the facilities provided by your implementation instead.
Those are also non-portable, but at least they'll be easier to use than
trying to guess all the system-dependencies yourself, correctly, every
time (because a mistake of a single bit _will_ byte you here).

Richard
 
P

polas

it's:
#include <stdio.h>

also, you are using malloc a little later so you need stdlib.h


preferable to use int main(void)


you should make sure that fopen succeeded.


you should make sure that malloc succeeded.


fread returns size_t. It shouldn't be a problem in your case but
it's a good thing to remember if you want values higher than 8000.




what is fctype?


x is a pointer to void. You are not allowed to print it with %d.
If you want to print it's address use: printf("%p\n",x);


That's not good. You can't assign a void pointer to a function
pointer. They're not the same thing.


You can't print it like that. Not even sure you can print that.




p is not pointing to a function so what is it supposed to do?



Suppose we don't see the other mistakes. If sample is executable
and you open it as a text file then you're not going to read the
file properly.




Try to use the system function. Anything else is both highly
system dependent and OT here.

Thanks for the replies - the question was to "see if it could be done"
in the way I was approaching it, has been answered and I appreciate
it. funcp=(fctype)x; should not have been in there (I edited the code
as I posted it and removed a previous attempt, but missed that line
unfortunately.)

Out of interest, if there was no OS (assuming we had some way of
allocating memory etc..) how would it be done then? - would C suffice
or would the programmer need to put in some assembly code
additionally?

Nick
 
R

Richard Bos

[ Dynamically calling a function loaded from a file ]
Out of interest, if there was no OS (assuming we had some way of
allocating memory etc..) how would it be done then? - would C suffice
or would the programmer need to put in some assembly code
additionally?

Nobody knows. That, too, depends on your system. Of course, if there's
no OS, you're going to have a little difficulty loading your function
code from that file to begin with... but even glossing over that, on
some systems you might be able to call that loaded function as if it
were a normal function, on other systems you're going to need to do one
hell of a lot of setup. It's not just the OS which regulates this (in
fact, in most cases it isn't the OS at all); it's the underlying
architecture, including the CPU, the way memory is arranged, and in some
cases the system ROM.

Richard
 
F

Flash Gordon

polas wrote, On 01/03/07 15:05:

Please don't quote peoples sigs, i.e. like the bit I left in above,
unless you are commenting on them. In fact, in general you should snip
the bits not relevant to your reply (possibly leaving in a summary) and
leave in only what is required.

Out of interest, if there was no OS (assuming we had some way of
allocating memory etc..) how would it be done then? - would C suffice
or would the programmer need to put in some assembly code
additionally?

Look up "Harvard Architecture" and you will understand that in general
the answer is no. Yes, there are processors based on the Harvard
Architecture, although the one I have used did provide a couple of
slight cheats.
 
N

Nelu

polas said:
On Mar 1, 2:55 pm, Nelu <[email protected]> wrote:

It's best if you remove the signatures when replying. It's good
to quote when replying to something so the context is preserved
but you can snip some of the irrelevant quoting.
Thanks for the replies - the question was to "see if it could be done"
in the way I was approaching it, has been answered and I appreciate
it. funcp=(fctype)x; should not have been in there (I edited the code
as I posted it and removed a previous attempt, but missed that line
unfortunately.)

Not portable and I'm not sure you can do it in general. I mean
making the function pointer point to a data region that can be
executed upon calling that function doesn't need to be impossible
but you need to find the right architecture/OS combination to
allow you to do that from C. Not sure if that exists or not.
Also, your chances are really slim even in that case since you're
not reading the file correctly. You should not read it in text mode.
Out of interest, if there was no OS (assuming we had some way of
allocating memory etc..) how would it be done then? - would C suffice
or would the programmer need to put in some assembly code
additionally?

This is getting way off topic and I'm also not sure I could give
you a correct answer - which would also involve a good amount of
speculations. You should probably look for groups related to
computer architectures and operating systems which may answer
your question. The only thing that C offers is the "system"
function but even its input and result are implementation and
host environment dependent.
 
B

Beej Jorgensen

polas said:
reader=fopen("sample", "r"); /* Open in TEXT mode */

Another reason you might not be able to just read in a binary and jump
to the code is the fact that there is likely to be all kinds of header
on the file "sample" that's not executable. Getting to the code itself
can potentially be extremely complicated, and is certainly
system-dependent.

About a billion years ago, a friend of mine and I did what you're trying
(under MS-DOS). We built a little "a-life" arena where the organisms'
behaviors were written in C, compiled to assembly, and carefully
assembled. We then loaded them up dynamically at runtime and jumped
into them when it was time to execute a particular behavior.

Very extremely non-portable. And it barely worked. For instance
(IIRC), the compiler would emit assembly for switch() statements that
assumed you weren't running in the data segment. And, hey; who can
blame it.

So... I'm probably going to make some people cringe, but here's a
program that illustrates more of what you're trying to see. Instead of
loading a binary off disk, it just copies a function that's already in
memory. At the very least, it's an example of what isn't portable in
code that you might conceivably find in the wild.

I should emphasize that this is really very not-portable. It produced a
"correct" result for me on my system (I was a little surprised I could
execute in that memory, but there we are), but really who knows what
it'll do on your system. Maybe it hangs your system! Maybe it
reformats your hard drive! Your mileage may vary, truly!

Working on the a-life program, once the system froze up and, upon
reboot, I found all my BIOS settings were demolished. That was fun.
Similar experiences sometimes occurred under PalmOS where the
double-secret reset was required.

All this adds up to one thing: in real life, do what everyone said and
use some kind of dynamic loader functionality. In fake life, however,
this kind of underhanded dealing can give you neat insights into how
your particular system and compiler work.

-Beej

========================== 8< ==========================

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

/* Some problems with this nonstandard nonportable code:
**
** Line 21: results of unrelated pointer arithmetic undefined
** Line 22: forbidden initialization of function pointer with void pointer
** Line 25: forbidden conversion of function pointers to void pointers
*/

int add1(int x)
{
return x+1;
}

void end_of_add1(void) {}

int main(void)
{
int add1size = (int)end_of_add1 - (int)add1; /* LINE 21 */
int (*newfunc)(int) = malloc(add1size); /* LINE 22 */
int res;

memcpy(newfunc, add1, add1size); /* LINE 25 */

res = newfunc(3);
printf("res = %d\n", res); /* prints "4" (if you're lucky) */

return 0;
}
 
K

Keith Thompson

Nelu said:
polas wrote: [...]
void (*p) (); [...]
void *x=malloc(8000); [...]
printf("%d\n",x);

x is a pointer to void. You are not allowed to print it with %d.
If you want to print it's address use: printf("%p\n",x);

Quibble: that prints the *value* of x (which happens to be an
address).
That's not good. You can't assign a void pointer to a function
pointer. They're not the same thing.

More specifically, the language allows conversions between any two
pointer-to-function types, but not between a pointer-to-function type
and a pointer-to-anything-else type.
You can't print it like that. Not even sure you can print that.

There's no direct way to print a pointer-to-function value. You can
print its representation by treating it as an array of unsigned char
and printing the individual byte values (say, in hexadecimal).

Note that many implementations do allow additional conversions as a
language extension. On such an implementation, you can probably get
meaningful output with:

printf("%p\n", (void*)p); /* non-portable! */

Under many, perhaps most, implementations, all pointers happen to have
the same representation (typically a one-word memory address --
whatever a "word" is), so such conversions make sense. But the
standard doesn't require this; it allows for systems where function
pointers have an entirely different representation than object
pointers (I think the IBM AS/400 is an example), or where they point
into a completely different address space (Harvard architecture).
 
K

Keith Thompson

Beej Jorgensen said:
Another reason you might not be able to just read in a binary and jump
to the code is the fact that there is likely to be all kinds of header
on the file "sample" that's not executable. Getting to the code itself
can potentially be extremely complicated, and is certainly
system-dependent.

About a billion years ago, a friend of mine and I did what you're trying
(under MS-DOS). We built a little "a-life" arena where the organisms'
behaviors were written in C, compiled to assembly, and carefully
assembled. We then loaded them up dynamically at runtime and jumped
into them when it was time to execute a particular behavior.
[...]

The Grand Prize winner of the first International Obfuscated C Code
Contest (IOCCC) in 1984 used a stunningly evil trick. Here's the
program:

short main[] = {
277, 04735, -4129, 25, 0, 477, 1019, 0xbef, 0, 12800,
-113, 21119, 0x52d7, -1006, -7151, 0, 0x4bc, 020004,
14880, 10541, 2056, 04010, 4548, 3044, -6716, 0x9,
4407, 6, 5568, 1, -30460, 0, 0x9, 5570, 512, -30419,
0x7e82, 0760, 6, 0, 4, 02400, 15, 0, 4, 1280, 4, 0,
4, 0, 0, 0, 0x8, 0, 4, 0, ',', 0, 12, 0, 4, 0, '#',
0, 020, 0, 4, 0, 30, 0, 026, 0, 0x6176, 120, 25712,
'p', 072163, 'r', 29303, 29801, 'e'
};

It declared main() not as a function, but as an array. The C startup
routine, though, just jumped to a location named "main"; it didn't
care what it was. The array contained a clever combination of PDP-11
and VAX machine code, and would execute on either system.

<http://www0.us.ioccc.org/years.html#1984_mullender>

Don't try this at home. In fact, don't even try this in a IOCCC
submission; like all great entries, it resulted in a rule change for
the following years.
 
J

jacob.navia

polas a écrit :
Hi everyone - I have a question. I am just playing around with C (I
realise there are better ways to do what I want, but I would like to
do it this way to increase my understanding of C) and would like to
read an executable file in to a portion of memory and then pass
execution to this and execute the file. However, I can not get it
working and my efforts have resulted in a Seg Fault.

Below is the code I have got

#include "stdio.h"
void (*p) ();
int main()
{
FILE *reader;
reader=fopen("sample", "r"); /* Open in TEXT mode */

void *x=malloc(8000);
int j=fread(x, 1, 8000,reader);

printf ("Read %d\n",j);
fclose(reader);
funcp=(fctype)x;
printf("%d\n",x);
p=x;
printf("%d\n",p);

p();
}

Where sample is a tested small executable file (compiled from c, just
to display a message.) It seems that the file is being read ok (as it
reports reading the correct number of bytes.)

I would appreciate any help on this - it seems to me that I need some
sort of equivalent jump instruction as in assembly, (instead of
function pointers) but I can not find one.

Thanks,
Nick

Why that approach can NEVER work?
---------------------------------

You obviously do not know what is in an executable file. Actually, the
pure executable section of the file (the machine opcodes) is fairly
small. Most of the executable file is filled with instructions for the
program loader as to how patch the opcodes to arrange for the fact that
the file can be loaded at ANY address.

For instance you have

jump 0xBADC0FFEE
....

And at the address 0xBADC0FFEE you have some other isntructions. This
will be unserstood by the processor, but that would suppose that you
always load the program at a certain address, what can't be guaranteed
in the general case.

This means that the executable contains "relocation records" that allow
the program loader to patch some addresses according to which address
the program was loaded to.

Basically you want to replace the system loader, i.e. the program that
takes an executable file and loads it into memory, and then it prepares
it for execution.

You have done the first part. You have loaded it into memory. Now you
have to prepare it for execution.


Have a nice time with it.
 
R

Racaille

It's not portably possible, and any attempt you might make in ISO C is
incredibly hairy. And still not portable. Quoth the FAQ:



Well, that's fundamentally wrong to begin with, and judging from the
comment you know it. So why do so? Open it binary.

The OP probably expects fopen() to extract the .text section (the
'code')
from the executable. :)

It's not the first time I've met with this strange misconception.
 
R

Richard Tobin

Keith Thompson said:
It declared main() not as a function, but as an array. The C startup
routine, though, just jumped to a location named "main"; it didn't
care what it was. The array contained a clever combination of PDP-11
and VAX machine code, and would execute on either system. ....
Don't try this at home.

Unless you have a PDP-11 or VAX at home, of course.

-- Richard
 
R

ramana

Hi everyone - I have a question. I am just playing around with C (I
realise there are better ways to do what I want, but I would like to
do it this way to increase my understanding of C) and would like to
read an executable file in to a portion of memory and then pass
execution to this and execute the file. However, I can not get it
working and my efforts have resulted in a Seg Fault.

Below is the code I have got

#include "stdio.h"
void (*p) ();
int main()
{
FILE *reader;
reader=fopen("sample", "r"); /* Open in TEXT mode */

void *x=malloc(8000);
int j=fread(x, 1, 8000,reader);

printf ("Read %d\n",j);
fclose(reader);
funcp=(fctype)x;
printf("%d\n",x);
p=x;
printf("%d\n",p);

p();

}

Where sample is a tested small executable file (compiled from c, just
to display a message.) It seems that the file is being read ok (as it
reports reading the correct number of bytes.)

I would appreciate any help on this - it seems to me that I need some
sort of equivalent jump instruction as in assembly, (instead of
function pointers) but I can not find one.

Thanks,
Nick

Hi,

Usually compiler tools (compiler - assembler - linker) will
generate the output files i.e. object files( can be an executable
file) with fixed memory/address space and it's from zero to the size
required for that program unless you specify the linker to generate
for a specific address space, which is tedious a job and you may
encounter with memory overlapping. So we let the operating system (OS)
do the stuff of allocating the address space and the loader which is a
part of OS move the file to the allocated space by performing some
stuff which may be irrelavent to you.

So you can't simply execute the program by reading the
executable file into memory and jumping to that location. Because, as
i said above, it needs code fix ups that will be done by the loader
once the OS did the address/memory allocation for that program.

Regards,
Ram
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top