


RETURN VALUES
If the function succeeds, the return value is TRUE; otherwise, it is FALSE.
The other fields in the optional header are as follows:
| SectionAlignment | A section needs to be loaded at an address that is a multiple of the section alignment. Refer to the discussion on RVA for more information. |
| FileAlignment | In the file, a section always starts at an offset that is a multiple of the file alignment. This value is some multiple of the sector size. |
| MajorOperatingSystemVersion, MinorOperatingSystemVersion | Minimum operating system version required to execute this file. |
| MajorImageVersion, MinorImageVersion | A developer can use these fields to version his or her files. It can be specified with a linker flag. |
| MajorSubsystemVersion, MinorSubsystemVersion | Minimum subsystem version required to execute this file. |
| Win32VersionValue | Reserved for future use. |
| SizeOfImage | Size of the image after considering the section alignment. This amount of virtual memory needs to be reserved for loading the file. |
| SizeOfHeaders | Total size of the headers, including the DOS header, the PE header, and the section table. The sections containing the actual data start at this offset in the file. |
| CheckSum | This is used only for the kernel-mode drivers/DLLs. It can be set to 0 for user-mode executables/DLLs. |
| Subsystem | Subsystem used by the file. The following values are defined in the WINNT.H file: |
| IMAGE_SUBSYSTEM_NATIVE | Image doesnt require a subsystem. The kernel-mode drivers and native applications such as CSRSS.EXE have this value for the field. |
| IMAGE_SUBSYSTEM_WINDOWS_GUI | File uses the Win32 GUI interface. |
| IMAGE_SUBSYSTEM_WINDOWS_CUI | File uses the character-based user interface. |
| IMAGE_SUBSYSTEM_OS2_CUI | File requires the OS/2 subsystem. |
| IMAGE_SUBSYSTEM_POSIX_CUI | File uses the POSIX API. |
| DllCharacteristics | Obsolete. |
| SizeOfStackReserve | Address space to be reserved for the stack. Only the virtual address space is markedthe swap space is not allocated. |
| SizeOfStackCommit | Actual memory committed for the stack. This much swap space is initially allocated. The committed stack size is increased on demand until it reaches the SizeOfStackReserve. |
| SizeOfHeapReserve | Address space to be reserved for the heap. Similar to the SizeOfStackReserve field. |
| SizeOfHeapCommit | Actual committed heap space. Similar to the SizeOfStackCommit field. |
| LoaderFlags | Obsolete. |
| NumberOfRvaAndSizes | Number of entries in the data directory that follows this field. It is always set to 16. |
| DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] | As mentioned earlier, each entry in the data directory points to some important piece of information. Each of these entries is of the type IMAGE_DATA_DIRECTORY, which is defined as follows: |
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
ImageDirectoryEntryToData()
The VirtualAddress field contains the RVA of the respective piece of information, and the Size field contains the size of the data. To get to the actual data, you need to convert the RVA to the actual address in the memory-mapped PE file. This can be accomplished with the ImageDirectoryEntryToData() function exported by IMAGEHLP.DLL.
PVOID ImageDirectoryEntryToData(
LPVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size
);
PARAMETERS
| Base | Base address where the file is mapped in memory. |
| MappedAsImage | Set this flag to TRUE if the system loader maps the file. Otherwise, set the flag to FALSE. |
| DirectoryEntry | Index into the data directory array. |
| Size | Upon return, the size from the data directory is filled here. |
RETURN VALUES
If the function succeeds, the return value is the address in the memory-mapped file where the required data resides. Otherwise, the function returns NULL.
INDICES IN THE DATA DIRECTORY
Each index in the data directory (except a few at the end that are still unused) represents some important piece of information. In the following sections, we discuss some of the important entries in this directory and the format in which the respective information is stored.
Export Directory
The data directory entry at the IMAGE_DIRECTORY_ENTRY_EXPORT index points to the export directory for the file. The RVA in this directory entry points to the .edata section. The information about the functions exported by the file (generally a DLL) is stored here. The data directory entry points to the export directory that is defined as the IMAGE_EXPORT_DIRECTORY structure in the WINNT.H file. The fields in this structure are as follows:
| Characteristics | Reserved field. Always set to 0. |
| TimeDateStamp | Date and time of creation. |
| MajorVersion, MinorVersion | Developer can set the version of the export table. |
| Name | RVA of the zero-terminated name of the DLL. |
| Base | Starting ordinal for the exported functionsthat is, the least of the ordinals. Generally, this field is 1. |
| NumberOfFunctions | Total number of functions exported from the DLL. |
| NumberOfNames | Number of functions that are exported by name. Some functions may be exported only by ordinal, so this number may be less than NumberOfFunctions. |
| AddressOfFunctions | RVA of an array (lets call it as the export-functions array) that has an entry for each function exported from the DLL. Hence, the size of this array is equal to the NumberOfFunctions field. The entry at index i corresponds to the function exported with ordinal i + Base. Each entry in this array is also an RVA. If the RVA for a particular array entry points within the export section, then it is a forwarder. Forwarder means that the function is not present in this DLL, but it is a forwarder reference to some function in another DLL. In such a case, the RVA points to an ASCIIZ string that stores the name of the other DLL and the function name separated by a period. In case the target DLL exports the function by ordinal, the function name is formed as # followed by the ordinal printed in decimal. For example, the KERNEL32.DLL for Windows NT forwards the HeapAlloc() function to the RtlAllocateHeap() function in the NTDLL.DLL. Hence, the corresponding RVA in this case points to a location within the export section that holds the string NTDLL.RtlAllocateHeap. The Win32 applications can import the HeapAlloc() function from the KERNEL32.DLL without worrying about all these details. When the application runs on Windows 95, the loader resolves the import reference to the function in the KERNEL32.DLL. When the same application runs on Windows NT, the loader finds that the function is forwarded to the NTDLL.DLL. Hence, the loader automatically loads the NTDLL.DLL and resolves the imported function to the RtlAllocateHeap() function. |
When an export-functions array entry is not a forwarderthat is, the RVA does not lie within the export sectionthe RVA points to the entry point of the function or to the location of the exported variable.
The export-functions array may have gaps. This is beacause some ordinals might be left unused while exporting functions, and some ordinals might not have any corresponding export. In such a case, the corresponding array entry is set to 0.
| AddressOfNames | RVA of an array called as the export-names array that has an entry for every function that is exported by name. Hence, the size of this array is equal to the NumberOfNames field. Each entry in this array is an RVA pointing to an ASCIIZ string containing the export name. The array is sorted on the lexical order so as to allow binary search. |
| AddressOfNameOrdinals | RVA of an array of ordinals henceforth called as the export-ordinals array. This array has the size same as that of the AddressOfNames array. All three arrays, namely, export-names, export-ordinals, and export-functions, are instrumental in resolving imports by name. For resolving an import by name, the loader first searches the name in the export-names array. If the name matches an entry with index i, the ith entry in the export-ordinals array is the ordinal of the function. Finally, the address of the function can be found from the export-functions array. |
|
Page: 1, 2, 3, 4, 5, 6 |
next page  |
|
|
|
|