기본적으로 알아야 할 Gdb의 기본적인 사용법을 알아보겠다.
여러 기본 명령어가 있지만, 사용하면서 기본적으로 알아야 할 명령어들이다.
1. gdb -q [binary] ==> gdb가 소리 안내고 켜지게 한다.
======> 아래 캡쳐를 보면 gdb를 통해 test 라는 파일을 디버깅할 때 -q 옵션의 유무에 따라 차이가 나타난다.
2.run or r ==> 바이너리를 실행한다.
=====> gdb로 파일을 여는 명령인 r 옵션.
3.about breakpoint
브레이크 포인트란 gdb와 같은 디버거가 프로그램을 실행시킬 때 브레이크 포인트를
만나면 프로그램의 흐름이 일시적으로 멈추게되고, 브레이크 포인트 전까지만
프로그램을 실행시키게 된다.
즉 브레이크 포인트를 어디에 거느냐에 따라 결과도 당연히 달라진다.
3가지 경우의 수를 살펴본다.
3-1 break or b function ==> 함수에 브레이크 포인트를 건다. cf) 함수 프롤로그는 skip
==> 함수에 브레이크 포인트를 거는 방법은 2가지가 존재한다.
첫번째로 함수의 프롤로그까지 프로그램을 동작시키고 그 이후 멈추게 되는 b function 형식으로 사용하는 방법.
main함수에 함수 프롤로그 skip 형태로 브레이크 포인트를 거니 b main의 결과, 함수 프롤로그 부분인
0x00400526과 0x00400527 부분까지 프로그램이 진행되고, 그 이후인 0x0040052a 부분은 진행되지 않은 상태로
브레이크 포인트가 걸린다.
3-2 break or b* function ==> 함수에 브레이크 포인트를 건다. cf) 함수 프롤로그 keep
==> 다음으로 함수의 프롤로그 시작 부분에 브레이크 포인트를 걸어 프로그램을 함수의 시작 부분까지만
작동시키는 방법에 대해 서술하겠다.
이 방식은 b*function 형식으로 사용하는데 역시 main함수에 b*main형식으로 브레이크 포인트를 걸어 본 결과
0x00400525부분까지는 프로그램이 진행되고, 브레이크 포인트를 걸어 준 위치에 해당하는 0x00400526부분에서 프로그램이
멈춘 것을 확인할 수 있다.
3-3 b* [address] ==> 특정 주소에 브레이크를 건다.
==> 메모리의 특정 주소 위치에 브레이크 포인트를 거는 것을 보여준다.
브레이크 포인트는 함수명에 사용할 수도 있지만 직접적으로 원하는 부분의 메모리 주소에
브레이크 포인트를 걸수도 있다.
4.continue or c ==> 다음 브레이크 포인트까지 실행.
==> gdb를 통해 파일을 실행한 뒤 브레이크 포인트의 위치까지 진행하는 명령이다.
아래 화면에서 볼 수 있듯이 브레이크 포인트가 걸려있는 지점 전까지 프로그램이
진행되고 브레이크 포인트가 걸려있는 주소에서 멈추는 것을 볼 수 있다.
5.quit or q ==> quit 단어 뜻대로 바이너리를 종료한다.
==> 종료
6.disassemble or disas [함수명] ==> 특정 함수의 어셈블리 코드를 출력한다.
==> 디버깅을 하면서 특정 함수의 어셈블리 코드를 출력하고자 할 때 사용하고자 하는 명령이다.
7.info function ==> 함수 정보를 출력한다.
break ==> 브레이크 포인트 정보를 출력한다.
reg ==> 레지스터 정보를 출력한다.
즉 함수 or 브레이크포인트 or 레지스터에 대한 정보를 볼 수 있다.
먼저 info function을 보면 메모리에 올라가있는 함수들의 목록과 주소를 알 수 있다.
그 다음 info breakpoint를 해보면 현재 걸려있는 브레이크 포인트의 위치 정보가 출력된다.
그 다음 info reg를 통해 현재 레지스터의 상태 또한 출력할 수 있다.
8. delete [number] or del[number] ==> 특정 브레이크 포인트를 제거한다.
cf) delete(del) ==> 모든 브레이크 포인트를 제거.
일단 break number를 통해 number에 해당하는 브레이크 포인터를 제거하는 화면.
걸려있는 브레이크 포인터를 모두 제거하는 화면.
9.stepi or si ==> 코드를 한 줄 실행 [함수를 만났을 때 함수 안으로 들어간다.]
nexti or ni ==> 코드를 한 줄 실행 [함수를 만났을 때 함수 안으로 들어가지 않는다.]
==> run이나 continue를 통해 코드를 한 번에 진행시킬 수도 있지만 stepinto or nexti를 통해
코드를 한 줄씩 진행시켜 나갈 수도 있다.
printf@plt 함수를 기준으로 stepi와 nexti를 통해 코드를 진행시켜본다.
stepi는 코드가 한 줄 진행되고, 함수를 만나면 함수 내부로 들어간다.
nexti는 코드가 한 줄 진행되고, 함수를 만나면 함수 내부로 들어가지는 않고 진행된다.
10. print [function] (p) ==> 해당 함수 주소를 출력한다.
==> 해당 함수의 주소를 출력하는 방법이다.
물론 info function을 통해 함수들을 한 번에 볼 수도 있지만, print 함수를 통해 함수의 주소를 하나만 출력할 수 있다.
11. p $reg ==> 해당 레지스터 값을 출력한다.
==> 해당 레지스터의 값을 출력하는 방법이다.
역시 info register로 모든 레지스터의 정보를 출력할 수 있지만, p $reg를 통해 해당 레지스터의 값 하나만 출력할 수 있다.
즉 ==> p/[출력 형식] [변수명] ==> 출력 형식에 맞추어 변수 값 출력
'#Tip' 카테고리의 다른 글
PLT and GOT (0) | 2018.04.06 |
---|---|
Function Prologue & Epilogue. (0) | 2018.04.06 |
Windows에서 VMware의 Ubuntu에 SSH로 접속. (0) | 2018.03.31 |
Cpu and assembly language. (0) | 2018.03.27 |
C language introduction. (0) | 2018.03.27 |