On 9 Jan 2007 07:04:11 -0800, sturlamolden <[EMAIL PROTECTED]> wrote: > > 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_string(PyObject *self, PyObject *args) > { > char *s; > int size; > int arg1, arg2, arg3; > typedef int (*func_t)(int,int,int); > func_t pfunc; > if(!PyArg_ParseTuple(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(arg1, 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_ParseTuple(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. -- http://mail.python.org/mailman/listinfo/python-list