GDB 는 GNU Debugger 의 약자로 리눅스의 대표적인 디버거 중 하나이다.
GNU란
GNU는 " GNU'x Not Unix! " 의 재귀 약자이다.
리처드 스톨먼이라는 개발자가 1983년 시작한 자유 소프트웨어 프로젝트로 사용자가 자유롭게 실행, 복사, 수정, 배포할 수 있는 완전히 자유로운 운영 체제를 만드는 것이 목표였다.
GNU라는 용어는 이 프로젝트로 만들어낸 소프트웨어들의 집합(운영 체제 구성 요소들)을 지칭하기도 한다.
주요 특징
- 자유 소프트웨어: GNU 프로젝트의 소프트웨어는 누구나 자유롭게 사용할 수 있으며 소스 코드도 공개되어 있어 수정과 배포가 가능하다.
- 유닉스 호환: GNU는 유닉스와 비슷한 구조를 가지고 있지만 유닉스의 코드를 전혀 포함하지 않고 완전히 새롭게 개발되었다.
- GPL 라이선스: 대부분의 GNU 소프트웨어는 GNU 일반 공중 사용 허가서(GPL)로 배포되어 자유 소프트웨어의 확산을 촉진한다.
- 운영 체제의 구성: GNU는 커널(운영 체제의 핵심)과 다양한 유틸리티, 개발 도구, 라이브러리 등으로 구성된다. 원래는 자체 커널(Hurd)을 개발했으나 현재는 리눅스 커널과 결합해 'GNU/Linux'로 널리 사용된다.
디버거란
소프트웨어나 하드웨어 프로그램의 실행 과정을 개발자가 직접 관찰하고 오류(버그)를 찾아내어 수정할 수 있도록 돕는 특수한 도구이다.
디버거의 주요 기능
- 중단점(브레이크포인트) 설정
코드의 특정 위치에서 프로그램 실행을 일시 정지시켜 그 시점의 상태를 분석할 수 있다. - 단계별 실행(싱글 스텝)
한 줄씩 코드를 실행하며 변수 값이나 흐름을 추적할 수 있다. - 변수 및 메모리 상태 확인
실행 중인 프로그램의 변수 값, 메모리 상태 등을 실시간으로 확인하거나 변경할 수 있다. - 함수 진입/탈출 추적
함수 내부로 들어가거나 함수 실행을 마치고 호출한 위치로 돌아가는 과정을 단계별로 볼 수 있습니다. - 실행 흐름 제어
프로그램을 원하는 위치에서 멈추거나 특정 조건에서만 멈추게 할 수 있다.
디버거를 사용하는 이유
- 버그의 원인 파악
프로그램이 예상과 다르게 동작할 때 디버거를 이용해 문제의 원인을 정확히 찾아낼 수 있다. - 효율적인 오류 수정
코드의 흐름과 변수 값을 직접 확인하면서 오류 발생 지점을 빠르고 정확하게 수정할 수 있다. - 프로그램 이해도 향상
초보자도 디버거를 사용하면 코드의 동작 원리를 쉽게 파악할 수 있다.
GDB (GNU Debugger)
GDB는 오픈소스로 개발되어 무료로 설치가능하고 오랜 역사를 가진 만큼 다양한 플러그인들이 개발되어 있다.
GDB의 플러그인 중 바이너리 분석 용도로 널리 사용되는 플러그인들은 다음과 같다.
- gef
- peda
- pwngdb
- pwndbg
GDB의 특징
- 명령줄 기반: GDB는 기본적으로 터미널에서 명령어로 조작하는 CLI(Command Line Interface) 디버거이다. 별도의 GUI가 없지만 다양한 프론트엔드(예: DDD, Eclipse, VSCode 등)와 연동할 수 있다.
- 다양한 언어 지원: C, C++, Fortran, Ada, Go, Rust 등 여러 언어를 지원한다.
- 플랫폼 호환성: 리눅스, 유닉스, 윈도우 등 다양한 운영체제와 아키텍처(ARM, RISC-V, MIPS 등)에서 동작한다.
- 원격 디버깅: 네트워크나 시리얼 포트를 통해 임베디드 시스템 등 원격 장비의 디버깅이 가능하다.
- 리버서블 디버깅: 실행을 되돌려가며 디버깅할 수 있는 기능을 제공한다.
- 스크립트 지원: Python, Guile 등으로 확장 및 자동화가 가능하다.
- 강력한 브레이크포인트/워치포인트: 특정 조건에서만 멈추거나 메모리/변수의 변화를 감지해 멈출 수 있습니다.
장점
- 오픈소스이며, 다양한 플랫폼/아키텍처 지원
- 원격 디버깅, 리버서블 디버깅 등 임베디드/저수준 개발에 강점
- 커뮤니티와 문서가 풍부하여 확장성 높음
단점
- 기본적으로 GUI가 없어 초보자에게 진입장벽이 있음
- Visual Studio Debugger 등 최신 GUI 디버거에 비해 사용 편의성은 떨어질 수 있음
- "Edit and Continue"(코드 수정 후 즉시 재실행)와 같은 고급 기능은 제한적
pwndbg와 사용법
pwndbg는 gdb에 속한 디버거이다.
linux에서 다음 명령어를 사용하면 gdb가 설치된다.
sudo apt-get install gdb
이후 pwndbg는 다음 명령어로 설치 가능하다.
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh
이후에 gdb를 입력해서 pwndbg> 로 입력창이 바뀌면 성공적으로 설치된 것이다.
file
gdb를 실행하고 디버깅을 진행할 바이너리을 gdb와 연결하려면 file 명령어를 사용하면 된다.
file ./example_file
처음 gdb를 실행할 때 gdb ./example_file 이런식으로 인자에 디버깅할 바이너리를 넘겨줘도 동일한 기능을 수행한다.
이 방법은 gdb로 바이너리를 가져와서 실행시키는 방법이지만 이미 실행중인 프로세스에 디버깅을 진행하려는 경우도 존재한다.
이를 위해서는 gdb -p <PID> 로 실행중인 프로세스의 PID 값을 넘겨주면 실행중인 프로세스의 디버깅이 가능해진다.
(PID(Process IDentifier)란 각 프로세스에 대하여 운영체제가 붙여주는 고유한 숫자 ID이다.)
run
GDB에서 프로그램을 실행하는 명령어이다. run <프로그램 인자> 로 인자를 넘겨서 실행시킬 수 도 있으며 r 만 입력하여 사용할 수 도 있다.
break와 continue
run 만 진행하면 단순하게 프로그램을 실행하는 것과 다른 점이 없다. 디버깅을 위해서는 프로그램의 구체적인 정보들이 필요하다.
그래서 대다수의 디버거에는 break 와 continue 명령어가 존재한다.
break 는 특정 주소에 중단점(breakpoint)를 설정하는 기능이고 continue 는 중단된 프로그램을 다시 실행시키는 명령어이다.
b와 c로 단축명령어가 존재한다.
break 는 함수명과 주소를 이용하여 걸 수 있다.
b main 이라고 명령어를 사용하면 main 함수에 중단점을 걸겠다는 의미이고 b *0x401010. 을 사용하면 0x401010 주소에 중단점을 걸겠다는 의미이다.
이후 프로그램을 진행시키고 싶다면 continue 또는 c를 입력해주면 된다.
entry 와 start
리눅스 ELF의 헤더 중 진입점(Entry Point, EP)이라는 필드가 존재한다. 운영체제는 ELF를 실행할 때 진입점의 명령어부터 프로그램을 실행한다.
GDB에서 entry 명령어를 사용하면 이 진입점부터 프로그램을 분석할 수 있게 해준다.
이 entry와 유사하지만 main 부터 분석할 수 있도록 start 라는 명령어가 존재한다.
entry가 ELF의 EP부터 분석할 수 있게 해준다면 start는 main 의 위치에서 부터 분석할 수 있게 한다.
ni 와 si 그리고 finish
Breakpoint 에 도달했다면 그 지점부터는 명령어를 한 줄 씩 분석해야 한다. 이 때 사용하는 명령어로 ni와 si가 있다.
ni와 si는 둘 다 명령어를 한 줄 씩 실행한다.
ni와 si의 차이점은 ni는 함수의 내부로 안들어가지만 si는 들어간다는 차이점이 있다.
si로 함수 내부에 들어가고 필요한 부분에 대한 분석이 끝나고서 빠져나가야 되는 상황일 때 함수의 규모가 너무 크다면 finish 명령어를 사용하여 함수의 끝까지 실행 시킬 수 있다.
이 외의 다양한 명령어들
GDB에서 명령어들을 보고 싶으면 help 를 사용하여 다양한 명령어들에 대한 사용법을 파악하는게 가능하다.
'보안, 해킹 > _Pwnable' 카테고리의 다른 글
| [Dreamhack] basic_exploitation_002 (0) | 2026.01.26 |
|---|---|
| C언어에서의 FSB (0) | 2025.11.25 |
| return address overwrite (2) | 2025.07.30 |
| shellcode (0) | 2025.07.14 |
| pwntools (0) | 2025.07.12 |