흰싸라기 2022. 3. 27. 02:36

Base Relocation Table : PE 파일의 재배치(Relocation) 과정에 사용됨

 

 PE 재배치 

  •  PE 파일(EXE/DLL/SYS)이 프로세스 가상 메모리에 로딩될 때 PE 헤더의 ImageBase 주소에 로딩
  •  PE 파일 재배치
    • DLL(SYS) 파일의 경우 ImageBase 위치에 이미 다른 DLL(SYS) 파일이 로딩되어 있다면 다른 비어 있는 주소 공간에 로딩
    • ImageBase에 로딩되지 못하고 다른 주소에 로딩될 때 수행되는 일련의 작업들

 DLL/SYS 

  • TEST.exe 프로세스에 A.DLL이 10000000 주소에 로딩
  • B.DLL이 같은 주소 10000000에 로딩 시도 -> 비어 있는 주소(3C000000)에 로딩시킴

 EXE 

  • 프로세스가 생성될 때 EXE 파일이 가장 먼저 메모리에 로딩되기 때문에 EXE는 재배치를 고려할 필요 없음
  • 그러나, 보안 강화를 위해 ASLR 기능이 추가됨 
    • ASLR(Address Space Layout Randomization) : EXE 파일이 실행될 때마다 랜덤한 주소에 로딩
    • 더 자세한 내용은 41장 참고
  • DLL도 ASLR기능으로 인해 매 부팅 시마다 ImageBase가 달라짐

 

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

: notepad.exe 프로그램을 통해 PE 재배치 확인

 

1) PEview를 통한 ImageBase 값 확인

  • notepad.exe의 ImageBase는 01000000

2) OllyDbg를 통해 notepad.exe EP코드 살펴보기 

  • 재실행[Ctrl+F2]할 때마다 위 그림에 표시된 주소 값이 로딩 주소에 맞게 매번 결정됨
    • 로딩주소 : 00130000
  • GetStartupInfo : STARTUPINFO 구조체를 반환
    • STARTUPINFO 구조체 : 프로세스 속성 지정

 PE 재배치 동작 원리 

  • 기본 동작 원리
    • 프로그램에서 하드코딩된 주소 위치를 찾는다.
    • 값을 읽은 후 ImageBase만큼 뺀다(VA -> RVA)
    • 실제 로딩 주소를 더한다(RVA -> VA)
  • 이를 위해, PE 파일 내부에 Relocation Table이 존재
    • Relocation Table : 하드코딩 주소들의 옵셋(위치)을 모아 놓은 목록
    • 찾는 방법 : PE 헤더의 Base Relocation Table 항목을 따라감.

 

 Base Relocation Table 

  • Base Relocation Table 주소 : PE 헤더의 DataDirectory 배열의 여섯번째 항목(Index 5)

 

  • PEView에서 notepad.exe의 Base Relocation Table 주소 확인

  • 주소 = RVA 2F000

  • 하드코딩 주소들의 옵셋(위치)들이 나열되어있음. 

 IMAGE_BASE_RELOCATION 구조체 

  • 구조체 멤버
    • VirtualAddress : 기준 주소(Base Address), RVA 값
    • SizeOfBlock : 각 단위 블록의 크기
    • (주석)TypeOffset : 해당 구조체 밑으로 WORD 타입의 배열이 따라온다는 의미. 이 배열이 하드코딩된 주소들의 옵셋

 

 Base Relocation Table의 해석 방법 

RVA Data Comment
0002F000 00001000 VirtualAddress
0002F004 00000150 SizeOfBlock
0002F008 3420 TypeOffset
0002F00A 342D TypeOffset
0002F00C 3436 TypeOffset
  • VirtualAddress 값 : 1000, SizeOfBlock : 150
  • 따라서, TypeOffset 배열의 기준(시작) 주소는 RVA 1000, 블록의 전체 크기는 150
  • TypeOffset 크기는 2바이트(16비트), Type(4비트)와 Offset(12비트)가 합쳐진 형태
    • ex) TypeOffset 값 : 3420, Type : 3, Offset : 420
    • Type 일반 값은 3, 64비트에서는
    • 하위 12비트가 진짜 Offset
  • VirtualAddress(1000) + Offset(420) = 1420(RVA)

 실습 

: Notepad.exe

 

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

  • 하드코딩 주소의 옵셋(위치) : 위에서 구한 RVA 1420
  • PEView

  • 하드코딩된 주소 010010C4

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

010010C4 - 01000000 = 000010C4

 

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

로딩 주소를 00AF0000으로 가정,

000010C4 + 00AF0000 = 00AF10C4

  •  PE 로더는 보정된 값(00AF10C4)에 덮어쓴다.
  • 이 과정을 모든 TypeOffset에 대해 반복하면 PE 재배치 작업이 수행된 것