C: Run machine code from memory -


i want execute code memory; longterm goal create self-decrypting app. understand matter started roots. created following code:

#define unencrypted true  #define sizeof_function(x) ( (unsigned long) (&(endof_##x)) - (unsigned long) (&x)) #define endof_function(x) void volatile endof_##x() {} #define declare_end_of_function(x) void endof_##x();  #include <unistd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/mman.h> #include <sys/types.h>  unsigned char *bin;  #ifdef unencrypted void hexdump(char *description, unsigned char *todump, unsigned long length) {     printf("hex-dump of \"%s\":\n", description);     (int = 0; < length; i++) {         printf("%02x", todump[i]);     }     printf("\n"); }   void hello_world() {     printf("hello world!\n"); } endof_function(hello_world); #endif  int main (void) {     errno = 0;     unsigned long hello_worldsize = sizeof_function(hello_world);     bin = malloc(hello_worldsize);      //compute start of page     size_t pagesize = sysconf(_sc_pagesize);     uintptr_t start = (uintptr_t) bin;     uintptr_t end = start + (hello_worldsize);     uintptr_t pagestart = start & -pagesize;     bin = (void *)pagestart;      //set mprotect bin write-only     if(mprotect(bin, end - pagestart, prot_write) == -1) {         printf("\"mprotect\" failed; error: %s\n", strerror(errno));         return(1);     }      //get size , adresses     unsigned long hello_worldadress = (uintptr_t)&hello_world;     unsigned long binadress = (uintptr_t)bin;      printf("address of hello_world %lu\nsize of hello_world %lu\nadress of bin:%lu\n", hello_worldadress, hello_worldsize, binadress);      //check if hello_worldadress points hello_world()     void (*checkadress)(void) = (void *)hello_worldadress;     checkadress();      //print memory contents of hello_world()     hexdump("hello_world", (void *)&hello_world, hello_worldsize);      //copy hello_world() bin     memcpy(bin, (void *)hello_worldadress, hello_worldsize);      //set mprotect bin read-execute     if(mprotect(bin, end - pagestart, prot_read|prot_exec) == -1) {         printf("\"mprotect\" failed; error: %s\n", strerror(errno));         return(1);     }      //check if contents @ binadress same of hello_world     hexdump("bin", (void *)binadress, hello_worldsize);      //execute binadress     void (*executebin)(void) = (void *)binadress;     executebin();      return(0); } 

however segfault-error; programs output following:

(on os x; i86-64):

adress of hello_world 4294970639

size of hello_world 17 adress of bin:4296028160 hello world! hex-dump of "hello_world": 554889e5488d3d670200005de95a010000 hex-dump of "bin": 554889e5488d3d670200005de95a010000 program ended exit code: 9 

and on raspi (linux 32-bit arm):

adress of hello_world 67688 size of hello_world 36 hello world! hello world! hex-dump of "hello_world": 00482de90db0a0e108d04de20c009fe512ffffeb04008de50bd0a0e10088bde8d20b0100 hex-dump of "bin": 00482de90db0a0e108d04de20c009fe512ffffeb04008de50bd0a0e10088bde8d20b0100 speicherzugriffsfehler //this german memory access error 

where mistake?


the problem was, printf-call in hello_world based on relative jump address, of course doesn't work in copied function. testing purposes changed hello_world to:

int hello_world() {     //_printf("hello world!\n");     return 14; } 

and code under "//execute binadress" to:

int (*executebin)(void) = (void *)binadress; int test = executebin(); printf("value: %i\n", test); 

which prints out 14 :d

on arm, have flush instruction cache using function cacheflush, or code may not run properly. required self-modifying code , jit compilers, not needed x86.

additionally, if move chunk of code 1 location another, have fixup relative jumps. typically, calls library functions implemented jumps relocation section, , relative.

to avoid having fixup jumps, can use linker tricks compile code start @ different offset. then, when decrypting, load decrypted code offset. two-stage compilation process used: compile real code, append resulting machine code decryption stub, , compile whole program.


Comments

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

android - Associate same looper with different threads -

visual studio 2010 - Connect to informix database windows form application -