티스토리 뷰
1. IAT
IAT(Import Address Table)은 프로그램에서 어떤 라이브러리에서 어떤 함수를 사용하고 있는지에 대한 정보를 갖고 있는 테이블입니다.
1.1 DLL
DLL이라는 개념은 다른 포스팅에서 자세하게 설명한 적이 있습니다. 링크 : wsw3998.tistory.com/29
지뢰 찾기 리버싱!_Win7 32bit (1)
안녕하세요 오늘 포스팅할 주제는 "지뢰 찾기 리버싱!" 입니다. 카테고리에 나온 것 처럼 지뢰 찾기를 통해서 DLL Injection을 해보려고 합니다 DLL Injection에 앞서 간단하게 DLL Injection에 대해서 설명
wsw3998.tistory.com
때문에 여기서는 가볍게 설명하고 넘어가보도록 하겠습니다. 먼저 DLL이라는 것은 동적 링크 라이브러리라고 합니다.
16비트 DOS 시절에는 프로그램에서 printf()라는 함수를 사용하고 싶다면 binary코드를 갖고와서 프로그램 자체에다가 삽입 해주어야 합니다. 하지만 Window OS가 나오면서 멀티 태스킹이 지원 됐습니다. 즉 기본적인 윈도우 함수들을 모든 프로그램에 삽입해줄 필요 없이 라이브러리들을 메모리에 띄워두고 그 메모리를 참조해서 사용하는 방식으로 발전 했습니다. 이것을 DLL 이라고 합니다.
이러한 DLL의 로딩 방식은 2가지로 나뉩니다.
1. Explicit Linking 2. Implicit Linking
먼저 Explicit Linking의 경우는 프로그램에서 사용되는 순간에 로딩하고 사용이 끝나면 메모리에서 해제 되는 방식입니다. 두 번째 방식인 Implicit Linking의 경우는 프로그램이 시작할 때 같이 시작되며, 프로그램이 종료되면 해제되는 방식입니다.
1.2 IMAGE_IMPORT_DESCRIPTOR
자신이 어떤 라이브러리를 import 하고 있는지 명시 해줍니다.
해당 구조체는 하나의 라이브러리당 하나를 갖게 됩니다. 따라서 보통은 여러개의 라이브러리를 import 하기 때문에 라이브러리의 개수만큼 "구조체 배열" 형식으로 존재합니다. 배열의 마지막은 NULL 구조체로 끝납니다.
이 배열에서 중요한 멤버는 세 가지 입니다. 위 구조체에서 빨간 상자로 표시한 부분입니다.
1. OriginalFirstThunk : INT(Import Name Table)의 주소(RVA)
2. Name : Library 이름 문자열 주소(RVA)
3. FirstThunk : IAT(Import Address Table)의 주소(RVA)
그럼 이제 PE 로더가 임포트 함수 주소를 IAT에 어떻게 입력하는지 알아봅시다.
1. IID(IMAGE_IMPORT_DESCRIPTOR)의 Name 멤버를 읽어 라이브러리 이름 문자열 획득
2. 해당 라이브러리를 로딩
-> LoadLibrary("Kernel32.dll")
3. IID의 OriginalFirstThunk 멤버를 읽어 INT 주소 획득
4. INT에서 배열의 값을 하나씩 읽어 IMAGE_IMPORT_BY_NAME 주소(RVA)를 획득
5. IMAGE_IMPORT_BY_NAME의 멤버들을 이용하여 해당 함수의 시작 주소 획득
-> GetProcAddress("GetCurrentThreadId")
6. IID의 FirstThunk(AT) 멤버를 읽어 IAT 주소 획득
7. 해당 IAT 배열 값에 위에서 구한 함수 주소 입력
8. INT가 NULL일 때 까지 위의 과정 반복
** IMAGE_IMPORT_DESCRIPTOR 구조체 배열은 PE 바디에 위치 **
2. EAT
EAT(Export Address Table)은 라이브러리 파일에서 제공하는 함수를 다른 프로그램에서 가져다 사용할 수 있도록 해주는 메커니즘으로, 라이브러리에서 Export 해주는 함수의 시작 주소를 정확히 구할 수 있습니다.
2.1 IMAGE_EXPORT_DIRECTORY (PE 헤더)
IMAGE_OPTIONAL_HEADER32.DataDirectory[0].VirtualAddress = IMAGE_EXPORT_DIRECTORY 시작 주소 입니다.
IMAGE_EXPORT_DIRECTORY 구조체를 살펴봅시다.
해당 구조체에는 5개의 중요 멤버가 있습니다.
1. NumberOfFunctions : 실제 Export 함수 개수
2. NumberOfNames : Export 함수 중에서 이름을 가지는 함수 개수(NumberOfFunctions 보다 작거나 같습니다.)
3. AddressOfFunctions : Export 함수 주소 배열 (배열의 원소 개수 = NumberOfFunctions)
4. AddressOfNames : 함수 이름 주소 배열(배열의 원소 개수 = NumberOfNames)
5. AddressOfNameOrdinals : Ordinal 주소 배열(배열의 원소 개수 = NumberOfNames)
라이브러리에서 함수 주소를 얻는 API는 GetProcAddress() 입니다. 이 API가 EAT를 참조해서 원하는 API의 주소를 구하는 것입니다. 그렇다면 GetProcAddress()는 함수 이름을 갖고 어떻게 함수 주소를 얻어낼까요?
GetProcAddress()의 동작 원리
1. AddressOfNames 멤버를 이용해 '함수 이름 배열'로 간다.
2. '함수 이름 배열'은 문자열 주소가 저장되어 있으므로, 문자열 비교를 하여 원하는 함수의 이름과 Index를 찾는다.
3. AddressOfNameOrdinals 멤버를 이용해 'ordinal 배열'로 이동한다.
4. 'ordinal 배열'에서 아까 찾은 Index로 ordinal 값을 찾는다.
5. AddressOfFunctions 멤버를 이용해 EAT로 이동한다.
6. EAT에서 아까 구한 ordinal을 배열 인덱스로 하여 함수의 시작 주소를 구한다.
'Reversing! > 기본 학습' 카테고리의 다른 글
PE File Format - PE 헤더_ (0) | 2020.09.20 |
---|
- Total
- Today
- Yesterday
- whitehat
- 탈단 후 입대
- 탈단
- docker.sock
- BlackBoard Helper
- Mano-CPU-Programming
- 군 취약점 제보
- Mano-CPU Sort
- systemctl start docker
- 2023 화이트햇
- fastapi 비동기 처리
- Mano-CPU 최댓값 찾기
- chrome extension
- and will not be enabled for virtual device 'serial0' will start disconnected
- Mano-CPU
- Docker daemon
- aiomysql
- 마노시피유정렬
- the virtual printing feature is globally disabled on this system
- 어셈블리 최댓값 찾기
- ict 인턴십
- JS 개발
- vmware 화면 버벅거림
- service docker start
- pwnable#basic_exploitation_003#dreamhack#dreamhack.io#SSG
- fastapi
- 2024년 회고
- Win7#Win7지뢰찾기#Win7 지뢰찾기#지뢰찾기#Win7 32bit#32bit#MineSweeper.exe#MineSweeper#WinMine
- express 아키텍쳐
- 정보보호병
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |