reversing

NT header, Section header

hauni 2025. 2. 12. 23:10

NT header

IMAGE_NT_HEADERS 구조체

signature은 PE값을 가짐. (dos에서 MZ를 갖는 것처럼)

  • IMAGE_FILE_HEADER //FileHeader << 이것도 구조체
    • WORD machine;
      • CPU 호환칩의 고유한 번호를 저장
    • WORD NumberOfSections;
      • PE파일은 코드, 데이터, 리소스 등이 각각 섹션에 나뉘어 저장되는데, 섹션 개수를 알려주는 것. 이 값은 무조건 0보다 커야 한다. 실제 개수와 섹션의 개수가 다르다면 실행이 되지 않는다.
    • WORD SizeOfOpticalHeader;
      • IMAGE_OPTIONAL_HEADER32의 크기를 알려줌. 운영체제 때문에 명시하는 것.
    • WORD Characteristics;
      • 파일 속성을 나타내는 값. 파일 속성이란, 실행 가능한 형태인지 DLL 파일인지 정보를 Bit OR로 저장한다.
      • Characteristics 가 없는 파일도 존재한다 (obj, res.dll)

NT Header - Optional Header

PE 헤더에서 가장 큰 구조체가 optional header

  • IMAGE_OPTIONAL_HEADER32
    • WORD magic;
      • 구조체의 크기를 나타냄. 사이즈를 담는 멤버
    • DWORD AddressOfEntryPoint;
      • 엔트리 포인트 EP의 RVA 상대주소의 값을 가지고 있음
      • 프로그램의 최초로 실행되는 코드의 시작주소로 매우 중요
    • DWORD ImageBase;
      • 프로세스의 가상 메모리는 0~FFFFFF의 범위이다 (32bit)
      • 광활한 메모리에서 PE 파일이 로드되는 시작 주소를 나타냄
      • PE 로더가 PE 파일을 실행하기 위해 프로세스를 생성하고 파일을 메모리에 로드한 후 EIP(RIP) 레지스터 값을 ImageBase + AddressOfEntryPoint 포인터 값으로 세팅한다
      • 매핑: 메모리에 파일을 적재하는 것의 정의
      • 로드: 매핑을 실제로 하는 것
      • EP와 IB의 차이점: IB는 실행파일이 로드될 때 Base Address 기본 주소를 나타내는 값. EP는 실행파일이 시작될 때 실행되는 함수의 주소. → EP와 IB는 모두 파일의 메모리의 로딩과 관련이 있지만, IB는 실행파일의 기본 주소를, EP는 실행파일 내의 시작 함수의 주소를 나타낸다.
    • DWORD SectionAlignment; & DWORD FileAlignment;
      • PE 파일의 바디부분은 섹션으로 나뉨. 파일에서 섹션의 최소단위를 나타내는 것이 FileAlignment 이고, 메모리에서 섹션의 최소 단위를 나타내는 것이 SectionAlignment임.
    • DWORD SizeOfImage;
      • PE 파일이 메모리에 로딩되었을 때 가상메모리 PE IMAGE가 차지하는 크기를 나타낸다. 일반적으로 파일의 크기와 메모리의 로딩된 파일의 크기는 다르다.
    • DWORD SizeOfHeaders;
      • PE 파일 전체의 크기를 나타냄
    • WORD Subsystem;
      • .sys인지 .dll or .exe인지 구별
    • DWORD NumberOfRvaAndSizes;
      • IMAGE_OPTIONAL_HEADER32의 마지막 멤버인 DataDirectory의 배열의 개수를 나타냄
    • IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
      • IMAGE_OPTIONAL_HEADER32 구조체의 배열

Section Header

각 섹션의 속성을 정의한 것이 섹션헤더이다…

code, data, rsrc 3가지로 나누어서 섹션을 저장하는 이유가 있다

  1. 프로그램 복잡함 감소
  2. 프로그램 안전성

→ code, data, rsrc 마다 각각의 섹션별로 권한이 주어져 있다

code: 실행, 읽기 권한

data: 비실행, 읽기 권한

rsrc: 비실행, 읽기 권한

IMAGE_SECTION_HEADER

DWORD VirtualSize; : 메모리에서 섹션이 차지하는 크기

DWORD VirtualAddress; : 메모리에서 섹션의 시작주소(RVA = 상대주소)

VA → 절대주소 아님

DWORD SizeOfRawData; : 파일에서 섹션이 차지하는 크기

DWORD PointerToRawData; : 파일에서의 섹션의 시작주소

DWORD Characteristics; : 섹션의 속성을 bit or 연산으로 저장

VirtualAddress, PointerToRawData 는 아무 값이나 가질 수 없음