기존에는 각 프로그램 별로 라이브러리를 포함시켜 사용을 했습니다.
컴파일러가 C 라이브러리에서 Binary 코드를 그대로 가져왔다고 볼 수 있습니다.
그런데 Window가 멀티태스킹을 지원하게 되면서
여러 프로그램이 동시에 실행이 가능해졌고 DLL의 이런 로딩 방식은 메모리의 낭비로 이어졌습니다.

따라서 프로그램에 라이브러리를 포함시키지 않고 메모리에 한 번 로딩된 라이브러리의 리소스를
Memory Mapping 기능을 사용해 여러 프로세스에서 공유해 쓰는 방식으로 라이브러리를 사용하게 되었습니다.

라이브러리는 링킹의 시점에 따라 Static과 Dynamic의 방식으로 나눌 수 있습니다.

  • Static Link : 컴파일 시점에서 라이브러리가 링킹 단계에서 연결되는 방식
    *.lib 파일을 링킹 과정에서 포함하게 되는데 해당 파일은 라이브러리 전체 코드를 포함하는 binary
  • Dynamic Link : 실행 파일에서 해당 라이브러리 기능을 사용 시 라이브러리 파일을 참고하여 기능을 호출
    마찬가지로 .lib파일을 이용하지만 여기에는 DLL이 제공하고자 하는 함수 정보를 가지는 파일

 

 

IAT


프로그램이 어떤 라이브러리에서 어떤 함수를 사용하는지에 대한 테이블
라이브러리가 PE의 NT 헤더에 명시된 ImageBase에 로딩된다고 보장할 수 없기 때문에 IAT의 RVA 값을 통해
함수에 접근합니다. 프로그램 안에 사용하고자 하는 함수에 대한 모든 정보가 없어도 주소만 가지고
DLL로 넘어가 함수 정보를 가져다쓰므로 용량이 크지도 않고, 메모리도 크게 점유하지 않는다는 점이 있습니다.

 

PE 헤더의 NT_Optional_Header -> DataDirectory [1]의 위치에 정보가 명시되어 있습니다.
DataDirectory[1]의 구조체의 경우 다음과 같습니다.

 

IAT는 IMAGE_IMPORT_DESCRIPTOR 구조체의 형태로 존재하는데요.

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
   union {
	DWORD Characteristics;
	DWORD OriginalFirstThunk;
    };
    DWORD TimeDateStamp;
    DWORD ForwarderChain;
    DWORD Name;
    DWORD FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR;

멤버의 의미를 살펴보면

  • OriginalFirstThunk : Import Name Table의 주소
  • Name : 라이브러리 이름의 주소
  • FirstThunk : IAT( Import Address Table )의 주소

winDBG로 notepad.exe를 분석해 해당 구조체를 살펴보겠습니다.

 

Import Directory ( RVA : 0x2D0A8 )

멤버별로 비교해보면 

  • OriginalFirstThunk : 0x2d3c0
  • Name : 0x2e1d8
  • FirstThunk : 0x268b8

임을 확인할 수 있습니다.

 

Import되는 함수를 찾을 수 있음.

 

 

 

EAT


다른 파일에게 자신이 제공하는 함수들에 대한 테이블

PE 헤더의 NT_Optional_Header -> DataDirectory[0] 의 위치에 정보가 명시되어 있습니다.
DataDirectory[0]의 구조체의 경우 다음과 같습니다.

EAT는 IMAGE_EXPORT_DIRECTORY 구조체의 형태로 존재합니다.

typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD Characteristics;
    DWORD TimeDateStamp;
    WORD MajorVersion;
    WORD MinorVersion;
    DWORD Name;
    DWORD Base;
    DWORD NumberOfFunctions;
    DWORD NumberOfNames;
    DWORD AddressOfFunctions;
    DWORD AddressOfNames;
    DWORD AddressOfNameOrdinals;
 } IMAGE_EXPORT_DEIRECTORY, *PIMAGE_EXPORT_DIRECTORY

중요 멤버로는

  • AddressOfFunctions : Export 함수 주소 배열
  • AddressOfNameOrdinals : Ordinal 주소 배열

EAT의 경우 제공하는 함수를 함수의 이름 RVA에서 몇 번째 인덱스에 있는지를 확인합니다.
찾은 인덱스를 바탕으로 해당 인덱스에 들어 있는 Ordinal 값을 참조해
원하는 함수의 시작 주소를 얻는 과정을 거치게 됩니다.

Export Directory ( RVA : 0x9A1E0 )

멤버별로 비교해보면

  • AddressOfFunctions : 0x9a208
  • AddressOfNames : 0x9bb8c
  • AddressOfNameOrdinals : 0x9d510

임을 확인할 수 있습니다.

Export되는 함수를 찾을 수 있음.

 

 

'System' 카테고리의 다른 글

Stack Pivot  (0) 2022.05.17
Linux] Seccomp  (0) 2022.04.28

+ Recent posts