PE Bear - looking inside
Video Contents
- Short PE-bear introduction [0:00]
- Analyzing PE file using PE-bear [0:26]
- Viewing section headers [1:11]
- Viewing resources [1:50]
- Analyzing PE file using dumpbin.exe [3:15]
Addendum
Key Windows API Structures
IMAGE_DOS_HEADER
represents the DOS header of a PE file and is primarily used for compatibility reasons with older versions of Windows that used the MS-DOS executable format.
IMAGE_DOS_HEADER
has the following structure:
typedef struct IMAGEDOS_HEADER {
WORD e_magic; // magic number (signature) used to identify the file format. In a valid PE file, this field should contain IMAGE_DOS_SIGNATURE (0x5A4D)
WORD e_cblp; // number of bytes on the last page of the file. This value is typically 0 and is used for alignment purposes
WORD e_cp; // number of pages in the file. This value is also used for alignment and is typically 0
WORD e_crlc; // number of relocation entries in the file. In modern PE files, this value is usually 0
WORD e_cparhdr; // size of the header in paragraphs. The value is typically 4 and is used for calculating the offset to the PE header
WORD e_minalloc; // minimum number of extra paragraphs (beyond the header) required by the program
WORD e_maxalloc; // maximum number of extra paragraphs (beyond the header) required by the program
WORD e_ss; // initial value of the SS (stack segment) register
WORD e_sp; // initial value of the SP (stack pointer) register
WORD e_csum; // checksum of the executable file. This field is often set to 0
WORD e_ip; // initial value of the IP (instruction pointer) register
WORD e_cs; // initial value of the CS (code segment) register
WORD e_lfarlc; // file address of the relocation table. This field is typically set to IMAGE_FIRST_SECTION_OFFSET (0x40)
WORD e_ovno; // overlay number. This field is typically 0 and is used when the executable has multiple overlays
WORD e_res[4]; // array of reserved words
WORD e_oemid; // OEM identifier. This field is often set to 0
WORD e_oeminfo; // OEM-specific information associated with e_oemid
WORD e_res2[10]; // Another array of reserved words
LONG e_lfanew; // file address of the new PE header. This field points to the beginning of the PE header in the file
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
IMAGE_NT_HEADERS structure is primarily used to locate and interpret the different sections and headers within the PE file. It contains essential information about the PE file, such as its architecture, entry point, and various optional headers.
The IMAGE_NT_HEADERS
is defined in the winnt.h header file and has the following structure (description for both 32- and 64-bit versions):
typedef struct IMAGE_NT_HEADERS {
DWORD Signature; // Indicates the PE file format's signature. It helps identify the file format as a PE file
IMAGE_FILE_HEADER FileHeader; // Instance of IMAGE_FILE_HEADER structure, containing info such as the target machine, number of sections, time stamp, etc.
IMAGE_OPTIONAL_HEADER32 OptionalHeader; // Provides detailed information about the PE file, including its entry point, image base address, sections, imports, exports
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct IMAGE_NT_HEADERS64 {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
IMAGE_FILE_HEADER structure contains generic information about the PE file.
The IMAGE_FILE_HEADER
is defined in the winnt.h header file and has the following structure:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; // architecture type of the computer, ex. x86, x64, Itanium
WORD NumberOfSections; // number of sections (limit: 96)
DWORD TimeDateStamp; // represents the date and time the image was created by the linker
DWORD PointerToSymbolTable; // offset of the symbol table (in bytes)
DWORD NumberOfSymbols; // number of symbols in the symbol table
WORD SizeOfOptionalHeader; // size of the optional header (in bytes)
WORD Characteristics; // characteristics of the image, ex. executable image, system file, DLL, etc.
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;ddd
IMAGE_OPTIONAL_HEADER structure provides crucial information to the loader. The name of the structure is misleading, as all image files are required to have it (although not all PE files do, ex. object files).
The IMAGE_OPTIONAL_HEADER
is defined in the winnt.h header file and has the following structure (description for both 32- and 64-bit versions):
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic; // state of the image file, ex. IMAGE_NT_OPTIONAL_HDR32_MAGIC, IMAGE_NT_OPTIONAL_HDR64_MAGIC, etc.
BYTE MajorLinkerVersion; // major version number of the linker
BYTE MinorLinkerVersion; // minor version number of the linker
DWORD SizeOfCode; // size of the code section (in bytes)
DWORD SizeOfInitializedData; // size of the initialized data section (in bytes)
DWORD SizeOfUninitializedData; // size of the uninitialized data section (in bytes)
DWORD AddressOfEntryPoint; // pointer to the entry point function, relative to the image base address
DWORD BaseOfCode; // pointer to the beginning of the code section, relative to the image base
DWORD BaseOfData; // pointer to the beginning of the data section, relative to the image base
DWORD ImageBase; // preferred address of the first byte of the image when it is loaded in memory (multiple of 64 kB)
DWORD SectionAlignment; // alignment of sections loaded in memory (in bytes)
DWORD FileAlignment; // alignment of the raw data of sections in the image file (in bytes)
WORD MajorOperatingSystemVersion; // major version number of the required OS
WORD MinorOperatingSystemVersion; // minor version number of the required OS
WORD MajorImageVersion; // major version number of the image
WORD MinorImageVersion; // minor version number of the image
WORD MajorSubsystemVersion; // major version number of the subsystem
WORD MinorSubsystemVersion; // minor version number of the subsystem
DWORD Win32VersionValue; // member is reserved and must be 0
DWORD SizeOfImage; // size of the image, including all headers (in bytes)
DWORD SizeOfHeaders; // combined size of the following items: e_lfanew (from IMAGE_DOS_HEADER), 4 byte signature, size of IMAGE_FILE_HEADER, size of optional header, size of all section headers
DWORD CheckSum; // image file checksum
WORD Subsystem; // subsystem required to run this image, ex. native, GUI, CUI, POSIX, etc.
WORD DllCharacteristics; // DLL characteristics of the image, ex. dynamic base, DEP, CFG, no SEH, etc.
DWORD SizeOfStackReserve; // number of bytes to reserve for the stack
DWORD SizeOfStackCommit; // number of bytes to commit for the stack
DWORD SizeOfHeapReserve; // number of bytes to reserve for the local heap
DWORD SizeOfHeapCommit; // number of bytes to commit for the local heap
DWORD LoaderFlags; // obsolete
DWORD NumberOfRvaAndSizes; // number of directory entries in the remainder of the optional header
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; // array of IMAGE_DATA_DIRECTORY structures, each index number is assiociated with different type of data directory (see below)
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_OPTIONAL_HEADER64 {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
ULONGLONG 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;
ULONGLONG SizeOfStackReserve;
ULONGLONG SizeOfStackCommit;
ULONGLONG SizeOfHeapReserve;
ULONGLONG SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
IMAGE_DATA_DIRECTORY structure holds information about the size and virtual address of specific data used by the system to initialize process, ex. imported DLLs and functions, used resources, digital certificates, etc.
The IMAGE_DATA_DIRECTORY
structure is defined in the winnt.h header file and has the following structure:
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress; // relative virtual address of the table
DWORD Size; // size of the table (in bytes)
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
Each index in DataDirectory[]
of IMAGE_OPTIONAL_HEADER
describes different type of data directory. These are:
NAME VALUE MEANING
================================================================================================
IMAGE_DIRECTORY_ENTRY_EXPORT 0 Export directory
IMAGE_DIRECTORY_ENTRY_IMPORT 1 Import directory
IMAGE_DIRECTORY_ENTRY_RESOURCE 2 Resource directory
IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 Exception directory
IMAGE_DIRECTORY_ENTRY_SECURITY 4 Security directory
IMAGE_DIRECTORY_ENTRY_BASERELOC 5 Base relocation table
IMAGE_DIRECTORY_ENTRY_DEBUG 6 Debug directory
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 Architecture-specific data
IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 The relative virtual address of global pointer
IMAGE_DIRECTORY_ENTRY_TLS 9 Thread local storage directory
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 Load configuration directory
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 Bound import directory
IMAGE_DIRECTORY_ENTRY_IAT 12 Import address table
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 Delay import table
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 COM descriptor table
IMAGE_SECTION_HEADER structure is used to represent a section in a PE (Portable Executable) file. The IMAGE_SECTION_HEADER
structure is defined in the winnt.h header file and has the following structure:
typedef struct IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // A fixed-length array of 8 bytes that represents the name of the section. It is a null-padded string,
union { // A union that can be used to access either the physical address or virtual size of the section.
DWORD PhysicalAddress; // The physical address of the section. This field is only used for object files
DWORD VirtualSize; // The size of the section in memory when loaded (in bytes)
} Misc;
DWORD VirtualAddress; // The virtual address of the section when loaded into memory
DWORD SizeOfRawData; // The size of the section's data on disk (in bytes)
DWORD PointerToRawData; // The file offset (in bytes) to the beginning of the section's data
DWORD PointerToRelocations; // This field is usually set to zero and is used for object files
DWORD PointerToLinenumbers; // This field is usually set to zero and is used for debugging purposes
WORD NumberOfRelocations; // The number of relocation entries for the section. It is set to zero for executable files
WORD NumberOfLinenumbers; // The number of line-number entries for the section. It is also set to zero for executable files
DWORD Characteristics; // A set of flags that define various characteristics of the section, such as its memory access permissions, alignment, and type
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;