?? pe-tut6.html
字號:
<html>
<head>
<title>Iczelion's PE Tutorial 6: Import Table</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#003366" text="#FFFFFF" link="#FFFFCC" vlink="#FFCCCC" alink="#CCFFCC">
<h1 align="center"><font face="Arial, Helvetica, sans-serif" color="#FFFFCC">Tutorial
6: Import Table</font></h1>
<p><font face="MS Sans Serif" size="-1">We will learn about import table in this
tutorial. Let me warn you first. This tutorial is a long and difficult one for
those who aren't familiar with the import table. You may need to read this tutorial
several times and may even have to examine the related structures under a debugger.</font></p>
<p><font face="MS Sans Serif" size="-1">Download<b><a href="files/pe-tut06.zip" style="text-decoration:none">
the example</a></b>.</font></p>
<h3><font face="MS Sans Serif">Theory:</font></h3>
<p><font face="MS Sans Serif" size="-1">First of all, you should know what an
import function is. An import function is a function that is not in the caller's
module but is called by the module, thus the name "import". The import
functions actually reside in one or more DLLs. Only the information about the
functions is kept in the caller's module. That information includes the function
names and the names of the DLLs in which they reside. <br>
Now how can we find out where in the PE file the information is kept? We must
turn to<font color="#FFFFCC"><b> the data directory</b></font> for the answer.
I'll refresh your memory a bit. Below is the PE header:</font></p>
<blockquote>
<p><font face="Fixedsys" size="-1">IMAGE_NT_HEADERS STRUCT<br>
Signature dd ?<br>
FileHeader IMAGE_FILE_HEADER <><br>
OptionalHeader IMAGE_OPTIONAL_HEADER <><br>
IMAGE_NT_HEADERS ENDS</font></p>
</blockquote>
<p><font face="MS Sans Serif" size="-1">The last member of the optional header
is the data directory:</font></p>
<p><font face="Fixedsys">IMAGE_OPTIONAL_HEADER32 STRUCT<br>
.... <br>
</font><font face="Fixedsys"> LoaderFlags dd ? <br>
NumberOfRvaAndSizes dd ? <br>
<font color="#FFCCCC"> DataDirectory IMAGE_DATA_DIRECTORY 16 dup(<>)
</font><br>
IMAGE_OPTIONAL_HEADER32 ENDS </font></p>
<p><font face="MS Sans Serif" size="-1">The data directory is an array of <font color="#CCFFCC"><b>IMAGE_DATA_DIRECTORY</b></font>
structure. A total of 16 members. If you remember the section table as the root
directory of the sections in a PE file, you should also think of the data directory
as the root directory of the logical components stored inside those sections.
To be precise, the data directory contains the locations and sizes of the important
data structures in the PE file. Each member contains information about an important
data structure. </font></p>
<table border="1" cellspacing="2" cellpadding="2" align="center">
<tr>
<th width="55" bgcolor="#006666">
<div align="center"><font face="MS Sans Serif" size="-1">Member</font></div>
</th>
<th width="162" bgcolor="#006666"><font face="MS Sans Serif" size="-1">Info
inside</font></th>
</tr>
<tr>
<td width="55" bgcolor="#999900">
<div align="center"><font face="MS Sans Serif" size="-1">0</font></div>
</td>
<td width="162" bgcolor="#999900"><font face="MS Sans Serif" size="-1">Export
symbols</font></td>
</tr>
<tr>
<td width="55" bgcolor="#999900">
<div align="center"><font face="MS Sans Serif" size="-1">1</font></div>
</td>
<td width="162" bgcolor="#999900"><font face="MS Sans Serif" size="-1">Import
symbols</font></td>
</tr>
<tr>
<td width="55" bgcolor="#999900">
<div align="center"><font face="MS Sans Serif" size="-1">2</font></div>
</td>
<td width="162" bgcolor="#999900"><font face="MS Sans Serif" size="-1">Resources</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">3</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">Exception</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">4</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">Security</font></td>
</tr>
<tr>
<td width="55" bgcolor="#999900">
<div align="center"><font face="MS Sans Serif" size="-1">5</font></div>
</td>
<td width="162" bgcolor="#999900"><font face="MS Sans Serif" size="-1">Base
relocation</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">6</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">Debug</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">7</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">Copyright string</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">8</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">Unknown</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">9</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">Thread local storage
(TLS)</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">10</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">Load configuration</font></td>
</tr>
<tr>
<td width="55" bgcolor="#999900">
<div align="center"><font face="MS Sans Serif" size="-1">11</font></div>
</td>
<td width="162" bgcolor="#999900"><font face="MS Sans Serif" size="-1">Bound
Import</font></td>
</tr>
<tr>
<td width="55" bgcolor="#999900">
<div align="center"><font face="MS Sans Serif" size="-1">12</font></div>
</td>
<td width="162" bgcolor="#999900"><font face="MS Sans Serif" size="-1">Import
Address Table</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">13</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">Delay Import</font></td>
</tr>
<tr>
<td width="55">
<div align="center"><font face="MS Sans Serif" size="-1">14</font></div>
</td>
<td width="162"><font face="MS Sans Serif" size="-1">COM descriptor</font></td>
</tr>
</table>
<p><font face="MS Sans Serif" size="-1">Only the members painted in gold are known
to me. Now that you know what each member of the data directory contains, we
can learn about the member in detail. Each member of the data directory is a
structure called <font color="#CCFFCC"><b>IMAGE_DATA_DIRECTORY</b></font> which
has the following definition:</font></p>
<p><font face="Fixedsys">IMAGE_DATA_DIRECTORY STRUCT <br>
VirtualAddress dd ? <br>
isize dd ? <br>
IMAGE_DATA_DIRECTORY ENDS </font></p>
<p><font face="MS Sans Serif" size="-1"><b><font color="#FFFFCC">VirtualAddress</font></b>
is actually the relative virtual address (RVA) of the data structure. For example,
if this structure is for import symbols, this field contains the RVA of the
<font color="#CCFFCC"> <b>IMAGE_IMPORT_DESCRIPTOR </b></font>array. <br>
<font color="#FFFFCC"><b>isize </b></font>contains the size in bytes of the
data structure referred to by <font color="#FFFFCC"><b>VirtualAddress</b></font>.
</font></p>
<p><font face="MS Sans Serif" size="-1">Here's the general scheme on finding important
data structures in a PE file:</font></p>
<ol>
<li><font face="MS Sans Serif" size="-1">From the DOS header, you go to the
PE header</font></li>
<li><font face="MS Sans Serif" size="-1">Obtain the address of the data directory
in the optional header.</font></li>
<li><font face="MS Sans Serif" size="-1">Multiply the size of <font color="#CCFFCC"><b>IMAGE_DATA_DIRECTORY
</b></font>with the member index you want: for example if you want to know
where the import symbols are, you must multiply the size of <font color="#CCFFCC"><b>IMAGE_DATA_DIRECTORY</b></font>
(8 bytes) with 1.</font></li>
<li><font face="MS Sans Serif" size="-1">Add the result to the address of the
data directory and you have the address of the <font color="#CCFFCC"><b>IMAGE_DATA_DIRECTORY</b></font>
structure that contains the info about the desired data structure.</font></li>
</ol>
<p><font face="MS Sans Serif" size="-1">Now we will enter into the real discussion
about the import table. The address of the import table is contained in the
<font color="#FFFFCC"> <b>VirtualAddress</b></font> field of the second member
of the data directory. The import table is actually an array of <font color="#CCFFCC"><b>IMAGE_IMPORT_DESCRIPTOR</b></font>
structures. Each structure contains information about a DLL the PE file imports
symbols from. For example, if the PE file imports functions from 10 different
DLLs, there will be 10 members in this array. The array is terminated by the
member which contain all zeroes. Now we can examine the structure in detail:</font></p>
<p><font face="Fixedsys">IMAGE_IMPORT_DESCRIPTOR STRUCT <br>
union <br>
Characteristics dd ? <br>
OriginalFirstThunk dd ? <br>
ends <br>
TimeDateStamp dd ? <br>
ForwarderChain dd ? <br>
Name1 dd ? <br>
FirstThunk dd ? <br>
IMAGE_IMPORT_DESCRIPTOR ENDS </font></p>
<p><font face="MS Sans Serif" size="-1">The first member of this structure is
a union. Actually, the union only provides the alias for <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>,
so you can call it "Characteristics". This member contains the the
RVA of an array of <font color="#CCFFCC"><b>IMAGE_THUNK_DATA</b></font> structures.
<br>
What is <font color="#CCFFCC"><b>IMAGE_THUNK_DATA</b></font>? It's a union of
dword size. Usually, we interpret it as <font color="#FFFFCC">the pointer</font>
to an <font color="#CCFFCC"><b>IMAGE_IMPORT_BY_NAME</b></font> structure. Note
that <font color="#CCFFCC"><b>IMAGE_THUNK_DATA</b></font> contains the pointer
to an <font color="#CCFFCC"><b>IMAGE_IMPORT_BY_NAME</b></font> structure: not
the structure itself. <br>
Look at it this way: There are several <font color="#CCFFCC"><b>IMAGE_IMPORT_BY_NAME</b></font>
structures. We collect the RVA of those structures (<font color="#CCFFCC"><b>IMAGE_THUNK_DATAs</b></font>)
into an array, terminate it with 0. Then we put the RVA of the array into <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>.<br>
The <font color="#CCFFCC"><b>IMAGE_IMPORT_BY_NAME</b></font> structure contains
information about an import function. Now let's see what <font color="#CCFFCC"><b>IMAGE_IMPORT_BY_NAME</b></font>
structure looks like:</font></p>
<p><font face="Fixedsys">IMAGE_IMPORT_BY_NAME STRUCT <br>
Hint dw ? <br>
Name1 db ? <br>
IMAGE_IMPORT_BY_NAME ENDS </font></p>
<p><font face="MS Sans Serif" size="-1"><b><font color="#FFFFCC">Hint </font></b>contains
the index into the export table of the DLL the function resides in. This field
is for use by the PE loader so it can look up the function in the DLL's export
table quickly.This value is not essential and some linkers may set the value
in this field to 0.<br>
<font color="#FFFFCC"><b>Name1</b></font> contains the name of the import function.
The name is an ASCIIZ string. Note that Name1's size is defined as byte but
it's really a variable-sized field. It's just that there is no way to represent
a variable-sized field in a structure. The structure is provided so that you
can refer to the data structure with descriptive names.<br>
</font></p>
<p><font face="MS Sans Serif" size="-1"><b><font color="#FFFFCC">TimeDateStamp</font></b>
and <font color="#FFFFCC"><b>ForwarderChain</b></font> are advanced stuff: We
will talk about them after you have firm grasp of the other members.</font></p>
<p><font face="MS Sans Serif" size="-1"><b><font color="#FFFFCC">Name1</font></b>
contains the RVA to the name of the DLL, in short, the pointer to the name of
the DLL. The string is an ASCIIZ one.</font></p>
<p><font face="MS Sans Serif" size="-1"><b><font color="#FFFFCC">FirstThunk</font></b>
is very similar to <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>, ie.
it contains an RVA of an array of <font color="#CCFFCC"><b>IMAGE_THUNK_DATA</b></font>
structures(a different array though). <br>
Ok, if you're still confused, look at it this way: There are several <font color="#CCFFCC">
<b>IMAGE_IMPORT_BY_NAME </b></font>structures. You create two arrays, then fill
them with the RVAs of those <font color="#CCFFCC"><b>IMAGE_IMPORT_BY_NAME</b></font>
structures, so both arrays contain exactly the same values (i.e. exact duplicate).
Now you assign the RVA of the first array to <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>
and the RVA of the second array to <font color="#FFFFCC"><b>FirstThunk</b></font>.</font></p>
<table border="0" cellspacing="1" cellpadding="1" align="center">
<tr>
<th bgcolor="#006666" width="152"><font face="MS Sans Serif" size="-1">OriginalFirstThunk</font></th>
<th width="58"><font face="MS Sans Serif" size="-1"></font></th>
<th width="183" bgcolor="#006666"><font face="MS Sans Serif" size="-1">IMAGE_IMPORT_BY_NAME</font></th>
<th width="27"><font face="MS Sans Serif" size="-1"></font></th>
<th bgcolor="#006666" width="152"><font face="MS Sans Serif" size="-1">FirstThunk</font></th>
</tr>
<tr>
<td width="152">
<p align="center"> | </p>
</td>
<td width="58"> </td>
<td width="183">
<div align="center"></div>
</td>
<td width="27"> </td>
<td width="152">
<div align="center"><font face="MS Sans Serif" size="-1">|</font></div>
</td>
</tr>
<tr>
<td width="152">
<table border="1" cellspacing="2" cellpadding="2" align="center">
<tr bgcolor="#666600">
<td>
<div align="center"><font face="MS Sans Serif" size="-1">IMAGE_THUNK_DATA</font></div>
</td>
</tr>
<tr bgcolor="#666600">
<td>
<div align="center"><font face="MS Sans Serif" size="-1">IMAGE_THUNK_DATA</font></div>
</td>
</tr>
<tr bgcolor="#666600">
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -