시스템 해킹

gdb 개념 및 사용법

kchabin 2022. 8. 19. 01:02

gdb(GNU Debugger)

 

다른 프로그램을 수행 중에 그 프로그램 내부에서 무슨 일이 일어나고 있는지 보여주거나 프로그램이 잘못 실행되었을 때 무슨 일이 일어나고 있는지 보여주는 것.

C, C++, Modula-2로 짠 프로그램을 디버그 할 수 있다.

코어파일 분석 또는 디버깅에 사용된다.

 

quit으로 종료 명령을 주기 전까지는 터미널로부터 명령 라인을 읽어들인다. 

 

디버깅 방법

'-g' 옵션을 주고 컴파일/링크

 

gdb 시작하기

gdb - gdb를 실행 후 file이라는 명령으로 program을 부른다.

 

gdb <프로그램명>

gdb < 프로그램명>, <코어파일명> - 코어 파일을 사용할 때 동시에 인자로 준다.

gdb <프로그램명>, <실행 중인 프로세스 PID> - 실행 중인 프로세스를 디버그 하려면.

gdb -g test.c -o test

gdb test

 

명령어 정리

1. 컴파일 시 디버깅 정보를 담기

gcc -g -o [프로그램명] [소스파일명]

디버깅 옵션인 -g로 컴파일

 

2. 실행 방법

gdb [프로그램명]

gdb [프로그램명] [코어파일명]

gdb [ 프로그램명] [실행중인 프로세스 pid]

 

3. 종료

q, Ctrl+d

 

4. 소스 찾아가기(list = 현재 위치에서 소스 파일의 내용을 10줄 보여줌)

l : main 함수를 기점으로 소스의 내용이 출력됨.

ㅣ 10 : 10행 주변의 소스 출력. 10행 -5 부터 10행 +5까지 총 10행 출력

5 6 7 8 9 10 11 12 13 14 15 

-> 색칠된 부분이 출력되는 부분.

 

l func : func 함수의 소스 출력

l a.c:func = a.c 파일의 func 함수 부분을 출력

l a.c:10 : a.c 파일의 10행을 기준으로 출력

 

5. 옵션

set listsize 20 : 한번에 출력하는 행의 개수를 20개로 늘림

Enter : 마지막으로 수행한 명령어를 다시 수행

 

6. 프로그램 실행, 종료(run, kill)

r : 프로그램 수행(재시작)

r arg1 arg2 : arg1과 arg2를 인자로 프로그램 수행

k : 프로그램 수행 종료

 

7. 역추적하기 (backtrack)

bt : 오류가 발생한 함수를 역으로 찾아감

 

8. 중단점 사용(breakpoint, temporary breakpoint)

b func : func 함수에 브레이크 포인트 설정

b a.c func :  a.c 파일의 func 함수에 브레이크

b a.c 10 : a.c 파일의 10행에 브레이크

b +2 : 현재 행에서 2개 행 이후 지점 브레이크

b -2 : 현재 행에서 2개 행 이전 지점 브레이크

b *0x8049000 : 0x8049000 주소에 브레이크(어셈블리로 디버깅 시 사용)

b 10 if var == 0 : 10행에 브레이크 포인트 설정하되, var 변수 값이 0일 때 작동

tb : 임시 중단점. 한번만 설정되며, 그 이후에 삭제됨

 

9. 중단점 설정(condition)

condition 2 var == 0 : 고유 번호가 2번인 브레이크 포인트에 var 변수가 0일 때 동작하라고 설정

-> 고유 번호는 1번째 브레이크 포인트, 2번째 브레이크 포인트 할 때 번호를 의미하는 건가?

 

10. 중단점 삭제하기(clear, delete)

cl func : func 함수의 시작 부분에 브레이크 포인트 지움

cl 10 :  10행의 브레이크 지움

delete 1 : 고유번호 1번 브레이크 삭제

cl a.c:func : a.c 파일의 func 함수의 bp 지움

cl a.c:10 : a.c 파일 10행의 bp 삭제

cl : 모든 브레이크 삭제

 

11. 중단점 정보 보기 (information)

info b : 현재 설정된 bp의 정보

방향키 up/down : 누르면 히스토리 기능 제공

info br + Tab : info br로 시작하는 키워드가 히스토리에 있다면 뿌림

info Tab + Tab : info 뒤에 올 수 있는 인자 리스트를 보임

Tab + Tab : 현재 사용 가능한 모든 명령어 리스트를 보임

 

12. 중단점 비활성화, 활성화하기(enable, disable)

disable 2 : 고유번호 2번 bp 비활성화

enable 2 : 2번 활성화

 

13. 디버깅하기 (step, next, continue, until, finish, return, step instruction, next instruction)

s : 현재 출력된 행을 수행하고 멈추지만, 함수의 경우 내부로 들어가서 수행

s 5 : s를 5번 입력한 것과 동일함

n : 현재 행을 수행하고 멈추지만, 함수는 수행하고 넘어감

n 5 : n 5번 입력

c : 다음 브레이크 포인트를 만날 때까지 계속 수행

u : for 문에서 빠져나와서 다음 브레이크 포인트까지 수행

finish : 현재 함수를 수행하고 빠져나감

return : 현재 함수 수행 않고 빠져나감

return 123 : 현재 함수 수행 않고 빠져나가는데 리턴 값이 123

si : 현재의 인스트럭션을 수행, 함수 호출 시 내부로 들어감.

ni : 현재의 인스트럭션을 수행, 함수 호출 시 내부로 들어가지 않음.

 

14. 감시점 설정 (watch)

watch i : i 변수에 watch 포인트 설정. 변수가 바뀔 때마다 브레이크가 걸리면서 이전 값과 현재 값을 출력함.

 

15. 변수 정보 보기(info, print)

info locals : 현재 상태 어떤 지역변수들이 있으며, 값은 어떤지

info variables : 현재 상태에서의 전역 변수 리스트들 확인

p lval : lval 값 확인

p func : func 함수 주소값

p pt : 구조체면 그 주소 확인

p *pt : 구조체면 구조체 값 확인

p **pt : 구조체면 구조체 값 확인

info registers :  레지스터 값 전체 한번에 확인

 

16. 레지스터 값 및 포인터가 가리키는 구조체의 배열 출력

info all-registers : MMX 레지스터를 포함하여 거의 대부분의 레지스터 값 확인

p $eax : eax 레지스터의 값 확인

p *pt@4 : 4 크기의 배열로 gdb가 알 수 있으므로 4개의 크기만큼 가져와서 확인

 

17. 중복된 변수명이 있으면 특정 변수를 지정해서 출력(print) 

p 'main.c'::var : main.c 파일에 있는 전역 변수인 var 변수의 값 출력

p hello::var : hello함수에 포함된 static 변수인 var 변수의 값 출력

 

18. 출력 형식의 지정

p/t var : var 변수를 2진수로 출력

p/o : 8진수로 출력

p/d : 부호가 있는 10진수

p/u : 부호가 없는 10진수(unsigned int)

p/x : 16진수로 출력

p/c : 최초 1바이트 값을 문자형으로 출력

p/f : 부동소수점형식

p/a addr : addr 주소와 가장 가까운 심벌의 오프셋 출력 (예 main+15)

 

19. 타입이 틀릴 경우 타입 변환해서 출력

p(char*)vstr : 실제 컴파일 시에 (void*)형이었어도 (char*)로 캐스팅하여 보여줌

 

20. 특정한 위치 지정

p lstr + 4 : lstr = "I like you." -> "ke you" 출력

0부터 시작인듯

 

21. 변수 값 설정

p lval = 1000 : 변수값 확인 이외에는 설정도 가능

 

22. 출력 명령 요약 (print)

p [변수명] : 변수 값을 출력

p [함수명] : 함수의 주소를 출력

p/[출력형식] [변수명] : 변수 값을 출력 형식으로 출력

p '[파일명]'::[변수명] : 파일명에 있는 전역변수 값을 출력

p [함수명]::[변수명] : 함수에 있는 변수 값을 출력

p [변수명]@[배열크기] : 변수의 내용을 변수 배열의 크기 형태로 출력

 

23. 디스플레이 명령 (display, undisplay)

display [변수명] : 변수 값을 매번 화면에 디스플레이

display/[출력형식] [변수명] : 변수 값을 출력 형식으로 디스플레이

-> display/f var : var을 부동소수점 형식으로 디스플레이

undisplay [디스플레이번호] : 디스플레이 설정을 없앤다

disable display [디스플레이번호] : 디스플레이를 일시 중단한다.

enable display [디스플레이번호] : 디스플레이를 다시 활성화한다.

 

24. 스택 프레임 관련 명령 (frame, up, down, info)

frame [n] : n번 스택 프레임으로 변경

