#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <xed/xed-interface.h>
#include <xed/xed-common-hdrs.h>
#define MMAP_LEN 1024
typedef int(*fn)(int,int);
int func(int a, int b) {
return a + b;
}
int main(int argc, char **argv) {
xed_tables_init();
const xed_uint8_t *inst = (const xed_uint8_t*)func;
xed_decoded_inst_t dec;
xed_error_enum_t error;
char buffer[1024];
void *execmem = mmap(NULL, MMAP_LEN, PROT_EXEC | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if(!execmem) {
perror("mmap");
return -1;
}
char *em = execmem;
printf("copy function code:\n\n");
for(int i=0;i<256;i++) {
memset(&dec, '\0', sizeof(xed_decoded_inst_t));
xed_decoded_inst_set_mode(&dec, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b);
error = xed_decode(&dec, inst, 15);
if(error != XED_ERROR_NONE) {
printf("%s\n", xed_error_enum_t2str(error));
break;
}
xed_format_context(XED_SYNTAX_ATT, &dec, buffer, 1024, 0, 0, 0);
printf("%s\n", buffer);
xed_uint_t instlen = xed_decoded_inst_get_length(&dec);
memcpy(em, inst, instlen);
em += instlen;
if(!memcmp("ret", buffer, 3)) {
break;
}
inst += instlen;
}
printf("\nexecute new code:\n\n");
fn f = (fn)execmem;
int a = 10;
int b = 50;
int res = f(a, b);
printf("f(%d, %d) = %d\n", a, b, res);
munmap(execmem, MMAP_LEN);
return 0;
}