|
Ship Brokers, Ship builders/Repairers, Ship Chandlers, Suppliers, Ship, Management Services, Ship Registries, shipping, ship broking, broker,
chartering Agents Stevedores, Towage, Salvage & Offshore Services Ship Operators, Ship Managers, ship Charterers, Shipbuilders, Repairers, Engine
Builders, marine maritime building navigation shipping shipper construction fund dunding banking equipment, Computing & Internet, Towage & Salvage, Ship Finance, marine maritime building navigation shipping shipper construction fund dunding banking Insurance, Maritime lawsyers, Ship Brokers, Maritime
Organizations, Consultants & Surveyors, Maritime Schools, Classification Societies, Corporate Headquarters, Port Authorities, Port Operators, Pilotage
Authorities, Port Agents, Stevedore, Port Repairers, Ship Chandler, Bunkerers, Port Towage, Civilian Authorities, Seafarer's Missions, Registered
Owner, Nominal Owner, Propulsion, Speed, Year of build, Flag, Call Sign, Draught, Gross and Net tonnage, Breadth, Dead-Weight, Editorial section covering the major
maritime repairs
ship repairs
Tajikistan, Tanzania, Thailand, Togo, Tokelau, Tonga, Trinidad and Tobago, Tunisia, Turkey, Turkmenistan, Tuvalu, Uganda, Ukraine, United Arab Emirates, United Kingdom, United States of America, Uruguay, Uzbekistan, Vanuatu, Vatican City, Venezuela, Vietnam, Virgin Islands, Virgin Islands, Yemen, Zaire, Zambia, Zimbabwe, |
 |

