0
votes

I'm trying to recode an existing EXE from scratch and having a problem figuring out what value the IMAGE_OPTIONAL_HEADER struct element "DataDirectory" has.

It's part of the Pe32 header.

I'm using NASM and the WIN32N.INC file.

I know that the IMAGE_OPTIONAL_HEADER struct element "DataDirectory" has the size DQ. Thats because the struct "DataDirectory" has the elements "VirtualAddress" and "isize" which are both DD.

STRUC IMAGE_DATA_DIRECTORY
.VirtualAddress RESD 1
.isize RESD 1
ENDSTRUC

STRUC IMAGE_OPTIONAL_HEADER
.Magic RESW 1
.MajorLinkerVersion RESB 1
.MinorLinkerVersion RESB 1
.SizeOfCode RESD 1
.SizeOfInitializedData RESD 1
.SizeOfUninitializedData RESD 1
.AddressOfEntryPoint RESD 1
.BaseOfCode RESD 1
.BaseOfData RESD 1
.ImageBase RESD 1
.SectionAlignment RESD 1
.FileAlignment RESD 1
.MajorOperatingSystemVersion RESW 1
.MinorOperatingSystemVersion RESW 1
.MajorImageVersion RESW 1
.MinorImageVersion RESW 1
.MajorSubsystemVersion RESW 1
.MinorSubsystemVersion RESW 1
.Reserved1 RESD 1
.SizeOfImage RESD 1
.SizeOfHeaders RESD 1
.CheckSum RESD 1
.Subsystem RESW 1
.DllCharacteristics RESW 1
.SizeOfStackReserve RESD 1
.SizeOfStackCommit RESD 1
.SizeOfHeapReserve RESD 1
.SizeOfHeapCommit RESD 1
.LoaderFlags RESD 1
.NumberOfRvaAndSizes RESD 1
.DataDirectory RESQ 1
ENDSTRUC

So what exact values does the DataDirectory elements have? There are way more Data Directory then just one. Like Export directory RVA + size, Import directory RVA + size etc.

Do I just put the Offset of the first virtual Address in "VirtualAddress" and its size in "isize"? That would be my guess but I'm not sure about it.

2

2 Answers

3
votes

It is an array of IMAGE_DATA_DIRECTORY structs. MSDN tells you what the struct looks like:

typedef struct _IMAGE_DATA_DIRECTORY {
  DWORD VirtualAddress;
  DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

The NumberOfRvaAndSizes field tells you how many there are. Usually 16 but there can be fewer.

Each directory tells you the offset and size of the thing they "point" to. The IMAGE_DIRECTORY_ENTRY_* defines tells you what they are. For example, IMAGE_DIRECTORY_ENTRY_DEBUG is 6 and tells you the location of IMAGE_DEBUG_DIRECTORY and the total size of it and it's data.

For more information, see the PE/COFF format documentation and the Matt Pietrek "An In-Depth Look into the Win32 Portable Executable File Format" and "Peering Inside the PE: A Tour of the Win32 Portable Executable File Format" MSDN/MSJ articles.

0
votes

Each entry contains an RVA and size.
The most important ones are:
the one at index 0 [export directory],
the one at index 1 [import directory],
the one at index 5 [relocation table].

Now, depending on what you try to achieve, this table may be completely useless to you.
It is, in fact, a kind of "shortcut" for the loader, allowing it to quickly lookup particular portions of data without having to iterate all the section header table stuff before. Thus, it is really only usefull for execution-time. If you just want to inspect the PE-file without it beeing loaded into virtual memory, it will not provide any usefull information.

As Anders already told, there are usually 16 of them, although in my PE-file I'm currently researching I can find only 10 (as the field NumberOfRvaAndSizes tells me, essentially the last entry of the optionla header, you called it .DataDirectory and seem to have found it to be a QUADWORD, but fyi it should really be a DOUBLEWORD. At least if I interpret your RESQ entry correctly).

EDIT: Turned out that there are indeed 16 entries, since the value "10" is in hexadecimal form...