Reputation: 175
I learned about function pointers recently in class and I was wondering if you could assign a function pointer to a block of memory allocated by a program, fill the memory block with assembly commands (hex values of op codes), then call the memory block using the function pointer.
I don't know much about function pointers, but I'm guessing you can't assign them wherever you want in memory, they need to point to a function. If that's true, how can you create a function in memory to be called? Is that even possible?
Here's some code I typed up to show the concept. I used various opcode values to see if anything would work, and 0x90 (NOP) did not break it sometimes (but it did other times), and 0xC3 (ret) always broke it.
#include <stdlib.h> //for malloc
#include <cstring> //for memcpy
int main() //program entry
{
void(*test)() = NULL; //create function pointer, initialize to NULL
void* hold_address = (void*)malloc(100); //allocate memory, save the address it returns in a dummy pointer
int asm_commands[] = {0x90}; //create array of assembly commands, hex values
memcpy(hold_address, asm_commands, sizeof(asm_commands)); //copy the array into the reserved memory
test = (void(*)())hold_address; //set the function pointer to start of the allocated memory
test(); //call the function, crashes here
return 0; //exit the program
}
Upvotes: 2
Views: 489
Reputation: 106096
A few points:
your asm_commands[]
should probably be unsigned char
(or uint8_t
) - as is, you'll be copying 3 NUL/0 characters as well as the 0x90
some Operating Systems will just not let you execute instructions in memory you've allocated with malloc()
- they'll SIGSEGV or similar instead - that's intended to prevent certain types of stack overflow and other hackery
I suggest you write an actual function void f() { }
and see what opcodes are generated for it, using g++ -S
or whatever your compiler offers, as you might need to do something more than just 0xC3
to return properly (e.g. pop certain registers)
Upvotes: 2
Reputation: 6293
You can do what you describe. However, memory allocated with malloc()
might not have the permission for code execution - depending on your platform.
The way to allocate executable memory differs from OS to OS. On Linux, check mmap
. On Windows, see VirtualAlloc
.
Upvotes: 2
Reputation: 19863
Function calling is more complex than that.
You must at least modify the base pointer. I suggest you look at the dissassembly of a function call and try to mimic it
Upvotes: 1