PE File Format
- PE(Portable Executable) file : windows os에서 사용되는 실행 파일 형식
- PE, PE32 - 32bit
- PE+, PE32+ - 64bit
종류 | 주요 확장자 |
실행 계열 | exe, scr |
라이브러리 계열 | dll, ocx, cpl, drv |
드라이버 계열 | sys, vxd |
오브젝트 파일 계열 | obj |
PE 파일 구조
- FIle 에서는 offset으로, 메모리에서는 VA(virtual address)로 위치를 표현
- 파일의 내용은 보통 .text, .data, .rsrc 섹션에 나눠 저장된다.
- 섹션 헤더에 각 섹션에 대한 파일/메모리에서의 크기, 위치, 속성 등이 정의되어있다.
- NULL padding?
- 섹션의 시작위치는 각 파일/메모리의 최소 기본단위의 배수에 해당하는 위치여야하므로 빈공간을 null로 채움
RVA + ImageBase = VA
- VA (virtual address)
- 프로세스 가상 메모리의 절대 주소
- RVA (Relative virtual address)
- 어느 기준 위치 imagebase 에서부터의 상대 주소
- PE 파일이 프로세스 가상 메모리의 특정 위치에 로딩되는 순간, 이미 그 위치에 다른 PE파일이 로딩되어있을 수 있음
- relocation 재배치로 비어있는 다른 위치에 로딩되어야함
- pe헤더 정보들이 rva로 되어있으면? 재배치가 발생해도 기준위치에 대한 상대주소가 변하지 않으므로 정상 작동 가능 (va는 X)
- relocation 재배치로 비어있는 다른 위치에 로딩되어야함
PE 헤더
DOS Header
- 필수
- e_magic : DOS signature (4D5A==”MZ”)
- e_lfanew : NT header의 옵셋 표시 (파일에 따라 가변적인 값을 가짐) 아래 000000E0IMAGE_DOS_HEADER
DOS Stub (필수X 옵션)
NT Header
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //PE
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
- File Header
- 파일의 개략적인 속성을 나타내는 IMAGE_FILE_HEADER 구조체
typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; //섹션 개수 >0 DWORD TimeDateStamp; //빌드시간 **DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; //IMAGE_OPTIONAL_HEADER32 구조체 크기 or 64 WORD Characteristics; //파일속성** } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
- Characteristics 값에 0002h없는 경우 (not executable)
- .obj, resource DLL
- IMAGE_FILE_HEADER
- Optional Header
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic; //**IMAGE_OPTIONAL_HEADER32 : 10B, 64: 20B**
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint; //EP의 RVA갖고있음 프로그램이 최초로 시작되는 주소
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase; // PE파일이 로딩되는 시작주소
DWORD SectionAlignment; //메모리에서 섹션의 최소단위
DWORD FileAlignment; //파일에서 섹션의 최소단위
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage; //로딩된 후 PE 이미지가 가상메모리에서 차지하는 크기
DWORD SizeOfHeaders; //PE헤더 전체 크기 FileAlignment 배수
DWORD CheckSum;
WORD Subsystem; //.sys? .exe? .dll?
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes; //밑에 DataDirectory 배열 개수
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
- PE 로더는 PE파일을 실행시키기 위해 프로세스를 생성하고 파일을 메모리에 로딩후 EIP 레지스터 값을 ImageBase + AddressOfEntryPoint로 세팅
- 파일 메모리 섹션 크기 : FileAlignment/SectionAlignment 배수.
- Subsystem
IMAGE_SUBSYSTEM_NATIVE1 | 하위 시스템이 필요하지 않습니다(디바이스 드라이버 및 네이티브 시스템 프로세스). |
IMAGE_SUBSYSTEM_WINDOWS_GUI2 | Windows GUI(그래픽 사용자 인터페이스) 하위 시스템. |
IMAGE_SUBSYSTEM_WINDOWS_CUI3 | Windows CUI(문자 모드 사용자 인터페이스) 하위 시스템. |
- DataDirectory
- 0 export
- 1 import
- 2 resource
- 9 TLS directory
섹션 헤더
- 각 섹션의 속성을 정의
- 메모리 속성별 엑세스 권한
종류 엑세스 권한 code 실행 읽기 data 비실행 읽기 쓰기 resource 비실행 읽기 - IMAGE_SECTION_HEADER
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
**DWORD VirtualSize; //메모리에서 섹션이 차지하는 크기**
} Misc;
**DWORD VirtualAddress; //메모리에서 섹션의 시작주소 rva**
**DWORD SizeOfRawData; //파일에서 섹션이 차지하는 크기**
**DWORD PointerToRawData; //파일에서 섹션의 시작위치**
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
**DWORD Characteristics; //섹션의 속성(bit OR)**
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
- VirtualAddress PointerToRawData는 sectionalignment와 filealignment에 맞게 결정됨
- Name은 null로 끝나지않고 아스키가 안와도됨
RVA to RAW
- PE파일이 메모리에 로딩되었을때 각 섹션에서 메모리주소rva와 파일 옵셋(raw)을 잘 매핑해야함
- RVA가 속한 섹션 찾기
- 간단한 비례식으로 raw계산
💡
RAW-PoinerToRawData = RVA - VirtualAddress
Raw = RVA - VirtualAddress + PointerToRawData
IAT (import Address Table)
- process, memory, DLL 구조 등에 대한 내용 함축,
- 프로그램이 어떤 라이브러리에서 어떤 함수를 사용하고있는지 기술한 테이블
DLL (Dynamic Linked Library)
- 프로그램에 라이브러리를 포함시키지말고 별도의 파일(DLL)로 구성해 필요할때 쓰자
- 일단 한번 로딩된 DLL코드, 리소스는 memery mapping 기술로 process에서 공유해 쓰자
- 라이브러리가 업데이트되었을때 해당 DLL 파일만 교체하면 됨
DLL 로딩 방식 2가지
- Explicit Linking
- 사용되는 순간 로딩, 사용종료시 메모리 해제
- Implicit Linking
- 시작시 로딩, 프로그램 종료시 메모리 해제
- IAT
실제주소를 하드코딩할 수 없는 이유, PE헤더 주소를 RVA써야하는 이유
- 모든 환경에서 A 함수 호출을 보장하기 위해 컴파일러는 A의 실제주소가 저장될 위치를 준비하고 CALL DWORD PTR DS:[실제주소] 형식의 명령어를 적어두기만 한다.
- 파일이 실행되는 순간 PE로더가 해당위치에 A주소를 입력해준다.
- dll relocation 도 발생
IMAGE_IMPORT_DESCRIPTOR
- import : 라이브러리에게 서비스 (함수)를 제공받는 일
- export : 라이브러리 입장에서 다른 pe파일에게 서비스(함수) 제공하는 일
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk; // INT(import name table) 주소 rva
} DUMMYUNIONNAME;
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name; // 라이브러리 이름 문자열 주소 rva
DWORD FirstThunk; //IAT(import address table) 주소 rva
} IMAGE_IMPORT_DESCRIPTOR;
EAT (Export Address Table)
- 라이브러리 파일에서 제공하는 함수를 다른 프로그램에서 가져다 사용할 수 있도록 해주는 방식
- EAT를 통해서만 해당 라이브러리에서 익스포트하는 함수의 시작주소를 정확히 구할 수 있음
IMAGE_EXPORT_DESCRIPTOR
public struct IMAGE_EXPORT_DIRECTORY
{
public UInt32 Characteristics;
public UInt32 TimeDateStamp;
public UInt16 MajorVersion;
public UInt16 MinorVersion;
public UInt32 Name;
public UInt32 Base;
public UInt32 NumberOfFunctions; //실제 ecport 주소
public UInt32 NumberOfNames; // export함수중 이름가지는 함수 개수
public UInt32 AddressOfFunctions; // export 함수 주소 배열
public UInt32 AddressOfNames; //함수 이름 주소 배열
public UInt32 AddressOfNameOrdinals; // ordinal 배열
}
실행 압축
데이터 압축
- 비손실 압축
- 100% 복원
- 데이터 크기 줄여서 보관 및 이동에 용이하게 함
- zip,rar
- Run-Length, Lempel-Ziv, Huffman
- 손실 압축
- 100% 복원 X
- jpg, mp3, mp4
실행 압축
- 실행 파일 대상으로 파일 내부에 압축해제 코드를 포함하고있어 실행되는 순간 메모리에서 압축해제
- 패커
- 실팽파일 압축기
- 프로텍터
- 리버싱코드엔지니어링으로부터 보호하기위한 유틸리티
- 리버싱을 막기위한 기법이 추가
-
'Rev' 카테고리의 다른 글
리버싱 핵심원리 20장 (0) | 2024.10.06 |
---|---|
리버싱 핵심원리 16장 (0) | 2024.09.28 |
KnockOn Bootcamp ROP (0) | 2024.09.18 |
KnockOn Bootcamp memory mitigation bypass (0) | 2024.09.18 |
KnockOn Bootcamp memory mitigation (0) | 2024.09.18 |