Skip to content

Instantly share code, notes, and snippets.

@stepancheg
Created January 26, 2010 03:19
Show Gist options
  • Save stepancheg/286509 to your computer and use it in GitHub Desktop.
Save stepancheg/286509 to your computer and use it in GitHub Desktop.
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int firstVersion(int param) {
printf("!%d\n", param);
return param;
}
int secondVersion(int param) {
printf("?%d\n", param);
return param;
}
int magicFunction(int param) {
// caller frame IP
char* pp = (char*) __builtin_return_address(0);
// we must be called using 5-byte call instruction
if (pp[-5] != char(0xE8))
abort();
// where address should be replaced
char* target = pp - 4;
// real function, choosing implementation randomly
int (*function)(int) = random() % 2 == 0 ? &firstVersion : &secondVersion;
uint32_t newValue = (uint32_t) (uint64_t) function;
// call jumps to relative address, so computing delta
uint32_t delta = newValue - (uint32_t) (uint64_t) target - 4;
printf("patching at %X with value %X\n", (int) (uint64_t) target, newValue);
if (0 != mprotect((void*) ((uint64_t) target / 4096 * 4096), 4096 * 2, PROT_READ|PROT_WRITE|PROT_EXEC))
abort();
// do patching
memcpy(pp - 4, &delta, 4);
// calling the function
return function(param);
}
int main() {
srandom(time(0));
for (int i = 0; i < 5; ++i) {
printf("@%d\n", magicFunction(i));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment