본문 바로가기
해킹/리버싱엔지니어링

Base Relocation Table

by 맑은청이 2020. 5. 1.
728x90
반응형

오늘은 PE 파일의 재배치 (Relocation) 과정에 사용되는 Base Relocation Table의 구조와 동작원리에 대해 알아보겠습니다. 

 

-PE 재배치 

PE파일(EXE/DLL/SYS) 이 프로세스 가상 메모리에 로딩(loadiong) 될때 PE 헤더의 ImageBase주소에 로딩 됩니다.(ImageBase 주소는 NT Header에 Optional Header 안 에 있습니다.) DLL이나 SYS 같은 경우 ImageBase 위치에 이미 다른 파일이 로딩되어있다면 충돌을 비해 다른 비어있는 주소 공간에 로딩됩니다. 이를 PE Relocation 이라고 합니다. 

 -> PE파일이 ImageBase에 로딩되지 못하고 다른 주소에 로딩될때 수행되는 일련의 작업들 의미.

 

참고) ImageBase EXE = 00400000, DLL = 10000000, SYS = 10000 

 

Relocation

 

-EXE

프로세스가 생성될때 EXE 파일이 가장 먼저 메모리에 로딩되기 때문에 EXE 에서는 재배치를 고려할 필요가 없습니다.  그러나 Windows Vista 이후에는 보안 강화를 위해 ASLR(Address Space Layout Randomization) 기능이 추가되었습니다

-> 실행할 때마다 랜덤한 주소에 로딩하는 것 

(DLL/SYS 에게도 해당, 고유한 주소 가지고 있음)

 

 

-PE재배치 발생시 수행되는 작업

보다시피 ImageBase 는 01000000 입니다.

Ollydbg 로 notepad.exe를 실행해보겠습니다. 

EP코드입니다. 포인트 주소가 보이지 않게 설정을 해놓긴 했지만 ASLR 기능에 이해 00610000 주소에 로딩된 상태입니다. 형광팬으로 표시 안에 프로세스 메모리 주소가 하드코딩 되어있습니다. ctrl+f2 재 시작을 할때마다 이 주소는 변하게 됩니다. 

이렇게 하드코딩된 메모리 주소를 현재 로딩된 주소에 맞게 변경해주는 작업이 바로 PE 재배치입니다. 

이 작업이 없다면 '잘못된 메모리 주소 참조 에러'에 의해 비정상 종료 될 것입니다. 

 

하드코딩된 메모리 주소를 확인 할 수 있습니다. 

 

-PE재배치 동작 원리

1. 프로그램에서 하드코딩된 주소 위치를 찾는다. 

2. 값을 읽은 후 ImageBase 만큼 뺀다(VA->RVA)

3. 실제 로딩 주소를 더한다.(RVA -> VA)

 

핵심은 하드코딩된 주소 위치 찾기 입니다. 이를 위해 PE파일 내부에 Relocation Table( 하드코딩 주소들의 옵셋을 모아놓은 목록)이 존재합니다. PE 파일 빌드 과정에서 제공됩니다. PE 헤더의 Base Relocation Table 항목을 따라가면 Relocation Table을 찾을 수 있습니다. 

 

-Base Reloation TablePE헤더

DataDirectory 배열 여섯번째 항목

Base Relocation Table

Base Relocation Table 주소는 RVA 2F000 입니다. PEView 로 확인해보겠습니다. 

 

IMAGE_BASE_RELOCATION 구조체의

첫번째 멤버는 VirtualAddress는 기준 주소(Base Address) 이며, 실제로는 RVA 값입니다. 

두번째 멤버 SizeOfBlock은 블록의 크기 의미합니다. 

마지막으로 구조체 멤버는 아니지만 주석으로 표시된 TypeOffset 배열의 의미는 이 구조체 밑으로 WORD(2바이트) 타입의 배열이 따라온다는 의미입니다. 이는 배열 항목 값이 바로 프로그램에 하드코딩된 주소들의 옵셋 입니다. 

 

 

-Base Relocation Table의 해석방법

Base Relocation Table

에 일부 내용을 표시해 보겠습니다.

RVA Data Comment
0002F000 00001000 VirtualAddress(구조체 첫번째 멤버)
0002F004 00000150 SizeOfBlock(구조체 두번째 멤버)
0002F008 3420 TYPEOFFSET
0002F00A 342D TYPEOFFSET
0002F00C 3436 TYPEOFFSET

표에 표시된 TypeOffset 배열의 기준 주소(시작주소)는 RVA 1000 입니다. 블록 젠체 크기는 150입니다. 

TypeOffset 값은 2바이트(16비트) 크기 인데 Type(4비트)와 Offset(12비트) 가 합쳐진 형태입니다.

TypeOffset 값이 3420 이라면 Type 3/ Offset 420 입니다. 

 

PE파일에서 일반적인 Type 값은

3(IMAGE_REL_BASEED_HIGHLOW) 이고

64비트에선 A(IMAGE_REL_BASED_DIR64)

악성코드중 정상 파일의 코드를 패치한 후 재배치 과정을 피하기 위해 Type을 0을 수정해버립니다. 

 

하위 12비트가 진짜 Offset 입니다. 이 값은 Virtual Address 기준의 옵셋 입니다. 

 

VirtualSize(1000) + Offset(420) = 1420(RVA) 

 

와 같이 계산됩니다.  

 

 

 

-실습해보기(재배치 작업이 어떻게 이루어지는지)

 

프로그램에서 하드코딩된 주소위치 찾는다.

RVA 1420 주소의 내용

 

1.프로그램의 하드코딩된 주소 010010C4 값이 들어있습니다. 

2.값을 읽은 후 ImageBase 만큼 뺀다 

010010C4 - 01000000 = 000010C4

 

3. 실제 로딩 주소 더한다. 

000010C4 + 00610000 = 006110C4 

 

 

 

 

이런 식으로 PE로더가 TypeOffset에 대해 반복하며 PE 재배치 작업을 수행합니다. 배열 값이 0이 되면 재배치가 끝납니다.

 

 

 

 

728x90
반응형

'해킹 > 리버싱엔지니어링' 카테고리의 다른 글

함수 호출 규약  (0) 2020.11.18
실행 압축  (0) 2020.04.28
EAT정리  (0) 2020.04.25
IAT 정리  (0) 2020.04.25
OllyDBG 단축키  (0) 2020.04.18