2

下午好。

我在一本书上得到了下面的代码。我正在尝试执行它,但我不知道 MakeCodeWritable 函数上的“第一个”和“最后一个”参数是什么,或者在哪里可以找到它们。有人可以帮忙吗?这段代码是关于 C 混淆方法的。我正在使用 Xcode 程序和 LLVM GCC 4.2 编译器。

#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();


}
4

1 回答 1

0

first参数应该是(char *)P,因为看起来您想修改函数内部的代码P。第二个参数是函数的结束地址P。可以先编译代码,然后使用objdump -d查看开始和结束的地址P,然后计算函数的大小,SIZE,然后在makeCodeWritable( (char *)P, ((char *)P) + SIZE.

第二种方法是利用as来获取 function 的大小P,但这取决于您平台上的汇编语言。这是我从您的代码中修改的代码狙击,它应该能够在 Linux 平台上的 GCC 4.x 中的 x86、x86_64 中编译和运行。

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();
}

经过一些修改以支持LLVM GCCas在 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);
于 2012-11-07T03:24:49.430 回答