Execute binary code

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chris Mellon

    #16
    Re: Execute binary code

    On 9 Jan 2007 07:04:11 -0800, sturlamolden <sturlamolden@y ahoo.nowrote:
    >
    Jorgen Grahn wrote:
    >
    For what it's worth[1], under Unix it /is/ impossible. The only way to bring in
    new code (short of dynamic libraries) is to call exec(2) or its variations,
    and all need a file system object to load the code from.
    >
    The x86 processor cannot tell the difference between code segments and
    data segments. If the executable code is stored in string, all you need
    is a pointer to the string holding the code. You can cast the string
    address to a function pointer (possibly through a void* if the compiler
    complains), then dereference (call) the function pointer.
    >
    Trojans, viruses and JIT compilers do this all the time. Here is an
    (untested) example:
    >
    static PyObject*
    call_code_in_st ring(PyObject *self, PyObject *args)
    {
    char *s;
    int size;
    int arg1, arg2, arg3;
    typedef int (*func_t)(int,i nt,int);
    func_t pfunc;
    if(!PyArg_Parse Tuple(args, "s#(iii)", &s, &size, &arg1, &arg2,
    &arg3)) return NULL;
    pfunc = (func_t)((void *)s); /* if it fails, try
    memcpy(&pfunc,& s,sizeof(void*) ) instead */
    return PyInt_FromLong( (long)pfunc(arg 1, arg2, arg3));
    }
    >
    Another possibility would be to just return the string address, and
    then make the call possibly using ctypes.
    >
    static PyObject*
    get_string_addr (PyObject *self, PyObject *args)
    {
    char *s;
    int size;
    if(!PyArg_Parse Tuple(args, "s#", &s, &size)) return NULL;
    return PyInt_FromLong( (long)((void*)s ));
    }
    >
    This works fine if the binary data is "pure" asm, but the impresssion
    the OP gave is that it's a compiled binary, which you can't just "jump
    into" this way.

    Comment

    • sturlamolden

      #17
      Re: Execute binary code


      Chris Mellon wrote:
      This works fine if the binary data is "pure" asm, but the impresssion
      the OP gave is that it's a compiled binary, which you can't just "jump
      into" this way.
      You may have to offset the function pointer so the entry point becomes
      correct.

      Comment

      • Chris Mellon

        #18
        Re: Execute binary code

        On 10 Jan 2007 08:12:41 -0800, sturlamolden <sturlamolden@y ahoo.nowrote:
        >
        Chris Mellon wrote:
        >
        This works fine if the binary data is "pure" asm, but the impresssion
        the OP gave is that it's a compiled binary, which you can't just "jump
        into" this way.
        >
        You may have to offset the function pointer so the entry point becomes
        correct.
        >
        That won't be enough. You basically would have to re-implement the OS
        loading process, handling relocations and loading any linked
        libraries. Possible, in theory, but very non-trivial.

        Comment

        • Jorgen Grahn

          #19
          Re: Execute binary code

          On 9 Jan 2007 07:04:11 -0800, sturlamolden <sturlamolden@y ahoo.nowrote:
          >
          Jorgen Grahn wrote:
          >
          >For what it's worth[1], under Unix it /is/ impossible. The only way to bring in
          >new code (short of dynamic libraries) is to call exec(2) or its variations,
          >and all need a file system object to load the code from.
          >
          The x86 processor cannot tell the difference between code segments and
          data segments. If the executable code is stored in string, all you need
          is a pointer to the string holding the code. You can cast the string
          address to a function pointer (possibly through a void* if the compiler
          complains), then dereference (call) the function pointer.
          >
          Trojans, viruses and JIT compilers do this all the time. Here is an
          (untested) example:
          [...]

          You probably need to flush the code cache somewhere there, too, don't you?
          Or will that resolve itself because that memory area hasn't been executed
          before?

          I must admit I haven't contemplated this since the MC68000 was state of the
          art, before caches became popular.

          /Jorgen

          --
          // Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
          \X/ snipabacken.dyn dns.org R'lyeh wgah'nagl fhtagn!

          Comment

          • Jorgen Grahn

            #20
            Re: Execute binary code

            On Wed, 10 Jan 2007 10:31:50 -0600, Chris Mellon <arkanes@gmail. comwrote:
            On 10 Jan 2007 08:12:41 -0800, sturlamolden <sturlamolden@y ahoo.nowrote:
            >>
            >Chris Mellon wrote:
            >>
            This works fine if the binary data is "pure" asm, but the impresssion
            the OP gave is that it's a compiled binary, which you can't just "jump
            into" this way.
            >>
            >You may have to offset the function pointer so the entry point becomes
            >correct.
            >>
            >
            That won't be enough. You basically would have to re-implement the OS
            loading process, handling relocations and loading any linked
            libraries. Possible, in theory, but very non-trivial.
            Yeah, that was implicitly my thinking a bit up in the thread. If all you
            have is an executable file (COFF/ELF/...) as a string, and you have no
            os.exec(string) or similar, then you're in trouble.

            At least if it has to work.

            /Jorgen

            --
            // Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
            \X/ snipabacken.dyn dns.org R'lyeh wgah'nagl fhtagn!

            Comment

            Working...