1. GNU Debugger (GDB)

설치

sudo apt-get install gdb

pwndbg

git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

 

- GDB vs. pwndbg

: gdb는 리눅스 기본 디버거, 명령어 위주로 가독성 낮고 직접 다 쳐야함

: pwndbg는 gdb 위에서 돌아가는 확장 플러그인으로 스택, 레지스터, 힙, pie, alsr 한눈에 보여줌


2. 사용 방법

1) 파일 불러오기

file ./debugee

디버깅 정보 포함: 컴파일 할때 -g 옵션을 주어 컴파일함

근데 대부분의 바이너리는 -g 옵션 없이 컴파일한 바이널임

2) 실행 흐름 제어

'run'

디버거는 프로그램을 실행시키면서 분석하는 도구

pwndbg> run <프로그램 인자>

 

'break & continue'

break로 breakpoint 잡음

continue로 실행 재개하고 다음 중단점까지 실행함, breakpoint없으면 끝까지 실행

-> 여러번 실행하고 싶으면 'c <숫자>' 입력

 

'entry & start'

리눅스는 실행파일의 형식으로 ELF(Executable and Linkable Format)를 규정하고 있음

ELF-> 헤더 + 여러 섹션으로 구성되어있음

           헤더 -> 실행에 필요한 여러 정보

           섹션 -> 머신 코드, 프로그램 문자열 등 데이터

 

ELF의 헤더 중 진입점(Entry Point, EP)라는 필드가 있음, 운영체제는 ELF를 실행할 때, EP의 명령어부터 프로그램을 실행함

'readelf' 명령어로 확인할 수 있음

ep가 0x401050임을 알 수 있음

 

start 명령어는 gdb에서 main()부터 분석할 수 있게 함

si(Step into) : 함수 흐름대로 진행, 함수에 들어감

ni(next instruction): 함수 스택프레임 건너뛰고 진행됨

finish: si한 후 함수 스택프레임 길어지면 원래 흐름대로 돌아감

 


3. 디버깅을 위해 사용하는 명령어

1) INFO

'info reg ~', 'info breakpoints'

pwndbg> b $rdi

info reg -> 단축어로 i r

info breakpoints -> 단축어로  i b

disable 1 -> 1번 중단점 비활성화

enable 1 -> 1번 중단점 활성화

delete 1 -> 중단점 1 삭제 d 1

 

2) disassemble

disass 로 사용가능

u, nearpc, pdisass -> 디어셈블된거 가독성 좋게 바꿔줌

 

 

3) examine / x/s ..

'x/< 포맷 및 크기>' 'x/<개수><포맷 및 크기>

ex)

pwndbg> x/5i $rip
=> 0x4004e7 <main>:     push   rbp
   0x4004e8 <main+1>:   mov    rbp,rsp
   0x4004eb <main+4>:   sub    rsp,0x10
   0x4004ef <main+8>:   mov    DWORD PTR [rbp-0xc],0x0
   0x4004f6 <main+15>:  mov    DWORD PTR [rbp-0x8],0x1

 

4) telescope

강력한 메모리 덤프임, 메모리가 참조하고 있는 주소를 재귀적으로 탐색하여 값을 보여줌

pwndbg> tele $rsp
00:0000│ rsp  0x7fffffffc228 —▸ 0x7ffff7a05b97 (__libc_start_main+231) ◂— mov    edi, eax
01:0008│      0x7fffffffc230 ◂— 0x1
02:0010│      0x7fffffffc238 —▸ 0x7fffffffc308 —▸ 0x7fffffffc557 ◂— '/home/dreamhack/debugee'
03:0018│      0x7fffffffc240 ◂— 0x100008000
04:0020│      0x7fffffffc248 —▸ 0x4004e7 (main) ◂— push   rbp
05:0028│      0x7fffffffc250 ◂— 0x0
06:0030│      0x7fffffffc258 ◂— 0x71eb993d1f26e436
07:0038│      0x7fffffffc260 —▸ 0x400400 (_start) ◂— xor    ebp, ebp

 

 

5) vmmap

가상의 메모리 레이아웃을 보여줌,  프로그램이 실행된 상태에서 이용 가능

pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
             Start                End Perm     Size Offset File
          0x400000           0x401000 r--p     1000      0 /home/dreamhack/debugee
          0x401000           0x402000 r-xp     1000   1000 /home/dreamhack/debugee
          0x402000           0x403000 r--p     1000   2000 /home/dreamhack/debugee
          0x403000           0x404000 r--p     1000   2000 /home/dreamhack/debugee
          0x404000           0x405000 rw-p     1000   3000 /home/dreamhack/debugee
          0x405000           0x426000 rw-p    21000      0 [heap]
    0x7ffff7d7f000     0x7ffff7d82000 rw-p     3000      0 [anon_7ffff7d7f]
    0x7ffff7d82000     0x7ffff7daa000 r--p    28000      0 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7daa000     0x7ffff7f3f000 r-xp   195000  28000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f3f000     0x7ffff7f97000 r--p    58000 1bd000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f97000     0x7ffff7f9b000 r--p     4000 214000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f9b000     0x7ffff7f9d000 rw-p     2000 218000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f9d000     0x7ffff7faa000 rw-p     d000      0 [anon_7ffff7f9d]
    0x7ffff7fbb000     0x7ffff7fbd000 rw-p     2000      0 [anon_7ffff7fbb]
    0x7ffff7fbd000     0x7ffff7fc1000 r--p     4000      0 [vvar]
    0x7ffff7fc1000     0x7ffff7fc3000 r-xp     2000      0 [vdso]
    0x7ffff7fc3000     0x7ffff7fc5000 r--p     2000      0 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7fc5000     0x7ffff7fef000 r-xp    2a000   2000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7fef000     0x7ffff7ffa000 r--p     b000  2c000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffb000     0x7ffff7ffd000 r--p     2000  37000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffd000     0x7ffff7fff000 rw-p     2000  39000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffffffde000     0x7ffffffff000 rw-p    21000      0 [stack]
0xffffffffff600000 0xffffffffff601000 --xp     1000      0 [vsyscall]
pwndbg>

** 파일 매핑?

-> 어떤 파일을 메모리에 적재하는 것을 파일 매핑이라고 함

 

6) backtrace

 bt 라는 명령어로 콜 스택을 확인할 수 있음, 어떤 인자가 어디서왔는지 추적 가능

pwndbg> b add
Breakpoint 1 at 0x40113e
pwndbg> r
[중략]
pwndbg> bt
#0  0x000000000040113e in add ()
#1  0x0000000000401177 in main ()
#2  0x00007ffff7dce1ca in __libc_start_call_main (main=main@entry=0x40114e <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffc938) at ../sysdeps/nptl/libc_start_call_main.h:58
#3  0x00007ffff7dce28b in __libc_start_main_impl (main=0x40114e <main>, argc=1, argv=0x7fffffffc938, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
    stack_end=0x7fffffffc928) at ../csu/libc-start.c:360
#4  0x0000000000401075 in _start ()
pwndbg>

 

 

7) dump memory

프로세스 메모리 상태를 파일로 저장하는 명령어

dump memory <파일명> <시작주소> <끝주소>

 

8) context

pwndbg는 주요 메모리들의 상태를 프로그램이 실행되고 있는 context라고 부름

기본적으로 프로그램이 중단되면 ctx를 출력하지만 별도로 ctx 명령어로 실행할 수도 있음

4개의 영역 -> reg, disasm(rip부터 여러 줄에 걸쳐 디스어셈블된 결과), stack(rsp부터 스택의 값), backtrace(현재 rip에 도달할 때까지 어떤 함수들이 중첩되어 호출됐는지 보여줌)

 

 

9) set

프로세스 메모리 상태를 변경할 수 있는 명령어

주로 레지나 특정 주소의 메모리 값을 변경함

실행 중에서 가능

set <주소/레지스터> = <변경할 값>
pwndbg> set $rax = 0
pwndbg> set $rsp = $rbp

자료형 변경

pwndbg> set *(unsigned int*)0x400000 = 10
# 0x400000 주소를 unsigned int * 형으로 역참조 후 여기에 정수 10을 저장한 것

pwndbg> set *(float*)0x400010 = 3.14
# 0x400010 주소를 float* 형으로 역참조 후 여기에 부동소수점 값 3.14 저장

타입크기

unsigned byte 1 byte
unsigned int 4 bytes
unsigned long 8 bytes

 

'computer basics' 카테고리의 다른 글

[GDB 명령어] 명령어 모음  (0) 2026.05.15
[Linux] Linux Memory Layout  (0) 2026.02.10

+ Recent posts