본문 바로가기

System Hacking

2일차] 어셈블리 확인하기

[ 실행파일 구조 ]

- 리눅스 : ELF    - 윈도우즈 : PE       - 유닉스 : COFF

#> xxd hello.o                                //  *xdd : 리눅스에서 제공하는 헥스뷰이다.

 

프로그램 & 프로세스 ]

1. 프로그램

- 실행중이지 않은 상태

- 디스크(보조 기억 장치)상에 파일 형태로 존재

 

2. 프로세스 (fore ground process 와 back ground process가 있다.)

- 실행중인 상태

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

- 파일이 메모리(주 기억 장치)에 존재

 

[ 어셈블리어로 메모리 영역 이해하기. ]

 

1. text section(세그먼트)

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

- 읽기전용

- 실행가능한 메모리 영역

- main 부분에 해당됨. 

 

 

2. DATA 섹션(세그먼트)

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

- 초기화된 데이터 영역

- 위의 예제의 "MAX VALUE : %d \n"에 해당하는 부분이다.

 

3. BSS 섹션(세그먼트)

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

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

 

4. 스택

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

 

 

*어셈블 프로그래밍 : 각 섹션(세그먼트)들을 직접 정의하는 작업 (메모리 직접 다룬다.)

 

 

 

[ 어셈블 Hello, World 작성하기 ]

#> vi hello.asm

# printf("Hello world!!!\n");를 어셈블 프로그래밍을 하면 위와 같다. c 표준 라이브러리 함수의 printf를 사용하기위해 extern printf 이용. nasm 어셈블러를 이용해 실행가능한 바이너리 파일을 만들고, 링킹과정은 gcc에게 목적파일을 넘겨주면 자동으로 해준다.

 

 

#> objdump -d hello.o                                      // objdump -d 옵션을 이용하면 어셈블 부분만 추출해서 보여준다.

 

 

 

 

[ printf 까지 어셈블리로 만들기 ]

# systemcall을 이용하여 printf까지 구현해냈다. 나중에 시스템콜이 나온다. 직접적으로 구현해 주는 것이기 때문에 extern조차 필요없다.

 

 

# objdump -x hello2 헤더정보를 확인해 보면 위와 같다. 4kb의 텍스트 세그먼트와 4kb의 데이터 세그먼트가 있으며, 각각 메모리에 올라갈 때 80, 92의 위치로 파일 사이즈만큼 올라가 있게 된다. 해당 offset을 이용하여 xdd로 주소값 계산을 해보면 값이 그대로 들어가 있는 것을 확인 할 수 있다.

 

 

[ 어셈블리 숫자표현하기 (10진수로 16) ]

10진수 - 16d

16진수 - 10h(hex)

8진수   - 20o(octal)

2진수   - 10000b(binary)