📄 lion-petut-c06.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=gb_2312-80">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Iczelion的PE教程6: Import Table(引入表)</title>
</head>
<body bgcolor="#003366" text="#FFFFFF" link="#FFFFCC"
vlink="#FFCCCC" alink="#CCFFCC">
<h1 align="center"><font color="#FFFFCC"
face="Arial, Helvetica, sans-serif">PE</font><font
color="#FFFFCC">教程</font><font color="#FFFFCC"
face="Arial, Helvetica, sans-serif">6: Import Table</font><font
color="#FFFFCC">(引入表)</font></h1>
<p><font size="2">本课我们将学习引入表。先警告一下,对于不熟悉引入表的读者来说,这是一堂又长又难的课,所以需要多读几遍,最好再打开调试器来好好分析相关结构。各位,努力啊!</font></p>
<p><font size="2">下载</font><a href="files/pe-tut06.zip"
style="text-decoration:none"><font size="2"><b>范例</b></font></a><font
size="2">。</font></p>
<h3>理论<font face="MS Sans Serif">:</font></h3>
<p><font size="2">首先,您得了解什么是引入函数。一个引入函数是被某模块调用的但又不在调用者模块中的函数,因而命名为</font><font
size="2" face="MS Sans Serif">"import</font><font size="2">(引入)</font><font
size="2" face="MS Sans Serif">"</font><font size="2">。引入函数实际位于一个或者更多的</font><font
size="2" face="MS Sans Serif">DLL</font><font size="2">里。调用者模块里只保留一些函数信息,包括函数名及其驻留的</font><font
size="2" face="MS Sans Serif">DLL</font><font size="2">名。现在,我们怎样才能找到</font><font
size="2" face="MS Sans Serif">PE</font><font size="2">文件中保存的信息呢</font><font
size="2" face="MS Sans Serif">? </font><font size="2">转到</font><font
color="#FFFFCC" size="2"><b> </b></font><font color="#FFFFCC"
size="2" face="MS Sans Serif"><b>data directory</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">寻求答案吧。再回顾一把,下面就是
</font><font size="2" face="MS Sans Serif">PE header:</font></p>
<blockquote>
<p><font size="2" face="Fixedsys">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 size="2" face="MS Sans Serif">optional header </font><font
size="2">最后一个成员就是 </font><font size="2"
face="MS Sans Serif">data directory</font><font size="2">(数据目录)</font><font
size="2" face="MS Sans Serif">:</font></p>
<p><font face="Fixedsys">IMAGE_OPTIONAL_HEADER32 STRUCT<br>
.... <br>
LoaderFlags dd ? <br>
NumberOfRvaAndSizes dd ? <br>
</font><font color="#FFCCCC" face="Fixedsys">
DataDirectory IMAGE_DATA_DIRECTORY 16 dup(<>) </font><font
face="Fixedsys"><br>
IMAGE_OPTIONAL_HEADER32 ENDS </font></p>
<p><font size="2" face="MS Sans Serif">data directory </font><font
size="2">是一个 </font><font color="#CCFFCC" size="2"
face="MS Sans Serif"><b>IMAGE_DATA_DIRECTORY</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构数组,共有</font><font
size="2" face="MS Sans Serif">16</font><font size="2">个成员。如果您还记得节表可以看作是</font><font
size="2" face="MS Sans Serif">PE</font><font size="2">文件各节的根目录的话,也可以认为
</font><font size="2" face="MS Sans Serif">data directory </font><font
size="2">是存储在这些节里的逻辑元素的根目录。明确点,</font><font
size="2" face="MS Sans Serif">data directory </font><font
size="2">包含了</font><font size="2" face="MS Sans Serif">PE</font><font
size="2">文件中各重要数据结构的位置和尺寸信息。
每个成员包含了一个重要数据结构的信息。</font></p>
<table border="1" cellpadding="2">
<tr>
<th width="55" bgcolor="#006666"><font size="2"
face="MS Sans Serif">Member</font> </th>
<th width="162" bgcolor="#006666"><font size="2"
face="MS Sans Serif">Info inside</font></th>
</tr>
<tr>
<td align="center" width="55" bgcolor="#999900"><font
size="2" face="MS Sans Serif">0</font> </td>
<td align="center" width="162" bgcolor="#999900"><font
size="2" face="MS Sans Serif">Export symbols</font></td>
</tr>
<tr>
<td align="center" width="55" bgcolor="#999900"><font
size="2" face="MS Sans Serif">1</font> </td>
<td align="center" width="162" bgcolor="#999900"><font
size="2" face="MS Sans Serif">Import symbols</font></td>
</tr>
<tr>
<td align="center" width="55" bgcolor="#999900"><font
size="2" face="MS Sans Serif">2</font> </td>
<td align="center" width="162" bgcolor="#999900"><font
size="2" face="MS Sans Serif">Resources</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">3</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">Exception</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">4</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">Security</font></td>
</tr>
<tr>
<td align="center" width="55" bgcolor="#999900"><font
size="2" face="MS Sans Serif">5</font> </td>
<td align="center" width="162" bgcolor="#999900"><font
size="2" face="MS Sans Serif">Base relocation</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">6</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">Debug</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">7</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">Copyright string</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">8</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">Unknown</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">9</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">Thread local storage (TLS)</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">10</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">Load configuration</font></td>
</tr>
<tr>
<td align="center" width="55" bgcolor="#999900"><font
size="2" face="MS Sans Serif">11</font> </td>
<td align="center" width="162" bgcolor="#999900"><font
size="2" face="MS Sans Serif">Bound Import</font></td>
</tr>
<tr>
<td align="center" width="55" bgcolor="#999900"><font
size="2" face="MS Sans Serif">12</font> </td>
<td align="center" width="162" bgcolor="#999900"><font
size="2" face="MS Sans Serif">Import Address Table</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">13</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">Delay Import</font></td>
</tr>
<tr>
<td align="center" width="55"><font size="2"
face="MS Sans Serif">14</font> </td>
<td align="center" width="162"><font size="2"
face="MS Sans Serif">COM descriptor</font></td>
</tr>
</table>
<p><font size="2">上面那些金色显示的是我熟悉的。了解
</font><font size="2" face="MS Sans Serif">data directory </font><font
size="2">包含域后,我们可以仔细研究它们了。</font><font
size="2" face="MS Sans Serif">data directory </font><font
size="2">的每个成员都是 </font><font color="#CCFFCC"
size="2" face="MS Sans Serif"><b>IMAGE_DATA_DIRECTORY</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构类型的,其定义如下所示</font><font
size="2" face="MS Sans Serif">:</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 color="#FFFFCC" size="2" face="MS Sans Serif"><b>VirtualAddress</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">实际上是数据结构的相对虚拟地址</font><font
size="2" face="MS Sans Serif">(RVA)</font><font size="2">。比如,如果该结构是关于</font><font
size="2" face="MS Sans Serif">import symbols</font><font size="2">的,该域就包含指向</font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_IMPORT_DESCRIPTOR
</b></font><font size="2">数组的</font><font size="2"
face="MS Sans Serif">RVA</font><font size="2">。 <br>
</font><font color="#FFFFCC" size="2" face="MS Sans Serif"><b>isize
</b></font><font size="2">含有</font><font color="#FFFFCC"
size="2" face="MS Sans Serif"><b>VirtualAddress</b></font><font
size="2">所指向数据结构的字节数。</font></p>
<p><font size="2">下面就是如何找寻</font><font size="2"
face="MS Sans Serif">PE</font><font size="2">文件中重要数据结构的一般方法</font><font
size="2" face="MS Sans Serif">:</font></p>
<ol>
<li><font size="2">从 </font><font size="2"
face="MS Sans Serif">DOS header </font><font size="2">定位到
</font><font size="2" face="MS Sans Serif">PE header</font></li>
<li><font size="2">从 </font><font size="2"
face="MS Sans Serif">optional header </font><font
size="2">读取 </font><font size="2"
face="MS Sans Serif">data directory </font><font size="2">的地址。</font></li>
<li><font color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_DATA_DIRECTORY
</b></font><font size="2">结构尺寸乘上找寻结构的索引号</font><font
size="2" face="MS Sans Serif">: </font><font size="2">比如您要找寻</font><font
size="2" face="MS Sans Serif">import symbols</font><font
size="2">的位置信息,必须用</font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_DATA_DIRECTORY</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构尺寸</font><font
size="2" face="MS Sans Serif">(8 bytes)</font><font
size="2">乘上</font><font size="2" face="MS Sans Serif">1</font><font
size="2">(</font><font size="2" face="MS Sans Serif">import
symbols</font><font size="2">在</font><font size="2"
face="MS Sans Serif">data directory</font><font size="2">中的索引号)。</font></li>
<li><font size="2">将上面的结果加上</font><font
size="2" face="MS Sans Serif">data directory</font><font
size="2">地址,我们就得到包含所查询数据结构信息的
</font><font color="#CCFFCC" size="2"
face="MS Sans Serif"><b>IMAGE_DATA_DIRECTORY</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构项。</font></li>
</ol>
<p><font size="2">现在我们开始真正讨论引入表了。</font><font
size="2" face="MS Sans Serif">data directory</font><font size="2">数组第二项的</font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>VirtualAddress</b></font><font
size="2">包含引入表地址。引入表实际上是一个 </font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_IMPORT_DESCRIPTOR</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构数组。每个结构包含</font><font
size="2" face="MS Sans Serif">PE</font><font size="2">文件引入函数的一个相关</font><font
size="2" face="MS Sans Serif">DLL</font><font size="2">的信息。比如,如果该</font><font
size="2" face="MS Sans Serif">PE</font><font size="2">文件从</font><font
size="2" face="MS Sans Serif">10</font><font size="2">个不同的</font><font
size="2" face="MS Sans Serif">DLL</font><font size="2">中引入函数,那么这个数组就有</font><font
size="2" face="MS Sans Serif">10</font><font size="2">个成员。该数组以一个全</font><font
size="2" face="MS Sans Serif">0</font><font size="2">的成员结尾。下面详细研究结构组成</font><font
size="2" face="MS Sans Serif">:</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>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -