EAT(Export Address Table)
- 라이브러리 파일에서 제공하는 함수를 다른 PE파일에서 가져다 사용할 수 있도록 해주는 핵심메커니즘
- 다른 PE파일에서 라이브러리(ex. kernel32.dll)의 함수를 사용하고 싶다면 kernel32.dll의 EAT를 통하여 함수의 시작주소를 구할 수 있다.
kernel32.dll을 대상으로 실습해보았다.
- 실습환경 : Window7 32bit
- 실습대상 : kernel32.dll
GetProcAddress() API동작원리 – 인자로 함수의 이름 또는 함수의 Ordinal 값이 들어간다.
1. AddressOfNames 멤버를 이용해 ‘함수 이름 배열’로 이동
2. ‘함수 이름 배열’은 문자열 주소가 저장되어 있다. 문자열 비교(strcmp)를 통하여 원하는 함수 이름 찾음 (이때 배열의 인덱스를 name_index 라고 가정)
3. AddressOfNameOrdinals 멤버를 이용해 ‘ordinal 배열’로 이동
4. ‘ordinal 배열’에서 name_index로 해당 ordinal 값을 찾음
5. AddressOfFuntions 멤버를 이용해 ‘함수 주소 배열(EAT)’로 이동
6 ‘함수 주소 배열(EAT)’에서 앞에서 구한 ordinal을 배열 인덱스로 하여 원하는 함수의 시작주소를 얻음
NT Header – Optional Header – DataDirectory[0] (Export Directory)의 VirtualAddress의 값(RVA)을 확인한다. (참고: RVA to RAW)
RAW 계산 시 VA와 PointerToRawData가 같기 때문에 그대로 000B5924를 사용하면 된다.
<Export Directory>
- IMAGE_EXPORT_DIRECTORY 구조체 (28h/40)
1 2 3 4 5 6 7 8 9 10 11 12 13 | typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristices; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFuntions; //실제 Export 함수 개수 DWORD NumberOfNames; //Export 함수 중에서 이름을 가지는 함수 개수 DWORD AddressOfFuntions; //Export 함수 주소 배열 (배열의 원소 개수 = NumberOfFuntions) DWORD AddressOfNames; //함수 이름 주소 배열 (배열의 원소 개수 = NumberOfNames) DWORD AddressOfNameOrdinals; //Ordinal 배열 (배열의 원소 개수 = NumberOfNames) } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; |
<IMAGE_EXPORT_DIRECTORY>
1. AddressOfNames 멤버를 이용해 ‘함수 이름 배열’로 이동
– 함수 이름 배열에서 첫 번째 배열(첫 번째 함수)의 이름을 갖고 있는 값을 확인한다. ( 000B8EAB)
– 해당 Offset으로 이동 시 함수의 이름을 찾을 수 있다. (AcquireSRWLockExclusive)
<함수이름배열 – 함수이름찾기>
2. AddressOfNameOrdinals 멤버를 이용해 ‘ordinal 배열’로 이동
– ‘AcquireSRWLockExclusive’함수의 Ordinal 값을 구하기 위해 Ordinal 배열(000B83F4)로 이동한다.
3. ‘ordinal 배열’에서 name_index로 해당 ordinal 값을 찾음
– ‘AcquireSRWLockExclusive’함수는 1번째 함수이므로 index(0) -> AddressOfNameOrdinals[0] -> Ordinal : 0002
<Ordinal 배열>
4. AddressOfFuntions 멤버를 이용해 ‘함수 주소 배열(EAT)’로 이동
– ‘AcquireSRWLockExclusive’함수의 실제주소를 알기위해 ‘함수 주소 배열(EAT)'(000B594C)로 이동한다.
5. ‘함수 주소 배열(EAT)’에서 앞에서 구한 ordinal을 배열 인덱스로 하여 원하는 함수의 시작주소를 얻음
– ‘AcquireSRWLockExclusive’함수의 Ordinal 값은 2 이기 때문에 AddressOfFuntions[2]의 값이 해당 함수의 RVA는 000BF807 이다.
– kernel32.dll 의 Imagebase(77DE0000) + ‘AcquireSRWLockExclusive’함수의 RVA(000BF807) = 77E9F807
<EAT>