https://www.youtube.com/playlist?list=PLY12b4RRLcSdsxgVvTW3mnNzMjVrd8JhO
위의 강의를 11-13강까지를 수강하여 학습한 다음 어려운 내용에 관해서 질의 응답하는 시간을 가졌다.
<11강 DOS stub>
▷DOS stub
-DOS header와 달리 DOS stub은 옵션이다.
-MS-Dos(마이크로소프트 사에서 만든 최초의 운영체제)에서만 실행되는 코드이므로 Window OS에서는 실행X
-이 특성을 잘 이용한다면 윈도우와 도스 두 개 다 실행 가능한 파일을 만들 수 있다.
DOS header에 있는 구조체의 첫 번째 맥락 'MZ'이다. 그러므로 문자열 MZ를 검색하여 빠르게 DOS header의 위치를 찾는다.
4D 5A 발견
밑줄 친 50 45 PE는 NT header의 첫번째 줄 시작 부분이다.
⇒ 그러므로 현재 이 파일에는 DOS stub이 없음을 확인할 수 있다.
※그렇다면 DOS stub이 있는 경우의 hex 값은 어떻게 될까?
<12강 NT Header-FileHeader>
▷ NT Header
IMAGE_NT_HEADERS라는 구조체로 구성되어 있다.
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
1. DWORD Signature;
-PE 값을 가짐
2.IMAGE_FILE_HEADER FileHeader;
▶machine : CPU 호환칩의 고유한 번호를 저장
4C 01 → 01 4C(리틀 엔디언 방식)
(참고: 014C는 32bit intel 호환칩에서 사용되는 값)
▶numberofsections:
PE파일은 코드, 데이터, 리소스 등이 각각 섹션(부분)에 나누어 저장되는데 PE파일에서 생성 된 개수를 알려준다.
이 값은 무조건 0보다 커야 한다.
ex) NumberOfSections=1; 원래 Sections의 개수가 3개라면 오류 발생→ 섹션의 개수와 실제 섹션이 다르면 실행 X
▶SizeOfOptionalHeader:
IMAGE_OPTIONAL_HEADER32 OptionalHeader; 의 크기를 나타냄.
💡 C언어에서 구조체를 생성하면서 구조체의 크기를 이미 크기를 정한 상태로 생성하는데 굳이 SizeOfOptionalHeader를 생성해서 크기를 알려주는 이유는?
→ 64bit를 사용 시 값이 달라지기 때문이다.
▶ Characteristics :
파일 속성을 나타내는 값이다. 여기서 파일 속성이란 실행 가능한 형태(executable) 혹은 DLL 파일인지 정보를 저장한다.(Bit OR 형태로 저장)
- *Characteristics 값이 없는 파일이 존재한다-obj, res.dll
- 참고) TimeDateStamp는 파일이 빌드된 시간을 저장
<13강 NT Header - OptionalHeader>
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
Optionalheader의 구조체는 IMAGE_OPTIONAL_HEADER32
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
▶Magic
구조체의 크기를 나타낸다.
IMAGE_OPTIONAL_HEADER32 10B
IMAGE_OPTIONAL_HEADER64 20B
▶AddressOfEntryPoint
EP(Entry Point)의 RVA(상대주소) 값을 가지고 있다. 프로그램의 최초로 실행되는 코드에 시작주소로 매우 중요하다.
▶ImageBase
프로세스의 가상 메모리는 0~FFFFFF 범위이다.
(32bit) ImageBase는 위의 광활한 메모리에서 PE파일이 로드되는 시작주소를 나타낸다.
PE로더는 PE파일을 실행하기 위해 프로세스를 생성하고 파일을 메모리에 로드한 후 EIP[32bit](RIP[64bit]) Reg 값을 ImageBase+AddressOfEntryPoint를 Point값으로 세팅한다.
*EIP: CPU가 다음 실행할 명령어
*EIP: CPU가 다음 실행할 명령어
💡 로드 VS 매핑
매핑은 간단히 말해서 메모리에 파일을 적재하는 것 로드는 매핑을 실제로 하는 것
<Entry point와 ImageBase의 차이점>
ImageBase는 실행파일이 로드될 때 BaseAddress(기본주소)를 나타내는 값이다.
Entry point 실행파일이 시작될 때 실행되는 맨 처음 함수의 주소를 나타내는 값이다.
⇒ ImageBase와 Entry point는 모두 파일의 메모리에 로딩과 관련이 있지만 ImageBase는 실행파일의 기본주소를, Entry point는 실행파일 내의 시작 함수의 주소를 나타낸다.
*BaseAddress(기본주소): 기본주소에 오프셋을 더하면 절대주소를 획득 가능
▶SectionAlignment & FileAlignment
PE파일의 바디 부분은 섹션으로 나뉜다. 파일에서 섹션의 최소 단위를 나타내는 것이 FileAlignment이고 메모리에서 섹션의 최소 단위를 나타내는 것이 SectionAlignment이다.
▶ SizeOfImage
PE파일이 메모리에 로딩되었을 때 가상메모리 PE IMAGE가 차지하는 크기를 나타낸다. 일반적으로 파일의 크기와 메모리의 로딩된 파일의 크기는 다르다.
▶ SizeOfHeaders
PE파일의 전체 크기를 나타낸다.
▶ Subsystem
<sys>인지 dll or exe를 구별한다(=시스템 파일인지 아닌지를 구별)
▶NumberOfRvaAndSizes
IMAGE_OPTIONAL_HEADER32의 마지막 멤버인 DataDirectory의 배열의 개수를 나타낸다.
▶ DataDirectory
IMAGE_OPTIONAL_HEADER32의 배열
'2. Reversing (리버싱)' 카테고리의 다른 글
[2024.05.18] 리버씽씽카 6주차 활동 (0) | 2024.05.19 |
---|---|
[2024.05.11] 리버씽씽카 5주차 활동 (0) | 2024.05.13 |
[2024.03.30] 리버씽씽카 3주차 활동 (0) | 2024.03.30 |
[2024.03.23] 리버씽씽카 2주차 활동 (1) | 2024.03.23 |
[2023.11.04] 리버싱 5주차 팀활동 (0) | 2023.11.10 |