tmxklab

EAT(Export Address Table) 본문

Security/02 Reversing

EAT(Export Address Table)

tmxk4221 2021. 8. 6. 16:01

1. EAT(Export Address Table)


EAT(Export Address Table)는 라이브러리 파일에서 제공하는 함수를 다른 프로그램에서 가져다 사용할 수 있도록 해주는 핵심 메커니즘이다. 즉, EAT를 통해서만 해당 라이브러리에서 익스포트하는 함수의 시작 주소를 정확히 구할 수 있다.

 

IAT와 마찬가지로 PE 파일 내의 IMAGE_EXPORT_DIRECTORY에 익스포트 정보를 저장하고 있다. IAT와는 달리 PE파일에 IMAGE_EXPORT_DIRECTORY 구조체는 하나만 존재한다.

 

[ PE파일에서 IMAGE_EXPORT_DIRECTORY 구조체의 위치 ]

IMAGE_OPTIONAL_HEADER32.DataDirectory[0].VirtualAddress 값이 실제 IMAGE_EXPORT_DIRECTORY 구조체 배열의 시작 주소이다.(RVA값)

 

1) IMAGE_EXPORT_DIRECTORY 구조체

typedef struct _IMAGE_EXPORT_DIRECTORY { 
	DWORD Characteristics; 
	DWORD TimeDateStamp ; // creation time date stamp 
	WORD MajorVersion; 
	WORD MinorVersion; 
	DWORD Name; // address of librar y file name 
	DWORD Base; // ordinal base 
	DWORD NumberOfFunctions; // number of functions 
	DWORD NumberOfNames; // number of names 
	DWORD AddressOfFunctions ; // address of function start address array

	DWORD AddressOfNames; // address of function name stri ng array 
	DWORD AddressOfNameOrdinals; // add ress of ordinal array 
} lMAGE_EXPORT_DIRECTORY, *PlMAGE_EXPORT_DIRECTORY; 

[ 주요 멤버 설명 ]

NumberOfFunctions : 실제 Export 함수 개수

NumberOfNames : Export 함수 중에서 이름을 가지는 함수 개수(≤ NumberOfFunctions)

AddressOfFunctions : Export 함수 주소 배열(배열의 원소 개수 = NumberOfFunctions)

AddressOfNames : 함수 이름 주소 배열(배열의 원소 개수 = NumberOfNames)

AddressOfNameOrdinals : Ordinal 주소 배열(배열의 원소 개수 = NumberOfNames)

 

라이브러리에서 함수 주소를 얻는 API는 GetProcAddress() 이며, 이 API함수가 바로 EAT를 참조해서 원하는 API의 주소를 구하나다.

 

[ GetProcAddress() 동작 원리 ]

AddressOfNames 멤버를 이용해 '함수 이름 배열'로 간다.

② 문자열 비교(stcmp)를 통하여 원하는 함수 이름을 찾는다.(배열의 인덱스를 name_index)

AddressOfNameOrdinals 멤버를 이용해 ordinal 배열로 간다.

④ ordinal 배열에서 name_index로 해당 ordinal 값을 찾는다.

AddressOfFunctions 멤버를 이용해 '함수 주소 배열(EAT)'로 간다.

⑥ '함수 주소 배열(EAT)'에서 아까 구한 ordinal을 배열 인덱스로 하여 원하는 함수의 시작 주소를 얻는다.

 

참고로 위 과정은 이전에 Universal Shell Code를 짜기 위한 루틴과 동일하다.

 
https://rninche01.tistory.com/entry/Universal-Shell-codex86%EC%9B%90%EB%A6%AC-%EB%B0%8F-%EC%8B%A4%EC%8A%B5?category=838537

 

위와 같이 복잡한 작업을 하는 이유는 익스포트하는 함수 중에 이름이 존재하지 않을 수도 있으며(Ordinal로만 익스포트) AddressOfNamesOrdinals 배열의 값이 index ≠ ordinal인 경우도 있기 때문이다. 따라서, 위와 같은 순서를 거쳐야 정확한 함수 주소를 얻을 수 있다.

 

 

'Security > 02 Reversing' 카테고리의 다른 글

IAT(Import Address Table)  (0) 2021.08.04
RVA to RAW  (0) 2021.08.04
Window API 관련  (0) 2021.04.18
ARM Assembly 정리 (기초)  (0) 2020.12.18
[리버싱] 어셈블리어 설명 및 종류  (0) 2020.02.03
Comments