1)Executing by reading from executable 2)Compileing in a program

Discussion in 'C Programming' started by noridotjabi@gmail.com, May 13, 2006.

  1. Guest

    Two questions.

    1)Is there any way that I can read from an executable and then execute
    what I have read.
    EXAMPLE:

    text
    text
    this is more
    text

    :::::START EXE CODE:::
    /* executable code in here */
    :::::END EXE CODE:::

    text text
    yep
    yeah
    text


    2)Is there anyway that I can modify the source code of a compiler so
    that I can include it in another program to compile other files in that
    program and place the output of the compiled files into a large file in
    a location specified by an argument to the call of the compiler. Here
    is an example.

    ##MY PSUDO FILE SYSTEM##
    $$fl.exe
    /* exe code for fl.exe */
    &&%

    Now I use the compiler that is included within the program. Say at my
    programs prompt I enter:(where cc is the compilers name)
    :: cc myprog.c -o myprog.exe

    This would result in, if all was well:

    ##MY PSUDO FILE SYSTEM##
    $$fl.exe
    /* exe code for fl.exe */
    &&%
    $$myprog.exe
    /* exe code for myprog.exe*/
    &&%

    I'm not sure if this is possible or not but I'm sure some people will
    understand what I'm saying, and perhaps some guru will know if it can
    be done.
    Nori
    , May 13, 2006
    #1
    1. Advertising

  2. Flash Gordon Guest

    wrote:
    > Two questions.
    >
    > 1)Is there any way that I can read from an executable and then execute
    > what I have read.
    > EXAMPLE:


    <snip>

    Not in standard C. Your implementation may provide some mechanism for
    doing this or may prevent you from doing this.

    > 2)Is there anyway that I can modify the source code of a compiler so
    > that I can include it in another program to compile other files in that
    > program and place the output of the compiled files into a large file in
    > a location specified by an argument to the call of the compiler. Here
    > is an example.


    <snip>

    Maybe yes, maybe no. It depends on whether you have the source code for
    the compiler and whether you are a good enough programmer. However, it
    is probably the wrong solution to whatever problem you are actually
    trying to solve.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc

    Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
    Flash Gordon, May 13, 2006
    #2
    1. Advertising

  3. Ben C Guest

    On 2006-05-13, <> wrote:
    > Two questions.
    >
    > 1)Is there any way that I can read from an executable and then execute
    > what I have read.


    Interesting idea; it is possible on a machine on which code and data are
    stored in the same memory (I think this is called a "von Neumann
    machine")-- most modern desktop machines are like that. So I gave it a
    go.

    First I made a file called blah.c with this in it:

    int add(a, b)
    {
    return a + b;
    }

    and compiled it to blah.o. [this would be called blah.obj on some
    systems].

    Then I disassembled blah.o and found the actual code of "add" was 11
    bytes long and started at offset 0x34L:


    0: 55 push %ebp
    1: 89 e5 mov %esp,%ebp
    3: 8b 45 0c mov 0xc(%ebp),%eax
    6: 03 45 08 add 0x8(%ebp),%eax
    9: 5d pop %ebp
    a: c3 ret

    So then I just loaded the code directly into an array in another
    program, cast the buffer to the proper function type (casting char * to
    to a function type I'm pretty sure is "undefined behaviour", but I
    thought it might work anyway), and called it:

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

    typedef int (*add_t)(int, int);

    add_t load_add(void)
    {
    FILE *fp = fopen("./blah.o", "rb");
    char *code = malloc(11);

    fseek(fp, 0x34L, SEEK_SET);
    fread(code, 1, 11, fp);

    fclose(fp);

    return (add_t) code;
    }

    int main(void)
    {
    add_t add = load_add();
    int result = add(4, 5);

    printf("%d\n", result);

    return 0;
    }

    and it printed out 9!

    Maybe you can use something like this, depending on what you're trying
    to do.

    > 2)Is there anyway that I can modify the source code of a compiler so
    > that I can include it in another program to compile other files in that
    > program and place the output of the compiled files into a large file in
    > a location specified by an argument to the call of the compiler. Here
    > is an example.
    >
    > ##MY PSUDO FILE SYSTEM##
    > $$fl.exe
    > /* exe code for fl.exe */
    > &&%
    >
    > Now I use the compiler that is included within the program. Say at my
    > programs prompt I enter:(where cc is the compilers name)
    >:: cc myprog.c -o myprog.exe
    >
    > This would result in, if all was well:
    >
    > ##MY PSUDO FILE SYSTEM##
    > $$fl.exe
    > /* exe code for fl.exe */
    > &&%
    > $$myprog.exe
    > /* exe code for myprog.exe*/
    > &&%
    >
    > I'm not sure if this is possible or not but I'm sure some people will
    > understand what I'm saying, and perhaps some guru will know if it can
    > be done.


    This part I don't really understand I'm afraid. I gather from your other
    posts that you're trying to do a kind of hosted OS, one of the features
    of which is its own filesystem that appears as a single file to the
    hosted OS. The mini-OS itself appears to the host OS as a single running
    process, and now it sounds like you want the mini-OS to be able to load
    executables from its own filesystem and run them.

    The executables it runs are in native compiled code, however.

    This makes me think you might be better to work at the level of .o (or
    ..obj), than .exe. An exe is likely to do all kinds of things required to
    start up a real process on the hosted OS, but it sounds like you don't
    want that, you just want to run some native code out of the middle of it
    somewhere.

    If you do use .obj files you will need to do your own "linking", but
    that might be part of what the mini-OS does... I don't know.
    Ben C, May 13, 2006
    #3
  4. Guest

    Ben C wrote:
    > On 2006-05-13, <> wrote:
    > > Two questions.
    > >
    > > 1)Is there any way that I can read from an executable and then execute
    > > what I have read.

    >
    > Interesting idea; it is possible on a machine on which code and data are
    > stored in the same memory (I think this is called a "von Neumann
    > machine")-- most modern desktop machines are like that. So I gave it a
    > go.
    >
    > First I made a file called blah.c with this in it:
    >
    > int add(a, b)
    > {
    > return a + b;
    > }
    >
    > and compiled it to blah.o. [this would be called blah.obj on some
    > systems].
    >
    > Then I disassembled blah.o and found the actual code of "add" was 11
    > bytes long and started at offset 0x34L:
    >
    >
    > 0: 55 push %ebp
    > 1: 89 e5 mov %esp,%ebp
    > 3: 8b 45 0c mov 0xc(%ebp),%eax
    > 6: 03 45 08 add 0x8(%ebp),%eax
    > 9: 5d pop %ebp
    > a: c3 ret
    >
    > So then I just loaded the code directly into an array in another
    > program, cast the buffer to the proper function type (casting char * to
    > to a function type I'm pretty sure is "undefined behaviour", but I
    > thought it might work anyway), and called it:
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef int (*add_t)(int, int);
    >
    > add_t load_add(void)
    > {
    > FILE *fp = fopen("./blah.o", "rb");
    > char *code = malloc(11);
    >
    > fseek(fp, 0x34L, SEEK_SET);
    > fread(code, 1, 11, fp);
    >
    > fclose(fp);
    >
    > return (add_t) code;
    > }
    >
    > int main(void)
    > {
    > add_t add = load_add();
    > int result = add(4, 5);
    >
    > printf("%d\n", result);
    >
    > return 0;
    > }
    >
    > and it printed out 9!
    >
    > Maybe you can use something like this, depending on what you're trying
    > to do.
    >
    > > 2)Is there anyway that I can modify the source code of a compiler so
    > > that I can include it in another program to compile other files in that
    > > program and place the output of the compiled files into a large file in
    > > a location specified by an argument to the call of the compiler. Here
    > > is an example.
    > >
    > > ##MY PSUDO FILE SYSTEM##
    > > $$fl.exe
    > > /* exe code for fl.exe */
    > > &&%
    > >
    > > Now I use the compiler that is included within the program. Say at my
    > > programs prompt I enter:(where cc is the compilers name)
    > >:: cc myprog.c -o myprog.exe
    > >
    > > This would result in, if all was well:
    > >
    > > ##MY PSUDO FILE SYSTEM##
    > > $$fl.exe
    > > /* exe code for fl.exe */
    > > &&%
    > > $$myprog.exe
    > > /* exe code for myprog.exe*/
    > > &&%
    > >
    > > I'm not sure if this is possible or not but I'm sure some people will
    > > understand what I'm saying, and perhaps some guru will know if it can
    > > be done.

    >
    > This part I don't really understand I'm afraid. I gather from your other
    > posts that you're trying to do a kind of hosted OS, one of the features
    > of which is its own filesystem that appears as a single file to the
    > hosted OS. The mini-OS itself appears to the host OS as a single running
    > process, and now it sounds like you want the mini-OS to be able to load
    > executables from its own filesystem and run them.
    >
    > The executables it runs are in native compiled code, however.
    >
    > This makes me think you might be better to work at the level of .o (or
    > .obj), than .exe. An exe is likely to do all kinds of things required to
    > start up a real process on the hosted OS, but it sounds like you don't
    > want that, you just want to run some native code out of the middle of it
    > somewhere.
    >
    > If you do use .obj files you will need to do your own "linking", but
    > that might be part of what the mini-OS does... I don't know.



    YES! Finally somebody understands what it is that I'm trying to do.
    You have hit the nail right on the head and this has been very helpful.
    I had no idea how to go about the execuatble portion of this and I
    thank you greatly for your help. This is likely exactly what I will
    do.
    As for the linking...I'm not exactly sure how to go about that, but it
    apears that you have done am I correct? I'm not sure how I could write
    a program that would link .o files makeing them executables, however,
    scince I don't really care what the operating system that my mini-OS is
    running on has to say about much of anything I'm not sure if it would
    make much of a differance. Or would it? I'm not intirely sure I know
    what I'm getting myself into here :p.
    Anyway if you could explain what you ment by the mini-OS linking and
    also about if it would be nesisary to have .exe files at all it would
    be much apreciated by me.
    Nori

    P.S. This is the most helpful post I have gotten thus far relating to
    my project.
    , May 13, 2006
    #4
  5. Flash Gordon Guest

    Ben C wrote:
    > On 2006-05-13, <> wrote:
    >> Two questions.
    >>
    >> 1)Is there any way that I can read from an executable and then execute
    >> what I have read.

    >
    > Interesting idea; it is possible on a machine on which code and data are
    > stored in the same memory (I think this is called a "von Neumann
    > machine")-- most modern desktop machines are like that. So I gave it a
    > go.


    <snip>

    It's not always possible. The OS might prevent it (mark all pages that
    are writeable by the application as not executable). Or you might have
    to do relocation which involves understanding the format of the file.

    On the other hand, with a few tricks it is possible on some processors
    which have separate program and data address spaces.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
    Flash Gordon, May 13, 2006
    #5
  6. In article <-gordon.me.uk>,
    Flash Gordon <> wrote:

    >It's not always possible. The OS might prevent it (mark all pages that
    >are writeable by the application as not executable).


    This is rare in current operating systems, since many programs rely on
    being able to do it (in fact, on many versions of unix, all programs
    do it). Even if it is disabled by default, there is likely to be a
    system call to allow it.

    -- Richard
    Richard Tobin, May 14, 2006
    #6
  7. >1)Is there any way that I can read from an executable and then execute
    >what I have read.


    You can write an emulator for the target CPU and hardware, then
    emulate the execution of the program. As long as the specs for the
    hardware are available, you should be able to do this, although I
    didn't say it would be as fast as the real thing. (For some
    processors such as the Z80, there are emulators using today's
    hardware that are much faster than the real thing ever got).

    You can also provide convenience facilities for dealing with the
    emulation, like loading an "emulated ROM" with a just-compiled
    program, memory and register dumps and patching, stack traces,
    symbolic debugging, breakpoints, emulated I/O devices, etc.

    ....
    >2)Is there anyway that I can modify the source code of a compiler so
    >that I can include it in another program to compile other files in that
    >program and place the output of the compiled files into a large file in
    >a location specified by an argument to the call of the compiler. Here
    >is an example.


    It would seem simpler to compile the code (if necessary using a
    cross-compiler), get an executable, and provide a utility to copy
    the executable into your emulated file system, possibly doing format
    conversion of the executable if needed. If you must, you can have
    a main program that invokes the compiler (the only C way of invoking
    another program is system()), then invokes the code that copies it
    into the emulated filesystem.

    Gordon L. Burditt
    Gordon Burditt, May 14, 2006
    #7
  8. Ben C Guest

    On 2006-05-13, <> wrote:
    >
    > Ben C wrote:
    >> On 2006-05-13, <> wrote:
    >> > Two questions.
    >> >
    >> > 1)Is there any way that I can read from an executable and then execute
    >> > what I have read.

    >>
    >> Interesting idea; it is possible on a machine on which code and data are
    >> stored in the same memory (I think this is called a "von Neumann
    >> machine")-- most modern desktop machines are like that. So I gave it a
    >> go.
    >>
    >> First I made a file called blah.c with this in it:
    >>
    >> int add(a, b)
    >> {
    >> return a + b;
    >> }
    >>
    >> and compiled it to blah.o. [this would be called blah.obj on some
    >> systems].
    >>
    >> Then I disassembled blah.o and found the actual code of "add" was 11
    >> bytes long and started at offset 0x34L:
    >>
    >>
    >> 0: 55 push %ebp
    >> 1: 89 e5 mov %esp,%ebp
    >> 3: 8b 45 0c mov 0xc(%ebp),%eax
    >> 6: 03 45 08 add 0x8(%ebp),%eax
    >> 9: 5d pop %ebp
    >> a: c3 ret
    >>
    >> So then I just loaded the code directly into an array in another
    >> program, cast the buffer to the proper function type (casting char * to
    >> to a function type I'm pretty sure is "undefined behaviour", but I
    >> thought it might work anyway), and called it:
    >>
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >>
    >> typedef int (*add_t)(int, int);
    >>
    >> add_t load_add(void)
    >> {
    >> FILE *fp = fopen("./blah.o", "rb");
    >> char *code = malloc(11);
    >>
    >> fseek(fp, 0x34L, SEEK_SET);
    >> fread(code, 1, 11, fp);
    >>
    >> fclose(fp);
    >>
    >> return (add_t) code;
    >> }
    >>
    >> int main(void)
    >> {
    >> add_t add = load_add();
    >> int result = add(4, 5);
    >>
    >> printf("%d\n", result);
    >>
    >> return 0;
    >> }


    [snip]

    > As for the linking...I'm not exactly sure how to go about that, but it
    > apears that you have done am I correct? I'm not sure how I could write
    > a program that would link .o files makeing them executables, however,
    > scince I don't really care what the operating system that my mini-OS is
    > running on has to say about much of anything I'm not sure if it would
    > make much of a differance. Or would it?
    > I'm not intirely sure I know what I'm getting myself into here :p.


    No nor am I :)

    > Anyway if you could explain what you ment by the mini-OS linking and
    > also about if it would be nesisary to have .exe files at all it would
    > be much apreciated by me.


    To see what I mean by "linking", try the example I posted, but add this
    to blah.c:

    int muladd(int a, int b, int c)
    {
    return add(a, b * c);
    }

    Now try to "call" muladd from the main program by loading it into
    memory... You will need to load both add and muladd, and somehow arrange
    for the call to add from muladd to jump to the right place. This is
    linking, basically-- setting up the path from one function to another.

    The thing about exe files is they contain a lot of information specific
    to the OS about how to load them into memory and run them. Doing
    anything with them except just running them in the way the OS expects is
    likely to be more complex than working with .obj files. If your mini-OS
    wants to just run them then it's really just a shell rather than a
    mini-OS.

    The best thing is to try some things out and you will realize what's
    needed and work out what's going on. Compile the .obj files you're
    loading with minimal compiler optimizations to keep them as simple as
    possible, and investigate disassembler programs; I would recommend GNU
    objdump.
    Ben C, May 14, 2006
    #8
  9. Guest

    Ben C wrote:
    > On 2006-05-13, <> wrote:
    > >
    > > Ben C wrote:
    > >> On 2006-05-13, <> wrote:
    > >> > Two questions.
    > >> >
    > >> > 1)Is there any way that I can read from an executable and then execute
    > >> > what I have read.
    > >>
    > >> Interesting idea; it is possible on a machine on which code and data are
    > >> stored in the same memory (I think this is called a "von Neumann
    > >> machine")-- most modern desktop machines are like that. So I gave it a
    > >> go.
    > >>
    > >> First I made a file called blah.c with this in it:
    > >>
    > >> int add(a, b)
    > >> {
    > >> return a + b;
    > >> }
    > >>
    > >> and compiled it to blah.o. [this would be called blah.obj on some
    > >> systems].
    > >>
    > >> Then I disassembled blah.o and found the actual code of "add" was 11
    > >> bytes long and started at offset 0x34L:
    > >>
    > >>
    > >> 0: 55 push %ebp
    > >> 1: 89 e5 mov %esp,%ebp
    > >> 3: 8b 45 0c mov 0xc(%ebp),%eax
    > >> 6: 03 45 08 add 0x8(%ebp),%eax
    > >> 9: 5d pop %ebp
    > >> a: c3 ret
    > >>
    > >> So then I just loaded the code directly into an array in another
    > >> program, cast the buffer to the proper function type (casting char * to
    > >> to a function type I'm pretty sure is "undefined behaviour", but I
    > >> thought it might work anyway), and called it:
    > >>
    > >> #include <stdio.h>
    > >> #include <stdlib.h>
    > >>
    > >> typedef int (*add_t)(int, int);
    > >>
    > >> add_t load_add(void)
    > >> {
    > >> FILE *fp = fopen("./blah.o", "rb");
    > >> char *code = malloc(11);
    > >>
    > >> fseek(fp, 0x34L, SEEK_SET);
    > >> fread(code, 1, 11, fp);
    > >>
    > >> fclose(fp);
    > >>
    > >> return (add_t) code;
    > >> }
    > >>
    > >> int main(void)
    > >> {
    > >> add_t add = load_add();
    > >> int result = add(4, 5);
    > >>
    > >> printf("%d\n", result);
    > >>
    > >> return 0;
    > >> }

    >
    > [snip]
    >
    > > As for the linking...I'm not exactly sure how to go about that, but it
    > > apears that you have done am I correct? I'm not sure how I could write
    > > a program that would link .o files makeing them executables, however,
    > > scince I don't really care what the operating system that my mini-OS is
    > > running on has to say about much of anything I'm not sure if it would
    > > make much of a differance. Or would it?
    > > I'm not intirely sure I know what I'm getting myself into here :p.

    >
    > No nor am I :)
    >
    > > Anyway if you could explain what you ment by the mini-OS linking and
    > > also about if it would be nesisary to have .exe files at all it would
    > > be much apreciated by me.

    >
    > To see what I mean by "linking", try the example I posted, but add this
    > to blah.c:
    >
    > int muladd(int a, int b, int c)
    > {
    > return add(a, b * c);
    > }
    >
    > Now try to "call" muladd from the main program by loading it into
    > memory... You will need to load both add and muladd, and somehow arrange
    > for the call to add from muladd to jump to the right place. This is
    > linking, basically-- setting up the path from one function to another.
    >
    > The thing about exe files is they contain a lot of information specific
    > to the OS about how to load them into memory and run them. Doing
    > anything with them except just running them in the way the OS expects is
    > likely to be more complex than working with .obj files. If your mini-OS
    > wants to just run them then it's really just a shell rather than a
    > mini-OS.
    >
    > The best thing is to try some things out and you will realize what's
    > needed and work out what's going on. Compile the .obj files you're
    > loading with minimal compiler optimizations to keep them as simple as
    > possible, and investigate disassembler programs; I would recommend GNU
    > objdump.


    And I really thought that I was getting somewere too. Okay one
    question and it sounds simple enough but here goes: How in the world do
    I set it up to that muladd would jump to the right place? Also, would
    doing things in this mannor require things that could not be automated?
    I was really hoping that there would be some way to execute things
    that were in the psudo-filesystem without actually doing manual work.
    Thanks.
    Nori
    , May 14, 2006
    #9
  10. >> 1)Is there any way that I can read from an executable and then execute
    >> what I have read.

    >
    >Interesting idea; it is possible on a machine on which code and data are
    >stored in the same memory (I think this is called a "von Neumann
    >machine")-- most modern desktop machines are like that. So I gave it a
    >go.


    It's not necessary for code and data to be in the same memory, or for
    the target machine and the host machine to have instruction sets anything
    like each other. All you need is a program running on the host that
    emulates the target machine. All of the state of the target machine
    (RAM, ROM, registers, etc.) is in the data space of the host machine.
    There are lots of emulators for various machines, especially those for
    CPUs often used in embedded controllers.

    >Then I disassembled blah.o and found the actual code of "add" was 11
    >bytes long and started at offset 0x34L:
    >
    >
    > 0: 55 push %ebp
    > 1: 89 e5 mov %esp,%ebp
    > 3: 8b 45 0c mov 0xc(%ebp),%eax
    > 6: 03 45 08 add 0x8(%ebp),%eax
    > 9: 5d pop %ebp
    > a: c3 ret


    Note that if you move code from one address to another, the code
    might change (particularly for (conditional) branch instructions
    that aren't PC-relative, or if the code uses local data). This is
    often called "relocation". An object (as opposed to executable)
    file has information needed to locate code anywhere. Executable
    files might not (particularly if the OS uses virtual memory and
    always loads executables at a fixed address).

    Gordon L. Burditt
    Gordon Burditt, May 14, 2006
    #10
  11. Guest

    Allow me to slightly rephrase my origional post based on information
    that I have now:
    Is there any way that I could execute say

    #include <stdio.h>
    main() {
    printf("hello world\n");
    }

    Within another program. Where hello.c or .o or .exe or .whatever is
    stored

    place one::
    yep
    place two::
    whatever
    place three::
    code for hello.o .exe or .whatever

    Thanks
    Nori

    wrote:
    > Two questions.
    >
    > 1)Is there any way that I can read from an executable and then execute
    > what I have read.
    > EXAMPLE:
    >
    > text
    > text
    > this is more
    > text
    >
    > :::::START EXE CODE:::
    > /* executable code in here */
    > :::::END EXE CODE:::
    >
    > text text
    > yep
    > yeah
    > text
    >
    >
    > 2)Is there anyway that I can modify the source code of a compiler so
    > that I can include it in another program to compile other files in that
    > program and place the output of the compiled files into a large file in
    > a location specified by an argument to the call of the compiler. Here
    > is an example.
    >
    > ##MY PSUDO FILE SYSTEM##
    > $$fl.exe
    > /* exe code for fl.exe */
    > &&%
    >
    > Now I use the compiler that is included within the program. Say at my
    > programs prompt I enter:(where cc is the compilers name)
    > :: cc myprog.c -o myprog.exe
    >
    > This would result in, if all was well:
    >
    > ##MY PSUDO FILE SYSTEM##
    > $$fl.exe
    > /* exe code for fl.exe */
    > &&%
    > $$myprog.exe
    > /* exe code for myprog.exe*/
    > &&%
    >
    > I'm not sure if this is possible or not but I'm sure some people will
    > understand what I'm saying, and perhaps some guru will know if it can
    > be done.
    > Nori
    , May 14, 2006
    #11
  12. SM Ryan Guest

    "" <> wrote:
    # Two questions.
    #
    # 1)Is there any way that I can read from an executable and then execute
    # what I have read.

    Many systems provide for things like dynamic loading or to store
    new instructions in memory and make those instructions executable,
    but the methods tend to be specific to each system.

    # 2)Is there anyway that I can modify the source code of a compiler so
    # that I can include it in another program to compile other files in that

    Not all installed systems have a c compiler anywhere on the machine.

    The usual way to do this is to use a portable interpretter such as
    Perl, Tcl, Forth, etc.These languages let you load source code
    and then run it, or a partially compiled form of the source. I wouldn't
    try to compile and load C fragments within a program: too complicated
    and not very portable.

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    GERBILS
    GERBILS
    GERBILS
    SM Ryan, May 14, 2006
    #12
  13. Ben C Guest

    On 2006-05-14, <> wrote:
    >
    >
    > Ben C wrote:
    >> On 2006-05-13, <> wrote:
    >> >
    >> > Ben C wrote:
    >> >> On 2006-05-13, <> wrote:
    >> >> > Two questions.
    >> >> >
    >> >> > 1)Is there any way that I can read from an executable and then execute
    >> >> > what I have read.


    [snip]

    >> The best thing is to try some things out and you will realize what's
    >> needed and work out what's going on. Compile the .obj files you're
    >> loading with minimal compiler optimizations to keep them as simple as
    >> possible, and investigate disassembler programs; I would recommend GNU
    >> objdump.

    >
    > And I really thought that I was getting somewere too. Okay one
    > question and it sounds simple enough but here goes: How in the world do
    > I set it up to that muladd would jump to the right place? Also, would
    > doing things in this mannor require things that could not be automated?
    > I was really hoping that there would be some way to execute things
    > that were in the psudo-filesystem without actually doing manual work.


    Of course, everything can be automated.

    Besides the compiled code for all the functions, the .o file also
    contains tables telling you where each function starts and how long the
    code for each function is, and also which bits of the compiled code need
    to be "patched" after the code for each function has been loaded into
    memory.

    Here's the source of an extended blah.c:

    int add(a, b)
    {
    return a + b;
    }

    int muladd(a, b, c)
    {
    return add(a, b * c);
    }

    int muladd2(a, b, c)
    {
    return muladd(a, b, c);
    }

    Now I compile it and look at the object file with objdump:

    $ objdump -r blah.o

    RELOCATION RECORDS FOR [.text]:
    OFFSET TYPE VALUE
    0000001a R_386_PC32 add
    00000030 R_386_PC32 muladd

    What this tells me is that at offset 0x1a into the text section (which
    is offset 0x4e in the file, since the text section starts at 0x34), I
    need to insert the offset to the start of the function <add>. And at
    offset 0x30 in the text section (0x64 in the file), I need to insert the
    offset to the start of the function <muladd>.

    The .o file also contains a table of where the start of each function
    is:

    $ objdump -t blah.o

    00000000 g F .text 0000000b add
    0000000b g F .text 00000018 muladd
    00000023 g F .text 00000016 muladd2

    This tells me the code for add is at the beginning, muladd starts at 0xb
    and muladd2 starts at 0x23. It also tells me how long each function is
    (0xb, 0x18 and 0x16 bytes respectively).

    So I have all the information I need here to load all the functions into
    memory and patch things up.

    Here's one way to do it for example:

    1. Load the whole .text section (from 0x34 to 0x34 + 0x23 + 0x16 in
    blah.o) into a char * buffer allocated with malloc.
    2. Patch the relocations. Code to do this at the end of this post.

    I have done this "manually" in the sense that I used objdump to examine
    blah.o and then hardcoded the numbers into the program. but the
    information is all there in blah.o (that's where objdump got it from
    after all).

    So to automate the process properly you need to parse the .o file.

    This is a helpful guide I found to loading and linking generally:

    http://www.linuxjournal.com/node/6463/print

    There is also a library called libelf you could consider using to parse
    the .o file:

    http://directory.fsf.org/libs/misc/libelf.html

    Note that all this applies to ELF files. If you're using .obj files on
    Windows, I don't think they're exactly the same, but the general
    principle is similar. You'd have to find some docs for that, which may
    be harder as Windows is not free software. Or, alternatively, just
    specify that the "executable format" your miniOS uses is based on ELF.

    Or you could write a script that actually invokes objdump to get the
    information you need and generates a much simpler ".xex" file for your
    miniOS in a format you define yourself.

    Here's the code then that does some minimal "linking":

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

    char *load_text(void)
    {
    FILE *fp = fopen("./blah.o", "rb");
    char *buf = malloc(0x57);
    int32_t *p;

    /* Read the whole of the .text section into the buffer */
    fseek(fp, 0x34L, SEEK_SET);
    fread(buf, 1, 0x57, fp);

    /* Fix up the "relocations". */
    p = (int32_t *) (buf + 0x1a);

    /*
    * This is the call from muladd to add. add starts at 0, muladd starts at
    * 0x1a. Offset is from instruction after muladd. So go back 0x1a + 4 bytes
    */
    *p = -(0x1a + 4 - 0);

    /*
    * This is the call from muladd2 to muladd. muladd2 starts at 0x30, muladd
    * starts at 0xb.
    */
    p = (int32_t *) (buf + 0x30);
    *p = -(0x30 + 4 - 0xb);

    return buf;
    }

    typedef int (*add_t)(int, int);
    typedef int (*muladd_t)(int, int, int);

    int main(int argc, char **argv)
    {
    char *code = load_text();
    add_t add = (add_t) code;
    muladd_t muladd = (muladd_t) (code + 0xb);

    int result = muladd(2, 3, 4);

    printf("%d\n", result);

    free(code);
    return 0;
    }
    Ben C, May 14, 2006
    #13
  14. Guest

    Perl...Why didn't I think of that. Seeing as I know some perl it was
    kindof stupid of me not to think of that. And if I'm correct there is
    some method of embeding perl into C code am I right? I'm not intirely
    sure how to do that in perl, however, it seems like it would be far
    easier to do in some sort of scripting language. I think that it is
    time to re ask my question in a Perl newsgroup. Thanks everyone.
    Nori

    SM Ryan wrote:
    > "" <> wrote:
    > # Two questions.
    > #
    > # 1)Is there any way that I can read from an executable and then execute
    > # what I have read.
    >
    > Many systems provide for things like dynamic loading or to store
    > new instructions in memory and make those instructions executable,
    > but the methods tend to be specific to each system.
    >
    > # 2)Is there anyway that I can modify the source code of a compiler so
    > # that I can include it in another program to compile other files in that
    >
    > Not all installed systems have a c compiler anywhere on the machine.
    >
    > The usual way to do this is to use a portable interpretter such as
    > Perl, Tcl, Forth, etc.These languages let you load source code
    > and then run it, or a partially compiled form of the source. I wouldn't
    > try to compile and load C fragments within a program: too complicated
    > and not very portable.
    >
    > --
    > SM Ryan http://www.rawbw.com/~wyrmwif/
    > GERBILS
    > GERBILS
    > GERBILS
    , May 14, 2006
    #14
  15. On Sun, 14 May 2006 08:44:23 UTC, SM Ryan
    <> wrote:

    > "" <> wrote:
    > # Two questions.
    > #
    > # 1)Is there any way that I can read from an executable and then execute
    > # what I have read.


    No, not in a portable way.

    > # 2)Is there anyway that I can modify the source code of a compiler so
    > # that I can include it in another program to compile other files in that


    No, not in a portable way.

    > Not all installed systems have a c compiler anywhere on the machine.
    >
    > The usual way to do this is to use a portable interpretter such as
    > Perl, Tcl, Forth, etc.These languages let you load source code
    > and then run it, or a partially compiled form of the source. I wouldn't
    > try to compile and load C fragments within a program: too complicated
    > and not very portable.



    There are some C interpreters around. You may even write such a kind
    by yourself.

    There is nothing in the standard that requires that a C program has to
    run natively. Simply write an interpreter that understunds C or a
    compiler that delivers not a binary but byte code or something else
    that can been interpreted easy by a program and an interpreter that
    interprets that byte code.

    --
    Tschau/Bye
    Herbert

    Visit http://www.ecomstation.de the home of german eComStation
    eComStation 1.2 Deutsch ist da!
    Herbert Rosenau, May 15, 2006
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    15
    Views:
    476
    Dave Thompson
    Aug 21, 2006
  2. pratap
    Replies:
    20
    Views:
    747
    Flash Gordon
    Mar 7, 2007
  3. Jason Cavett
    Replies:
    8
    Views:
    606
    Sanjay
    May 16, 2007
  4. Kaiser S.
    Replies:
    3
    Views:
    962
  5. Replies:
    0
    Views:
    425
Loading...

Share This Page