본문 바로가기
프로그래밍/SYSTEM HACKING

[SYSTEM HACKING] 디버거(DeBugger) 사용법( GDB ) / 바이트 오더( byte order )

by B T Y 2017. 11. 13.
반응형


디버거(DeBugger) 사용법( GDB ) / 바이트 오더( byte order )에 대해서 정리한다.




! 디버거 사용법


  - De + Bugger


  - Bug: 벌레( 그레이스 호퍼 )

  - 프로그램에 오류를 일으킬수 있는 존재( Bug )


  - De Bug -> Debugging -> DeBugger


  - linux에는 GDB가 있다.


  !! gcc 컴파일시에 -g 옵션을 이용하면 디버깅 모드로 컴파일이 된다.

     ( 컴파일시 디버깅에 대한 정보를 담는다 )



! 디버거를 통한 프로그램의 실행


  #> ./myshell -> execve -> 프로세스

      - 그냥 실행할 시에는 실행되는 프로세스에  접근 불가


  #> ./myshell -> 디버거 -> execve -> 프로세스

      - 디버거를 통해 프로세스를 직접 제어(접근)


  !! 디버거에서는 항상 절대 경로로 실행된다.

  !!! 디버거의 명령어는 인터넷 검색을 통해서 사용할때마다 참고할 것!!







1. 코드 확인


  - gdb [파일]

  - C로 작성된 경우 entry point -> main

  - assembly로 작성된 경우 entry point -> _start


      * 확인을 할때 처음 entry point부터 시작해서 프로그램의 전체적인 구조와 동작방식을 파악해 나간다.


  !! gdb에서는 INTEL 방식이 아닌 AT&T 방식을 지원한다.

       ( 인텔 방식으로 보려면 set disassemble-flavor intel 명령을 이용해서 변경 해준다 )

  !! gdb에서는 tab키 기능을 지원해준다.


  (gdb) disassemble 주소

      * 위 명령을 이용하면 프로그램의 코드를 해당 주소부터 시작해서 disassemble 된 형태로 보여준다.





( 보통 프로세스의 흐름을 파악할때는 entry point부터 시작해서 전체 어셈블리 코드를 보면서

파악하기 때문에 위에서는 어셈블리로 컴파일된 프로그램이기 때문에 _start로 entry point를 지정 해줬다 )



( GDB에서는 AT&T 방식을 지원하기 때문에 INTEL 방식으로 보는게 편하다면 set disassembly-flavor intel 명령을

이용해서 출력해주는 방식을 INTEL 방식으로 설정 해줄수 있다. )



2. 프로그램 실행 제어


  1). 브레이크 포인트


      (gdb) break *(주소)

         * break를 주소에 걸어두게 되면 해당 주소가 실행될때 break가 걸리게 된다. 

             ( 즉, 해당 코드가 실행되지 않는다면 break는 걸리지 않게 되니 주의한다!! )


      (gdb) continue

         * continue 명령을 이용하면 break 상태에서 다시 break가 걸리기 전까지 실행이 된다.

             ( continue로 실행을 했을때 break가 없다면 프로세스의 끝까지 실행이 된다 )


          * 브레이크 포인트는 해당 명령이 실행될때마다 멈추게 된다.

             ( 해당 명령어가 실행되지 않으면 브레이크에 걸리지 않게 된다!! )



! 소프트웨어 브레이크 포인트( gdb가 사용하는 브레이크 포인트 )


  - 갯수의 제한없이 설정이 가능

  - 해당 주소의 명령어가 실행되지 않으면 브레이크도 걸리지 않는다.




( break 명령으로 break point를 지정해주게 되면 해당 주소 이전까지만 명령이 실행되게 된다 )



( break point를 만난 이후에 다음 break point까지 실행을 하고 싶다면 continue 명령을 이용한다 )


* 프로세스의 실행과정에 대한 흐름이나 메모리 상태를 한단계씩 파악하려고 할때는 

si 명령이나 ni 명령을 이용해준다!!






3. 출력 명령어: x, print


  - 메모리 덤프: x/출력갯수/출력형태/출력단위 메모리주소


  - 기본형태 ( 1개, 16진수, 4바이트 )

    (gdb) x/1xh


  - 출력형태: 10진수( d ), 8진수( o ), 16진수( x ), 문자열( s ), 명령어( i )

  - 출력단위: 1바이트( b ), 2바이트( h ), 4바이트( w )


     * 다음 명령 실행시 출력 형태와 단위를 지정하지 않는다면 마지막에 지정한 출력 형태와 출력 단위를 그대로 사용한다.

     * 주소를 붙여주지 않으면 명령을 실행 할 때마다 그다음 주소를 계속해서 출력한다.





! 바이트 오더


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


1). little-endian


  - 일반적으로 사람이 읽는 순서 왼쪽 -> 오른쪽 방식이 아닌 바이트 단위로 거꾸로 저장

  - intel CPU는 little-endian 방식을 사용


  - 0x12345678  -> 0x78563412


2). big-endian


  - 0x12345678  -> 0x12345678




  !! x 명령어를 사용하면 해당 값을 주소로 인식해서 접근하기 때문에 사용할 때 주의가 필요하다.


  !! 디버거 모드에서 프로세스를 한줄씩 실행하려면 si 명령이나 ni 명령을 사용한다.


  !! 현재 사용하는 gdb 버전에서는 프롤로그와 에필로그 부분에서는 si 명령을 이용해서 실행해줘야 한다.

      ( 그 외에는 ni 명령을 사용하고 두 명령의 차이점은 si 명령을 사용하면 함수로 실행을 따라 들어가게 되고

         ni 명령의 경우에는 함수로 따라 들어가지 않고 다음 명령을 실행하게 된다. )




반응형

댓글