DLL
동적 연결 라이브러리(Dynamic Link Library)의 약어다.
① 프로그램에 라이브러리를 포함시키지 않고 별도의 파일로 구성하여 필요할 때마다 불러 쓴다.
② 일단 한 번 로딩된 DLL의 코드, 리소스는 Memory Mapping 기술로 여러 Process에서 공유해 쓴다.
③ 라이브러리가 업데이트되었을 때 해당 DLL 파일만 교체하면 된다.
IAT
프로그램이 어떤 라이브러리에서 어떤 함수를 사용하고 있는지를 기술한 테이블이다.
위의 프로세스 A의 Page 1이 Frame 5를 가리키고, 프로세스 B의 Page 7도 마찬가지로 Frame 5를 가리킨다. 이것은, DLL을 한번 메모리에 로드 시키고, 그 영역을 프로세스 별로 공유한다는 것을 뜻한다. 여기서 주의할 점은, DLL이 메모리에 어느 곳에 로딩되어 있는지 프로그래밍 할 당시에 확인할 방법이 없다는 것이다. 그래서, IAT라는 공간을 만들어 두고, PE Loader가 이 공간에 DLL이 메모리상 어디에 위치 되어 있는지 쓰는 과정을 거치게 된다.
IAT 로딩 과정
1. IID의 Name 멤버를 읽어서 라이브러리의 이름 문자열을 얻는다
2. 해당 라이브러리를 로딩한다.
→ LoadLibrary(“ADVAPI32.dll”)
3. IID의 OriginalFirstThunk 멤버를 읽어서 INT 주소를 얻는다.
4. INT에서 배열의 값을 하나씩 읽어 해당 IMAGE_IMPORT_BY_NAME주소(RVA)를 얻는다.
5. IMAGE_IMPORT_BY_NAME의 Hint or Name의 이용하여 해당 함수의 시작 주소를 얻는다.
→ GetProcAddress(“OpenProcessToken”)
6.IID의 FirstThunk 멤버를 읽어서 IAT의 주소를 얻는다.
7.해당 IAT 배열 값에 위에서 구한 함수 주소를 입력한다.
8. INT가 끝날 때까지 (NULL을 만날때 까지) 4~7의 과정을 반복한다.
32 bit Notepad.exe를 이용한 실습
위 사진에서 보이는 것처럼 처음 4byte는 RVA값, 다음 값은 Size를 나타낸다
RVA 값 = 1A3B0
[RAW = RVA – VirtualAddress + PointerToRawData]
파일의 임의 위치 = 메모리 임의 위치
RVA to RAW 공식을 이용하여 값을 구해 보자 RVA는 아는 상태이므로 VirtualAddress와 PointerToRawData를 알아야 된다.
SECTION.idata 영역은 1A000부터 1B9F0까지 이므로 RVA값인 1A3B0은 .idata 영역에 속함
VA= 해당 영역의 시작 주소 1A000이 된다
해당 섹션 시작위치는 16000
RAW=1A3B0 - 1A000 + 16000 즉 RAW 값은 163B0이 된다
IMPORT Directory Table에서 163B0을 찾아가면 각 멤버의 값을 확인할 수 있다
<Name>
163B0에서 Name값은 1A982가 된다(RVA값) 이를 RAW로 변경하면 16982가 된다.
HxD Editor로 찾아보니까 16982에서도 존재하는 것을 알 수 있었다.
<OriginalFirstThunk-INT>
RAV값이 1A554 이므로 RAW로 변환하면 16554가 된다.
첫 번째 값인 00 01 A9 1E를 찾아가보자
RAW=1691E가 된다
<FirstThunk-IAT>
RVA 값이 16000이므로 RAW값은 160000이다.
EAT
라이브러리 파일에서 제공하는 함수를 다른 프로그램에서 가져다 사용할 수 있도록 해주는 핵심 메커니즘이다. ( 라이브러리가 가진 함수를 다른 프로그램에서 사용할 수 있도록 하는 것)
EAT 로딩 과정
1. AddressOfNames 멤버를 이용해 '함수 이름 배열'로 이동
2. '함수 이름 배열'은 문자열 주소가 있으므로, 문자열 비교를 통하여 원하는 함수 이름을 찾는다.(name_index)
3. AddrssOfNameOrdinals멤버를 이용하여 'ordinal' 배열로 이동
4. 'ordinal 배열'에서 name_index를 이용하여 해당 ordinal 값을 찾는다.
5. AddrssOfFunctions 멤버를 이용하여 함수 주소 배열(EAT)로 이동
6. EAT에서 ordinal을 배열 인덱스로 하여 원하는 함수의 시작주소를 얻는다.
32 bit kernel32.dll를 이용한 실습
RVA 값은 75930이다. 이를 이용해 RAW 를 구하면 다음과 같다.
RAW=RVA-VirtualAddress+PoinerToRawData
RAW=75930-170+170=75930이다.
IMAGE_EXPORT_DIRECTORY에서 75930으로 가서 각 멤버의 값을 확인한다.
<함수 이름 배열 찾기>
NumberOfNames의 값이 771DC라 Section.text에 존재 RAW로 변환하려면
771DC-1000+1000=771DC
AddAtomW 함수라는 것을 알게 되었다. 위의 데이터 79797을 따와서
<함수 이름 찾기>
79797을 RAW로 변환한 값도 79797이 되고 AddAtomW 함수를 찾았다.
HxD Editor에서 이를 확인
<Ordinal 배열>
AddressOfNameOrdinals의 값을 RAW 변환시 78A60이 된다.
<함수 주소 배열 - EAT>
AddressOfFunctions의 값은 75958이고 RAW 변환시 75958이 된다.
'CS' 카테고리의 다른 글
네트워크 보안 과제[aws] (0) | 2020.11.25 |
---|---|
[네트워크 보안] google cloud platform(gcp)에서 instance 만들기 (0) | 2020.11.09 |
네트워크 보안 2주차 (0) | 2020.09.19 |
네트워크 보안 1주차 (0) | 2020.09.14 |
DDos 공격 대응 가이드 pdf (http 위주) (0) | 2020.02.24 |