농소

디버거 GDB 사용법 본문

Security/System Hacking

디버거 GDB 사용법

농소 2018. 1. 26. 04:28


1. 디버거 사용법: GDB (콘솔상에서 사용하는 디버거)


  - bug : 프로그램에 존재하는 잠재적인 오류

  - de-bugging : 버그를 찾는 행위

  - de-bugger : 버그를 찾는데 도와주는 도구


일반 사용자 shell(user)가 메모리에 접근할 수 없고, 커널은 메모리에 접근권한을 가지고있다.

우리가 프로세스에 접근하기 위해선 디버거를 이용하여 메모리에 접근 할 수 있다.


유명한 디버거 IDA, OLLY..


GDB 사용법


  - 실행 : run

  - 종료 : quit


1). #>gdb <실행프로그램>



2). #>gdb

  (gdb) file <실행프로그램>




2. 자주 사용하는 GDB 명령어, 기능


  - 명령어 축약 : (r)un   - r만 입력해서 run으로 인식

  - 명령어 완성 : r<tab>  - r로 시작하는 명령어를 보거나 완성 할 수 있다.



tab을 통해 r, in, d로 시작하는 명령어를 보여준다.


*프로그램 실행 : run

*gdb 종료 : quit


*디스어셈블 : disassemble <주소>

  - 특정 주소에 있는 값을 자동으로 어셈블로 해석한다.


*문법 변환기능 : set disassembly-flavor intel or at

  - gdb에서는 intel방식이 아닌 at&t방식을 지원한다.

  - at&t방식 같은경우 intel과는 다르게 src와 dst가 바뀌어서 표현되는데

     intel방식으로 배워온 입장에서 보기에 햇갈릴수도 있다. 그래서 이 기능으로 intel문법에 맞게 변환시켜준다.


*메모리 or 레지스터 값 덤프(출력)


  레지스터 값 확인 : info

    - 특정 레지스터 값 확인 - info registers eax ebx esp ebp  <= eax ebx esp ebp 레지스터만 확인>


  메모리 값 확인 : x/nfu <주소>

    - n: number -> 출력 갯수

    - f: format -> 출력 형태 // x, d, o, s, c, i(=instruction 해당 메모리값을 명령어로 출력)

    - u: unit -> 출력 단위 // b(1byte), h(2byte), w(4byte)

  ex) x/20xw = 4바이트 단위(w)로 짜른 메모리값을 16진수(x) 형태로 20개 출력


기본값(default)은 xw이다. 16진수, 4바이트 형태


*프로세스 실행 흐름 제어


  프로세스 실행 멈춤 : break *<주소>

    - info breakpoints : 현재 설정된 breakpoints를 확인가능

    - delete : 설정된 breakpoint 제거

    - disable / enable : 설정된 breakpoint 비활성/ 활성화


  프로세스 다시 실행 : continue


  프로세스 멈춰놓고 한단계씩 추적 

    ni(=nexti) : 함수를 넘김

    si(=stepi) : 함수이동



현재 c로 구동하는 실행파일이 처음으로 시작하는

 엔트리포인트 main 을 disassemble 하였고( asm은 엔트리 포인트가_start )

지역변수 공간을 할당하기 전에 break을 걸어주었다.

그리고 실행을 했을시에 break건 곳에서 실행이 멈추게 됐고

그때의 스택포인터값들을 확인해 보았다.

main이 실행하면서 saved eip가 생성되고 push ebp까지 진행이 되었으므로

0xbffffb58이 ebp, 0x400349cb가 eip, 0x00000001 이 argc 0xbffffb84가 argv인것을 알 수 있다.



이렇게 ni, si하면서 차례차례 진행하면서 분석하는기법을 동적분석이라고 한다.



Byte order


  - cpu가 메모리에 저장하는 바이트 순서


Little - endian : Intel <바이트를 뒤집어서 표현하는 방식> 4바위트 단위로 뒤집힘

Big - endian : Netwark, motolora 바뀌지않고 돌아감


0x12 0x34 0x56 0x78

------------------------

0x78 0x56 0x34 0x12  이러한 방식이 cpu가 연산하기 편하다고함. 사람이 보기엔 불편.

메모리를 다룰때 이것을 생각해가면서 진행해야함.


< xxd 명령어로 해당 주소에 대한 메모리값 출력 >


<gdb 디버거로 메모리 출력했을 경우>


디버거로 4바이트씩 짤라서 메모리를 볼때 위와같이 0x7f454c46이 아닌 0x464c457f로 표현된다.


< 1바이트씩 짤라서 확인한 모습 >


결과적으로 little - endian 방식을 사용 하므로 디버거를 이용할 때

 4바이트씩 짤라서 거꾸로 표현되는걸 확인 할 수 있다.

그러므로 디버거를 사용할때 이점에 유의해야한다.