up : 상위 프레임으로 이동

up [n] : n번 상위 스택 프레임으로 이동

down : 하위 프레임으로 이동

down [n] : n번 하위 스택 프레임으로 이동

info frame : 현재 스택 프레임 정보 출력

info args : 현재 스택 프레임의 함수가 호출될 때 인자 출력

info locals : 현재 스택 프레임의 함수 내의 지역변수 출력

info catch : 현재 스택 프레임의 함수내의 예외 핸들러 출력

 

25 . 메모리 상태 검사(x)

x/[범위][출력 형식][범위의 단위] : 메모리의 특정 범위의 값들을 확인

 

26. 출력형식

x/10 main : main 함수 시작부터 40바이트 출력

x/10t main : main 함수 시작부터 40바이트를 2진수로 출력

x/10o main : main 함수 시작부터 40바이트를 8진수로 출력

x/10d main : main 함수 시작부터 40바이트를 부호가 있는 10진수로 출력

x/10u main : main 함수 시작부터 40바이트를 부호가 없는 10진수로 출력

x/10x main : main 함수 시작부터 40바이트를 16진수로 출력

x/10c main : main 함수 시작부터 40바이트를 최초 1바이트 값을 문자형으로 출력

x/10f main : main 함수 시작부터 40바이트를 부동 소수점 값 형식으로 출력

x/10a main : 가장 가까운 심볼의 오프셋을 출력

x/10s main : 문자열로 출력

x/10i main : 어셈블리 형식으로 출력

 

27. 범위의 단위 (기본 word - 4바이트)

x/10b main : byte - 1바이트 단위 - 10바이트 출력

x/10h main : halfword - 2바이트 단위 - 20바이트 출력

x/10w main : word - 4바이트 단위 - 40바이트 출력

x/10g main : giant word - 8바이트 단위 - 80바이트 출력

 

28. 디스어셈블링 (disas)

disas func : 어셈블리 코드를 좀 보편적으로 보기 위한 명령어

disas 0x8048300 0x8048400 : 특정 주소 범위 사이의 어셈블리 코드를 보기

 

29. 함수 호출 (call)

call func(arg1, arg2) : 특정 함수 func를 arg1, arg2 파라미터를 포함하여 호출하고, 반환 값은 출력

 

30. 점프 (jump)

jump *0x08048321 : 해당 주소로 무조건 분기하여 인스트럭션을 계속 수행

jump 10 : 무조건 10행으로 분기하여 수행

jump func : func 함수로 무조건 분기하여 수행

*분기 = 프로그램의 실행 순서를 변경하여 다른 명령을 실행할  있게 하는 .

 

31. 시그널 전송 (signal)

info signals : 보낼 수 있는 시그널의 종류를 확인

signal SIGKILL : 디버깅 대상의 프로세스에게 KILL 시그널을 보냄

 

32. 메모리의 특정 영역에 값을 설정 ( set )

set {타입}[주소] = [값] : 메모리의 특정 주소에 저장

 

33. gdb 환경설정 (set)

info set : 변경 가능한 환경설정 정보를 출력

info functions : 함수들의 리스트를 출력

info types : 선언된 타입에 대한 리스트를 출력

set prompt psyoblade: : 프롬프트를 psyoblade: 로 변경할 수 있음

set print array on : 배열을 출력할 때 여러 행에 출력한다.

  

         

코어 파일 분석

코어 파일 = 충돌할 당시 프로세스의 메모리 이미지를 덤프한 것. 

코어 파일을 gdb로 함께 사용하여 프로그램의 상태를 조사하고 실패 원인을 규명할 수 있다.

 

어떤 예기치 않은 일로 비정상적인 종료가 발생할 때 운영체계는 디스크에 코어 파일을 남긴다. 

메모리 관한 문제 = Checker 패키지로 예방. 

메모리 fault = 충돌하면서 파일을 덤프한다. 

코어 파일은 일반적으로 프로세스를 실행시킨 현재 작업 디렉토리에 생성되지만 프로그램 내에서 작업 디렉토리를 바꾸는 경우도 있다.

 

'시스템 해킹' 카테고리의 다른 글

SSTF Hacker's Playground  (0) 2022.08.23
4주차 질문  (0) 2022.08.19
basic exploitaion 001 문제 풀이  (0) 2022.08.19
pwnable.kr bof 문제 풀이  (0) 2022.08.19
Stack Overflow  (0) 2022.08.18