In the last post, we dumped the NT header and looked at the file header and the optional header. We also compared the output generated by !dh command with the actual values in the structure dumped using dt command. By now, you already know all the details necessary to execute a program. To start execution of a program, these are the steps that a loader would perform:
Locate the DOS Header
Using the RVA in e_lfanew member of the DOS header, locate the NT Header.
From the NT header, get the optional header and locate the AddressOfEntryPoint member.
This is an RVA, so calculate the actual address and call that address.
Here is the pseudocode:
In our case, the base address was 00007ff63f030000 and AddressofEntryPoint was 0x193e0 (RVA). So the actual address was calculated as 00007ff63f0493e0. You can use the u and uF commands to unassemble code at a given address. For more details type .hh u to view the help file.
As you can see - the Entry Function is not exactly main() or WinMain() - this is just a stub that will call the Runtime’s main function. In my case, WinMainCRTStartup() is the function that was called. After the run time performs its initialization, it calls your main function and proceeds from there.
The next part of you exploration of the PE - involves dumping members of the NT header. The dt command gives you hyperlinks to dump members, you can also dump embedded member structures using dt if their types are known using the syntax dt <type> <address> <member>.. If the member is not a structure but a pointer, then replace . with ->*, so the syntax becomes dt <type> <address> <member>->*.
The DataDirectory member is actually an array of 16 IMAGE_DATA_DIRECTORY structures. The offset of this member is at 0x00007ff63f0300f8 + 0x18 + 0x70 = 0x00007ff63f030180. To dump an array, we use the syntax:
dt -a<number of elements> <type> <address>
These directories each have a special meaning, Here’s the list of the directories and a brief description. I’ll add the remaining as I explore and learn.
Directory
Description
Export table address and size
Contains the export table, which lists the functions exported from this module
Import table address and size
Contains the import table, which lists functions imported by this module
Resource table address and size
Resources added to this module
Exception table address and size
Exception handling information
Certificate table address and size
Base relocation table address and size
Debugging information starting address and size
Symbols and debugging info
Architecture-specific data address and size
Global pointer register relative virtual address
Thread local storage (TLS) table address and size
Thread local storages
Load configuration table address and size
Loader configuration
Bound import table address and size
Import address table address and size
Delay import descriptor address and size
The CLR header address and size
Contains information for use by CLR if this is a .NET assembly
Reserved
well, that’s it for now - see you in the next post!