티스토리 뷰

PE Header - EAT (Export Address Table)

이전 장에서, DLL에 대한 간략한 내용과, IAT(Import Address Table)및 IID(Image Import Directory)를 이용해,

프로그램이 어떻게 dll(라이브러리)를 가져와 import 하여 그 기능을 사용하는지 살펴보았다.


그렇다면, 이번에는 이러한 기능을 제공해주는 dll과 같은 라이브러리(sys 파일과 같은 것도 해당된다)가 어떻게 다른 프로그램에

함수 형태로 기능을 제공하는지 알아보자.


IMAGE_IMPORT_DIRECTORY 가 프로그램이 어떠한 외부 라이브러리를 사용할 것인지에 대한 정보를 제공한다면,

IMAGE_EXPORT_DIRECTORY 는 자신에게서 어떠한 함수를 제공받을 수 있는지를 선언해놓은 테이블이라고 할 수 있다.



해당 테이블을 찾아보자.

NT Header 안의 Optional Header를 살펴보면, IMPORT 디렉터리 다음에 EXPORT 디렉터리의 RVA 주소가 Dword 형태로 저장되어 있는 것을 찾아볼 수 있으며,

해당 구조체는 다음과 같이 이루어져 있다.

typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; // Current dll name! DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD AddressOfFunctions; // RVA from base of image DWORD AddressOfNames; // RVA from base of image DWORD AddressOfNameOrdinals; // RVA from base of image } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

NumberOfFunctions : EXPORT 하고 있는 함수의 갯수이다.

NumberOfNames : EXPORT하고 있는 함수 중, 이름을 가지고 있는 함수의 갯수이다. ( <= NumberOfFunctions )

AddressOfFunctions : EXPORT 하는 함수들의 시작 위치 배열의 주소이다. ( Ordinal - word ARRAY)

AddressOfNames : EXPORT 하는 함수들의 이름값 배열의 주소이다. ( Name PTR Table - ARRAY )

AddressOfNameOrdinals : 함수들의 시작 위치 배열의 순서대로 IDX 를 저장한다. (배열)

이는 이름을 가지고 있는 함수의 갯수와 EXPORT 하는 함수의 갯수가 다를 경우, AddressOfFunctions 배열의 데이터가 AddressOfNames 포인터에 저장되어있는 함수와 인덱스 값이 달라질 수 있으므로, 이를 조정하기 위해 존재한다.



라이브러리에서 함수 주소를 얻는 방법으로는 WIN32 API의 GetProcAddress()가 있는데,

대략적으로 이 함수가 함수 주소를 얻어내는 순서에 대해 정리하였다.

1. AddressOfNames 를 이용하여 함수 이름 포인터 배열로 이동한다.

2. 이 문자열 배열을 하나씩 strncmp 와 같은 것을 이용해, 원하는 함수의 인덱스 값을 찾는다.

3. 찾은 인덱스 값으로 AddressOfNamesOrdinals 의 배열에서 값을 꺼내온다. 이 값이 AddressOfFunctions의 인덱스로 이용된다.

4, AddressOfFunctions 에서 해당 함수의 RVA값을 가져와 함수의 시작 주소를 얻는다.


+ IMPORT 테이블에서 하나의 dll 당 IMPORT 테이블이 하나씩 존재했듯이, EXPORT 테이블은 본인 dll 의 정보만 저장하고 있으므로, 

테이블이 1개만 존재한다. (여기서는 테이블의 마지막 구조체를 null로 채우지 않는다.)


+ 함수의 이름이 주어지지 않는 경우도 있으며, EAT는 단지 dll을 IMPORT 할 때, 좀 더 편리하게 사용할 수 있는 함수들을 저장해 놓음으로써 제 3자가 라이브러리를 IMPORT하여 작업할 때 혼동을 줄이기 위해 사용되며, 굳이 EAT가 존재하지 않아도, Ordinal(RVA) 값 만을 이용해서 사용할 수 도 있다.


++ dll 에도 exe와 같은 단일 실행 파일과 마찬가지로 AddressOfEntryPoint가 존재하며, 이는 dll 이 메모리에 적재되었을 때 Initialize 용도로 흔히 사용된다.

DllEntryPoint : 기본적인 EntryPoint (return result)

DllMain 이라는 함수도 존재하지만, 흔히 DllEntryPoint에서 내부적으로 호출된다.

_DllMainCRTStartup : runtime implementation(?)


참고 :

http://www.reversecore.com/24

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함