Search code examples
windowsportable-executable

Which PE header fields are used by windows loader?


I'm trying to understand PE header files produced by an executable compressor.

I've been told all the header fields that Windows uses in this case are intact. All other, on the other hand, contain complete garbage from the PE header perspective. I'm trying to understand which ones are relevant ones.

Let's say I got this IMAGE_DOS_HEADER:

enter image description here

And this IMAGE_FILE_HEADER:

enter image description here

When I open my executable on the debugger, it immediately stops at this address:

CPU Disasm
Address   Hex dump          Command                                  Comments
0040005C    53              PUSH EBX

So, how does the debugger knows 0x0040005C is the location it needs to start debugging at? What'd be the formula to calculate this "entry point" address?

I guess the main question here is, which PE header files are relevant from the windows perspective loader and which ones will be used for some other purposes by these type of packers?


Solution

  • from IMAGE_DOS_HEADER only e_magic (for check) and e_lfanew(offset to IMAGE_NT_HEADERSXX (32 or 64) ) used. you need look for IMAGE_NT_HEADERS fields. entry point calc very easy

    PIMAGE_DOS_HEADER ImageBase;
    if (ImageBase->e_magic == IMAGE_DOS_SIGNATURE)
    {
        union {
            PVOID pv;
            PIMAGE_NT_HEADERS32 pinth32;
            PIMAGE_NT_HEADERS64 pinth64;
    
        };
        pv = RtlOffsetToPointer(ImageBase, ImageBase->e_lfanew);
        DWORD AddressOfEntryPoint = 0;
        switch (pinth32->OptionalHeader.Magic)
        {
        case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
            AddressOfEntryPoint = pinth32->OptionalHeader.AddressOfEntryPoint;
            break;
        case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
            AddressOfEntryPoint = pinth64->OptionalHeader.AddressOfEntryPoint;
            break;
        }
        PVOID EntryPoint = AddressOfEntryPoint ? RtlOffsetToPointer(ImageBase, AddressOfEntryPoint) : 0;
    }
    

    so look to IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint

    When I open my executable on the debugger, it immediately stops at this address:

    bad debugger :) good must stop at LdrInitializeThunk