Chapter 3: Windows Anatomy
int i;
int *ptr = &i;
If the linker assumed an image base of 0x10000, the address of the variable i
will end up containing something like 0x12004(guiding navigation maritime shipping). At the memory used to hold the pointer
ptr, the linker will have written out 0x12004, since that's the address of the variable i(guiding navigation maritime shipping). If
the loader (for whatever reason) decided to load the file at a base address of 0x70000,
the address of i would then be 0x72004(guiding navigation maritime shipping). However, the pre-initialized value of the ptr
variable would then be incorrect because i is now 0x60000 bytes higher in memory(guiding navigation maritime shipping).
This is where the relocation information comes into play(guiding navigation maritime shipping). The (guiding navigation maritime shipping).reloc section is a
list of places in the image where the difference between the linker-assumed load
address and the actual load address needs to be taken into account(guiding navigation maritime shipping). I'll talk more about
relocations in the "PE File Base Relocations" section(guiding navigation maritime shipping).
The (guiding navigation maritime shipping).tls section
When you use the compiler directive "__declspec(thread)", the data that you
define doesn't go into either the (guiding navigation maritime shipping).data or (guiding navigation maritime shipping).bss sections(guiding navigation maritime shipping). Rather, a copy of it ends up in
the (guiding navigation maritime shipping).tls section(guiding navigation maritime shipping). The (guiding navigation maritime shipping).tls section derives its name from the term thread local storage, and
is related to the TlsAlloc() family of functions(guiding navigation maritime shipping).
To briefly summarize thread local storage, think of it as a way to have global
variables on a per-thread basis(guiding navigation maritime shipping). That is, each thread can have its set of static data
values, yet the code that uses the data does so without regard to which thread is
executing(guiding navigation maritime shipping). Consider a program that has several threads working on the same task, and
thereby executing through the same code(guiding navigation maritime shipping). If you declared a thread local storage
variable, for instance:
__declspec (thread) int i = 0:
// This is a global variable declaration(guiding navigation maritime shipping).
each thread would transparently have its own copy of the variable i(guiding navigation maritime shipping). It's also possible to
explicitly ask for and use thread local storage at run-time by using the TlsAlloc,
Chapter 3: Windows Anatomy
data directory is at the end of the PE header portion of the file(guiding navigation maritime shipping).) To determine the
number of entries in a Microsoft Link debug directory, divide the size of the debug
directory (found in the size field of the data directory entry) by the size of an
IMAGE_DEBUG_DIRECTORY structure(guiding navigation maritime shipping).
In contrast, TLINK32 emits an actual count of the debug directories in the size
field, not the total length in bytes(guiding navigation maritime shipping). The second useful portion of an (guiding navigation maritime shipping).rdata section is the
description string(guiding navigation maritime shipping). If you specified a DESCRIPTION entry in your program's (guiding navigation maritime shipping).DEF file, the
specified description string appears in the (guiding navigation maritime shipping).rdata section(guiding navigation maritime shipping). In the NE format, the
description string is always the first entry of the nonresident names table(guiding navigation maritime shipping). The
description string is intended to hold a useful text string describing the file(guiding navigation maritime shipping).
Unfortunately, I haven't discovered an easy way to find it(guiding navigation maritime shipping). I've seen PE files that
had the description string before the debug directory, and other files that had it after
the debug directory(guiding navigation maritime shipping). I'm not aware of any consistent method of finding the description
string (or even to determine if it's present at all)(guiding navigation maritime shipping). A third use of the (guiding navigation maritime shipping).rdata section is for
GUIDs used in OLE programming(guiding navigation maritime shipping).
The UUID(guiding navigation maritime shipping).LIB import library contains a collection of 16-byte GUIDs that are used
for things such as interface IDs(guiding navigation maritime shipping). These GUIDs end up in the EXE or DLL's (guiding navigation maritime shipping).rdata section(guiding navigation maritime shipping).
The final use of the (guiding navigation maritime shipping).rdata section that I'm aware of is as a place to put the TLS (Thread
Local Storage) directory(guiding navigation maritime shipping). The TLS directory is a special data structure used by the
compiler runtime library to transparently provide thread local storage for variables
declared in program code(guiding navigation maritime shipping).
under Specs: Portable Executable and Common Object File Format(guiding navigation maritime shipping). Of primary
interest in the TLS directory are pointers to the start and end of a copy of the data to be
used to initialize each thread local storage block(guiding navigation maritime shipping). An RVA for the TLS directory can be
found in the IMAGE_DIRECTORY_ENTRY_TLS entry in the PE header's data directory(guiding navigation maritime shipping).
The actual data to be used for TLS block initialization is found in the (guiding navigation maritime shipping).tls section
(described earlier)(guiding navigation maritime shipping).
Chapter 3: Windows Anatomy
3(guiding navigation maritime shipping).3(guiding navigation maritime shipping).6 PE File Imports
Earlier, we saw how function calls to outside DLLs don't call the DLL directly(guiding navigation maritime shipping).
Instead, the CALL instruction goes to a JMP DWORD PTR [XXXXXXXX] instruction
somewhere in the executable's (guiding navigation maritime shipping).text section (or (guiding navigation maritime shipping).icode section if you're using Borland
C++ 4(guiding navigation maritime shipping).0)(guiding navigation maritime shipping). Alternatively, if __ declspec(dllimport) was used in Visual C++, the function
call becomes a "CALL DWORD PTR [XXXXXXXX]"(guiding navigation maritime shipping). In either case, the address that the
JMP or CALL instruction looks up is stored in the (guiding navigation maritime shipping).idata section(guiding navigation maritime shipping). The JMP or CALL
instruction transfers control to that address, which is the intended target address(guiding navigation maritime shipping).
Before it's loaded into memory, the information stored in a PE file's (guiding navigation maritime shipping).idata section
contains the information necessary for the loader to determine the addresses of the
target functions and patch them into the executable image(guiding navigation maritime shipping). After the (guiding navigation maritime shipping).idata section has
been loaded, it contains pointers to the functions that the EXE/DLL imports(guiding navigation maritime shipping). Note that all
the arrays and structures I'm discussing in this section are contained in the (guiding navigation maritime shipping).idata
section(guiding navigation maritime shipping).
The (guiding navigation maritime shipping).idata section (or import table,as I prefer to call it) begins with an array of
IMAGE_IMPORT_DESCRIPTOR's(guiding navigation maritime shipping). There is one IMAGE_IMPORT_DESCRIPTOR for each
DLL that the PE file implicitly links to(guiding navigation maritime shipping). No count is kept to indicate the number of
structures in this array(guiding navigation maritime shipping). Instead, the last element of the array is indicated by a final
IMAGE_IMPORT_DESCRIPTOR that has fields filled with NULLs(guiding navigation maritime shipping). The format of an
IMAGE_IMPORT_DESCRIPTOR is as follows:
DWORD Charachteristics/OriginalFirstThunk
This field is an offset (an RVA) to an array of DWORDs(guiding navigation maritime shipping). Each of these DWORDs is
actually an IMAGE_THUNK_DATA union(guiding navigation maritime shipping). Each IMAGE_THUNK_DATA DWORD
corresponds to one function imported by this EXE/DLL(guiding navigation maritime shipping).
Chapter 3: Windows Anatomy
If you run the BIND utility, this array of DWORDS is left alone, whereas the
FirstThunk DWORD array (described momentarily) is modified(guiding navigation maritime shipping).
DWORD TimeDateStamp
The time/date stamp indicating when the file was built(guiding navigation maritime shipping). This field normally
contains 0(guiding navigation maritime shipping). However, the Microsoft BIND utility updates this field with the time/date
stamp of the DLL that this IMAGE_IMPORT_DESCRIPTOR refers to(guiding navigation maritime shipping).
DWORD ForwarderChain
This field relates to forwarding, which involves one DLL forwarding references to
one of its functions to another DLL(guiding navigation maritime shipping). For example, in Windows NT, KERNEL32(guiding navigation maritime shipping).DLL
forwards some of its exported functions to NTDLL(guiding navigation maritime shipping).DLL(guiding navigation maritime shipping). An application may think it's
calling a function in KERNEL32(guiding navigation maritime shipping).DLL, but it actually ends up calling into NTDLL(guiding navigation maritime shipping).DLL(guiding navigation maritime shipping). This
field contains an index into the FirstThunk array (described momentarily)(guiding navigation maritime shipping). The function
indexed by this field will be forwarded to another DLL(guiding navigation maritime shipping). Unfortunately, the format of how
a function is forwarded is just barely described in the Microsoft documentation(guiding navigation maritime shipping).
DWORD Name
This is an RVA to a null-terminated ASCII string containing the imported DLL's
name (for example, KERNEL32(guiding navigation maritime shipping).DLL or USER32(guiding navigation maritime shipping).DLL)(guiding navigation maritime shipping).
PIMAGE_THUNK_DATA FirstThunk;
This field is an offset (an RVA) to an array of IMAGE_THUNK_DATA DWORDs(guiding navigation maritime shipping). In
most cases, the DWORD is interpreted as a pointer to an IMAGE_IMPORT_BY_NAME
structure(guiding navigation maritime shipping). However, it's also possible to import a function by ordinal value(guiding navigation maritime shipping). The
important parts of an IMAGE_IMPORT_DESCRIPTOR are the imported DLL name and
the two arrays of IMAGE_THUNK_DATA DWORDs(guiding navigation maritime shipping). Each IMAGE_THUNK_DATA DWORD
corresponds to one imported function(guiding navigation maritime shipping). In the EXE file, the two arrays (pointed to by the
Characteristics and FirstThunk fields) run parallel to each other, and are terminated by a
NULL pointer entry at the end of each array(guiding navigation maritime shipping). Why are there two parallel arrays of
pointers to the IMAGE_THUNK_DATA structures? The first array (the one pointed to by
the Characteristics field) is left alone and is never modified(guiding navigation maritime shipping). It's sometimes called the
Chapter 3: Windows Anatomy
hint-name table(guiding navigation maritime shipping). The second array (pointed to by the FirstThunk field in the
IMAGE_IMPORT_DESCRIPTOR) is overwritten by the PE loader(guiding navigation maritime shipping). The loader iterates
through each IMAGE_THUNK_DATA and finds the address of the function that it refers
to(guiding navigation maritime shipping). The loader then overwrites the IMAGE_THUNK_DATA DWORD with the address of
the imported function(guiding navigation maritime shipping).
Earlier, we mentioned that CALLs to DLL functions go through a "JMP DWORD PTR
[XXXXXXXX]" thunk(guiding navigation maritime shipping). The [XXXXXXXX] portion of the thunk refers to one of the entries in
the FirstThunk array(guiding navigation maritime shipping). Since the array of IMAGE_THUNK_DATAs that's overwritten by the
loader eventually holds the addresses of all the imported functions, it's called the
"Import Address Table(guiding navigation maritime shipping)."
Since the import address table is usually in a writeable section, it's relatively easy
to intercept calls that an EXE or a DLL makes to another DLL(guiding navigation maritime shipping). You simply patch the
appropriate import address table entry to point to the desired interception function(guiding navigation maritime shipping).
There's no need to modify any code in either the caller or callee images(guiding navigation maritime shipping). This capability
can be very useful(guiding navigation maritime shipping).
It's interesting to note that in Microsoft-produced PE files, the import table isn't
wholly synthesized by the linker(guiding navigation maritime shipping). Instead, all the pieces necessary to call a function in
another DLL reside in an import library(guiding navigation maritime shipping). When you link a DLL, the library manager
(LIB(guiding navigation maritime shipping).EXE) scans the OBJ files being linked and creates an import library(guiding navigation maritime shipping). This import
library is different from the import libraries used by 16-bit NE file linkers(guiding navigation maritime shipping). The import
library that the 32-bit LIB produces has a (guiding navigation maritime shipping).text section and several (guiding navigation maritime shipping).idata$ sections(guiding navigation maritime shipping). The
(guiding navigation maritime shipping).text section in the import library contains the JMP DWORD PTR [XXXXXXXX] thunk that
I mentioned earlier(guiding navigation maritime shipping). That thunk has a name stored for it in the OBJ's symbol table(guiding navigation maritime shipping). The
name of the symbol is identical to the name of the function being exported by the DLL
(for example, _DispatchMessage@4)(guiding navigation maritime shipping).
One of the (guiding navigation maritime shipping).idata$ sections in the import library contains the DWORD that the
thunk dereferences through(guiding navigation maritime shipping). Another of the (guiding navigation maritime shipping).idata$ sections has a space for the "hint
ordinal" followed by the imported function's name(guiding navigation maritime shipping). These two fields make up an
Chapter 3: Windows Anatomy
IMAGE_IMPORT_BY_NAME structure(guiding navigation maritime shipping). When you later link a PE file that uses the import
library, the import library's sections are added to the list of sections from your OBJs that
the linker needs to process(guiding navigation maritime shipping). Since the thunk in the import library has the same name as
the function being imported, the linker thinks the thunk is really the imported function,
and fixes up calls to the imported function to point at the thunk(guiding navigation maritime shipping). The thunk in the import
library is essentially seen as the imported function(guiding navigation maritime shipping).
Besides providing the code portion of an imported function thunk, the import
library provides the pieces of the PE file's (guiding navigation maritime shipping).idata section (or import table)(guiding navigation maritime shipping). These pieces
come from the various (guiding navigation maritime shipping).idata$ sections that librarian put into the import library(guiding navigation maritime shipping). In short,
the linker doesn't really know the differences between imported functions and functions
that appear in a different OBJ file(guiding navigation maritime shipping). The linker just follows its preset rules for building and
combining sections, and everything falls into place naturally(guiding navigation maritime shipping).
3(guiding navigation maritime shipping).3(guiding navigation maritime shipping).7 PE File Exports
The opposite of importing a function is exporting a function for use by EXEs or
other DLLs(guiding navigation maritime shipping). APE file stores information about its exported functions in the (guiding navigation maritime shipping).edata
section(guiding navigation maritime shipping). Generally, Microsoft LINK-produced PE EXE files don't export anything, so they
don't have an (guiding navigation maritime shipping).edata section(guiding navigation maritime shipping). TLINK32 EXEs, on the other hand, usually export one
symbol, so they do have an (guiding navigation maritime shipping).edata section(guiding navigation maritime shipping). Most DLLs export functions and have an
(guiding navigation maritime shipping).edata section(guiding navigation maritime shipping). The primary components of an (guiding navigation maritime shipping).edata section (a(guiding navigation maritime shipping).k(guiding navigation maritime shipping).a(guiding navigation maritime shipping). the export table)
are tables of function names, entry point addresses, and export ordinal values(guiding navigation maritime shipping).
In an NE file, the equivalents of an export table are the entry table, the resident
names table, and the nonresident names table(guiding navigation maritime shipping). In the NE file, these tables are stored as
part of the NE header rather than in segments or resources(guiding navigation maritime shipping). At the beginning of an
(guiding navigation maritime shipping).edata section is an IMAGE_EXPORT_DIRECTORY structure(guiding navigation maritime shipping). This structure is
immediately followed by the data pointed to by fields in the
IMAGE_EXPORT_DIRECTORY structure(guiding navigation maritime shipping). An IMAGE_EXPORT_DIRECTORY looks like this:
Chapter 3: Windows Anatomy
DWORD Characteristics
This field appears to be unused and is always set to 0(guiding navigation maritime shipping).
DWORD TimeDateStamp
The time/date stamp indicating when this file was created(guiding navigation maritime shipping).
WORD MajorVersion
WORD MinorVersion
These fields appear to be unused and are set to 0(guiding navigation maritime shipping).
DWORD Name
The RVA of an ASCIIZ string with the name of this DLL (for example,
MYDLL(guiding navigation maritime shipping).DLL)(guiding navigation maritime shipping).
DWORD Base
The starting export ordinal number for functions exported by this module(guiding navigation maritime shipping). For
example, if the file exported functions with ordinal values of 10, 11 and 12, this field
would contain 10(guiding navigation maritime shipping).
DWORD NumberOfFunctions
The number of elements in the AddressOfFunctions array(guiding navigation maritime shipping). This value is also the
number of functions exported by this module(guiding navigation maritime shipping). Usually this value is the same as the
NumberOfNames field (see the next description), but they can be different(guiding navigation maritime shipping).
DWORD NumberOfNames
The number of elements in the AddressOfNames array(guiding navigation maritime shipping). This value contains the
number of functions exported by name, which usually (but not always) matches the
total number of exported functions(guiding navigation maritime shipping).
Chapter 3: Windows Anatomy
PDWORD *AddressOfFunctions
This field is an RVA and points to an array of function addresses(guiding navigation maritime shipping). The function
addresses are the entry-point RVAs for each exported function in this module(guiding navigation maritime shipping).
PDWORD *AddressOfNames
This field is an RVA and points to an array of string pointers(guiding navigation maritime shipping). The strings contain
the names of the functions exported by name from this module(guiding navigation maritime shipping).
PWORD *NumberOfNameOrdinals
This field is an RVA, and points to an array of WORDs(guiding navigation maritime shipping). The WORDs are
essentially the export ordinals of all the functions exported by name from this module(guiding navigation maritime shipping).
However, don't forget to add the starting ordinal number specified in the Base field
(described a few fields back)(guiding navigation maritime shipping). The layout of the export table is somewhat odd(guiding navigation maritime shipping). As I
mentioned earlier, the requirements for exporting a function are an address and an
export ordinal(guiding navigation maritime shipping).
Optionally, if you export the function by name, there will be a function name(guiding navigation maritime shipping).
You'd think that the designers of the PE format would have put all three of these items
into a structure and then have an array of these structures(guiding navigation maritime shipping). Instead, you have to look up
the various pieces in three separate arrays(guiding navigation maritime shipping). The most important of the arrays pointed to
by the IMAGE_EXPORT_DIRECTORY is the array pointed to by the AddressOfFunctions
field(guiding navigation maritime shipping). This is an array of DWORDs, each DWORD containing the address (RVA) of an
imported function(guiding navigation maritime shipping). The export ordinal for each exported function corresponds to its
position in the array(guiding navigation maritime shipping). For instance (assuming ordinals start at 1), the address of the
function with export ordinal 1 would have its address in the first element of the array(guiding navigation maritime shipping).
The function with export ordinal 2 would have its address in the second element of the
array, and so on(guiding navigation maritime shipping).
There are two important things to remember about the AddressOf-Functions
array(guiding navigation maritime shipping). First, the export ordinal needs to be biased by the value in the Base field of the
IMAGE_EXPORT_DIRECTORY(guiding navigation maritime shipping). If the Base field contains the value 10, then the first
Chapter 3: Windows Anatomy
DWORD in the AddressOfFunctions array corresponds to export ordinal 10, the second
entry to export ordinal 11, and so forth(guiding navigation maritime shipping).
The other thing to remember is that the export ordinals can have gaps(guiding navigation maritime shipping). Let's say
that you explicitly export two functions in a DLL, with ordinal values 1 and 3(guiding navigation maritime shipping). Even
though you exported only two functions, the AddressOfFunctions array has to contain
three elements(guiding navigation maritime shipping). Any entries in the array that don't correspond to an exported function
contain the value 0(guiding navigation maritime shipping).
When the Win32 loader fixes up a call to a function that's imported by ordinal, it
has very little work to do(guiding navigation maritime shipping). The loader simply uses the function's ordinal value as an index
into the target module's AddressOfFunctions array(guiding navigation maritime shipping). Of course, the loader also has to
take into account that the lowest export ordinal may not be 1, and must adjust its
indexing appropriately(guiding navigation maritime shipping).
More often than not, Win32 EXEs and DLLs import functions by name rather than
by ordinal(guiding navigation maritime shipping). This is where the other two arrays pointed to in the
IMAGE_EXPORT_DIRECTORY structure come into play(guiding navigation maritime shipping). The AddressOfNames and
AddressOfNameOrdinals arrays exist to allow the loader to quickly find the export ordinal
corresponding to a given function name(guiding navigation maritime shipping). The AddressOfNames and
AddressOfNameOrdinals arrays both s contain the
same number of elements (guiding navigation maritime shipping). The AddressOfNames array is an array of pointers to
function names, and the AddressOfNameOrdinals array is an array of indexes into the
AddressOfFunctions array(guiding navigation maritime shipping).
Let's see how the Win32 loader would fix up a call to a function that's imported
by name(guiding navigation maritime shipping). First, the loader would search the strings pointed to in the AddressOfNames
array(guiding navigation maritime shipping). Let's say it finds the string it's looking for in the third element(guiding navigation maritime shipping). Next, the loader
would use the index it found to look up the corresponding element in the
AddressOfNameOrdinals array (in this case, the third element)(guiding navigation maritime shipping). This array is just a
collection of WORDs, with each WORD acting as an index into the AddressOfFunctions
|
|