In c you can copy the code as a block of memory, so I was wondering if it was done by some developers or otherwise sensible and safe to copy the code of a function into a block allocated in the heap, change the code of the function in the heap, and then (mprotect ...) perform the "copied and modified" function, and what might be the consequences of leaving heap blocks executable from a security point of view. Or is there a way to run code defined at runtime in c?
void* handler(void* arg1, void* arg2, void* arg3) {
typedef void* (*function)(void*, void*, void*, void*);
return ((function)FUNCTION_ADDRESS_TO_REPLACE)(SELF_ADDRESS_TO_REPLACE,
arg1,
arg2,
arg3);
}
void* allocate_new_function(void* function, void* self) {
void* (*fun) () = 0;
uint64_t size = (uint64_t) &allocate_new_function - (uint64_t) &handler; //48 byte
fun = malloc(size);
memcpy(fun, handler, size);
replace(fun, size, SELF_ADDRESS_TO_REPLACE, self);
replace(fun, size, FUNCTION_ADDRESS_TO_REPLACE, function);
char *to_mprotect = (char*) (((uint64_t) fun / PAGE_SIZE) * PAGE_SIZE);
uint64_t offset = (uint64_t) fun % PAGE_SIZE;
if (offset + size > PAGE_SIZE) {
mprotect(to_mprotect,
PAGE_SIZE,
PROT_READ | PROT_EXEC | PROT_WRITE);
mprotect(to_mprotect + PAGE_SIZE,
PAGE_SIZE,
PROT_READ | PROT_EXEC | PROT_WRITE);
} else {
mprotect(to_mprotect,
PAGE_SIZE,
PROT_READ | PROT_EXEC | PROT_WRITE);
}
return fun;
}
Here the allocated_function will execute the function "function" with implicit parameter self. Is there a better way to do this, or this method could be valid?
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1 Apple clang version 12.0.0 (clang-1200.0.32.29) Target: x86_64-apple-darwin20.2.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin