what is ptrace

문제를 풀면서 최근 ptrace 함수가 자주 보인다. 따라서 이 함수에 대해 간단한 분석을 하려고 한다.

원형

C
#include <sys/ptrace.h>
#include <sys/types.h>

long ptrace(enum __ptrace_request request, pid_t pid,
            void *addr, void *data);

원형을 다음과 같다. request에 이제 흔히 유명한 PTRACE_TRACEME , PTRACE_ATTACH .. 등등 같은 요청들이 들어간다. gdb 같은 디버거가 이 함수들 통해 구현이 되어 있다.

대표적인 예시를 보여주자면,

Anti-debug

C
    if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
        printf("디버거가 붙어있음!\n");
        return 1;
    }

디버깅이 붙어 있는지를 PTRACE_ATTACH 를 통해 알 수 있다. pid가 0인 이유는 PTRACE_TRACEME는 어차피 자신 프로세스에 대해 진행하므로 관례상 아무값도 아닌 0 즉, NULL을 넣어준다.

다른 프로세스에 디버깅 붙이기

C
   if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
        perror("PTRACE_ATTACH");
        return 1;
    }

PTRACE_ATTACH 으로 pid에 붙일 수가 있다.

attach 후에 해당 프로세스 메모리 읽기, 쓰기

C

    void *addr = (void*)0x601000;  // 대상의 메모리 주소 예시
    data = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
    printf("원래 값: 0x%lx\n", data);

    ptrace(PTRACE_POKEDATA, pid, addr, data ^ 0xdeadbeef);  // 값 XOR

PTRACE_PEEKDATA → 메모리 읽기

PTRACE_POKEDATA. → 메모리 쓰기