Chapter 8. PE Header III - IAT & EAT
1. IAT(Import Address Table)
- IAT
· Windows의 Program이 어떤 Library에서 어떤 함수를 사용하고 있는지를 기술한 Table
· PE File 내의 특정 구조체인 'IMAGE_IMPORT_DESCRIPTOR'에 Import에 관한 정보를 저장한다.
· PE Header에서 Table은 배열을 의미한다.
· 각 Section마다 존재한다.
· IAT의 구조체 : IMAGE_IMPORT_DESCRIPTOR
◦ PE File은 자신이 어떤 library에게 함수를 제공(Import)받는지 IMAGE_IMPORT_DESCRIPTOR 구조체에 명시한다.
◦ IMAGE_IMPORT_DESCRIPTOR의 주요 Member
▹ OriginalFirstThunk : IAT(Import Name Table)
▸ INT(Import Name Table)의 주소(RVA)
▸ 구조체에서는 OriginalFirstThunk로, PEView에서는 Import Name Table(INT)로 명시된다.
▹ Name
▸ Library 이름 문자열의 주소(RVA)
▹ FirstThunk
▸ IAT(Import Address Table)의 주소
▸ 구조체에서는 FirstThunk로 PEView에서는 Import Address Table(IAT)로 명시된다.
· IAT(Import Address Table) & INT(Import Name Table)
◦ INT(Import Name Table:OriginalFirstThunk)의 원소 값은 IMAGE_IMPORT_BY_NAME의 구조체 Pointer로 주소 값이 명시된다.
◦ INT(Import Name Table:OriginalFirstThunk)와 IAT(Import Address Table:FirstThunk)의 실제 크기는 같아야하며 Member의 내용 및 개수도 같다.
◦ IAT(Import Name Table:OriginalFirstThunk)는 Memory 상의 실제주소가 입력되고 INT는 IAT(Import Address Table:FirstThunk) Memeber의 Pointer 주소가 입력된다.
◦ INT(Import Name Table:OriginalFirstThunk)와 IAT(Import Address Table:FirstThunk)는 long Type의 배열이고 크기가 따로 명시되어있지 않아 문자열과 같이 NULL로 끝난다.
· IMAGE_IMPORT_DESCRIPTOR의 구조 및 IAT 입력 순서
◦ PE Loader가 Import 함수 주소를 IAT에 입력하는 순서
▹ ① : IMAGE_IMPORT_DESCRIPTOR의 Name Member를 읽어 Library의 이름 문자열 kernel32.dll을 얻는다.
▹ ② : 해당 Library를 LoadLibrary 함수를 이용해 Process 내에 불러온다.
▹ ③ : IMAGE_IMPORT_DESCRIPTOR의 OriginalFirstThunk(INT) Member를 읽어들여 INT(Import Name Table)의 주소를 얻는다.
▹ ④ : INT(Import Name Table)에서 배열의 값을 하나씩 읽어 해당 배열에 해당하는 IMAGE_IMPORT_BY_NAME 주소를 얻는다.
▹ ⑤ : IMAGE_IMPORT_BY_NAME의 Hint를 이용해 해당 함수의 시작 주소를 얻는다.
▹ ⑥ : IMAGE_IMPORT_DESCRIPTOR의 FirstThunk(IAT : Import Address Table) Member를 읽어 IAT의 주소를 얻는다.
▹ ⑦ : IAT 배열 값을 위에서 함수를 이용해 구한 주소 값으로 덮어쓴다.
▹ ⑧ : INT내에서 NULL 구조체를 만날 때까지 ④ ~ ⑦ 과정을 반복한다.
2. EAT(Export Address Table)
- EAT
· Library FIle에서 제공하는 함수를 다른 Program에서 가져다 사용할 수 있도록 해주는 Table
· EAT를 통해서만 해당 Library에서 Export하는 함수의 시작 주소를 정확히 구할 수 있다.
· IAT와 동일하게 PE File 내의 특정 구조체인 'IMAGE_EXPORT_DIRECTORY'에 Export에 관한 정보를 저장한다.
· 각 Section마다 존재하는 IAT와는 달리 EAT는 PE File내에 하나만 존재한다.
· IMAGE_EXPORT_DIRECTORY의 위치
◦ PEView를 이용해 살펴보면 IMAGE_EXPORT_DIRECTORY 구조체가 존재하지 않는다는 것을 알 수 있으며 IMAGE_OPTIONAL_HEADER 부분에 'Loader Flags' 부분부터 구조체 배열의 시작 주소가 된다.
◦ 구조체 배열이 시작되는 부분은 'IMAGE_OPRIONAL_HEADER32.DataDirectory[0]'이라고 한다.
◦ IMAGE_OPRIONAL_HEADER32.DataDirectory 구조체 배열의 Member
▹ Loader Flags
▹ Number of Data Diectories
▹ RVA of Export Directory
▹ Size of Export Directory
▹ RVA of Import Directory
▹ Size of Import Directory
· 실제 IMAGE_EXPORT_DIRECTORY 구조체
◦ IMAGE_EXPORT_DIRECTORY의 주요 Member
▹ NumberOfFunction
▸ 실제 Export 함수의 개수
▹ NumberOfNames
▸ Export 함수 중 이름을 가지는 함수의 개수
▸ 'NumberOfFunction'와 값보다 작거나 같다.
▹ AddressOfFunction
▸ Export 함수 주소 배열
▸ 배열의 Index(배열의 원소 개수)와 'NumberOfFunctions' 값이 같다.
▹ AddressOfNames
▸ 함수 이름 주소 배열
▸ 배열의 Index(배열의 원소 개수)와 'NumberOfNames' 값이 같다.
▹ AddressOfNameOrdinals
▸ 함수 이름의 Ordinal(서수) 주소 배열
▸ 배열의 Index(배열의 원소 개수)와 'NumberOfNames' 값이 같다.
· GetPorcAddress() API와 EAT를 이용해 원하는 API의 주소를 얻어내는 과정
◦ 'GetProcAddress()'라는 함수는 Library에서 함수 주소를 얻는 API로 EAT를 참조해 원하는 API의 주소를 구한다.
◦ GetProcAddress() 함수의 동작 과정
▹ ① : AddressOfNames Member를 이용해 함수 이름 배열(Function Name Table)을 찾아간다.
▹ ② : 함수 이름 배열에는 문자열 주소가 저장되어 있으며 strcmp 함수를 이용해 원하는 함수의 이름을 찾아 해당 함수가 위치한 배열의 Index(Index Of Name)를 찾는다.
▹ ③ : AddressOfNameOrdinals Member를 이용해 'Ordinal 배열'을 찾는다.
▹ ④ : Ordinal 배열에서 ②단계에서 찾아낸 Index Of Name을 이용해 Ordinal 값을 찾는다.
▹ ⑤ : AddressOfFunctions Member를 이용해 EAT(Export Address Table)로 간다.
▹ ⑥ : EAT에서 ④단계에서 찾은 Ordinal을 배열 Index로 하여 원하는 함수의 시작주소를 얻는다.
'Reversing > Theory' 카테고리의 다른 글
Chapter 10. 실행 압축(Run-Time Packer) II - UPX (0) | 2015.08.16 |
---|---|
Chapter 9. 실행 압축(Run-Time Packer) I (0) | 2015.08.16 |
Chapter 7. PE Header II - RVA to RAW (0) | 2015.08.16 |
Chapter 6. PE header I - PE Format (0) | 2015.08.16 |
Chapter 5. Calling Convention (0) | 2015.08.16 |