imnyang's workspace

뒤로

Debugger 원리#

디버거는 단순히 프로그램을 실행하는 것이 아니라, 실행 중인 프로그램을 관찰하고 제어할 수 있도록 도와줘요.
이를 위해 GDB는 먼저 fork()를 이용해 자식 프로세스를 생성하고, 이후 execve()를 통해 분석 대상 프로그램을 실행해요.

이 과정에서 자식 프로세스는 ptrace(PTRACE_TRACEME)를 호출하여 부모 프로세스가 자신을 추적할 수 있도록 설정해요.
이후 GDB는 레지스터 값을 읽거나, 메모리를 확인하거나, 프로그램 실행을 중단하고 재개하는 등의 작업을 수행할 수 있어요.

ptrace 함수#

ptrace()는 Linux에서 프로세스를 추적하기 위한 시스템 콜이에요.

디버거는 이 함수를 이용해 대상 프로세스(tracee)를 제어하고 관찰해요. 반대로 추적을 수행하는 프로세스는 tracer라고 불러요.

함수는 다음과 같이 사용해요.

ptrace(op, pid, addr, data);
c

각 인자는 다음과 같은 의미를 가져요:

  • op: 수행할 작업을 지정하는 명령어. 예를 들어, PTRACE_TRACEME는 현재 프로세스가 추적될 수 있도록 설정하는 명령어에요.
  • pid: 추적할 프로세스의 ID. PTRACE_TRACEME의 경우, 이 인자는 무시돼요.
  • addr: 추적할 메모리 주소. 특정 명령어에서는 이 인자가 사용돼요.
  • data: 추적할 데이터. 특정 명령어에서는 이 인자가 사용돼요.

대표적인 ptrace 명령어로는 다음과 같은 것들이 있어요:

  • PTRACE_TRACEME: 현재 프로세스가 추적될 수 있도록 설정하는 명령어에요.
  • PTRACE_PEEKTEXT: 추적 중인 프로세스의 텍스트(코드) 영역에서 데이터를 읽는 명령어에요.
  • PTRACE_POKETEXT: 추적 중인 프로세스의 텍스트(코드) 영역에 데이터를 쓰는 명령어에요.
  • PTRACE_CONT: 추적 중인 프로세스의 실행을 계속하는 명령어에요.
  • PTRACE_SINGLESTEP: 추적 중인 프로세스를 한 단계씩 실행하는 명령어에요.

Anti-Debugging 원리#

Anti-Debugging은 디버깅을 어렵게 만들거나 방해하기 위한 기술이에요.

소프트웨어 개발자들은 프로그램 분석을 어렵게 만들기 위해 이러한 기법을 사용해요. 대표적으로 게임에서는 치트 프로그램 제작을 방지하기 위해 사용되고, 상용 소프트웨어에서는 무단 분석이나 크랙을 방지하기 위해 활용돼요.

대표적인 Anti-Debugging 기법은 다음과 같아요.

1. ptrace 검사#

프로그램이 ptrace 시스템 콜을 사용하여 자신이 디버깅되고 있는지 확인하는 방법이에요.
예를 들어, 프로그램이 ptrace(PTRACE_TRACEME)를 호출하여 자신이 추적되고 있는지 확인할 수 있어요.
만약 ptrace 호출이 실패하면, 프로그램은 디버깅되고 있다고 판단하고 실행을 중단하거나 다른 행동을 할 수 있어요.

2. 브레이크포인트 탐지#

소프트웨어 브레이크포인트는 일반적으로 특정 주소의 명령어를 int3 명령어로 덮어써서 구현돼요.

따라서 프로그램은 자신의 .text 섹션을 검사하여 원래 코드가 변경되었는지 확인할 수 있어요. 만약 코드가 수정되어 있다면 디버거가 개입했다고 판단할 수 있어요.

3. 실행 시간 측정#

디버깅 중에는 프로그램이 일시 중단되거나 한 줄씩 실행되기 때문에 실행 시간이 비정상적으로 길어질 수 있어요.

프로그램은 특정 구간의 실행 시간을 측정하여 디버깅 여부를 추정할 수 있어요.

4. 코드 난독화#

코드를 복잡하게 만들어 분석을 어렵게 하는 방법이에요. 예를 들어, 불필요한 명령어를 추가하거나, 제어 흐름을 복잡하게 만들어 분석을 어렵게 만들 수 있어요.

Anti-Debugging 우회#

Anti-Debugging 기법이 존재하더라도 다양한 방법으로 우회할 수 있어요.

디버거 탐지 우회#

디버거 탐지 함수가 존재한다면 GDB를 이용해 해당 함수의 반환값을 강제로 변경할 수 있어요.
예를 들어 디버거 탐지 함수가 1을 반환하면 “디버거가 존재한다”고 판단하는 경우, 반환값을 0으로 수정하여 프로그램이 정상적으로 실행되도록 만들 수 있어요.
이를 통해 탐지 로직을 우회할 수 있어요.

브레이크포인트 탐지 우회#

일반적인 소프트웨어 브레이크포인트는 코드 영역을 수정하기 때문에 탐지될 수 있어요.
이 경우 하드웨어 브레이크포인트(hbreak)를 사용할 수 있어요.
하드웨어 브레이크포인트는 CPU의 디버그 레지스터를 사용하기 때문에 코드 영역을 직접 수정하지 않아요. 따라서 .text 섹션 무결성 검사를 수행하는 Anti-Debugging 기법을 우회할 수 있어요.

Screenshot_2026-06-09_at_23-49-38_Anti-Reversing_Path_Dreamhack.png

-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg4c/dn4BitGH1/xNjKoKEp97I2b
eU57QXvkDBEdNNrEMAAAATYmxvZy5pbW55YS5uZy9wb3N0cwAAAAAAAAAGc2hhNTEyAAAA
UwAAAAtzc2gtZWQyNTUxOQAAAEAeOWJzc79LvyvTO/gY286PluXS26oJp4Cjf2udEnvB0G
ofIiVruOsIyvZGiXiq6vVWIebEEGmC6h1Qk67D9UQD
-----END SSH SIGNATURE-----
[Layer7] 2026년 6월 8일 리버싱 4차시 과제
http://blog.imnya.ng/layer7/11
저자 imnyang
게시일 2026년 06월 10일