2

I want to take a piece of code, copy it into a global array and execute it from there.

In other words, I am trying to to copy a bunch of instructions from the code-section into the data-section, and then set the program-counter to continue the execution of the program from the data-section.

Here is my code:

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

typedef void(*func)();

static void code_section_func()
{
    printf("hello");
}

#define CODE_SIZE 73
// I verified this size in the disassembly of 'code_section_func'

static long long data[(CODE_SIZE-1)/sizeof(long long)+1];
// I am using 'long long' in order to obtain the maximum alignment

int main()
{
    func data_section_func = (func)data;
    memcpy((void*)data_section_func,(void*)code_section_func,CODE_SIZE);
    data_section_func();
    return 0;
}

I might have been naive thinking it could work, so I'd be happy to get an explanation why it didn't.

For example, after a program is loaded into memory, does the MMU restrict instruction-fetching to a specific area within the memory address space of the process (i.e., the code-section of the program)?

For the protocol, I have tested this with VS2013 compiler over a 64-bit OS and an x64-based processor.

Thanks

barak manos
  • 29,648
  • 10
  • 62
  • 114
  • Is [this](http://stackoverflow.com/questions/3755491/is-it-possible-to-execute-code-from-the-stack-in-standard-c) relevant to your question? – roelofs Aug 14 '14 at 15:31
  • 2
    [Another](http://unix.stackexchange.com/questions/5449/is-it-possible-to-execute-code-in-heap-space) - related to heap space this time – roelofs Aug 14 '14 at 15:33
  • [This](http://stackoverflow.com/questions/2019923/executing-machine-code-in-memory) might also be relevant – roelofs Aug 14 '14 at 15:34
  • 1
    @roelofs assuming OP is running on Windows (based on usage of VS2013), none of those are completely relevant, as they all deal with unix/linux – Drew McGowen Aug 14 '14 at 15:35
  • @roelofs: A little bit, because OP asks a similar thing (for 'stack' instead of 'data-section'). But the accepted answer refers only to the problem of how to compute the "size" of the function, whereas in my question I have computed that size and added it hard-coded. So my question relates strictly to why have I failed executing the code from the data-section (to which the other answer does not refer at all). – barak manos Aug 14 '14 at 15:35
  • The second answer on the third link (20 upvotes, but not the accepted one) deals with write and execute permissions - it sounds like that might be related? – roelofs Aug 14 '14 at 15:36
  • @roelofs: Yes, that one is much closer to my question. Except for the fact that it does not explain how to do it for a statically allocated global array (or if it's even possible). – barak manos Aug 14 '14 at 15:41

1 Answers1

4

Windows (and many other modern OSes) by default sets the data section as read/write/no-execute, so attempting to "call" a data object will fail.

Instead, you should VirtualAlloc a chunk of memory with the PAGE_EXECUTE_READWRITE protection. Note, it may be necessary to use FlushInstructionCache to ensure the newly-copied code is executed.

Drew McGowen
  • 11,471
  • 1
  • 31
  • 57