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

[SYSTEM HACKING] 실습 환경 세팅 / 컴파일 과정 / ELF 섹션(ELF Section) / 어셈블 프로그래밍

by B T Y 2017. 10. 14.
반응형

실습 환경 세팅 / 컴파일 과정 / ELF 섹션(ELF Section) / 어셈블 프로그래밍에 대해서 정리한다.




- 실습 환경

  - Red Hat Linux 6.2

    * 부팅시마다 LILO BOOT에서 linux-up을 입력해줘야 한다.



  - 원격접속 설정


    1). /etc/securetty

    pts/0

    pts/1

    pts/2

    ..

    pts/8


    * 위 내용을 해당 파일에 추가 시켜주기만 하면 다음 부팅시부터 Telnet을 이용한 원격접속이 가능하다.



    2). PAM: /etc/pam.d/login

        - 두번째 라인을 주석 처리

        - # auth required /lib/security/pam_securetty.so



  - 사용하는 도구


         * C 컴파일러 : GCC ( GNU C Complier)

         * 어셈블러    : GAS( GNU Assembler ): AT&T 문법

                        NASM( Netwired Assembler ): AT&T, INTEL 문법을 지원

         * 디버거  :  GDB( GNU DeBugger ): 바이너리 분석 도구



  - nasm 설치


     #> wget http://www.nasm.us/pub/nasm/releasebuilds/0.99.05/nasm-0.99.05.tar.gz

     #>  tar xvfz nasm-0.99.05.tar.gz

     #> cd nasm-0.99.05

     #> ./configure

     #> make

     #> make install

     #> cp nasm /usr/bin


    * 실습환경 운영체제를 Red Hat Linux6.2를 사용하기 때문에 nasm은 제일 낮은 버전인 0.99.05를 설치했다.



  ! C 컴파일


    - windows: visual studio, eclipse, ...

    - IDE: 개발환경( 컴파일러 + 편집기 + 디버거 + ... )


    - 실습에는 컴파일러: GCC, 편집기: VI, 디버거: GDB를 사용한다.


    * 컴파일러를 이용해서 c언어를 컴파일 할때는 .c 확장자를 붙여준다.

    * gcc 컴파일러를 이용해서 컴파일하게 되면 실행 가능한 프로그램(바이너리) 파일 하나가 나오게 된다.

    * 생성할 파일 이름을 지정하지 않으면 default 파일 이름으로 a.out이 나온다.

      ( 같은 이름의 프로그램이 있는 경우에는 내용을 덮어쓴다 )


    * 컴파일시 생성되는 파일 이름을 지정하려면 -o 옵션을 이용해서 지정해준다.

      ( 예를 들어서 gcc -o hello hello.c를 하게 되면 hello라는 이름으로 프로그램이 생성된다 )


   * 컴파일 과정

  

          hello.c -> hello.i -> hello.s( .asm ) -> hello.o -> hello




1. 컴파일 과정


  1). 전처리 과정: cpp

    -  hello.c   ->   hello.i


   * 전처리 과정에는 해당 되는 지시문들을 치환해서 가져온다.

     ( c언어를 예로 들면 #include, #define 등의 지시문들을 치환해서 가져온다 )



  2). 컴파일 과정: cc1

    - hello.i   ->   hello.s


    - c 코드를 어셈블 코드로 바꿔주는 과정

    - GAS는 .s 확장자를 사용하고 nasm은 .asm 확장자를 사용한다.


  3). 어셈블리 과정:  as(GAS)

    - hello.s   ->   hello.o


    - 어셈블 코드를 바이너리 형태로 바꿔주는 과정


  4). 링킹 과정: ld, collect2( GCC )

   - hello.o   ->   hello


    - 여러개의 목적파일(object file)을 묶어서 하나의 프로그램을 만드는 과정


   * 리눅스에서 xxd 명령어를 이용하면 object file 내용을 16진수와 ASCII 형태로 볼수 있다.














! 실행파일 구조


    - 리눅스 : ELF ( 파일 시그니처: ELF (7f45 4c46) )

    - 윈도우즈 : PE ( 파일 시그니처: MZ )

    - 유닉스: COFF


    * 각 운영체제별로 실행파일의 구조가 다르다. 

      그렇기 때문에 리눅스 운영체제에서 만든 실행파일을 윈도우 운영체제에서 실행 할 수 없다.

    * 악성코드를 분석할때 실행파일 구조 파악은 필수!!


   * ELF 구조



( 실행파일을 실행할때는 ELF 헤더에 들어있는 내용을 보고 해당 섹션들을 실행한다 )



! 프로그램 & 프로세스


1. 프로그램

  - 실행중이지 않은 상태

  - 디스크상에 파일 형태로 존재


2. 프로세스

  - 실행중인 상태

  - 운영체제가 관리하는 작업의 단위

  - 파일이 메모리에 존재


  * 리눅스에서는 objdump -x 명령을 이용해서 ELF 파일에 모든 헤더들을 읽어드릴수 있다.


  * objdump -d를 이용하면 object file에 바이너리 내용을 어셈블러로 변환시켜 볼 수 있다.





- section


  1. text 섹션(세그먼트)


    - 실행코드가 존재하는 영역

    - 읽기전용

    - 실행가능한 메모리 영역



  2. DATA 섹션(세그먼트)


    - 읽기/쓰기 가능한 메모리 영역

    - 초기화된 데이터 영역



  3. BSS 섹션(세그먼트)


    - 읽기/쓰기 가능한 메모리 영역

    - 초기화 되지 않은 데이터 영역



  4. 스택


    - 파일상에서는 나타나지 않는다.

      예) 전역변수는 실행시에 스택 영역을 사용




software engineering( 소프트웨어 공학 )


  - 소프트웨어를  만드는 전체 과정

  - 기획 -> 설계 -> 구현 -> 배포 -> 유지보수


  * 리버싱배포단계를 구현단계로 되돌리는 엔지니어링 기법이다.

     ( 컴파일 단계에서 보면 4단계에서 3단계, 즉 프로그램에서 바이너리 코드로 되돌려 어셈블리어로 변환이 가능해진다 )



어셈블 프로그래밍


  - 각 섹션(세그먼트)들을 직접 정의


  - ;(세미콜론)어셈블 프로그래밍을 할때 주석으로 사용된다.

  - extern을 이용해서 외부 라이브러리를 가져오고 call 명령을 이용해서 사용할 수 있다.

     * 시스템 콜을 이용하면 외부 라이브러리 없이 어셈블리어로만 프로그램을 작성 할 수 있다.

       ( 순수 어셈블리어로 프로그램을 작성하게 되면 성능적인 면에서도 c언어를 사용할때보다 더 좋다는 

         태생적인 장점이 있다 )


     * nasm에 대한 사용법은 공식홈페이지에 문서를 참고하면 된다.

         nasm 공식 홈페이지http://www.nasm.us/











 ! 32bit 메모리 운영체제 기준으로 가상메모리를 4GB 사용한다.

     ( 1GB는 kernel이 사용하고 나머지 3GB를 사용 )


     * kernel이 사용하는 메모리는 접근 불가능

     * 64bit 메모리의 경우에는 개념은 같고 32bit에 비해 가상메모리의 크기가 확장될뿐이다.




반응형

댓글