2012-02-16 2 views
4

나는 역동적으로 생성 된 코드로 좀더 해커 일을하려고 노력하고 있으며 알 수없는 opcode에 도달하면 OS가 신호를 보내길 원합니다. 이렇게하면 내 프로그램에 대한 메타 정보 레이어를 추가 할 수 있습니다.강제로 프로그램에 신호를 보내려면 어떻게합니까?

그러나 내 작은 테스트 프로그램의 경우 OS가 SIGILL을 보내는 것이 아니라 SIGBUS 또는 SIGSEGV를 보냅니다. 이것은 메모리가 위치한 페이지에 NX 비트가 설정되어 있음을 의미합니다.

메모리를 실행 가능하게 만드는 방법에 대한 정보는 무엇입니까?

#include <stdio.h> 
#include <signal.h> 
#include <stdlib.h> 
#include <string.h> 

void SIGILL_handler(int sig) 
{ 
    printf("Handling SIGILL\n"); 
} 

typedef void(*FUNC)(void); 

int main() 
{ 
    signal(SIGILL, SIGILL_handler); 

    int *bad = malloc(16); 
    memset(bad, 255, 16); 
    ((FUNC)bad)(); 

    printf("Returning like it's no big deal\n"); 

    return 0; 
} 

답변

6

mprotect 여기에 당신의 친구입니다 :

는 참고로, 여기 내 테스트 프로그램입니다. POSIX 호환 (SVr4, POSIX.1-2001)이므로 OS X 및 Linux에서 작동해야합니다.

int pagesize = sysconf(_SC_PAGE_SIZE); 
if (pagesize == -1) { 
    perror("sysconf"); 
    exit(1); 
} 

/* allocate 16 aligned pages */ 
void *bad = memalign(pagesize, 16 * pagesize); 
if (NULL == bad) { 
    fprintf("aah, out of mem :-(\n"); 
    exit(1); 
} 

if (-1 == mprotect(bad, 16 * pagesize, PROT_READ | PROT_WRITE | PROT_EXEC)) { 
    perror("mprotect"); 
    exit(1); 
} 

해야합니다.

두 번째 편집 : memalign의 호환성은 그렇게 쉽지 않을 것 같습니다. do memalign, valloc OS X 및 Linux에서 작동하지 않을 경우 그냥 malloc 일반 사용하고 반환 된 포인터에 충분한 바이트를 추가하여 정렬되도록 :-).

+3

사용을 고려 [ 'mmap (3)'] (http://linux.die.net/man/3/mmap) 대신에 하나의 시스템 콜에서 적절한 보호 비트를 가진 메모리를 할당 할 수있게 해주 며 의도하지 않게 보호 비트를 변경하는 것을 피할 수있다 같은 페이지에있는 다른 메모리에 저장됩니다. –

+0

@AdamRosenfield, 좋은 지적입니다! 더 나은 소리 :-) –

+0

그것이 효과가 있는지 궁금합니다. 나는이 접근법을 mmap과 함께 사용하지만 SIGSEGV 만 얻는다. 'addr = mmap (NULL, 8, PROT_EXEC, MAP_ANONYMOUS, 0, 0); ((FUNC) addr)(); ' –

0

나는이 오래 실현,하지만 다른 사람이 SIGILL 생성을 강제하려고하는 경우 다음 다른 대안은 다음과 같이 인라인 어셈블리를 사용하는 것입니다

asm(".byte 0x0f, 0x0b"); 

또는

asm("ud2"); 
관련 문제