2011년 3월 17일 목요일

코드를 힙에 복사해서 실행 하기

mprotect() 함수

int mprotect(const void * addr, size_t len, int prot);

메모리 영역 보호 설정하기

호출 프로세스의 메모리 페이지들 가운데 addr, addr+len -1  주소 범위를 포함하고 잇는 것들에 대한 보호 방식을 변경 한다.

PROT_NONE : 접근할 수 없다.
PROT_READ : 읽기
PROT_WRITE : 쓰기
PROT_EXEC : 실행

이걸로 다음과 같은 작업을 할수 있다.

함수를 함수 포인터에 카피한다음
그걸 수행 하게 할수 있다.
즉 heap영역에 코드를 복사하고 수행 할수도 있다.

func();  < --- 어떤 수행을 하는 코드가 있다고 하고

memcpy( p, func , 대강 크기);

p어드레스를 수행 가능하게 mprotect()를 해주면

p를 수행 시킬수도 있다.

ex) binary hacks라는 책에서 발췌
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>

double func(void)
{
    return 3.14;
}

void allow_execution(const void *addr)
{
    long pagesize = (int)sysconf(_SC_PAGESIZE);
    char *p = (char *)((long)addr & ~(pagesize -1L));
    mprotect(p, pagesize * 10L, PROT_READ | PROT_WRITE | PROT_EXEC);
}

int main(int argc, char **argv)
{
    void *p = malloc(100);
    memcpy(p, func, 1000);
    allow_execution(p);
    printf("PI equals to %g\n", ((double (*) (void))p) ());
}

$./mprotect2
PI equals to 3.14

댓글 없음: