【问题标题】:MakeCodeWritable使代码可写
【发布时间】:2012-10-26 14:30:27
【问题描述】:

下午好。

我在一本书上得到了下面的代码。我正在尝试执行它,但我不知道 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();


}

【问题讨论】:

    标签: xcode gcc mprotect


    【解决方案1】:

    first 参数应该是(char *)P,因为看起来您想修改函数P 内的代码。第二个参数是函数P 的结束地址。可以先编译代码,用objdump -d查看P的首尾地址,然后计算出函数的大小SIZE,然后在makeCodeWritable( (char *)P, ((char *)P) + SIZE中手动指定。

    第二种方法是利用as 获取函数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();
    }
    

    经过一些修改以支持 Mac OS X 中的 LLVM GCCas

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

    【讨论】:

    • 非常感谢。我试试看。
    猜你喜欢
    • 1970-01-01
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 2014-08-20
    • 1970-01-01
    • 2010-09-14
    • 2013-08-27
    相关资源
    最近更新 更多