← 목록으로

동적 분석: 디버거로 실행 흐름 추적하기

[Rev] 리버싱 · 작성: 2026-07-19 19:32:50 · 수정: 2026-07-21 23:27:57 · 조회 20

디버거를 "브레이크포인트 걸고 F5 누르는 도구"로만 알면, gdb가 실제로 다른 프로세스의 실행을 어떻게 멈추고, 메모리를 어떻게 들여다보는지를 놓치게 된다. 이건 커널이 제공하는 단 하나의 시스템 콜, ptrace() 위에 전부 세워진 기능이다.

커널 레벨: ptrace()가 디버거에게 주는 권한

리눅스 커널은 ptrace(PTRACE_ATTACH, pid, ...) 시스템 콜을 통해, 한 프로세스(디버거)가 다른 프로세스(대상)의 메모리·레지스터·시그널 전달을 완전히 통제할 수 있게 해준다. 이건 일반적인 프로세스 격리 원칙(각 프로세스는 자기 메모리만 본다)에 대한 명시적 예외다 — 커널이 "디버거 프로세스는 이 대상 프로세스에 대해 특별한 권한을 가진다"고 승인해주는 것.

실전 흐름: 크래시 지점을 스택 프레임까지 추적하기

(gdb) b *0x401234        # 특정 주소에 브레이크포인트
(gdb) run < input.txt
(gdb) info registers      # 현재 레지스터 상태 확인
(gdb) x/20xg $rsp         # 스택 상위 20개 8바이트 값을 hex로 확인
(gdb) bt                  # 콜스택(백트레이스) — 어떤 함수가 어떤 함수를 호출해 여기까지 왔는지

pwndbg/gef 같은 gdb 확장은 이 원시 명령어들을 조합해서, 레지스터·스택·현재 명령어를 한 화면에 자동으로 보여준다 — 원리는 위의 ptrace 기반 기본 명령어 조합과 동일하고, 편의성만 크게 개선된 것이다.

여기서 끝나지 않는다: 다음 단계로의 연결

디버거를 "따로 존재하는 마법 같은 도구"가 아니라 **"커널이 ptrace로 열어준 문 하나를 편리하게 감싼 래퍼"**로 이해하면, 왜 안티 디버깅이 대부분 이 ptrace 시스템 콜 자체를 겨냥하는지, 그리고 왜 그 우회 방법들도 결국 "커널에게 다른 방식으로 같은 정보를 요청하는" 형태로 수렴하는지가 같은 논리로 설명된다.

리버싱 카테고리의 글 (3/11)

  1. 리버싱이란 무엇인가: 정적 분석 기초
  2. 어셈블리어 읽기 기초 (x86-64)
  3. 동적 분석: 디버거로 실행 흐름 추적하기
  4. 안티 디버깅 / 안티 리버싱 기법과 우회
  5. 패킹과 언패킹: 실행 파일을 압축/암호화해서 숨기기
  6. Frida로 동적 계측/후킹하기
  7. 안드로이드 앱 리버싱: APK 분석 기초
  8. iOS 앱 리버싱 기초
  9. 크랙미(Crackme) 실습 방법론
  10. PE 포맷 내부 구조: Windows 실행 파일 뜯어보기
  11. 코드 난독화 해제: Control Flow Flattening 분석하기
← 어셈블리어 읽기 기초 (x86-64) 안티 디버깅 / 안티 리버싱 기법과 우회 →