PC리버싱/PE구조

IAT (Import Address Table / PE File 관련)

Lamed_Dhhd 2020. 5. 21. 10:16
반응형

 

 

IAT(Import Address Table)
  · Windows의 Program이 어떤 Library에서 어떤 함수를 사용하고 있는지를 기술한 Table

  · PE File 내의 특정 구조체인 'IMAGE_IMPORT_DESCRIPTOR'에 Import에 관한 정보를 저장한다.
  · PE Header에서 Table은 배열을 의미한다.

  · 각 Section마다 존재한다.

 

1. IMAGE_IMPORT_DESCRIPTOR 구조체

 

 

typedef struct _IMAGE_IMPORT_DESCRIPTOR{

  union {

  DWORD   Characteristics;

  DWORD   OriginalFirstThunk;

  };

  DWORD   TimeDataStamp;

  DWORD   ForwarderChain;

  DWORD   Name;

  DWORD   FirstThunk;

} IMAGE_IMPORT_DESCRIPTOR;

 

OriginalFirstThunk : INT(Import Name Table)의 RVA 값

INT는 IMAGE_THUNK_DATA32 구조체 배열이다.

고로 OriginalFirstThunk == IMAGE_THUNK_DATA32 구조체 배열 주소(RVA)

 

  ◦ 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. IMAGE_THUNK_DATA32 구조체

 

typedef struct _IMAGE_THUNK_DATA32{

  union{

  DWORD   ForwarderString;

  DWORD   Function;

  DWORD   Ordinal;

  DWORD  AddressOfData;

  } u1;

} IMAGE_THUNK_DATA32;

 

AddressOfData : IMAGE_IMPORT_BY_NAME 구조체 주소

Ordinal : 순서를 나타낸다.

 

다시 IMAGE_IMPORT_DESCRIPTOR로 돌아가서 나머지 부분을 살펴보자

 

FirstThunk : IAT의 RVA값을 가지는 변수

 

* FirstThunk와 OriginalFirstThunk의 차이? IAT와 INT는 동일하게 IMAGE_THUNK_DATA32 구조체 배열로 구성되어 있다. 하지만 바인딩 과정이라는걸 거치면서 INT에 값이 들어가면서 IAT가 된다. 즉, OriginalFirstThunk == INT, FirstThunk == IAT

 

Name : 해당 라이브러리의 이름 문자열이 존재하는 주소(RVA)

(임포트하려는 라이브러리의 이름이 있는 곳을 가리키는 포인터 역할)

 

반응형