PE 재배치
PE 파일이 프로세스 가상 메모리에 로딩(Loading)될 때 PE 헤더의 ImageBase 주소에 로딩된다. DLL(SYS) 파일의 경우 ImageBase 위치에 이미 다른 DLL 파일이 로딩되어 있다면 다른 비어 있는 주소 공간에 로딩된다. 이를 PE 재배치라고 한다.
즉, PE 재배치는 PE 파일이 ImageBase에 로딩되지 못하고 다른 주소에 로딩되는 작업을 말한다.
DLL/SYS
TEST.EXE 프로세스에 A.DLL이 10000000 주소에 로딩되어 있다. 이후 B.DLL이 A.DLL과 같은 주소에 로딩을 시도하면 PE 로더는 B.DLL을 비어있는 3C000000에 로딩 시킨다.
EXE
프로세스가 생성될 때 EXE파일이 가장 먼저 메모리에 로딩되기 때문에 EXE에서는 재배치를 고려할 필요가 없다. Windows Vista 이후부터는 ASLR(Address Space Layout Randomization) 기능이 추가되었다 이는 매번 프로세스가 실행될 때마다 랜덤한 주소를 매핑한다. DLL 또한 고유한 ImageBase를 가지고 있지만 ASLR 기능으로 인해 로딩 주소는 매번 다르다.
PE 재배치 발생시 수행되는 작업
notepad.exe의 ImageBase는 00400000이다.
PE 재배치 동작 원리
- 프로그램 하드코딩된 주소 위치를 찾는다.
- 값을 읽은 후 ImageBase 만큼 뺀다(VA->RVA)
- 실제 로딩 주소를 더한다(RVA->VA)
핵심은 하드코딩된 주소 위치를 찾는 것이다. 이를 위해 PE 파일 내부에 Relocation Table이라고 하는 하드코딩 주소들의 옵셋을 모아 놓은 목록이 존재한다. Relocation Table로 찾아가는 방법은 PE 헤더의 Base Relocation Table 항목을 따라가는 것이다.
Base Relocation Table
Base Relocation Table 주소는 PE 헤더에서 DataDirectory 배열의 여섯 번째 항목에 들어있다.
IMAGE_NT_HEADERS\IMAGE_OPTIONAL_HEADER\IMAGE_DATA_DIRECTORY[5]
위 그림에서 Base Relocation Table 주소는 RVA 2B000 이다.
IMAGE_BASE_RELOCATION 구조체
Base Relocation Table에 하드코딩 주소들의 옵셋들이 나열되어 있다. 이 테이블만 읽어 내면 하드코딩 주소 옵셋을 정확히 알아낼 수 있다. Base Relocation Table은 IMAGE_BASE_RELOCATION 구조체 배열이다.
//
// Base relocation format
//
typedef struct _IMAGE_BASE_RELOCATION
{
DWORD VirtualAddress;
DWORD SizeOfBlock;
// WORD TypeOffset[1];
} IMAGE_BASE_RELOCATION;
typdef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
//
// Based relocation types.
//
#define IMAGE_REL_BASED_ABSOLUTE 0
#define IMAGE_REL_BASED_HIGH 1
#define IMAGE_REL_BASED_LOW 2
#define IMAGE_REL_BASED_HIGHLOW 3
#define IMAGE_REL_BASED_HIGHADJ 4
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
#define IMAGE_REL_BASED_IA64_IMM64 9
#define IMAGE_REL_BASED_DIR64 10
IMAGE_BASE_RELOCATION 구조체의 첫 번째 멤버인 VirtualAddress는 기준 주소(Base Address)이며, 실제로는 RVA 값이다. 두 번째 멤버 SizeOfBlock은 각 단위 블록의 크기를 의미한다. 마지막으로 구조체 멤버는 아니지만 주속으로 표시도니 TypeOffset 배열의 의미는 이 구조체 밑으로 WORD 타입의 배열이 따라 온다는 뜻이다.
'Reversing' 카테고리의 다른 글
PE File Format (0) | 2021.12.15 |
---|---|
윈도우 기초 (0) | 2021.04.22 |
easy-crackme1 (0) | 2021.02.20 |
x64 (0) | 2021.01.29 |
Reverse Engineering (0) | 2021.01.28 |
댓글