컴파일러 디버깅 옵션
gcc -g -W -Wall -o [실행파일] [C파일]
소스 수준의 디버깅을 위한 정보를 실행파일에 포함시킨다.
디버깅 관련 리눅스 기본 명령어
-
file <파일이름> : 파일 정보 -> not stripped 출력 시 symbol을 볼 수 있다.
-
strings <파일이름> : 문자열 정보
-
nm -D <파일이름> : 동적으로 남아 있는 정보 -> 프로그램이 사용하는 함수 출력(정적 라이브러리만 해당)
-
objdump -d <파일이름> : 덤프따기
-
gdb <파일이름> : 디버깅
GDB 명령어 (gdb 실행 후 사용하는 명령어들)
1. 기본 설정
-
layout asm : 어셈블리 정보창 출력
-
layout reg : 레지스터 정보창 출력
-
set disassembly-flavor intel : 인텔 아키텍쳐로 설정
2. 프로그램 실행
-
r <명령인자> : 실행(run)
-
c : 중단된 프로그램 실행 재개(continue)
-
kill : 프로그램 실행 종료
-
s <숫자> : 몇 단계 씩 수행(step)
-
ni, si : 한단계 진행
-
finish : 현재 함수의 리턴까지 실행
-
return <return 값> : 함수를 실행하지 않고 리턴
-
q : 디버깅 종료
3. 중단점(breakpoint)
-
b <함수이름/라인넘버/*메모리주소> : breakpoint 설정
-> b *main+43 : main문자열(함수이름참조)이 참조하는 주소 + 43
-> break 80484a8
-
i b : 설정된 breakpoint 표시(= info breakpoint 또는 info b)
-
delete <breakpoint 번호> : 설정된 bp 삭제
-
enable <breakpoint 번호> : bp 활성
-
disable <breakpoint 번호> : bp 비활성
-
clear <함수이름> : 함수 내의 모든 bp 삭제
4. 메모리 확인
-
display [/표시형식] <변수이름> : 변수의 값이 유효한 코드 부분에서 값을 계속해서 출력 (표시형식: d, x, t)
-
undisplay : display 모드를 종료
-
print [/표시형식] <변수이름/*메모리주소/레지스터이름> : 현재 또는 지정된 위치의 프로그램 소스 코드 출력
-
x/[개수][표시형식][단위크기] <주소/함수이름> : 지정된 위치의 메모리 데이터를 지정된 형식으로 출력
-> 표시형식: d, o, x, t, f, s, i 등
-> 단위 크기: b, h, w, g
예시) x/x <주소> : 해당 주소의 내용물을 바이트 단위로 출력
-> x/10x : opcode 10개 출력
-> x/10i : 명령어 10개 출력
-> x/10s : 문자열 10개 출력
-> x/10wx : word단위로 10개 출력
-> x/s, x/i, ... etc
예시) mov $eax, [0xbfffefc4] : 대괄호는 포인터를 의미
-> 대괄호 없이 0xbfffefc4일 경우 그 주소의 내용이다.
-> 포인터는 그 주소에 저장된 포인터주소가 참조하는 주소의 내용물을 저장하는 것.
-> '*'기호 사용 : x/s *0xbfffefc4 처럼 한단계 더 보아야함
예시) 레지스터도 포인터처럼 사용해서 내용물을 볼 수 있다.
-> x/s $eax : eax에 저장된 내용(주소일수도있음)
-> x/s *$eax : eax에 저장된 포인터가 가리키는 내용
5. 프로그램 코드 확인
-
list <함수이름/라인넘버/변수이름> : 현재 또는 지정된 위치의 프로그램 소스 코드 출력
-
disas <함수이름/메모리주소> : 함수 디스어셈 내용(기계어 코드)
6. 변수값 변경 감지
-
watch <변수이름> : 변수에 데이터가 쓰여질 때 실행 멈춤(breakpoint역할)
-
rwatch <변수이름> : 변수 읽을 때 실행 멈춤
-
awatch <변수이름> : 변수 관련 모든 경우에 실행 멈춤
7. 기타 명령어
-
backtrace, where : 현재 실행 위치의 주소와 스택 상태 출력
-
i locals : 모든 지역 변수 목록과 현재 값 출력(= info locals)
-
i program : 프로그램 실행 정보 출력(= info program)
-
i reg : 현재 레지스터 정보 출력(= info reg)
-
set <수정할주소의 포인터> = <내용> : 메모리 데이터 변경
예시) 잘못된 경우 : 레지스터 주소에 문자열 주소를 넣을 때
set $esp = 0x08048585 : esp가 바뀜
예시) 옳은 경우 : 레지스터가 참조하는 주소에 문자열 주소를 넣을 때
set *0xbfffefa0 = 0x08048585
레지스터는 포인터참조(*)를 사용할 수 없다.
즉, 레지스터의 주소를 적을 것!
'Debugger > GDB' 카테고리의 다른 글
[GEF] gef missing (python3 에러) (0) | 2020.01.05 |
---|---|
[GEF] Pattern 생성과 활용 (0) | 2020.01.04 |
[GDB] GDB의 인자값으로 파이썬 출력 값을 사용하기 (0) | 2019.12.29 |
[GCC] 컴파일시 보호기법 해재 플래그 (0) | 2019.12.28 |
[GDB] 사용자 input으로 hex값 입력 값하기 (0) | 2019.12.28 |