본문 바로가기

Security study/Reversing

32bit IAT, EAT 로딩 과정 및 개념

[0] DLL (Dynamic Linked Library)

- 정의 : 동적링크, 실행파일에서 해당 라이브러리 기능을 사용 시 파일을 참조하여 기능을 호출.

- 파일형식 : Linux - *.so, Windows - *.dll

- Explicit Linkint : 프로그램에서 사용되는 순간 로딩하고 사용이 끝나면 메모리에서 해제

- Implicit Linking : 프로그램이 시작할 때 같이 로딩되어 프로그램이 종료될 때 메모리에서 해제

 

[1] IAT(Import Address Table)

- 정의 : 프로그램이 어떤 라이브러리에서 어떤 함수를 사용하고 있는지 기술한 테이블

 

(1) IMAGE_IMPORT_DESCRIPTOP(IID)

-> 자신이 어떤 라이브러리를 import하고 있는지 명시해주는 구조체, 라이브러리 개수만큼 위 구조체의 배열 형식으로 존재하며, 구조체 배열의 마지막은 NULL

-> 주요 멤버

OriginalFirstThunk : INT(Import Name Table)의 주소 (RVA)
Name : Library 이름문자열의 주소 (RVA)
FirstThunk : IAT(Import Address Table)의 주소 (RVA)

 

(2) IMAGE_THUNK_DATA32

-> IAT와 INT를 구성하고 있는 구조체 (INT와 IAT의 크기는 동일)

 

(3) IMAGE_IMPORT_BY_NAME

-> INT(Import Name Table)에서 각 원소 값의 구조체 포인터 Import할 함수의 이름들을 저장함

 

(4) IAT 입력 순서

① IID의 Name 멤버를 읽어 라이브러리의 이름 문자열 획득
② 해당 라이브러리 로딩 -> LoadLibrary(“kernel32.dll”)
③ IID의 OriginalFirstThunk 멤버를 읽어 INT 주소 획득
④ INT에서 배열의 값을 하나씩 읽어 해당 IMAGE_IMPORT_BY_NAME 주소(RVA) 획득
⑤ IMAGE_IMPORT_BY_NAME의 Hint(ordinal) 또는 Name 항목을 이용해 해당 함수의 시작 주소 획득 -> GetProcAddress(“GetCurrentThreadld”)
⑥ IID의 FirstThunk(IAT) 멤버를 읽어 IAT 주소 획득
⑦ 해당 IAT 배열 값에 위에서 구한 함수 주소를 입력
⑧ INT가 끝날 때까지(NULL을 만날 때까지) 위에서 4~7 과정을 반복

 

(5) notepad.exe 32bit - IAT 실습

Tool : CFF Explorer

Import Directory RVA 값 확인
VA, Raw Address 값 확인
RAW 
comdlg32.dll

OFT(OriginalFirstThunk)의 File Offset = 6A40

Name 부분을 구해보자.

RVA = 7A3B

VA = 1000

PointerToRawData = 400

RAW = 7A3B - 1000 + 400 = 6E3B

Hxd에서 확인했다.

[2] EAT(Export Address Table)

- 정의 : 라이브러리 파일에서 제공하는 함수를 다른 프로그램에서 가져다 쓸 수 있도록 해주는 핵심 메커니즘. 즉, 라이브러리가 가진 함수를 다른 프로그램에서 사용할 수 있도록 하는 것

 

(1) IMAGE_EXPORT_DIRECTORY

-> 주요 멤버

 NumberOfFunctions : 실제 Export 함수의 개수, IMAGE_EXPORT_DIRECTORY 구조체의 중요 멤버
NumberOfNames : Export 함수 중 이름을 갖는 함수의 개수 (<= NumberOfFunctions)
AddressOfFunctions : Export 함수 주소 배열 (배열의 원소 개수 = NumberOfFunctions)
AddressOfNames : 함수 이름 주소 배열 (배열 원소 개수 = NumberOfNames)
AddressOfNameOrdinals : Ordinal 배열 (배열의 원소 개수 = NumberOfNames)

 

(2) 동작원리

① AddressOfNames 멤버를 이용해 ‘함수 이름 배열’로 이동
② ‘함수 이름 배열'은 문자열 주소가 저장되어 있어, 문자열 비교를 통해 원하는 함수
이름 찾기
③ IID의 OriginalFirstThunk 멤버를 읽어 INT 주소 획득
④ INT에서 배열의 값을 하나씩 읽어 해당 IMAGE_IMPORT_BY_NAME 주소(RVA) 획득
⑤ IMAGE_IMPORT_BY_NAME의 Hint(ordinal) 또는 Name 항목을 이용해 해당 함수의 시작 주소 획득 -> GetProcAddress(“GetCurrentThreadld”)
⑥ IID의 FirstThunk(IAT) 멤버를 읽어 IAT 주소 획득
⑦ 해당 IAT 배열 값에 위에서 구한 함수 주소 입력
⑧ INT가 끝날 때까지(NULL을 만날 때까지) 위에서 4~7 과정을 반복

 

(3) kernel32.dll - EAT 실습

Tool : CFF Explorer

Export Directory RVA 값 확인
VA와 PointerToRawData 값 확인

RAW 계산 : 9A1E0 - 80000 + 7EA00 = 98BE0

 

98BE0 부터 구조체 멤버들이 쭉 나열되고 있다.

함수 이름 배열 AddressOfNames 멤버의 RVA = 9BB8C 이다.

RAW = 9BB8C - 80000 + 7EA00 = 9A58C

Hxd에서 9A58C 위치로 갔더니 함수들의 이름 배열이 나왔다.

배열의 첫 번째 원소의 RAW 값을 구하자. RVA = 9E1DF

RAW = 9E1DF - 80000 + 7EA00 = 9CBDF

Hxd에서 9CBDF로 이동했다.

CFF Explorer의 첫 번째 원소 값이 맞는지 확인하자.

일치하는 것을 알 수 있다.

 

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

DLL Ejection 코드  (0) 2021.11.13
DLL Injection 코드  (0) 2021.11.13
notepad.exe 패킹 언패킹(tool없이 패킹 풀기 & PEID 결과 비교)  (0) 2021.09.13
PE 헤더(PE Header)  (0) 2021.09.13
어셈블리 명령어 정리  (0) 2021.09.13