Post

gdb 사용법과 pwndbg

gcc options



Link
jayy-h.tistory.com/9






gdb 사용법

break point



  • info b (i b): 현재 브레이크 포인트 보기

  • d : 모든 브레이크 포인트 지우기

  • d n : n번 브레이크 포인트 지우기

  • enable/disable (브레이크 포인트 번호) : 활성화/비활성화



변수 출력



  • info locals : 현재 스택의 로컬변수 모두를 출력

  • info variables : 전역변수 모두 출력

  • p [변수명] : 해당변수 value 출력

  • p $[레지스터명] : 레지스터값 출력

  • p [변수명] = [value] : 특정 변수의 값을 설정

  • p 함수명 = 함수의 주소 출력

  • info registers (i r): 레지스터 전체 출력



스택 상태



  • info f (i f): 스택 프레임 내용 출력

  • info args : 함수 호출시 인자를 출력

  • info locals : 함수의 지역변수를 출력



메모리 상태



  • x/[범위][출력형식][범위의단위] [메모리주소나 함수명]

범위는 기본 4byte



출력형식



  • t : 2진수

  • o : 8진수

  • u : 부호없는 10진수

  • x : 16진수

  • f : float

  • c : char

  • s: 문자열로 출력

  • i : 어셈블리 형식으로 출력 (instruction)

  • a : address



범위의 단위



  • b : 1 byte

  • h : 2 byte

  • w : 4 byte

  • g : 8 byte






기타



  • c : break point까지 실행

  • stepi(si)/nexti(ni) : 코드 한줄 실행, si는 함수 안으로 들어가고 ni는 들어가지 않음.

  • set {타입}[주소] = [값] : 특정 메모리에 값을 지정 ( set {int}0x8048300 = 100 )

  • catch {event} : event 발생 시 프로세스 중지, ex) catch syscall arch_prctl

  • watch {주소} : 특정 주소에 저장된 값이 변경되면 프로세스를 중단, ex) watch *(0x7ffff7fdb4c0+0x28)






pwndbg

기본적인 gdb 명령어 (ni, si, break, continue, run 등) 외에 pwndbg에서 제공하는 명령어 정리



start



Linux는 실행파일의 형식으로 ELF(Execute and Linkable Format)을 규정하고 있음.

크게 헤더와 여러 섹션들로 구성되어 있는데, 헤더에는 실행에 필요한 여러 정보가 적혀 있고 섹션들에는 컴파일된 기계어 코드, 프로그램 문자열을 비롯한 여러 데이터가 포함됨.

ELF 헤더 중 진입점(Entry Point, EP)라는 필드가 있는데, 운영체제는 ELF를 실행할 때 진입점의 값부터 프로그램을 실행한다고 함.

readelf 명령어로 확인할 수 있으며 readelf -h {file}로 ELF 헤더를 확인할 수 있음.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ readelf -h debugee
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400400     ---> 진입점
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6376 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 28


start 명령어는 진입점부터 프로그램을 분석할 수 있게 해주는 gdb 명령어임.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pwndbg> start
Temporary breakpoint 1 at 0x400400
Temporary breakpoint 1, 0x0000000000400400 in _start ()
[중략]
───────────────────────────[ DISASM ]─────────────────────────────
 ► 0x400400 <_start>       xor    ebp, ebp
   0x400402 <_start+2>     mov    r9, rdx
   0x400405 <_start+5>     pop    rsi
   0x400406 <_start+6>     mov    rdx, rsp
   0x400409 <_start+9>     and    rsp, 0xfffffffffffffff0
   0x40040d <_start+13>    push   rax
   0x40040e <_start+14>    push   rsp
   0x40040f <_start+15>    mov    r8, __libc_csu_fini <0x4005a0>
   0x400416 <_start+22>    mov    rcx, __libc_csu_init <0x400530>
   0x40041d <_start+29>    mov    rdi, main <0x4004e7>
   0x400424 <_start+36>    call   qword ptr [rip + 0x200bc6] <__libc_start_main>
[중략]
pwndbg>




u, nearpc, pd



gdb에는 disassemb (disas) 함수로 함수를 디스어셈블 할 수 있는데, u, nearpc, pdisassemble은 pwndbg에서 제공하는 가독성 좋은 디스어셈블 명령어이다.


image







finish



step into(si)로 함수 내부에 들어가서 필요한 부분을 모두 분석했는데, 함수의 규모가 커서 ni로는 원래 실행 흐름으로 돌아가기 어려울 수 있다.

이때 finish라는 명령어를 사용하여 함수의 끝까지 한 번에 실행할 수 있다고 한다.






telescope(tele)



pwndbg에서 제공하는 강력한 메모리 덤프 기능이라고 한다.

특정 주소의 메모리 값들을 보여주는 것에서 그치지 않고, 메모리가 참조하고 있는 주소를 재귀적으로 탐색하여 값을 보여준다고 한다.


1
2
3
4
5
6
7
8
9
pwndbg> tele
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







vmmap



vmmap은 가상 메모리의 레이아웃을 보여준다고 한다.

어떤 파일이 매핑된 영역일 경우, 해당 파일의 경로까지 보여준다.


파일 매핑이란 어떤 파일을 메모리에 적재하는 걸 뜻한다고 한다.

리눅스에서는 ELF를 실행할 때 먼저 ELF의 코드와 여러 데이터를 가상 메모리에 매핑하고, 해당 ELF에 링크된 공유 오브젝트(Shared Object, so)를 추가로 메모리에 매핑하는데, so 파일은 자주 사용되는 함수들을 미리 컴파일해둔 것이라 한다.

C언어의 printf, scanf 등이 리눅스에서는 libc(library C)에 구현되어 있고, 공유 오브젝트에 이미 구현된 함수를 호출할 때는 매핑된 메모리에 존재하는 함수를 대신 호출한다고 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
          0x400000           0x401000 r-xp     1000 0      /home/dreamhack/debugee
          0x600000           0x601000 r--p     1000 0      /home/dreamhack/debugee
          0x601000           0x602000 rw-p     1000 1000   /home/dreamhack/debugee
    0x7ffff79e4000     0x7ffff7bcb000 r-xp   1e7000 0      /lib/x86_64-linux-gnu/libc-2.27.so
    0x7ffff7bcb000     0x7ffff7dcb000 ---p   200000 1e7000 /lib/x86_64-linux-gnu/libc-2.27.so
    0x7ffff7dcb000     0x7ffff7dcf000 r--p     4000 1e7000 /lib/x86_64-linux-gnu/libc-2.27.so
    0x7ffff7dcf000     0x7ffff7dd1000 rw-p     2000 1eb000 /lib/x86_64-linux-gnu/libc-2.27.so
    0x7ffff7dd1000     0x7ffff7dd5000 rw-p     4000 0
    0x7ffff7dd5000     0x7ffff7dfc000 r-xp    27000 0      /lib/x86_64-linux-gnu/ld-2.27.so
    0x7ffff7dd5000     0x7ffff7dfc000 rwxp    27000 0      <explored>
    0x7ffff7fe3000     0x7ffff7fe5000 rw-p     2000 0
    0x7ffff7ff7000     0x7ffff7ffa000 r--p     3000 0      [vvar]
    0x7ffff7ffa000     0x7ffff7ffc000 r-xp     2000 0      [vdso]
    0x7ffff7ffc000     0x7ffff7ffd000 r--p     1000 27000  /lib/x86_64-linux-gnu/ld-2.27.so
    0x7ffff7ffd000     0x7ffff7ffe000 rw-p     1000 28000  /lib/x86_64-linux-gnu/ld-2.27.so
    0x7ffff7ffe000     0x7ffff7fff000 rw-p     1000 0
    0x7ffffffdc000     0x7ffffffff000 rw-p    23000 0      [stack]







출처



Link
mitny.github.io/articles/2016-08/gdb-command -> GDB 명령어
Dreamhack Tool: gdb –> pwndbg 명령어
a1ways-hyerang.tistory.com/entry/System-Hacking-STAGE-3-Tool-gdb



This post is licensed under CC BY 4.0 by the author.