xcodegccmprotect

MakeCodeWritable


good afternoon.

I got the code below on a book. I'm trying to execute it, but I don't know what is the "first" and "last" parameters on the MakeCodeWritable function, or where I can find them. Someone can help? This code is about C obfuscation method. I'm using Xcode program and LLVM GCC 4.2 compiler.

#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

typedef unsigned int uint32;
typedef char* caddr_t;
typedef uint32* waddr_t;


#define Tam_celula  64

#define ALIGN __attribute__((aligned(Tam_celula)))

void makeCodeWritable(char* first, char* last) {

 char* firstpage = first - ((int)first % getpagesize());

   char* lastpage = last - ((int)last % getpagesize());

    int pages = (lastpage-firstpage)/getpagesize()+1;

    if (mprotect(firstpage,pages*getpagesize(), PROT_READ|PROT_EXEC|PROT_WRITE)==-1)         perror("mprotect");

}


void xor(caddr_t from, caddr_t to, int len){
    int i;
    for(i=0;i<len;i++){
        *to ^= *from; from++; to++;
    } }
void swap(caddr_t from, caddr_t to, int len){
    int i;
    for(i=0;i<len;i++){
        char t = *from; *from = *to; *to = t; from++; to++;
    } }
#define CELLSIZE 64
#define ALIGN asm volatile (".align 64\n");


void P() {
    static int firsttime=1; if (firsttime) {
        xor(&&cell5,&&cell2,CELLSIZE);
        xor(&&cell0,&&cell3,CELLSIZE);
        swap(&&cell1,&&cell4,CELLSIZE);
        firsttime = 0; }

    char* a[] = {&&align0,&&align1,&&align2,&&align3,&&align4,&&align5};
    char*next[] ={&&cell0,&&cell1,&&cell2,&&cell3, &&cell4,&&cell5};
    goto *next[0];

align0: ALIGN
cell0: printf("SPGM0\n");
    xor(&&cell0,&&cell3,3*CELLSIZE);
    goto *next[3];

align1: ALIGN
cell1: printf("SPGM2\n"); xor(&&cell0,&&cell3,3*CELLSIZE);
    goto *next[4];

align2: ALIGN
cell2: printf("SPGM4\n"); xor(&&cell0,&&cell3,3*CELLSIZE);
    goto *next[5];

align3: ALIGN
cell3: printf("SPGM1\n"); xor(&&cell3,&&cell0,3*CELLSIZE);
    goto *next[1];

align4: ALIGN
cell4: printf("SPGM3\n"); xor(&&cell3,&&cell0,3*CELLSIZE);
    goto *next[2];

align5: ALIGN
cell5: printf("SPGM5\n");
    xor(&&cell3,&&cell0,3*CELLSIZE);

}

int main (int argc, char *argv[]) {


     makeCodeWritable(...);
    P(); P();


}

Solution

  • The first argument should be (char *)P, because it looks like you want to modify code inside function P. The second argument is the ending address of function P. You can first compile the code, and using objdump -d to see the address of beginning and end of P, then calculate the size of the function, SIZE, then manually specify in the makeCodeWritable( (char *)P, ((char *)P) + SIZE.

    The second way is utilizing the as to get the size of function P, but it depends on the assembler language on your platform. This is code snipe I modified from your code, it should be able to compile and run in x86, x86_64 in GCC 4.x on Linux platform.

    align5: ALIGN
    cell5: printf("SPGM5\n");
        xor(&&cell3,&&cell0,3*CELLSIZE);
    
      // adding an label to the end of function P to assembly code
      asm ("END_P: \n");
      ;
    }
    
    extern char __sizeof__myfunc[];
    
    int main (int argc, char *argv[]) {
        // calculate the code size, ending - starting address of P
        asm (" __sizeof__myfunc = END_P-P \n");
        // you can see the code size of P
        printf("code size is %d\n", (unsigned)__sizeof__myfunc);
        makeCodeWritable( (char*)P, ((char *)P) + (unsigned)__sizeof__myfunc);
        P(); P();
    }
    

    With some modification to support LLVM GCC and as in Mac OS X

    int main (int argc, char *argv[]) {
        size_t sizeof__myfunc = 0;
        asm volatile ("movq $(_END_P - _P),%0;"
                : "=r" (sizeof__myfunc)
                : );
        printf("%d\n", sizeof__myfunc);