Skip to content

Instantly share code, notes, and snippets.

@sciolist
Created August 5, 2012 14:09
Show Gist options
  • Select an option

  • Save sciolist/3265035 to your computer and use it in GitHub Desktop.

Select an option

Save sciolist/3265035 to your computer and use it in GitHub Desktop.
A little method builder
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <limits.h>
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
struct state {
int32_t test;
};
#define M_BEGIN \
if(ofs != ~ofs) goto __end; \
__start: { \
#define M_END \
} \
__end: { \
void *_start = &&__start; \
void *_end = &&__end; \
memcpy(&program[ofs], _start, _end - _start); \
return ofs + (_end - _start); }
uint32_t op1(struct state *state, void *program, size_t ofs) {
M_BEGIN;
state->test = 50;
M_END;
}
uint32_t op2(struct state *state, void *program, size_t ofs) {
M_BEGIN;
state->test += 5;
M_END;
}
size_t add_ops(struct state *state, void *ptr) {
size_t ofs = 0;
ofs = op1(state, ptr, ofs);
ofs = op2(state, ptr, ofs);
ofs = op2(state, ptr, ofs);
return ofs;
}
void create_and_execute(struct state *state) {
size_t max = PAGESIZE * 10;
void *ptr = malloc(max);
memset(ptr, 0xc3, max);
size_t ofs = add_ops(state, ptr);
size_t size = PAGESIZE * ((ofs / PAGESIZE) + 1);
void *run = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_ANON, -1, 0);
memset(run, 0xc3, size);
memcpy(run, ptr, ofs);
free(ptr);
void(*method)(void) = run;
method();
}
int main(void) {
struct state state;
state.test = 0;
create_and_execute(&state);
printf("state.test = %d\n", state.test);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment