UNIXworkcode

1 /* 2 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 3 * Version 2, December 2004 4 * 5 * Copyright (C) 2016 Olaf Wintermann <olaf.wintermann@gmail.com> 6 * 7 * Everyone is permitted to copy and distribute verbatim or modified 8 * copies of this license document, and changing it is allowed as long 9 * as the name is changed. 10 * 11 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 12 * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 13 * 14 * 0. You just DO WHAT THE FUCK YOU WANT TO. 15 */ 16 17 /* 18 * compile instruction 19 * dependency: https://github.com/intelxed/xed 20 * 21 * export XED=/path/to/xed/installation 22 * cc -std=gnu99 -m64 -o x86dec -I$XED/include -L$XED/lib x86decode.c -lxed -lxed-ild 23 */ 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 29 30 #include <sys/mman.h> 31 32 #include <xed/xed-interface.h> 33 #include <xed/xed-common-hdrs.h> 34 35 #define MMAP_LEN 1024 36 37 typedef int(*fn)(int,int); 38 int func(int a, int b) { 39 return a + b; 40 } 41 42 int main(int argc, char **argv) { 43 xed_tables_init(); 44 45 const xed_uint8_t *inst = (const xed_uint8_t*)func; 46 47 xed_decoded_inst_t dec; 48 xed_error_enum_t error; 49 50 char buffer[1024]; 51 52 // allocate executable memory 53 void *execmem = mmap(NULL, MMAP_LEN, PROT_EXEC | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 54 if(!execmem) { 55 perror("mmap"); 56 return -1; 57 } 58 char *em = execmem; 59 60 printf("copy function code:\n\n"); 61 for(int i=0;i<256;i++) { 62 // init xed_decoded_inst_t struct 63 memset(&dec, '\0', sizeof(xed_decoded_inst_t)); 64 xed_decoded_inst_set_mode(&dec, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b); 65 66 // decode instruction 67 error = xed_decode(&dec, inst, 15); 68 if(error != XED_ERROR_NONE) { 69 // decode error 70 printf("%s\n", xed_error_enum_t2str(error)); 71 break; 72 } 73 74 // print instruction 75 xed_format_context(XED_SYNTAX_ATT, &dec, buffer, 1024, 0, 0, 0); 76 printf("%s\n", buffer); 77 78 xed_uint_t instlen = xed_decoded_inst_get_length(&dec); 79 80 // copy instruction to new memory 81 memcpy(em, inst, instlen); 82 em += instlen; 83 84 // stop loop after any ret instruction 85 if(!memcmp("ret", buffer, 3)) { 86 break; 87 } 88 89 inst += instlen; 90 } 91 92 printf("\nexecute new code:\n\n"); 93 94 fn f = (fn)execmem; // function pointer to execmem 95 96 int a = 10; 97 int b = 50; 98 int res = f(a, b); // run code from mmap memory 99 100 printf("f(%d, %d) = %d\n", a, b, res); 101 102 munmap(execmem, MMAP_LEN); 103 104 return 0; 105 } 106