-
[리버싱 핵심원리 study] 16장 Base Relocation TableReverse Engineering 2020. 12. 29. 23:29
1. PE 재배치
PE 파일이 메모리에 로딩될 때 ImageBase 주소에 로딩이 된다. DLL의 경우 이미 다른 DLL이 로딩되어 있다면 다른 비어 있는 주소 공간에 로딩된다. 이와 같은 것을 PE 재배치라고 한다. DLL과 달리 EXE 파일은 가장 먼저 메모리에 로딩되기 때문에 재배치를 고려할 수가 없었으나, Windows Vista 이후부터는 보안 강화를 위해 ASLR(Address Space Layout Randomization) 기능이 추가되어 실행될 때마다 랜덤 한 주소에 로딩이 된다.
=> 이 글을 작성하는 시점에 Windows 10 환경에서 OllyDbg로 notepad.exe를 여러번 재실행해보았지만, 로딩되는 주소에는 변화가 없었다. 해당 부분에 대한 궁금증을 해소하기 위해서 구글링을 해보았고 다음 링크의 글들이 궁금증을 해결하는데 도움을 주었다.
프로그램을 단시간내에 실행했을 때에 ASLR이 작동하기보다는 재부팅 등을 수행한 후에 ASLR이 작동한다는 등의 내용을 포함하고 있는 글이다. 참고해보면 좋을 것 같다.
2. PE 재배치 발생시 수행되는 작업
PEView를 통해 Windows7의 notepad.exe의 ImageBase를 확인해보면 다음과 같다.
OllyDbg로 notepad.exe를 실행하면 다음과 같다.
PEView에 나타난 ImageBase와는 다른 001D0000에 프로그램이 로딩된 것을 확인할 수 있으며, 위 첨부 사진에서 빨간색 동그라미는 각 프로세스 메모리 주소가 하드 코딩되어 있다. notepad.exe 프로그램이 재 실행되었을 때, 메모리의 다른 위치에 로딩된다면 위의 빨간 영역들은 로딩된 주소에 맞게 relocation을 해주어야 한다.
3. PE 재배치 동작 원리
Windows의 PE 로더가 수행하는 PE 재배치 작업의 동작 원리는 다음과 같다.
1) 프로그램에서 하드코딩된 주소 위치를 찾는다.
2) 값을 읽은 후 ImageBase를 뺀다. (VA -> RVA)
3) 실제로 로딩된 주소를 더한다. (RVA -> VA)
여기서 핵심은 하드코딩된 주소의 위치를 찾는 것으로, PE 파일 내부에 Relocation Table이라고 하는 하드코딩 주소들의 offset을 모아놓은 목록이 존재한다. Relocation Table을 찾아가기 위해서는 PE 헤더의 Base Relocation Table을 따라가면 된다.
(1) Base Relocation Table
PE 헤더의 DataDirectory의 5번 Index (6번째)에 존재한다. PEView를 통해 확인하면 다음과 같다.
RVA는 0002F000이다. PEView에서 해당 위치를 찾아보자.
(2) IMAGE_BASE_RELOCATION 구조체
위 그림에는 하드코딩 주소들의 offset이 나열되어 있다. 이 테이블을 이용하여 하드코딩 주소의 offset을 정확히 알아낼 수 있다. Base Relocation Table은 IMAGE_BASE_RELOCATION 구조체 배열인데, 그 정의는 다음과 같다.
typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; // WORD TypeOffset[1]; } IMAGE_BASE_RELOCATION; typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION; #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
첫 번째 멤버 Virtual Address는 기준 주소를 나타내며(RVA), 두 번째 멤버 SizeOfBlock은 각 단위 블록의 크기를 가리킨다. 마지막으로 주석 처리된 TypeOffset[1]의 의미는 구조체 밑으로 WORD 타입의 배열이 따라온다는 의미를 나타낸다.
위의 구조체 정의를 기반으로 Base Relocation Table을 분석해보자. VirtualAddress 멤버의 값은 1000이고, 블록 전체 크기는 150(hex)이다. 이후로는 2byte짜리 TypeOffset이 나오는데 앞의 4비트는 매크로로 정의된 TYPE, 뒤의 12비트는 offset이 된다. TypeOffset의 개수는 블록 사이즈가 150이므로 (150-8)/2 = A4(hex) 이다. 이제 실제로 1420 RVA에 PE 재배치가 필요한지 OllyDbg에서 확인해보자.
(3) 실습
간단한 실습을 통해 PE 재배치 작업의 동작 원리를 이해해보자. 앞에서 설명한 3.PE 동작 원리를 바탕으로 진행한다.
#1 프로그램에서 하드코딩된 주소 위치를 찾기
RVA 1420 주소에는 010010C4가 들어있다.
#2 ImageBase 만큼 빼기
010010C4 - 01000000 = 000010C4
#3 실제 로딩 주소 더하기
000010C4 + 001D0000 = 001D10C4
반응형'Reverse Engineering' 카테고리의 다른 글
[리버싱 핵심원리 study] 18장 UPack PE 헤더 상세 분석 (0) 2020.12.30 [리버싱 핵심원리 study] 17장 실행 파일에서 .reloc 섹션 제거하기 (0) 2020.12.29 [리버싱 핵심원리 study] 15장 UPX 실행 압축된 notepad 디버깅 (0) 2020.12.29 [리버싱 핵심원리 study] 14장 실행 압축 (0) 2020.12.29 [리버싱 핵심원리 study] 13장 PE File Format (3) (0) 2020.12.28