본문 바로가기

리버스 엔지니어링

IAT란? -3. notepad.exe를 이용한 실습

실제로 notepad.exe를 대상으로 하나씩 살펴보자. 어떤곳에 IMAGE_IMPORT.DESCRIPTOR 구조체 배열은 PE파일의 어느곳에 존재하는가


바로 PE헤더가 아닌 PE바디에 위치한다. 그곳에 찾아가기 위한 정보는 역시 PE헤더에 있는데 IMAGE_OPTIONAL_HEADER32.DataDirectory[1].VirtualAddress 값이 실제 IMAGE_IMPORT_DESCRIPTOR 구조체 배열의 시작 주소이다(RVA 값). IMAGE_IMPORT_DESCRIPTOR 구조체 배열을 다른 용어로는 IMPORT Directory Table이라고 한다.

 IMAGE_OPTIONAL_HEADER32.DataDirectory[1] 구조체는 다음 그림과 같다(첫번째 4바이트가 VirtualAddress,두 번째 4바이트가 Size맴버이다.)


다음은 notepad.exe의 IMAGE_OPTIONAL_HEADER32.DataDirectory[1]이다.


offesets

value

description

 00000158

 00000000

 RVA of EXPORT Directory

 0000015C

 00000000

 size of EXPORT Directory

 00000160

 00007604

 RVA of IMPORT Directory

 00000164

 000000C8

 size of IMPORT Directory

 00000168

 0000B000

 RVA of RESOURCE Directory

 0000016C

 00008304

 size of RESOURCE Directory



위를 보면 RVA가 7604이므로 RVA to RAW 공식을 사용해서 7604-1000+400을 하면 File  Offset은 6A04가 나오고 파일에서 6A04를 참고




notepad.exe의 IMAGE_IMPORT_DESCRIPTOR 구조체 배열


위의그림에서 음영으로 표시된 부분이 전부 IMAGE_IMPORT_DESCRIPTOR 구조체 배열이고 박스로 되어ㅓ 있는 부분은 구조체 배열의 첫번째 원소이다. (참고로 배열의 마지막 NULL 구조체로 되어 있는것도 확인할 수 있다.) 박스 부분의 IMAGE_IMPORT_DESCRIPTOR 구조체를 살펴보자


File Offset

Member

 RVA

 RAW

 6A04

 OriginalFirstThunk(INT)

 00007990

 00006D90

 6A08

 TimeDateStamp

 FFFFFFFF

 -

 6A0C

 ForwarderChain

 FFFFFFFF

 -

 6A10

 Name

 00007AAC

 00006EAC

 6A14

 FirstThunk

 000012C4

 000006C4



IAT를 공부하는 입장에서 하나하나따라가도록 해보자.



1. 라이브러리 이름(Name)


Name 항목은 임포트 함수가 소속된 라이브러리 파일의 이름 문자열 포인터이다. RVA: 7AAC -> RAW : 6EAC 파일 오프셋 6EAC에 "comdlg32.dll"이 보인다.


2. OriginalFirstThunk -INT(Import Name Table)


INT는  임포트하는 함수의 정보(Ordinal, Name)가 담긴 구조체 포인터 배열이다. 이 정보를 얻어야 프로세스 메모리에 로딩된 라이브러리에서 해당 함수의 시작 주소를 정확히 구할수 있다. (이후 나올 EAT를 참고)

 OriginalFirstThunk 맴버를 따라간다.(RVA:7990 -> RAW: 6D90)


위의 사진이 INT이다. 주소 배열 형태로 되어 있다.(배열의 끝은  NULL로 되어있다).



주소 값 하나하나가 각각의 IMAGE_IMPORT_BY_NAME 구조체를 가리키고 있다.


배열의 첫번째 값인 7A7A(RVA)를 따라가보면 임포트 하는 API 함수 이름 문자열이 나타날것이다.


3. IMAGE_IMPORT_BY_NAME


RVA:  7A7A는 RAW : 6E7A이다.


파일 오프셋 6E7A의 최초 2바이트 값(000F)은 Oridinal로, 라이브러리에서 함수의 고유 번호이다. Ordinal 뒤로  'PageSetupDigW' 함수 이름 문자열이 보인다.(문자열의 마지막은 C언어와 마찬가지로 Terminating NULL['\0']로 끝난다.)

 여기까지 정리하면 INT는 IMAGE_IMPORT_BY_NAME 구조체 포인터 배열이다. 배열의 첫 번째 원소가 가리키는 함수의 Ordinal 값은 000F이고 함수의 이름은 'PageSetupDigW'이다.


4.FirstThunk-IAT(Import Address Table)


IAT의 RVA: 12C4는  RAW: 6C04이다.



 

위의 그림에서 파일 오프셋이 6C04~6E0B 영역이 'comdlg32.dll' 라이브러리에 해당하는 IAT 배열 영역이다. I NT와 마찬가지로 구조체 포인터 배열 형태로 되어 있으며 배열은 NULL로 끝난다.

 IAT의 첫 번째 원소 값은 이미 76324906로 하드코딩 되어있다. 이 값은 의미 없는 값으로, notepad.exe 파일이 메모리에 로딩될 때 이 값은 정확한 주소값으로 대체된다.





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

PE재배치 동작 원리  (0) 2018.05.14
PE 재배치 -1  (0) 2018.05.14
Lenas_Reversing_for_Newbies를 크랙해보자  (0) 2018.05.06
IAT란? -2 IMAGE_IMPORT_DESCRIPTOR  (0) 2018.01.19
IAT란? -1 DLL  (0) 2018.01.18