0
votes

I have 2 questions:

  1. The Pe32 header consists of many subheaders. One of them is the optional header. MSDN says that the last element of IMAGE_OPTIONAL_HEADER is a pointer to the first IMAGE_DATA_DIRECTORY struct of the executable. When I look into the WIN32N.INC for NASM everything is the same as listed in MSDN with the difference that the pointer to the first struct has the size 8 bytes instead of 4 (like a normal 32bit pointer):

    STRUCT IMAGE_OPTIONAL_HEADER
        .Magic RESW 1
        ...
        .DataDirectory RESQ 1 <----- why RESQ?
    ENDSTRUC
    
  2. When I want to copy the 16 DataDirectories out of the binary data I stored as a "variable" in NASM into an struct: Is it ok to create a struct with 32 entries (Export Directory RVA + size, Import Directory RVA + size, etc...) and have the pointer to the first DataDirectory struct in the optional header point to its beginning? Because otherwise there would be no way to get from the first element to the other ones, wouldn't it?

Can someone explain this?

1

1 Answers

4
votes

DataDirectory is an array of structs, not a pointer.

MSDN tells you that the layout is actually

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

and your .INC file just defines it as a QWORD for some unknown reason.

WinNT.h in the SDK defines the optional header as:

  ...
  DWORD   NumberOfRvaAndSizes;
  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

where IMAGE_NUMBEROF_DIRECTORY_ENTRIES is 16.

You should not just copy 16 items, the NumberOfRvaAndSizes member specifies the size and it could be < 16.