Skip to content

Latest commit

 

History

History
63 lines (55 loc) · 4.55 KB

File metadata and controls

63 lines (55 loc) · 4.55 KB

<- .file-formats[PE Files] ->


Overview


PE file format overview


PE File In Memory


PE file in memory


Virtual Address(VA) To File Offset Translation


  • file_offset = VA - image_base - section_base_RVA + section_file_offset
    1. VA - image_base = RVA. RVA (Relative Virtual Address) is virtual address relative to the image base (HMODULE). It is used to avoid hardcoded memory addresses since the image base might not always get loaded to its preferred load address. As a result, address obtained from disassembler might not match the address obtained from a debugger
    2. RVA - section_base_RVA = offset from base of the section
    3. offset_from_section_base + section_file_offset = file offset on disk

DOS Header


  • Starts at offset 0. The 2 fields of interest in the DOS header are e_magic and e_lfanew. e_magic contains the magic number 0x5A4D (MZ). e_lfanew contains PE header's file offset
  • e_lfanew field is necessary since PE Header does not directly follows DOS Header. In between is the DOS Stub, which for backward compatibility prints "This program cannot be run in DOS mode" if a 32-bit PE file is ran in a 16-bit DOS environment

PE Header (IMAGE_NT_HEADERS)


  • Signature: always 0x00004550 ("PE00")
  • IMAGE_FILE_HEADER (COFF Header): contains basic information on the file (e.g. target CPU, number of sections). Always 20 bytes long
  • IMAGE_OPTIONAL_HEADER32 (PE Optional Header): contains most of the meaningful information. Can be further broken down into 3 parts:
    • Standard Fields: notable fields are MagicNumber and AddressOfEntryPoint
      • MagicNumber: determines whether the file uses 64-bit address space (PE32+) or 32-bit address space. PE32+ contained widened PE Optional Header
      • AddressOfEntryPoint: RVA to the entry point function
    • Windows Specific Fields (Additional Fields): notable fields are ImageBase, SectionAlignment, and SizeOfImage
      • ImageBase: preferred address when loading into memory
      • SectionAlignment: alignment for section when loading into memory such that a section's VA will always be a multiple of this value
      • SizeOfImage: size of image starting from image base to the last section rounded to the nearest multiple of SectionAlignment
    • Data Directory (IMAGE_DATA_DIRECTORY): array of IMAGE_DATA_DIRECTORY structures that contains RVAs and sizes of many important data structures (e.g. imports, exports, base relocations). Locations of those data structures reside in sections. Data structures allows loader to quickly locate an important section. Here are the notable IMAGE_DATA_DIRECTORY entries:
      • Program Exception Data: pointed by IMAGE_DATA_DIRECTORY's entry IMAGE_DIRECTORY_ENTRY_EXCEPTION. It is an exception table that contains an array of IMAGE_RUNTIME_FUNCTION_ENTRY structures. Each IMAGE_RUNTIME_FUNCTION_ENTRY contains the address to an exception handler
      • Base Relocations: pointed by IMAGE_DATA_DIRECTORY's entry IMAGE_DIRECTORY_ENTRY_BASERELOC. Refers to as the .reloc section. Contains every location that needs to be rebased if the executable doesn't load at the preferred load address

Section Header Table (IMAGE_SECTION_HEADERs)


  • Comes right after PE Header. Each IMAGE_SECTION_HEADER contains information on a section, such as a section's virtual address or its pointer to data on disk
  • 2 sections can be merged into a single one if they have similar attributes
    • .idata is often merged into .rdata in release-mode executable

Overlay


  • data appended to end of a PE File. It is not mapped into memory

ELF Files <- RERM[.file-formats] -> Obfuscation