Skip to content

Instantly share code, notes, and snippets.

@NHollmann
Created April 3, 2021 00:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NHollmann/462d491220c7e648c9ce360f1925a7ee to your computer and use it in GitHub Desktop.
Save NHollmann/462d491220c7e648c9ce360f1925a7ee to your computer and use it in GitHub Desktop.
Run dynamic code on Unix (x86)
// Run dynamic code on Unix (x86)
// Compile with: gcc -o dynamicCodeUnix dynamicCodeUnix.c
// Tutorial: https://nicolashollmann.de/blog/run-dynamic-code-unix/
#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;
}
/**
* Entrypoint of the program.
*
* @return exit code of the program, 0 if successful,
* -1 in case of an error
*/
int main(void)
{
// Define the code we want to execute
const char code[] = {
// Direct set
0xb8, 0x05, 0x00, 0x00, 0x00, // mov eax, 0x05
// Addition
0x05, 0x06, 0x00, 0x00, 0x00, // add eax, 0x06
// Subtraction
0x2d, 0x01, 0x00, 0x00, 0x00, // sub eax, 0x01
// Return (result in EAX)
0xc3 // ret
};
// Run the code
if (!run_code(code, sizeof code)) {
return -1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment