본문 바로가기

컴퓨터와 보안/리버싱

PE File Format3

 IAT

IAT(Import Address Table)에는 Windows 운영체제의 핵심 개념인 process, memory, DLL 구조 등에 대한 내용이 함축되어 있다. 

즉, 프로그램이 어떤 라이브러리에서 어떤 함수를 사용하고 있는지를 기술한 테이블로 IAT를 잘 이해하면 Windows 운영체제의 근간을 이해할 수 있다.

우선 IAT를 알아보기 전에 DLL에 대해 먼저 알아보겠다.

DLL

DLL이란 Dynamic Linking library(동적 연결 라이브러리)의 약어로 windows에서 사용되는 공유 라이브러리이다.

DLL의 특징은 다음과 같다.

 

  • 프로그램에 라이브러리를 포함시키지 않고 별도의 파일로 구성하여 필요할때마다 불러쓸 수 있다.
  • 한번 로딩된 DLL의 코드, 리소스는 Memory Mapping 기술로 여러 process에서 공유해 쓸 수 있다.
  • 라이브러리가 업데이트되었을 때 해당 DLL 파일만 교체할 수 있다.

실제 DLL 로딩 방식은 2가지인데, 다음과 같다.

 

  1. 프로그램에서 사용되는 순간에 로딩하고 사용이 끝나면 메모리에서 해제되는 방법(Explict Linking)
  2. 프로그램 시작할 때 같이 로딩되어 프로그램 종료할 때 메모리에서 해제되는 방법(Implict Linking)

IAT는 바로 Implict Linking에 대한 메커니즘을 제공하는 역할을 한다.

메커니즘의 확인을 위해 Ollydbg로 notepad.exe를 열어본다.

 

DLL메커니즘
DLL메커니즘2

 

DLL메커니즘3

위 그림을 보면 CreateFileW를 호출할 때 직접 호출하지 않고 101A150 주소에 있는 값을 가져와서 호출한다.

 

이렇게 호출하는 이유는 Kernel32.dll의 버전이 틀려지고, CreateFileW 함수의 위치가 틀려지는 모든 환경에서 

CreateFileW 함수 호출을 보장하기 위해서이다.

컴파일러는 CreateFileW 의 실제 주소가 저장될 위치를 준비하고 CALL DWORD PTR DS:[&KERNEL32.CreateFileW] 형식의 명령어를 적어두기만 한다.

 

또 다른 이유는 DLL Relocation 때문이다.

 

어떤 프로그램이 a.dll 과 b.dll 을 사용한다고 했을 때, PE Loader는 먼저 a.dll 을 ImageBase 값인 메모리 10000000h 에 로딩한다. (일반적인 DLL 파일의 ImageBase 값은 10000000h 이다.) 그 다음 b.dll 을 ImageBase 값인 메모리 10000000h 에 로딩하려고 봤더니, 이미 그 주소는 a.dll 이 사용하고 있었다. 

그래서 PE Loader 는 다른 비어있는 메모리 공간을 찾아서 b.dll을 로딩시켜 준다.

 

이것이 DLL Relocation 이며 실제 주소를 하드코딩 할 수 없는 이유이다.

또한 PE Header 에서 주소를 나타낼 때 VA 를 쓰지 못하고 RVA 를 쓰는 이유이기도 하다.

 

 

IMAGE_IMPORT_DESCRIPTOR

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

 

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

IMAGE_IMPORT_DESCRIPTOR 구조체는 다음과 같다.

IMAGE_IMPORT_DESCRIPTOR

출처 - k3y6reak's Blog

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

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

 

PE Loader가 Import 함수 주소를 IAT 에 입력하는 기본적인 순서를 정리해보면

  1. IID 의 Name 멤버를 읽어서 라이브러리의 이름 문자열("kernel32.dll")을 얻는다.
  2. 해당 라이브러리("kernel32.dll")를 로딩한다.
  3. IID 의 OriginalFirstThunk 멤버를 읽어서 INT 주소를 얻는다.
  4. INT 에서 배열의 값을 하나씩 읽어 해당 IMAGE_IMPORT_BY_NAME 주소 (RVA)를 얻는다.
  5. IMAGE_IMPORT_BY_NAME 의 Hint(ordinal) 또는 Name 항목을 이용하여 해당 함수의 시작 주소를 얻는다.
  6. IID 의 FirstThunk(IAT) 멤버를 읽어서 IAT 주소를 얻는다.
  7. 해당 IAT 배열 값에 위에서 구한 함수 주소를 입력한다.
  8. INT 가 끝날때까지 (NULL 을 만날때까지) 위 4~7 과정을 반복한다

 

 

 

 

'컴퓨터와 보안 > 리버싱' 카테고리의 다른 글

PE File Format - pestudio  (0) 2021.04.02
PE File Format4  (0) 2021.04.01
PE File Format  (0) 2021.03.29
Hello World! 리버싱3  (0) 2021.03.28
Hello world! 리버싱2  (0) 2021.03.28