GDB등 리눅스 디벙깅 툴에서도 ptrace를 기본적으로 사용하여 프로세스를 추적합니다.
기본적인 수행
- PTRACE_ATTACH : 프로세스를 추적하기 위해 붙잡음
- PTRACE_PEEKDATA : 프로세스 데이터 쓰기
- PTRACE_KILL : 프로세스 죽이기
- PTRACE_GETSIGINFO : 레지스터 값 가져오기
- PTRACE_DETACH : 프로세스를 놓아줌
이를 코드로 나타내면,
#include <stdio.h>
#include <sys/ptrace.h>
void main(int argc, char* argv[]) {
int pid = atoi(argv[1]);
if(ptrace(PTRACE_ATTACH, pid, 0, 0) == -1) {
printf("[%d] ATTACH fail...\n");
}
/* 작업 수행 */
sleep(10);
if( ptrace(PTRACE_DETACH, pid, 0, 0) == -1) {
printf("[%d] DETACH fail...\n");
}
}
PTRACE_ATTACH가 실패하는 경우
리눅스에서는 기본적으로 ptrace를 사용안함으로 설정되어 있다고 합니다.
ptrace를 사용함으로 바꾸기 위해서 다음과 같이 환경변수를 바꿔줍니다.
$sudo bash
#echo 0 > /proc/sys/kernel/yama/ptrace_scope
또는 부팅시 자동으로 적용되기 위해 ptrace.conf를 수정합니다.
$vi /etc/sysctl.d/10-ptrace.conf
kernel.yama.ptrace_scope = 0 #이 값이 초기에 1로 설정되어 있음, 0으로 변경