[Tool] DBG(디버거) 사용법
버그(bug)와 디버깅(debugging)
개발을 하면서 발생한 프로그램의 결함을 버그라고 한다. 버그는 '벌레'라는 뜻으로 최초의 프로그래머 그레이스 호퍼에 의해 발생한 용어이다. 그가 Mark Ⅱ를 개발할 당시 컴퓨터가 오작동이 계속 일어났지만, 원인을 찾지 못해 헤매었다. 하지만 원인은 생각보다 간단했다. 바로 컴퓨터에 나방(벌레)가 붙어있어서 오작동이 발생했던 것이다. 이때부터 프로그래밍 과정 중 오류를 버그라고 하게 되었으며, 오류를 찾는 일을 벌레를 잡는 일 즉, '디버깅'이라고 하게 되었다.
디버거(debugger)
디버거는 용어 그대로 디버깅을 할 때 도움을 주는 도구이다. 디버거는 프로그램을 어셈블리 코드 단위로 실행시키면서 실행결과를 사용자에게 보여준다. 디버깅을 거치면서 개발자는 자신 코드의 문제점을 발견하고 고쳐나간다. 디버거는 종류가 다양하고 그 중 가장 많이 쓰이는 디버거 중 하나인 리눅스의 디버거 gdb의 사용법에 대해 알아보자.
정확한 설명은 이곳을 참고하자.
https://www.sourceware.org/gdb/
gdb 실행방법
리눅스 터미널에 접속 한 후 gdb라고 입력하면 실행할 수 있다.
간단한 프로그램 디버깅 해보기
일단 디버깅을 할 프로그램을 만들어 준다. 처음이니까 간단한 프로그램을 만들어 보았다.
gcc -o debugger debugger.c
gcc를 이용해 컴파일 해준다.
※gcc란?
GNU Compiler Collection의 약자로 GNU(GNU's not UNIX) 프로젝트의 컴파일러이다. 처음에는 C만 지원했지만 점점 범위를 넓혀 objective c, pascal, ada와 같은 언어도 지원하고 있으며, 수많은 운영체제에 사용할 수 있다.
※GNU란?
GNU's not UNIX 의 약자이다. 특이한 점은 재귀적으로 단어를 정의하고 있다. 간략하게 소개하자면 리처드 스톨먼의 소프트웨어 재단에서 진행하는 OS 프로젝트이다.
내가 만든대로 잘 실행하는 모습을 볼 수 있다.
그럼 이 프로그램에 디버거를 실행해보겠다.
gdb debugger
gdb 명령어
gdb는 한줄의 입력을 받아서 실행한다.
help로 명령어 목록을 확인해 보았다.
본격적으로 gdb를 실행하기 전에 설정을 하나 해주고 가겠다.
(gdb) set disassembly-flaver intel
intel 방식이 더 보기도 편하고 많은 사람들이 사용하는 것 같아서 intel 방식을 사용하겠다.
설정 후 main함수를 디스어셈블해보겠다.
(gdb) disass main
아까전에 만든 프로그램을 어셈블리 언어로 나타내서 보여준다.
이 포스팅은 어셈블리 언어에 관한 것은 아니니 코드에 대한 자세한 설명은 건너뛰겠다. 곧 어셈블리에 관련해서도 포스팅 할 예정이다.
하지만, 이렇게 코드만 보고서는 완벽한 디버깅이 불가능하다. 그렇기 때문에 한줄씩 실행시키면서 프로그램의 흐름을 살펴보아야 한다. 가장 먼저 할 일은 종단점을 찍는 일이다. 어디서부터 디버깅을 시작할지 알려주는 표시라고 생각하면 쉽다. 나는 main함수의 첫번째부터 할 것이기 때문에 main 함수 첫부분에 종단점을 찍겠다.
(gdb) break * main
break를 축약해서 그냥 b로 사용하기도 한다. (b * main 과 같은 의미라는 것이다.)
그럼 아래와 같이 종단점이 찍힌 모습을 볼 수 있다.
종단점이 찍힌 위치는 위에서 disass 로 확인했던 main함수의 첫번째 주소라는 것을 쉽게 알 수 있다. 추가적으로 첫번째가 아니라 다른 부분에 종단점을 찍고 싶다면 +로 해당되는 주소까지 이동을 하면 된다. 또는 해당되는 주소를 바로 입력해도 좋다.
ex) break *main + 8
만든 종단점은 info break로 확인 할 수 있고 삭제는 delete로 할 수 있다. 특정 종단점을 삭제하고 싶으면 delete <번호>를 입력하면 된다.
run을 입력하면 프로그램의 작동한 결과를 알려준다. 만약 인자가 필요하다면 run 뒤에 인자를 입력해주면 된다. run은 종단점이 걸려있다면 처음부터 실행하다가 종단점에서 멈추게 된다. 만약 그 곳에서 다시 시작을 하고 싶으면 continue를 처음으로 돌아가고 싶으면 run을 다시 입력하면 된다.
진짜 본격적으로 사용을 해보겠다.
종단점을 찍고 start를 입력하면 시작한다. ni를 입력하면 다음으로 넘어가게 된다.
(gdb) b*main
(gdb) start
(gdb) ni
register는 info reg에서 확인할 수 있다.
<명령어 정리>
dissasemble (disass) | 디스어셈블 해줌 |
start (s) | 시작함 |
next instruction(ni) | 다음으로 넘어감 |
break (b) | 종단점을 설정함 |
info (i) | 정보를 알려줌 |
gdb에 대한 내용은 여기까지만 소개하도록 하겠다. 왜냐하면 gdb에 편한 플러그인인 pwndbg를 설치해서 사용할 것이기 때문에 간략하게만 하겠다. 중요한 명령어는 더 많고, 그 것을 확인하려면 아래 pwndbg 포스팅을 참고하자!
'Linux' 카테고리의 다른 글
[Linux] 3. 셸을 능숙하게 다루는 방법 (0) | 2022.08.10 |
---|---|
[Linux] 2. 셸이란 무엇인가? (0) | 2022.08.10 |
[Linux] 1장. 리눅스 설치하기 (0) | 2022.08.09 |
[Tool] Pwntool 설치 및 사용법 (0) | 2022.02.07 |
[Tool] pwndbg 설치 & 사용법 (0) | 2022.02.07 |