How can I copy a function into a buffer in memory?

0

I'm trying to copy a function into a buffer in memory and execute it from there. I have created a reference to the actual function and copied it into the memory address with PAGE_EXECUTE_READ privileges. For some reason I'm getting an access violation error.

This is the code:

void function1()
 {

    WinExec("calc.exe", SW_NORMAL);
 }


int main() 
{

    void* mem = VirtualAlloc(nullptr, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    CopyMemory(mem, &function1, 4096);
    VirtualProtect(mem, 4096, PAGE_EXECUTE_READ, NULL);
    ((void(*)())mem)();
    return 1;
}

The buffer in mem:

e9 b1 03 00 00 e9 7c 28 00 00 e9 63 40 00 00 e9 52 2e 00 00 e9 dd 24 00 00 e9 28 41 00 00 cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc

The error message:

0xC0000005: Access violation executing location 0x0000*****

memory
buffer
function-pointers
asked on Stack Overflow Jan 1, 2021 by gal • edited Jan 1, 2021 by Dhrumil shah

1 Answer

0

One problem that you are having for sure is that compilers usually generate code that uses relative calls and jumps.

So for example, your buffer in mem starts with the following 5 bytes in hex:

e9 b1 03 00 00

That 0xe9 is an opcode that says to treat the next 4 bytes as a signed number in little-endian order and to jump to the address formed by adding that signed number to the address of the first byte following the instruction.

By copying the code from the actual function to the buffer you are changing that relative jump instruction to mean "jump to the address formed by adding 0x3b1 to the address of the end of that 5 byte instruction in the buffer" which resolves to "jump to the address of the buffer + 0x3b6".

The point is that you generally can't just copy a function from one place to another without checking first that you don't have any relative addressing that will break as a result of the copying. You can disassemble your function (for example by using the "u" command from windbg) to check for such instructions.

answered on Stack Overflow Jan 2, 2021 by Tim Boddy

User contributions licensed under CC BY-SA 3.0