?? 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 + -