⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-petut-c06.htm

📁 在DOS下编程因为实模式的限制
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">...</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">IMAGE_THUNK_DATA</font>
                </td>
            </tr>
        </table>
        </td>
    </tr>
</table>

<p><font size="2">现在您应该明白我的意思。不要被</font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_THUNK_DATA</b></font><font
size="2">这个名字弄糊涂</font><font size="2"
face="MS Sans Serif">: </font><font size="2">它仅是指向 </font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_IMPORT_BY_NAME
</b></font><font size="2">结构的</font><font size="2"
face="MS Sans Serif">RVA</font><font size="2">。 如果将 </font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_THUNK_DATA</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
color="#FFFFCC" size="2" face="MS Sans Serif"><b>OriginalFirstThunk</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">和 </font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>FirstThunk</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">kernel32.dll</font><font size="2">中引入</font><font
size="2" face="MS Sans Serif">10</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
color="#FFFFCC" size="2" face="MS Sans Serif"><b>Name1</b></font><font
size="2">域包含指向字符串</font><font size="2"
face="MS Sans Serif">&quot;kernel32.dll&quot;</font><font
size="2">的</font><font size="2" face="MS Sans Serif">RVA</font><font
size="2">,同时每个</font><font color="#CCFFCC" size="2"
face="MS Sans Serif"><b>IMAGE_THUNK_DATA</b></font><font size="2"
face="MS Sans Serif"> </font><font size="2">数组有</font><font
size="2" face="MS Sans Serif">10</font><font size="2">个元素。</font></p>

<p><font size="2">下一个问题是</font><font size="2"
face="MS Sans Serif">: </font><font size="2">为什么我们需要两个完全相同的数组</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">PE</font><font size="2">装载器将查找</font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_THUNK_DATA</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">和 </font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_IMPORT_BY_NAME</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">这些结构数组,以此决定引入函数的地址。然后用引入函数真实地址来替代由</font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>FirstThunk</b></font><font
size="2">指向的</font><font color="#CCFFCC" size="2"><b> </b></font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_THUNK_DATA</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">:</font></p>

<table border="0" cellspacing="1">
    <tr>
        <th bgcolor="#006666"><font size="2" face="MS Sans Serif">OriginalFirstThunk</font></th>
        <th> </th>
        <th bgcolor="#006666"><font size="2" face="MS Sans Serif">IMAGE_IMPORT_BY_NAME</font></th>
        <th> </th>
        <th bgcolor="#006666"><font size="2" face="MS Sans Serif">FirstThunk</font></th>
    </tr>
    <tr>
        <td align="center"><p align="center">| </p>
        </td>
        <td align="center"> </td>
        <td align="center"> </td>
        <td align="center"> </td>
        <td align="center"><font size="2" face="MS Sans Serif">|</font>
        </td>
    </tr>
    <tr>
        <td align="center"><table border="1" cellpadding="2">
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">IMAGE_THUNK_DATA</font>
                </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">IMAGE_THUNK_DATA</font>
                </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">IMAGE_THUNK_DATA</font>
                </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">IMAGE_THUNK_DATA</font>
                </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">...</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">IMAGE_THUNK_DATA</font>
                </td>
            </tr>
        </table>
        </td>
        <td align="center"><table border="0" cellpadding="2">
            <tr>
                <td align="center" nowrap><font size="2"
                face="MS Sans Serif">---&gt;</font></td>
            </tr>
            <tr>
                <td align="center" nowrap><font size="2"
                face="MS Sans Serif">---&gt;</font></td>
            </tr>
            <tr>
                <td align="center" nowrap><font size="2"
                face="MS Sans Serif">---&gt;</font></td>
            </tr>
            <tr>
                <td align="center" nowrap><font size="2"
                face="MS Sans Serif">---&gt;</font></td>
            </tr>
            <tr>
                <td align="center" nowrap><font size="2"
                face="MS Sans Serif">---&gt;</font></td>
            </tr>
            <tr>
                <td align="center" nowrap><font size="2"
                face="MS Sans Serif">---&gt;</font></td>
            </tr>
        </table>
        </td>
        <td align="center"><table border="1" cellpadding="2">
            <tr>
                <td align="center" bgcolor="#660066"><font
                size="2" face="MS Sans Serif">Function 1</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#660066"><font
                size="2" face="MS Sans Serif">Function 2</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#660066"><font
                size="2" face="MS Sans Serif">Function 3</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#660066"><font
                size="2" face="MS Sans Serif">Function 4 </font></td>
            </tr>
            <tr>
                <td align="center" bgcolor="#660066"><font
                size="2" face="MS Sans Serif">...</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#660066"><font
                size="2" face="MS Sans Serif">Function n</font> </td>
            </tr>
        </table>
        </td>
        <td align="center"><table border="0" cellpadding="2">
            <tr>
                <td align="center" nowrap>&nbsp;&nbsp;&nbsp;</td>
            </tr>
            <tr>
                <td align="center" nowrap> </td>
            </tr>
            <tr>
                <td align="center" nowrap> </td>
            </tr>
            <tr>
                <td align="center" nowrap> </td>
            </tr>
            <tr>
                <td align="center" nowrap> </td>
            </tr>
            <tr>
                <td align="center" nowrap> </td>
            </tr>
        </table>
        </td>
        <td align="center"><table border="1" cellpadding="2">
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">Address of Function
                1</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">Address of Function
                2</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">Address of Function
                3</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">Address of Function
                4</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">...</font> </td>
            </tr>
            <tr>
                <td align="center" bgcolor="#666600"><font
                size="2" face="MS Sans Serif">Address of Function
                n </font></td>
            </tr>
        </table>
        </td>
    </tr>
</table>

<p><font size="2">由</font><font color="#FFFFCC" size="2"
face="MS Sans Serif"><b>OriginalFirstThunk</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">PE</font><font size="2">装载器还能找寻到。<br>
  </font><font size="2" face="MS Sans Serif">当然再简单的事物都有其复杂的一面。</font><font size="2">有些情况下一些函数仅由序数引出,也就是说您不能用函数名来调用它们</font><font
size="2" face="MS Sans Serif">: </font><font size="2">您只能用它们的位置来调用。此时,调用者模块中就不存在该函数的</font><font
color="#CCFFCC" size="2"><b> </b></font><font color="#CCFFCC"
size="2" face="MS Sans Serif"><b>IMAGE_IMPORT_BY_NAME</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构。不同的,对应该函数的 </font><font color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_THUNK_DATA</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">值的低位字指示函数序数,而最高二进位 </font><font size="2" face="MS Sans Serif">(MSB)</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">1234h</font><font size="2">,那么对应该函数的 </font><font color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_THUNK_DATA</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">值是</font><font
size="2" face="MS Sans Serif">80001234h</font><font size="2">。</font><font
size="2" face="MS Sans Serif">Microsoft</font><font size="2">提供了一个方便的常量来测试</font><font
size="2" face="MS Sans Serif">dword</font><font size="2">值的</font><font
size="2" face="MS Sans Serif">MSB</font><font size="2">位,就是 </font><font color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_ORDINAL_FLAG32</b></font><font
size="2">,其值为</font><font size="2" face="MS Sans Serif">80000000h</font><font
size="2">。<br>
假设我们要列出某个</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">PE</font><font size="2">。</font></li>
    <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><font
        size="2">。</font></li>
    <li><font size="2">获取位于 </font><font color="#FFFFCC"
        size="2" face="MS Sans Serif"><b>OptionalHeader </b></font><font
        size="2">数据目录地址。</font></li>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -