Skip to content

Instantly share code, notes, and snippets.

@kristianlm
Created January 11, 2021 18:03
Show Gist options
  • Save kristianlm/5a1c150d9c90dfabca6f16cd18948dd9 to your computer and use it in GitHub Desktop.
Save kristianlm/5a1c150d9c90dfabca6f16cd18948dd9 to your computer and use it in GitHub Desktop.
how to execute self-generated x86 machine code on Linux
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
int main(int argc, char *argv[]) {
unsigned int pagesize;
pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1) { perror("sysconf"); }
size_t bufsize = 4 * pagesize;
uint8_t *buf = aligned_alloc(pagesize, bufsize);
if (buf == 0) { perror("memalign"); }
// write x86 opcodes directly into memory. this is almost always a
// very bad idea.
memcpy(buf,
"\xB8\x00\x11\x22\x33" // literal => eax
"\xC3" // => retn (return from near procedure)
, 6);
// then write-protect and make executable
if (mprotect(buf, bufsize, PROT_EXEC|PROT_READ ) < 0) {
fprintf(stderr, "mprotect failed: %s\n", strerror(errno));
return 1;
}
int (*ptr)(int) = (int (*)(int)) buf;
printf("returns: 0x%X\n", ptr(42));
return 0;
}
@kristianlm
Copy link
Author

kristianlm commented Jan 11, 2021

$ gcc x86-codegen-at-runtime.c -o x86-codegen-at-runtime && ./x86-codegen-at-runtime
returns: 0x33221100

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment