자료 저장소

지난번에 PE Header 이후 Section을 거쳐서 Import Directory 에 대해서 간단히 언급하였다. 여러가지 구조체 그림도 나오고, 복잡하게 엮어진 체인도 나오고 사실 구조체의 각각의 필드의 의미란 것들도 자세리 들어가다보면 정말 포기하고 싶게 만든다. -_-;

 

그냥 심플하게 Import Directory 는 DLL (Kernel32.dll, User32.dll.. 등)이 가진 함수(GetMessage, LoadIcon..등)를 호출하기 위해서 각각의 함수의 주소를 가리키고 있는(항상 고정적이지는 않음) 테이블(IAT)에 대한 정보의 집합체라는 것으로만 정리를 해두자.

 

자 이제 Imports에 대해서 좀더 자세하게 들어가 보도록 하는데 디스크와 메모리를 구분하여imported 함수가 호출되는 방식을 알아보도록 한다.

 

[Navigating Imports in Disk]

 

(기본 순서)

만약 "bar"라는 DLL이 가지고 있는 "foo"라는 함수를 호출한다고 할 때 가장먼저,

 

 1) Data Directory로 부터 Import Directory 에대한 RVA를 찾는다.

 

 

2) 해당 RVA를 파일의 정확한 영역으로 사용되어지는 raw offset 으로 변환해야 한다.

이때 section table을 참조하여 Import directory 를 가리키고 있는 주소를 확인한다.

 

 

위와 같이 00 02 AC 00 가 실제적인 .idata 가 위치하는 옵셋이 되며,

PEID를 통해서도 간단하게 확인할 수 있다.

 

 

※ RVA(2D000h)와 Raw 옵셋(2AC00h)과의 차이는 2400h 이다 . 이것은 나중에 RVA 변환에 대한 중요한 옵셋인자가 될 것이다.

 

이제 실질적인 Raw offset의 위치로 가서 어떤 형태로 Import table이 위치하고 있는지 살펴보도록 하자.

 

지난번 강좌에서 Import Table은 20바이트의 구조체  IMAGE_IMPORT_DESCRIPTOR 의 마지막으로 0으로 모두 채워진 것을 포함하여 8개의 DLL 함수가 로드되어 있는 것을 알 수 있다.

 

3) 해당  IMAGE_IMPORT_DESCRIPTOR 에서 함수의 Name 을 가리키는 문자열을 확인

 

예를 들어 위의 예에서 첫번째 IMAGE_IMPORT_DESCRIPTOR의 4번째 필드인 NAME은 RVA 00 02 D5 30h 를 가지고 있는데 이를 실질적인 옷셋으로 변환하려면 아까 찾아낸 RVA와 RAW 옷셋과의 차이값인2400h를 빼게 되면 실질적인 위치 2B130h를 얻게 된다.

 

결국 아래와 같이 해당 DLL 명을 가리키는 문자열(Ascii값)의 위치를 찾아낸다.

 

 

첫번째 IMAGE_IMPORT_DESCRIPTOR의 5번째 필드의 RVA 00 02 D0 B4h 를 마찬가지로 Raw 옵셋으로 변환하게 되면 2ACB4h 가 얻어지는데,  이것이 바로 4바이트 크기의 IMAGE_THUNK_DATA구조체를 가리키는 옵셋이며,  IAT 이다.  

 

 

위와 같이  2ACB4h의 옵셋 위치에서의 4바이트 값 00 02 D5 3E 은 또다른 RVA 값이 되며 이를 다시 Raw 옵셋으로 변환하게 되면 아래와 같이 2B13E 로 변환할 수 있고 실질적인 imported 함수의 이름을 알 수 있다.

 

 

즉 결론적으로 Kernel32.dll 에서  DeleteCriticalSection 이라는 함수가 호출됨을 알 수 있고,

이와 같은 작업을 PE Browser를 통해서 보면 심플하게 확인 할 수 있다.

 

 

4) 파일이 메모리로 로드되는 경우

 

해당 파일이 메모리로 로드되게 되면 위  디스크 상에서 3E D5 02 00  를 포함하고 있던 TunkTableRVA 2D0B4 가 로더에 의해서 다음과 같이 덮어쓰여짐을 알 수 있다.

 

결국 이 값은 7C91188A 가 된다.

나머지 자세한 부분은 메모리 에서의 Import 에서.... 휴~

 

댓글 로드 중…

최근에 게시된 글