본문 바로가기

리버스 엔지니어링

IAT란? -2 IMAGE_IMPORT_DESCRIPTOR

2. IMAGE_IMPORT_DESCRIPTOR

PE 파일은 자신이 어떤 라이브러리를 임포트(Import)하고 있는지 IMAGE_IMPORT_DESCRIPTOR 구조체에 명시하고 있다.


Import: library에게 서비스(함수)를 제공받는 일

Export: library 입장에서 다른 PE 파일에게 서비스(함수)를 제공하는 일


IMAGE_IMPORT_DESCRIPTOR 구조체는 다음과 같다.



typedef struct _IMAGE_IMPORT_DESCRIPTOR {

    union {

        DWORD   Characteristics;            

        DWORD   OriginalFirstThunk;       // INT(Import Name Table) address (RVA)

    };

    DWORD   TimeDateStamp;

    DWORD   ForwarderChain; 

    DWORD   Name;                         // library name string address (RVA)

    DWORD   FirstThunk;                   // IAT(Import Address Table) address (RVA)

} IMAGE_IMPORT_DESCRIPTOR;


typedef struct _IMAGE_IMPORT_BY_NAME {

    WORD    Hint;                         // ordinal

    BYTE    Name[1];                      // function name string

} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; 


일반적인 프로그램에서 보통 여러 개의 라이브러리를 임포트하기 때문에라이브러리리의 개수만크 위 구조체의 배열 형식으로 존재하며 구조체 배열의 마지막은 NULL 구조체로 끝나게 된다. IMAGE_IMPORT_DESCRIPTOR 구조체에서 중요한 맴버는 다음과 같다.


 항목

의미 

OriginalFirstThunk 

INT(Import Name Table)의 주소(RVA) 

Name 

Library 이름 문자열의 주소(RVA) 

FirstThunk 

IAT(Import Address Table)의 주소(RVA) 



--------------------------------------------------------

PE 헤더에서 Table이라고 하면 배열을 뜻함

INT와 IAT type(4바이트 자료형) 배열이고 NULL로 끝난다.(크기가 따로 명시되어있지 않다.)

INT에서 각 원소의 값은  IMAGE_IMPORT_BY_NAME 구조체 포인터이다.(IAT도 같은 값을 가지는 경우가 있다.)

INT와 IAT의 크기는 같아야 한다.

---------------------------------------------------------


그림은 notepad.exe의 kernel32.dll에 대한  구조를 표시하고 있고 순서는 다음과 같다.


1. IID(IMAGE_IMPORT_DESCRIPTOR) 의 Name 맴버를 읽어서 라이브러리의 이름 문자열("kernel32.dll")을 얻는다.

2. 해당 라이브러리를 로딩한다 ->LoadLibrary("kernel32.dll")

3. IID의 OriginalFirstThunk 맴버를 읽어서 INT주소를 얻는다.

4. INT에서 배열의 값을 하나씩 읽어 해당 IMAGE_IMPORT_BY_NAME 주소(RVA)를 얻는다.

5. IMAGE_IMPORT_BY_NAME의 Hint(Ordinal) 또는 Name 항목을 이용하여 해당 함수의 시작 주소를 얻는다.

    -> GetProcAddress("GetCurrentThreadld")

6. IID의 FirstThunk(IAT) 맴버를 읽어서 IAT 주소를 얻습니다.

7. 해당 IAT 배열값에 위에서 구한 주소를 입력한다.

8. INT가 끝날 떄까지(NULL을 만날때까지) 위 4~7과정을 반복한다.



실제로  notepad.exe를 이용한 실습을 해보자.

'리버스 엔지니어링' 카테고리의 다른 글

IAT란? -3. notepad.exe를 이용한 실습  (0) 2018.05.07
Lenas_Reversing_for_Newbies를 크랙해보자  (0) 2018.05.06
IAT란? -1 DLL  (0) 2018.01.18
RVA to RAW  (0) 2018.01.18
섹션 헤더  (0) 2018.01.16