Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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
Tags
more
Archives
Today
Total
관리 메뉴

Study

리버싱 핵심원리_16_Base Relocation Table 본문

Reversing/리버싱 핵심원리

리버싱 핵심원리_16_Base Relocation Table

마늘부추 2019. 2. 10. 21:34

16. Base Relocation Table

 

16.1 PE 재배치

 

- PE 파일(EXE/DLL/SYS)이 프로세스 가상 메모리에 로딩될 때 PE 헤더의 ImageBase 주소에 로딩된다.

- DLL(SYS) 파일의 경우 ImageBase 위치에 이미 다른 DLL(SYS) 파일이 로딩되어 있다면 다른 비어 있는 주소 공간에 로딩된다.

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

 

 

16.1.1 dll/sys

 

이미지 베이스 10000000을 갖는 a와 b 두 dll이 있다.
a.dll이 먼저 로드되어 있을 때 b.dll을 로드하려 하면 a.dll가 로드된 주소를 포기하고 다른 주소를 찾아 로드된다.

 

ex) 메모장을 로드한 후 실행시키고 dll 인젝션을 통해 공통된 ImageBase(10000000) 값을 갖는 dll 두 가지를
인젝션 해보았다.(리버싱 핵심원리 23장 내용 참고. win 7 이하의 환경에서 시도하는 것을 추천)

 

 

첫 번째 myhack.dll은 성공적으로 10000000에 로드되었고, 두 번째 myhack2.dll은 비어있는 주소 00760000에 로드되었다.

 

순서를 바꾸면 myhack2.dll이 10000000에 로드된다.

 

※ 여기서 잠깐!

특정 실행파일 실행 이후에 사용되는 dll은 로드될 메모리의 사용 여부에 따라 재배치가 일어난다.

그러나 kernel32.dll, user32.dll 등과 같은 os에서 자주 사용되는 주요 시스템 dll들은 버전별로 각각 고유한 imagebase를 가지고 있기 때문에 실제로 시스템 dll들끼리는 재배치가 발생할 일이 없다.

 

 

 

16.1.2 exe

 

프로세스가 생성될 때 exe 파일이 가장 먼저 메모리에 로딩되기 때문에 exe에서는 재배치를 고려할 필요가 없다.

그러나 보안 강화를 위해 ASLR(Address Space Layout Randomization) 기능이 추가되었다.
이것은 exe 파일이 실행될 때마다 랜덤한 주소에 로딩되는 것이다.

 

 

EP가 3689이고 imagebase가 01000000인 notepad.exe를 ollydbg에 올려보았다.

 

 

ImageBase가 정해져 있음에도 마지막 3689를 제외한 주소가 프로그램 실행할 때마다 바뀌는 것을 볼 수 있다.
(win 7까지는 매 실행마다 가상주소가 변경되었지만 win 8 이후 환경에서는 재부팅 시 주소가 바뀐다.)

 

 

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

 

 

notepad.exe의 EP코드를 보자.
빨간색과 파란색의 네모로 표시된 부분은 호출할 데이터 세그먼트의 위치로, 현재 베이스 주소(00AA0000)에 맞춰 수정된 상태이다.
이 부분을 HxD로 보면(.text 영역) 빨간색의 경우 AA10FC가 아니라 010010FC로 하드코딩되어있음을 알 수 있다.
AA1100도 마찬가지로 01001100으로 하드코딩되어있다.

 

ollydbg에서 notepad.exe를 재실행 할 때마다 이와같은 주소들은 로딩주소에 맞게 매번 재구성된다.
이렇게 하드코딩된 주소를 실행시마다 변경해주는 작업을 PE 재배치라고 한다.

 

 

 

16.3 재배치 동작 원리

 

① 하드 코딩된 주소 위치를 찾는다.

② 하드코딩된 주솟값을 읽어내 ImageBase 값을 빼고 로딩 주소를 더해준다.

 

여기서 중요한 것은 ① 하드코딩 주소 위치를 찾는 일이다.
이 위치를 찾기 위해 PE 파일 내부에 Relocation Table이라고 하는 하드코딩 주소들의 offset을 모아놓은 목록이 존재한다.

(이것은 PE 파일 컴파일, 링크 과정에서 제공된다.)

 

IMAGE_OPTIONAL_HEADER의 Base Relocation Table(6번째 항목)을 확인하여 테이블의 주소를 찾아간다.


 


.reloc 섹션의 내용을 보면 다음과 같은 table을 확인할 수 있다.

 

 

 

16.3.1 IMAGE_BASE_RELOCATION 구조체

 

 

IMAGE_BASE_RELOCATION 구조체의 정의이다.

 VirtualAddress

 각 블록들의 기준 주소. RVA값.

 SizeOfBlock

 각 단위 블록의 크기.(기준 주소별로 이러한 블록이 배열 형태로 존재)

 TypeOffset

 이 구조체 밑으로 WORD 타입의 배열이 따라온다는 뜻. 프로그램에 하드코딩된 주소들의 offset.

 

 

 

16.3.2 Base Relocation Table의 해석 방법

 

 

기준 주소, 블록 크기, TypeOffset(WORD 크기) 집합들이 하나의 블록을 형성하여 모여있다.
이러한 블록들은 Relocation Table에 배열 형태로 여러 개 존재한다.(스크롤을 내려보면 또 나타남)
블록의 끝은 0000으로 표시한다.

 

그중 마지막 TypeOffset은 총 2바이트의 크기를 가지며 Type(4bit)와 Offset(12bit)이 합쳐진 형태이다.

첫 번째 TypeOffset의 값을 보면 3420이 적혀있다.
이중 offset 부분은 420이고 맨 앞 3은 IMAGE_BASE_RELOCATION 구조체의 type 중 IMGAE_REL_BASED_HIGHLOW에 해당한다.
(PE 파일에서 일반적인 값은 3이고 64비트용 PE+ 파일에서는 A이다.)
420에 블록의 시작 주소(VirtualAddress = 1000)을 더한 값 1420이(파란색 네모로 표시한 영역) 메모리상 주소의 RVA 값이다.

 

 

 

16.3.3 실습

 

notepad.exe를 실행시켜 주소를 참조하는 명령어를 하나 선택한다.

 

 

00AA36A6 주소에 적힌 명령어의 하드코딩을 알아보기 위해 PEview를 확인한다.
36A6은 명령어(FF15)이고 36A8부터 4byte까지가 주소이다.

 

Relocation Table을 보면 주소 변환이 있음을 확인할 수 있다.

 

 

text 영역에서 36A8 영역을 찾는다. 36A6에 FF15, 36A8에 하드코딩된 주소 010010FC가 있음을 볼 수 있다.

 

이 주소에서 ImageBase(01000000)를 뺀 후 실제 로딩 주소(00AA0000)를 더하면 처음 ollydbg에서 발견한 주소 00AA36A6가 된다.

 

PE 로더는 이렇게 로딩된 메모리 주소에 맞게 보정된 값을 같은 위치에 덮어쓴다.
이 과정을 IMAGE_BASE_RELOCATION 구조체의 모든 TypeOffset에 대해 반복하면 모든 하드코딩 주소에 대해 PE 재배치 작업이 수행된다.

 

 

 

TypeOffset 값이 0이 되면 하나의 IMAGE_BASE_RELOCATION 구조체가 끝난다.