'컴퓨터 서적 정리/Binary Hacks'에 해당되는 글 21건

  1. 2011.07.01 [Hack #5] Object file - ELF 파일
  2. 2011.06.29 [Hack #4] od - 바이너리 파일 덤프
  3. 2011.06.29 [Hack #3] file – 파일 종류 확인 1
  4. 2011.06.29 [Hack #2] Binary Hack 용어 정리 1
  5. 2011.06.29 [책소개] Binary Hacks
2011. 7. 1. 15:50

♧ ELF :: Executable and Linking Format 의 약자로,

실행 가능한 바이너리 또는 오브젝트 파일 등의 형식을 규정한 것.

▷ ELF 파일은 ELF헤더가 맨 앞에 위치.

▷ 프로그램 헤더 테이블과 섹션 헤더 테이블이 그 뒤에 위치.

▷ 이러한 헤더의 구조는 elf.h 참조

   

   

   

:: ELF 에서 사용하는 자료형

▷ ELF 바이너리에는 32bit와 64비트, 두 가지가 있다.

자료형

N = 32

N = 64

설명

ElfN_Half

uint16_t

uint16_t

부호 없는 16비트 값

ElfN_Word

uint32_t

uint32_t

부호 없는 32비트 값

ElfN_Sword

int32_t

int32_t

부호 있는 32비트 값

ElfN_Xword

uint64_t

uint64_t

부호 없는 64비트 값

ElfN_Sxword

int64_t

int64_t

부호 있는 64비트 값

ElfN_Addr

uint32_t

uint64_t

주소

ElfN_Off

uint32_t

uint64_t

오프셋

ElfN_Section

uint16_t

uint16_t

섹션 인덱스

ElfN_Versym

uint16_t

uint16_t

버전 심볼 정보

  

   

   

:: [ ELF 헤더 ] readelf 의 -h옵션 (--file-header)

▷ ELF헤더는 ELF파일 맨 앞에 반드시 존재하며, 그 파일이 ELF 파일임을 나타냄.

   

[ ELF헤더 구조 ] (/usr/include/elf.h)

   

▷ e_ident::

ELF의 매직 넘버(MAGIC NUMBER)와 기타 정보를 갖고 있다.

ELF 파일은 첫 4바이트에 다음과 같은 매직 넘버를 갖는다

| 0x7F | 0x45 | 0x4c | 0x46 | → "\177ELF"가 된다.

그 다음 바이트는 32비트인 경우 ELFCLASS32(1), 64바이트인 경우 ELFCLASS(2)가 된다.

다음 바이트는 엔디안을 나타냄.(리틀 엔디안인=ELFDATA2LSB(1),빅 엔디안인=ELFDATA2MSB(2))

나머지 바이트는 ELF버전과 OS, ABI 등의 정보를 1바이트씩을 사용해 나타냄.

   

▷ e_type:: 다음 타입 중 하나를 나타낸다.

타입

설명

ET_REL

1

재배치 가능한 파일

ET_EXEC

2

실행 가능한 파일

ET_DYN

3

공유 오브젝트 파일

ET_CORE

4

코어 파일

   

▷ e_machine:: 아키텍처 타입을 타나낸다. (EM_으로 시작하는 상수로 정의되어 있음.)

▷ e_version:: ELF 버전을 나타낸다. (위 예(/bin/ls)는 EV_CURRENT(1)이다)

▷ e_entry:: 이 ELF에서 실행 시작하는 가상 주소.

▷ e_ehsize:: ELF 헤더 자체의 크기.

▷ e_phoff, e_phentsize, e_phnum:: 프로그램 헤더 테이블의 위치, 크기, 헤더 개수.

▷ e_shoff, e_shentsize, e_shnum:: 섹션 헤더 테이블의 위치, 크기, 개수.

▷ e_shstrndx:: 섹션명의 스트링 테이블을 갖는 섹션 헤더 인덱스를 나타냄.

   

   

:: [ 프로그램 헤더 ] readelf의 -l 옵션 (--program-headers)

▷ 프로그램 헤더 테이블은 ELF 헤더의 e_phoff로 지정된 오프셋에서 시작.

▷ e_phentsize(헤더크기)와 e_phnum(프로그램 헤더 개수)으로 정해진 크기를 갖는 테이블.

(※ 즉, 프로그램 헤더 테이블의 전체 크기 = e_phentsize * e_phnum)

   

 [ 프로그램 헤더 구조 ]

   

▷ 『Program Headers:』의 각 행에 해당.

▷ p_type:: 다음과 같다.

p_type

설명

PT_LOAD

1

로드된 프로그램 세그먼트

PT_DYNAMIC

2

동적 링크 정보

PT_INTERP

3

프로그램 인터프리터

PT_NOTE

4

추가 정보

PT_PHDR

6

프로그램 헤더 테이블 자신

PT_TLS

7

스레드 지역 저장소

PT_GNU_EH_FRAME

0x6474e550

GNU .eh_frame_hdr 세그먼트

PT_GNU_STACK

0x6474e551

스택 실행 가능성

   

▷ 『Section to Segment mapping:』 이후의 행에 나타난 정보는

『Program Headers:』의 각 프로그램 헤더에 나타난 세그먼트에

그 세그먼트 메모리 범위를 포함하는 섹션명을 나열하고 있다.

   

(인덱스 00) 프로그램 헤더에 표시된 세그먼트는 PHDR 타입이고 그에 속하는 섹션은 없다.

(인덱스 01) 프로그램 헤더에 표시된 세그먼트는 INTERP 타입이고 그에 속하는 섹션은 .interp가 있다.

(인덱스 02) 프로그램 헤더에 표시된 세그먼트는 LOAD 타입이고 그 안에는 .interp, .note.ABI-tag, ...등등

▷ 『Section to Segment mapping:』 ↔ 『Program Headers:』 이 둘을 연결해서 봄.

type

segment

section

PHDR

00

없음.

INTERP

01

.interp

LOAD

02

.interp , .note.ABI-tag , .note.gnu.build-id, .hash ...[등등]

  

   

   

:: [ 섹션 헤더 ] readelf의 -S 옵션 (--section-headers)

▷ 섹션 헤더 테이블은 ELF 헤더의 e_shoff로 지정된 오프셋에서 시작.

▷ e_shentsize(섹션 헤더 크기)와 e_shnum(섹션 헤더 개수)으로 정해진 크기를 갖는 테이블.

(※ 즉, 섹션 헤더 테이블의 전체 크기 = e_shentsize * e_shnum)

   

[ 섹션 헤더 구조 ]

▷ 『Section Headers:』의 각 행에 해당.

▷ 섹션명(Section name)은

ELF 헤더의 e_shstrndx로 지정된 섹션에 포함된 스트링 테이블의 인덱스로 지정.

▷ 위의 /bin/ls 예의 경우,

e_shstrndx는 28이므로, 28번째 섹션 헤더가 그 스트링 테이블을 갖는 섹션이 된다.

- sh_offset이 '0x0192d4' 이고, 크기가 '0x0000f2' 바이트인 스트링 테이블(STRTAB)임을 알 수 있다.

   

▷ 섹션 타입(sh_type):

 섹션 타입

 값 

 설명

 SHT_PROGBITS

 1

 프로그램 데이터

 SHT_STRTAB

 2

 심볼 테이블

 SHT_STRTAB

 3

 스트링 테이블

 SHT_RELA

 4

 재배치 엔트리

 SHT_HASH

 5

 심볼 해시 테이블

 SHT_DYNAMIC

 6

 동적 링크 정보

 SHT_NOTE

 7

 Notes (호환 체크정보)

 SHT_NOBITS

 8

파일상에  데이터가 없는 부분 (.bss)

 SHT_REL

 9

 재배치 엔트리

 SHT_DYNSYM

 11

 동적 링크의 심볼테이블

 SHT_INIT_ARRAY

 14

 생성자 배열 (.init) 

 SHT_FINI_ARRAY

 15

 소멸자 배열 (.fini)

 SHT_GNU_verdef

 0x6ffffffd

 버전 정의 섹션

 SHT_GNU_verneed 

 0x6ffffffe

 필요한 버전 섹션

 SHT_GNU_versym

 0x6fffffff

 버전 심볼 테이블

  

   

   

:: [ 스트링 테이블 ]

▷ 스트링 테이블은 단순한 문자열 리스트이다.

▷ /bin/ls의 경우 다음 섹션이 스트링 테이블이다.

▷ 예를 들어 [28] .shstrtab의 오프셋은 '0x0192d4', 크기는 '0xf2'이므로

od를 사용하여 테이블을 확인하자.

# od --skip-bytes 0x192d4 --read-bytes 0xf2 -t x1z /bin/ls

▷ 이 경우 스트링 테이블은 다음과 같이 되어 있다.

인덱스

문자열

1

.shstrtab

11

.interp

19

.note.ABI-tag

즉, .shstrtab의 맨 앞부터의 오프셋이 스트링 테이블의 인섹스가 된다.

   

   

:: [ 심볼 테이블 ] readelf의 -s 옵션 (--syms)

▷ 심볼 테이블은 심볼과 그 값 등을 대응시키는 테이블이다.

▷ /bin/ls의 경우 strip되어 있으므로 동적 심볼 테이블만 있다.

...(중략)...

▷ 이를 ELF 헤더로부터 찾아 보자.

우선 섹션 헤더에서 .dynsym이라는 심볼 테이블이 있다는 것을 알 수 있다.

▷ 덤프해 보면 다음과 같다.

...(중략)...

▷ 심볼 테이블은 다음과 같은 구조 테이블이다.

32비트와 64비트 ELF 바이너리에서는 st_value의 정렬 순서에 따라 변한다.

▷ st_name=스트링 테이블의 인덱스, st_value=심볼 값, st_size=심볼크기.

▷ st_info의 하위 4비트는 심볼 테이블 등의 정보로 다음과 같은 것이 있다.

심볼 타입

설명

STT_OBJECT

1

데이터 오브젝트

STT_FUNC

2

실행 코드

STT_SECTION

3

섹션 관련

STT_FILE

4

오브젝트 관련 소스코드 파일

STT_COMMON

5

일반 데이터

STT_TLS

6

스레드 지역 저장 데이터

▷ 또한 st_info의 상위 4비트는 그 심볼의 바인딩 방법을 타나낸다.

심볼 바인딩

설명

STB_LOCAL

0

지역 심볼

STB_GLOBAL

1

전역 심볼

STB_WEAK

2

WEAK

   

▷ st_shndx는 관련된 섹션을 나타낸다.

섹션

설명

SHN_UNDEF

0

미정의

SHN_ABS

0xfff1

절대값을 갖는 심볼

SHN_COMMON

0xfff2

일반적인 심볼

   

/bin/ls의 예를 보자. 0번째 심볼 정보는 다음과 같이 비어 있다.

▷ /bin/ls의 위의 예에서 맨 마지막에 있는 심볼 정보를 알아 보자.

주소 0006104 부터 시작하는 이 바이트 열은 다음과 같은 의미를 갖는다.

( ※ 아키텍처(x86) 리틀 엔디안 이기 때문에 반대로 읽는다)

st_name = 0x2db

st_value = 0x08061320

st_size = 0x4

st_intfo = 0x11 = (STB_GLOBAL | STT_OBJECT)

st_other = 0

st_shndx = 0x1a = 26

   

▷ 여기서 심볼명을 가리키는 오프셋 값 st_name은 '0x2db'로 되어 있다.

.dynstr 섹션을 보면 스트링 테이블은 시작 위치로부터 '0xc54' 바이트 떨어진 위치에서 시작한다.

- 여기서 '0xc54'에 0x2db(st_name)를 더한 값인 '0xf2f' 위치에서 시작하는 문자열을 보면,

' optarg'라는 문자열을 찾을 수 있다.

- 이와 같이 st_name = '0x2db'에 해당하는 심볼은 'optarg'임을 알 수 있다.

   

▷ 이는 readelf -s 출력 결과에서 위의 심볼 정보를 확인 할 수 있다.

  

   

   

:: [ 재배치 정보 ]

▷ SHT_RELA 또는 SHT_REL 타입의 섹션은 재배치 정보를 갖는다.

▷ SHT_RELA는 다음과 같은 Rela 구조의 테이블을 갖는다.

   

▷ SHT_REL의 경우는 다음과 같이 r_addend가 없는 Rel 구조의 테이블을 갖는다.

   

▷ r_offset은 재배치를 해야 하는 위치를 가리키는, 섹션 첫 위치로부터의 오프셋이다.

▷ r_info는 재배치 타입 또는 심볼테이블의 인덱스 등의 정보를 포함한다.

▷ Rela의 경우 재배치할 경우에 항상 더해야 할 값을 r_addend로 갖고 있다.

  

Posted by devanix
2011. 6. 29. 23:17

♧ od는 octal dump(『octal』은 8진법을 뜻함)로, 기본적으로 바이너라 파일을 8진수로 덤프해서 출력.

   

[ 기본적인 8진수 덤프 ]

⊙ 행 앞 첫 컬럼에 해당하는 숫자(밝은녹색 테두리 부분)는 시작점으로부터의 오프셋을 8진수로 표시한 것.

(※ offset은 좌측 메모리 시작점을 0으로 하여 숫자를 통해 위치를 알려주는 좌표계 역할을 함)

   

[ 출력 형식 지정 ] -t옵션(--format=TYPE)

⊙ 일반적으로 8진수 보다 16진수로 표시되는 게 알기 쉽다.

의미

a

문자의 이름(7비트 ASCII)

c

ASCII문자 or 이스케이프(escape)문자

f[SIZE]

부동소수점 수

o[SIZE]

8진수

d[SIZE]

부호가 있는 10진수

u[SIZE]

부호가 없는 10진수

x[SIZE]

16진수

(※ a,c → 바이트 단위로 출력)

   

[ o, d, u, x :: 뒤에 올 수 있는 크기 지정자]

C

char

S

short

I

int

L

long

   

[ f :: 뒤에 올 수 있는 크기 지정자]

F

float

D

double

L

long double

   

⊙ 오프셋 표기도 8진수 외에 다른 형태로 표시할 수 있다.

'-A 옵션'에 다음 지정자를 이용하면 오프셋의 기수를 변경할 수 있음.

-A옵션 (--address-radix=RADIX)

[radix]

[의미]

o

8진수(기본 설정)

d

10진수

x

16진수

n

오프셋을 표시하지 않음

   

⊙ 또한 z를 덧붙이면 우측에 ASCII문자 표시가 추가.

   

ex) 출력 형식을(-t) 16진수(x) 1Byte단위(1)로 출력하고 우측에 ASCII문자 표시를 추가(z)

오프셋의 기수를 16진수로 출력(-A x)

   

[ 덤프를 생략하지 않기 ] -v옵션 (--output-duplicates)

⊙ 기본적으로 od는 같은 내용이 여러 행에 걸쳐 반복될 경우 그 부분을 생략 한다.

[ 0x0021d0~0x002220 까지는 00이 계속되고 있으므로 『*』와 같이 생략]

   

이 부분을 생략하지 않으려면 -v 옵션을 사용한다.

   

[ 문자열 덤프 기능] -S옵션 (--strings)

⊙ od에는 strings처럼 문자열 덤프 기능이 있다.

ASCII문자가 최소 세 자리 이상이고 \0으로 끝나는 바이트 열을 찾아 오프셋과 내용을 표시한다.

   

⊙ 다음은 위와 같지만 '--strings'옵션을 사용하고 '-An'으로 오프셋 출력을 하지 않는다.

   

(※ 책에서는 '소문자 -s옵션' 이라고 되어 있지만 이건 예전 버전의 옵션이다.

현재 버전에서는 '대문자 -S 옵션'이며 출력되는 최소문자 바이트를 넣어 주어야 한다.

그러므로 그냥 일반 적인 경우는 "--strings" 옵션을 사용하는 것이 호환성 측면에서 좋을 듯하다.)

※ 버전 별로 옵션이 조금씩 틀리므로 man od로 확인 하여 사용하자.

   

테스트 환경 :

  

Posted by devanix
2011. 6. 29. 16:22

♧ file 명령을 이용해서 파일 내용, 종류를 조사.

일반적으로 파일 종류를 알기 위해 확장자를 정해 두고 그 종류를 추측하는 방법을 사용하지만,

file 명령은 파일 내용을 읽어 특징적인 데이터(시그니처)를 찾아 그 종류를 결정.

   

[ 일반적인 file 명령 ]

$ file /usr/bin/file

/usr/bin/file: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs),

for GNU/Linux 2.6.15, stripped

[ -i옵션 : MIME 미디어 타입 문자열로 표시 ]

$ file -i /usr/bin/file

/usr/bin/file: application/x-executable; charset=binary

 

[ file명령이 파일 종류를 판별 하는 순서]

① 디바이스, 디렉토리, 심볼릭 링크 등의 스페셜 파일 체크
② 압축 파일 체크
③ tar 파일 체크
④ magic 데이터베이스 파일에 따른 체크
⑤ ASCII, Unicode 등의 텍스트 파일 종류 체크

위의 어떤 경우에도 해당하지 않으면 단순 바이너리 파일로 판단.

   

[ magic 데이터베이스에는 시그니처 정보가 기록 ]

♧ magic 파일 경로

⊙ /etc/magic
⊙ /usr/share/misc/file/magic (/usr/share/file/magic)

   

♧ magic 파일 내용 ( ※ 현재 집에 설치되어 있는 "Ubuntu 10.04.2 LTS"로 테스트)

   

♧ magic 파일의 엔트리는 4개의 필드로 구성

처음 혹은 이전 레벨로부터의 오프셋 값

데이터 종류

출력 문자열

 

⊙ 여기서 레벨은 오프셋 값의 앞에 적힌 '>'을 의미.

'>4'이라고 적혀 있으면, 다시 처음부터 4바이트 떨어진 위치를 읽고 비교.

⊙ 같은 수의 '>'가 나열되어 잇는 경우.

같은 방식으로 이전 레벨로부터의 오프셋 값에 해당 하는 내용을 보고 진행

⊙ '일치한 엔트리 앞에 '>'가 하나 더 많은('>>') 엔트리가 있으면 계속해서 그 엔트리에 대한 일치처리.

 

[ 앞서 살펴본 elf파일에 대한 file 명령 자신을 판별하는 순서. ]

0     string     \177ELF     ELF

파일의 처음부터 0바이트 떨어진 위치의 문자열이 "\177ELF"와 일치하는지 확인.

→ 일치하므로 "ELF"라고 표시

>4    byte       0           invalid calss

처음부터 4바이트 떨어진 위치의 1바이트가 1임을 확인.

→ 일치하지 않으므로 다음 행으로 이동.

>4    byte       1           32-bit

처음부터 4바이트 떨어진 위치의 1바이트가 1임을 확인.

→ 일치하므로 "32-bit"라고 표시

④ 이후 당분간 일치하지 않으므로 계속 진행.

>5    byte       1           LSB

처음에서부터 5바이트 떨어진 위치의 1바이트가 1임을 확인.

→ 일치하므로 "LSB"라고 표시.

⑥ 이 과정을 끝까지 반복.

 

[ 정리 ]

file 명령을 사용하면 파일 내용으로부터 파일 종류를 판별할 수 있다.
또한 새로운 파일 형식이 생겨나도 그 파일의 고유한 시그니처를 알면
magic 파일에 엔트리를 추가하여 그 파일을 인식할 수 있도록 되어 있다.

(※ 자세한 내용은 man magic 참조)

Posted by devanix
2011. 6. 29. 15:04

[ ABI(Application Binary Interface) ]

애플리케이션이 지켜야 할 바이너리 레벨의 규약.

함수호출 시 스택 또는 레지스터 사용법, 심볼 name mangling 규칙 등이 정해져 있다.

OS, 프로세서별로 규정되어 있다.

   

[ API(Application Programming Interface ]

애플리케이션 프로그램에서 OS나 라이브러리의 기능을 이용하기 위한 함수, 데이터 구조 규약.

API를 이용한 프로그래밍은 동일한 API를 지원하는 플랫폼 간 소스코드 호환성을 갖는다는 이점이 있다.

   

[ BSS 세그먼트(Block Started by Symbol Segment) ]

초기화되지 않은 데이터가 위치하는 세그멘트.

C의 전역 변수로 int global;과 같이 초기값이 지정되지 않은 데이터가 들어간다.

오브젝트 파일 내에서는 크기를 갖지 않고 프로그램 시작 시에 커널에 의해 0으로 초기화 된다.

ELF에서의 명칭은 .bss이다.

   

[ DSO(Dynamic Shared Object) ]

GNU/리눅스에서는 동적 링크하는 공유 라이브러리를 DSO 라고 한다.

.so라는 확장자를 갖는다

   

[ DWARF(Debug With Arbitrary Record Format) ]

디버그 정보를 저장하기 위한 데이터 형식.

GNU/리눅스 + GCC 환경에서는 표준으로 사용되고 있다.

DWARF 또는 ELF는 그 이름 때문에 '반지의 제왕'과 관계가 있는 게 아닌지 의심받기도 한다.

   

[ ELF(Executable and Linking Format) ]

실행 파일, 오브젝트 파일, 공유 라이브러리, 코어 파일에 사용되는 파일 형식 중 하나.

GNU/리눅스, FreeBSD 등에서 사용되고 있다.

   

[ GCC(GNU Compile Collection) ]

GNU의 각종 컴파일러 모음. 원래는 GNU C Compiler를 의미했다.

GNU C Compiler를 나타낼 때는 gcc라고 표기한다.

   

[ glibc(GNU C Library) ]

GNU의 C 라이브러리. GNU/리눅스나 Hurd 등의 OS에서 사용되고 있다.

   

[ GNU(GNU's Not Unix) ]

본래는 GNU 프로젝트가 개발되고 있는 OS를 일컬었으나,

GNU 프로젝트 자체를 GNU로 부르는 경우가 많다

   

[ GNU/리눅스 ]

리눅스 커널 기반의 시스템.

GNU를 앞에 붙이는 이유는 커널 외의 컴포넌트를 개발하고 있는 GNU 프로젝트에 경의를 표하기 위함.

   

[ GOT(Global Offset Table) ]

PIC를 실현하기 위해 필요한 데이터.

PIC에서는 전역 데이터로의 접근을 GOT를 이용해 간접적으로 참조한다.

   

[ LLP64 ]

long long과 포인터가 64비트인 환경.

int와 long은 32비트. 64비트 윈도우에서는 LLP64.

   

[ LP64 ]

long과 포인터가 64비트인 호나경. int는 32비트. 64비트 리눅스에서는 LP64.

대부분의 유닉스 계열 OS에서는 LP64를 사용.

   

[ PIC(Position Independent Code) ]

임의의 주소에 로드 가능한 코드.

데이터 액세스나 점프는 상대 주소로 수행한다. 위치 독립 코드.

   

[ PIE(Position Independent Executable) ]

위치독립인 실행 파일. 최근의 GNU/리눅스에서 작성할 수 있다.

보안 향상 등의 장점이 있다.

   

[ PLT(Procedure Linkage Table) ]

동적 링크를 실현하기 위해 필요한 데이터.

GOT와 함께 사용해서 동적 링크한 공유 라이브러리 함수를 간접적으로 호출할 수 있다.

   

[ POSIX(Portable Operating System Inerface for UNIX) ]

시스템콜, 시그널과 같은 OS의 API를 규정하는 규약.

대부분의 유닉스 계열 OS는 POSIX를 기반으로 하고 있다(or POSIX 표준을 따르려 한다).

   

[ SUS(Single UNIX Specification) ]

유닉스로 불리는 OS를 위한 규격. 최신 버전인 SUSv3는 웹상에서 볼 수 있다.

SUSv3는 POSIX를 포함하고 있다.

   

[ TLS(Thread Local Storage) ]

여러 스레드에서 동일한 이름의 변수를 사용하더라도 실제로는 각 스레드의 독립된 영역에 저장되는데,

이를 TLS라 한다. GCC에서는 __thread라는 키워드를 사용해서 TLS를 다룬다.

   

[ prelink ]

동적 링크를 빠르게 하기 위한 방법 중 하나.

실행 파일과 공유 라이브러리를 수정함으로써 동적 링크 시 발생하는 비용을 대부분 삭감한다.

많은 리눅스 배포판에 사용되고 있다.

   

[ x86 ]

인텔(Intel)사의 8086 계열의 프로세서를 약칭함.

80486 이후 Pentium, Xeon 등의 제품명을 갖는다. IA-32라고도 한다.

   

[ x86_32 ]

x86_64와 구별하기 위해 32비트의 x86 아키텍처를 x86_32로 표기하는 경우도 있다.

   

[ x86_364 ]

AMD에서 설계한 x86 상위호환의 64비트 프로세서 아키텍처. AMD64라고도 함.

인텔도 동일한 아키텍처를 채택하고 있다. EM64T는 인텔에서 사용하는 제품명.

   

[ 인라인 어셈블리 코드(inline assembly code) ]

C와 같은 고급언어 프로그램에 삽입된 어셈블리 코드를 일컬음.

아키텍처 의존적인 처리, 최적화 등에 사용된다.

   

[ 엔디안(endian) ]

여러 바이트로 된 데이터를 어떤 순서로 저장할지를 정하는 규칙.

바이트 순서라고도 함. 엔디안이라는 명칭은 걸리버 여행기에서 유래함.

   

[ 오브젝트 파일(object file) ]

컴파일러가 생성한 중간 단계 파일.

실행 파일이나 라이브러리는 오브젝트 파일을 링크해서 만든다.

GNU/리눅스에서는 .o라는 확장자를 갖는다.

넓은 의미로는 실행 파일이나 라이브러리도 오브젝트 파일에 포함하기도 한다.

   

[ 역어셈블(disassemble) ]

기계어를 어셈블리어로 변환하는 것.

   

[ 공유 라이브러리(shared library) ]

프로그램 실행 중 메모리상에서 여러 프로그램에 의해 공유되는 라이브러리.

통상 공유 라이브러리는 동적 링크된다. 정적 링크되는 공유 라이브러리도 있으나 드물다.

공유 오브젝트라고도 함.

   

[ 재배치(relocation) ]

기계어 코드에 포함된 주소를 링크 시에 또는 로드 시에 수정하는 것.

   

[ 시그널(signal) ]

프로세스에 보내지는 동기적인 또는 비동기적인 이벤트.

POSIX에서는 SIGKILL과 SIGSTOP외의 시그널은 시그널 핸들러로 처리할 수 있다.

   

[ 시그널 핸들러(signal handler) ]

시그널을 처리하는 함수. sigaction() 또는 signal() 함수로 설정할 수 있다.

   

[ 시그니처(signature) ]

이름, 인수, 반환 값의 형태에 따라 결정되는 함수의 형식.

보통 C나 C++ 등의 컴파일 언어에서는 이름이 같아도

시그니처가 다른 함수를 호출하려 하면 경고 또는 에러가 발생한다.

   

[ 시스템콜(system call) ]

유저 레벨의 애플리케이션에서 OS 커널의 기능을 호출하기 위한 방법.

(예: open(), read(), fork(), signal())

   

[ 심볼(symbol) ]

일반적으로는 기호를 의미하지만,

Binary Hacks의 문맥에서는 링커가 함수나 변수를 식별할 때 사용하는 이름을 말한다.

   

[ 심볼 테이블(symbol table) ]

오브젝트 파일 등에 포함된 심볼의 표.

명시적으로 삭제하지 않는 한 실행 파일이나 라이브러리에 남아 있다.

   

[ 스택(stack) ]

스택 프레임을 단계적으로 쌓아가는 메모리 영역. Binary Hacks의 문맥상

스택은 「데이터 구조의 스택」이 아니라 「메모리 영역의 스택」을 가리키는 경우가 많다.

   

[ 스택 프레임(stack frame) ]

인수나 지역 변수, 보존된 레지스터, 반환 값 주소 등 함수호출에 필요한 정보를 정리한 것.

간단히 프레임이라고도 한다.

   

[ 스택 포인터(stack pointer) ]

스택 프레임을 조작하기 위해 사용하는 포인터.

x86등은 스택 포인터를 위한 전용 레지스터를 갖고 있다.

RISC 프로세서에서는 범용 레지스터 중에 하나를 스택 포인터로 정해서 사용하는 경우가 많다.

   

[ 스레드(thread) ]

프로그램 실행 단위의 하나.

프로세스와의 주된 차이점은 자원 공유 방법에 있다.

통상, 프로세스에 비해 스레드 간 자원 공유가 더 쉽다.

하나의 프로세스는 여러 스레드를 갖는다.

   

[ 스레드 안전(thread safe) ]

멀티스레드 프로그램에서 안전하게 실행할 수 있음을 일컬음.

대개의 경우 static 변수를 내부에 지닌 함수는 스레드에 안전하지 않다.

   

[ 세그먼테이션 폴트(segmentation fault) ]

접근 불가한 주소 영역에 접근하거나 쓰기 불가능한 주소 영역에 쓰기를 할 경우 발생하는 에러.

C, C++ 프로그래머는 자주 접하게 된다. 세그먼트 위반이라고도 한다.

   

[ 실행 파일(executable file) ]

실행 가능한 파일. GNU/리눅스에서는 /bin, /usr/bin등에 있다.

   

[ 정적 라이브러리(static library) ]

정적 링크되는 라이브러리. GNU/리눅스에서는 .a라는 확장자를 갖는다.

   

[ 정적 링크(static link) ]

실행 파일을 생성할 때 라이브러리를 링크하는 것.

대개 라이브러리 내용을 실행 파일내에 포함시키기 때문에 실행 시에는 라이브러리 파일이 필요 없다.

   

[ 툴 체인(toolchain) ]

컴파일러, 링커, 어셈블러 등 네이티브 프로그램을 생성하기 위해 필요한 일련의 툴을 총칭.

   

[ 데이터 세그먼트(data segment) ]

초기화된 데이터가 위치하는 세그먼트. ELF에서의 명칭은 .data 이다.

   

[ 텍스트 세그먼트(text segment) ]

기계어 코드가 위치하는 세그먼트.

통상, read-only로 설정된다. ELF에서의 명칭은 .text 이다.

   

[ 디버거(debugger) ]

프로그램 버그의 원인을 찾는 데 유용한 툴.

디버거로 프로그램을 구동시킨 후 백트레이스나 변수 조사 등을 수행한다.

   

[ 디버그 정보(debug information) ]

디버거가 필요로 하는 정보. 실행 파일이나 공유 라이브러리에 포함되어 있다.

gcc에서는 -g 옵션을 주면 생성.

   

[ demangle ]

name mangling된 심볼을 원래의 읽기 쉬운 심볼로 복원시키는 것을 말함.

(예: _ZN3Foo3BarE => Foo::Bar)

   

[ 동적 링크(dynamic link) ]

실행 시에 라이브러리를 링크하는 것.

실행 시에 라이브러리 파일이 필요함. 라이브러리가 존재하지 않으면 실행 시에 에러가 발생한다.

   

[ 동적 링크 라이브러리(dynamic link library) ]

동적 링크된 라이브러리. 윈도우에서는 DLL이라 불린다.

GNU/리눅스에서는 DSO라고 불리는 경우가 많다.

   

[ name mangling ]

함수명과 시그니처로부터 유일한 심볼을 생성하는 것을 말함.

C++나 자바(Java)등의 언어에서 사용된다. (예: Foo::Bar => _ZN3Foo3BarE)

   

[ 바이너리안(binarian) ]

Binary Hack에 정통한 엔지니어.

   

[ 백트레이스(backtrace) ]

현재 함수에 도달할 때까지 지나온 함수를 추적하는 것. 스택 트레이스라고도 함.

   

[ 힙(heap) ]

malloc() 등에 의해 동적으로 확보된 메모리 영역.

Binary Hack의 문맥상으로 힙은 「데이터 구조의 힙」이 아니라 「메모리 영역의 힙」을 가리킨다.

자유기억 영역 이라고도 함.

   

[ 중단점(break point) ]

디버거로 프로그램 실행을 일시 중지시킬 지점. 함수명이나 소스코드의 행 번호로 지정한다.

   

[ 프로그램 카운터(program counter) ]

CPU내의 레지스터 중 하나로, 현재 실행하고 있는 명령의 주소를 저장하고 있다.

PC로 줄여서 일컫기도 함. 인스트럭션 포인터라고도 함.

   

[ 프로세스(process) ]

프로그램 실행 단위의 하나. 실행 중인 프로그램의 인스턴스.

통상, 프로세스는 하나의 프로세스 ID를 갖는다.

   

[ 프로파일러(profiler) ]

프로그램의 성능을 분석하는 툴. (이 책에서는 gprof, sysprof, oprofile을 소개한다.)

   

[ 호출 규약(calling convention) ]

함수를 호출할 때 데이터를 어떤 식으로 스택에 쌓을지를 정하는 규약.

ABI의 일종. OS나 프로세서에 따라 다르다.

   

[ 런타임(runtime) ]

실행 시를 뜻함. 실행 시에 발생하는 에러를 런타임 에러라고 한다.

   

[ 링크(link) ]

오브젝트 파일이나 라이브러리를 연결하는 것. 재배치 등의 처리를 수행한다.

   

[ 리플렉션(reflection) ]

실행 중인 프로그램 자신의 정보를 조사하거나 수정하는 것을 말함.

C언어 에서는 리플렉션을 위한 기능은 없지만, Binary Hack을 이용하기에 따라 유사한 기능을 구현할 수 있다.

   

[ 로드(load) ]

실행 파일이나 라이브러리를 메모리상에 배치하는 것.

Posted by devanix
2011. 6. 29. 12:26

BINARYHACKS:해커가전수하는테크닉100선
카테고리 컴퓨터/IT > 네트워크/보안 > 보안/인증/해킹
지은이 타카바야시 사토루 (아이티씨, 2007년)
상세보기


♧ 이 책에서 주로 GNU Binary Utilities에 대한 간략한 테크닉과
 
gcc 기반의 Linux(or Unix)에서 각종 버그를 찾는 방법들을 다루고 있다.
 
저수준에 대한 접근 문제 해결능력을 키울 수 있는 서적인 듯 하다.


   

목차 :

1장 소개 1

2장 오브젝트 파일 Hack 21

3장 GNU 프로그래밍 Hack 93

4장 보안 프로그래밍 Hack 177

5장 런타임 Hack 245

6장 프로파일러쪾디버거 Hack 379

7장 그 밖의 Hack 399

Posted by devanix