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  }