security/리버싱핵심원리

PE 재배치

민사민서 2023. 3. 11. 23:01

[Base Relocation Table]

Base Relocation Table 주소 = IMAGE_OPTIONAL_HEADER32.DataDirectory[6] 통해 구함

.reloc 섹션에 존재한다

// Relocation Table (구조체 + WORD 타입 배열)
// RVA=1000 단위로 블록 하나씩 추가됨
typedef struct _IMAGE_BASE_RELOCATION {
    DWORD VirtualAddress; // RVA
    DWORD SizeOfBlock; // Size of Relocation Table
} IMAGE_BASE_RELOCATION;
WORD TypeOffset[N]; // N = (SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION))/2

TypeOffset 값은 Type(상위 4bit) + Offset(하위 12비트) 합쳐진 형태

- 32bit PE:3, 64bit PE:A, 재배치 안함:0

구조체의 VirtualAddress 값에 TypeOffset 원소의 offset 값을 합치면 => 재배치 필요한(하드코딩된) 곳의 RVA

 

TypeOffset 배열은 NULL 값으로 끝난다, 0x1000 단위로 Relocation Table 새로 생김

ex) VirtualAddress(1000) + Offset(420) = 1420(재배치가 필요한 곳의 RVA)

ex) VirtualAddress(2000) + Offset(00D) = 200D(재배치가 필요한 곳의 RVA)

ex) VirtualAddress(2000) + Offset(016) = 2016(재배치가 필요한 곳의 RVA)

 

[.reloc 섹션 제거 - notepad.exe]

1. IMAGE_FILE_HEADER의 섹션 수 0x1 감소

 - Number of Sections 4->3

2. IMAGE_OPTIONAL_HEADER의 Size of Image 0x1000 감소

 - .reloc section's virtual size 0xE34 => section alignment 맞게 확장 시 0x1000

 - Size of Image 0x30000->0x2F000

 - Size of Image 잘못 세팅 시 "Program is not a valid win32 application" 오류 뜬다

3. .reloc 섹션 헤더 널 패딩으로 채우기

 - 물리적으로 제거해버리면 뒤 섹션 바디들의 RVA 값 전부 꼬여서 안 됨

 - HXD의 선택 영역 채우기 사용하면 ez

4. .reloc 섹션 바디 물리적으로 제거

 

[.minseo 섹션 추가 - notepad.exe]

1. .minseo 섹션 헤더 추가

 - 0x278~0x29F 위치에 BOUND IMPORT Directory Table 존재함. 

 - Null padding으로 채워도 잘 동작. 여기다가 .minseo section 헤더 추가해볼까?

 - Name = ".minseo"

 - Virtual Size = 0xE00
 - RVA = RVA of .reloc + Virtual Size of .reloc = 0x2F000 + 0x1000(Section Alignment) = 0x30000
 - Size of Raw Data = 0x1000
 - Pointer to Raw Data = .reloc의 Pointer to Raw Data + Size of Raw Data = 0x2AE00 + 0x1000 = 0x2BE00
 - 12byte = 0
 - Characteristics = Write+Read+Executable+doesn't contain code/uninitialized/initialized data = 0xE0000000

 

2. PE 헤더 수정

 - IMAGE_FILE_HEADER의 Num of sections 4=>5

 - IMAGE_OPTIONAL_HEADER의 Size of Image 0x30000 => 0x31000

 

3. .minseo Section body 추가

 - 0x2BE00 ~ 0x2CDFF까지 파일 크기 0x1000만큼 늘린다

// 응용 프로그램을 제대로 시작하지 못했습니다 (0xc000007b) - Bound IDT 덮어쓴 것 때문??

Bound imports allow an executable to specify which modules it wants to bind to at load time, instead of at runtime when the import table is processed.

When an executable has bound imports, the operating system checks the bound import directory table during the loading process to see if the requested modules are already loaded into memory.

Therefore, the bound import directory table serves a different purpose than the import directory table in the .text section. It is not redundant and removing it may affect the functionality of the executable.

 

// .reloc 섹션 헤더 끝(0x298)부터 PE 헤더 끝(0x3FF)까지 NULL padding으로 차 있는 reloc.exe 실습 파일로 해보면 잘 동작한다!!

'security > 리버싱핵심원리' 카테고리의 다른 글

인라인 패치 - unpackme#1  (0) 2023.03.14
UPack 파일 분석 - HXD, Ollydbg  (0) 2023.03.12
UPX 압축  (0) 2023.03.11
tiny PE 분석  (0) 2023.03.11
PE File Format 정리  (0) 2023.03.09