English | German

Hi, I'm Nicolas Hollmann and this is my personal site and blog.
Happy reading! 📖

Run dynamic code in C on Unix

April 03, 20212 min read

Run dynamic code in C on Unix

This is just a short extension of my previous post regarding dynamic code execution on Windows. While you can find examples of this technique for unix on other pages, I liked to try it out myself and post it here for documentation purposes. Please read my previous post for more information, espacially regarding the limitations.

How it works (on Unix)

The technique is really the same as on windows, only that we need to call other system functions to allocate and manage our memory. As always, the full sourcecode is on GitHub.

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/mman.h>

* Helper function to execute dynamic code.
* @param code a pointer to the code to execute
* @param length the length of the code
* @return true if the code run successfully, otherwise false
bool run_code(const void* code, size_t length)
	// Allocate new memory for code execution.
	// We don't set the execute flag because we won't want to
	// open doors to malicious software.
	void* dynMemory = mmap(0, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if (dynMemory == MAP_FAILED)
		printf("Alloc Error\n");
		return false;

	// Copy code to new memory.
	memcpy(dynMemory, code, length);

	// Change protection.
	// We remove the write flag and set the execute flag on that page.
	if (mprotect(dynMemory, length, PROT_EXEC))
		printf("Protect Error\n");
		return false;

	// Call the new function in memory.
	int result = ((int (*)(void))dynMemory)();
	printf("Result: %d\n", result);

	// At the end we free the memory.
	if (munmap(dynMemory, length))
		printf("Free Error\n");
		return false;

	return true;

The explanation for this code is the same as in the Windows version, only with some different functions:

Windows Unix
VirtualAlloc mmap
VirtualProtect mprotect
VirtualFree munmap

Make sure you don’t run code from an untrusty source. It will run with the same permissions as the calling process/thread.

Full sourcecode on GitHub: GitHub Gist

© 2022, Nicolas Hollmann