농소

3. ELF파일 구조, nasm 데이터표현 본문

Security/System Hacking

3. ELF파일 구조, nasm 데이터표현

농소 2018. 1. 13. 04:37

ELF 구조


< 실행파일을 실행할 때 elf헤더의 내용을 참조해 섹션들을 실행함. >


linux 32bit의 경우


하나의 process 사용하는 메모리 4gb( 가상메모리 )  1gb / 3gb 나눔

1gb = 커널사용 우리는 커널에 접근x 접근한다면 해킹

3gb= 운영체제를 위한 / 3gb를 나눠서 사용 = [ text영역( =Segment or Page or Section ) , data영역 , stack영역 ]

3gb의 메모리 영역중 0번지 주소부터 일정영역 까지는 사용x



1). data segment


  - 읽기/쓰기 가능한 메모리 영역 / 실행x  ex) rw-

  - 프로그램 실행에 필요한 데이터

  - 초기화된 데이터  ex) int var =10;


2). bss segment


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

  - 초기화 안된 데이터 ex) int var;  ,  char str[];


2). text segment


  - 실행 가능한 메모리 영역 / 쓰기 x  ex) r-x

  - 주로 실행할 명령어들이 들어있다.



* objdump -x 명렁어로 elf파일의 헤더를 분석할 수 있고

  -d 옵션으로 이진언어를 어셈블리 언어로 바꾸어 볼 수 있다.


< 좌측에는 16진수 우측에는 어셈블 언어로 표현 >




1. ELF헤더분석


  - 미리만든 hello2.asm을 통해 분석을 해보겠다.


< hello2.asm 파일>


  - 현재 data 세그먼트와 text 세그먼트 2개로 이루어져 있는걸 볼 수 있다.

  - 다음으로 OBJDUMP -X 로 헤더를 분석해본다.


< objdump -x hello2 입력으로 해당 헤더정보를 추출 >



우선 파일이 elf형식이라고 나타내고 있고, 엔트리 포인트 start의 주소가 0x08048080인것을 알 수 있다.

hello2.asm 에서 보았듯이 segment .data와 segment .text 두개만 사용 했으므로 두개의 섹션 헤더가 출력되었다.

text 섹션 헤더를 보면 맨 처음 시작주소가 0이 아닌 0x8048000인데

메모리 영역 중에 0부터 0x7ffff이하 주소는 사용을 안하기 때문에 시작 주소가 0x8048000부터 시작하게 된다.

파일 크기를 보면 16진수로 96으로 되어있는데 10진수로 표기하면 150의 크기이므로

즉 text섹션의 범위는 0x08048000부터 150크기만큼의 범위를 가진다고 보면 된다.


다음으로는 실행파일을 디스어셈블하여 헤더에서 본 대로 text section,data section 를 찾아보겠다.


< xxd hello2 입력으로 16진수와 아스키코드값 출력모습 >


  - text section offset 기준으로 0x00000000 ~ 0x00000096 

  - data section offset 기준으로 0x00000098 ~ 0x00000109 




2. data, bss segment 데이터 표현


1) 데이터 타입


< C > 


  - 숫자( 정수, 실수 ), 문자( ' =단일쿼트 ), 문자열( " 더블쿼트 )


< Assemble >


숫자( 정수, 실수 ), 문자or문자열 구분x 오로지 '(단일쿼트)사용,

문자열 사용시 이스케이프 시퀸스(\n) 대신 10 , \0대신 00 으로 아스키문자를 HEX로 표현하여 사용한다.

ex) String    db    'hello, world!!!', 10, 00


<nasm 공식 홈페이지 문자열 정식 표기법>



 2) 레이블 vs 변수


http://www.nasm.us/xdoc/2.13.02/html/nasmdoc3.html#section-3.1 >



3.1  Layout of a NASM Source Line

형식 = label:    instruction operands        ; comment

ex)     string:   db  'hello, world!!!' ,10 , 00


1) 레이블

  - 이름표: 주소 

string: db 'hello, world!!!' ,10 , 00

hello, world~라는 시작주소를 넣음


2). 변수

  - 값, 주소, 크기

  - int var = 10;


  - 레이블은 단순 주소를 표현, 변수는 값, 주소, 크기 전부표현



예시 string:   db  'hello, world!!!' ,10 , 00 중에서 이제 레이블과 'hello, world!!!' ,10 , 00이 무엇을 뜻 하는지 알 수 있다.

그러나 db는 무엇을 하는걸까?


우선 nasm 어셈블에서는 segment마다 특정 접두사가 붙게 된다.



보시다시피 data segment에는 d라는 접두사가 붙게되고, bss segment에는 res라는 접두사가 붙게된다.

그러면 접두사 뒤에붙는 b는 무엇을 뜻하는 것일까? 바로 데이터 크기를 나타낸다.


3) 데이터의 크기


 Byte

unit 

(b)yte 

char 

2

(w)ord 

short 

(d)word 

int, float, pointer, ... 

(q)word 

long long, double 

10 

(t)enbyte 



즉  string:   db  'hello, world!!!' ,10 , 00 는 
string으로 레이블로 붙혀진 (b)yte가 hello~ 문자열로 초기화 된다는 뜻이 된다.



3. text segment에서의 명령어 표현


  - segment .text에서는 segment .data의 인자값 들을 불러와 출력하는데

  - 어셈블리에서 데이터를 출력할때 인자값을 역순으로 push명령어를 통해 인자들을 넣어주고

    마지막에 call명령어로 함수를 호출한다.



< 출력을 할때에는 반드시 역순으로 인자를 넣어야한다는 것에 유의한다!! >