﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-包建强的开源地带</title><link>http://www.cnblogs.com/Jax/</link><description>我的微软梦，实现了一半</description><language>zh-cn</language><lastBuildDate>Thu, 28 Aug 2008 10:57:36 GMT</lastBuildDate><pubDate>Thu, 28 Aug 2008 10:57:36 GMT</pubDate><ttl>60</ttl><item><title>(翻译)《Expert .NET 2.0 IL Assembler》 第四章 托管可执行体文件的结构 4.3 小结</title><link>http://www.cnblogs.com/Jax/archive/2008/08/27/1278153.html</link><dc:creator>包建强</dc:creator><author>包建强</author><pubDate>Wed, 27 Aug 2008 15:51:00 GMT</pubDate><guid>http://www.cnblogs.com/Jax/archive/2008/08/27/1278153.html</guid><wfw:comment>http://www.cnblogs.com/Jax/comments/1278153.html</wfw:comment><comments>http://www.cnblogs.com/Jax/archive/2008/08/27/1278153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Jax/comments/commentRss/1278153.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Jax/services/trackbacks/1278153.html</trackback:ping><description><![CDATA[<p><a href="http://www.cnblogs.com/Jax/archive/2008/07/19/1246490.html">返回目录</a></p>
<p>&nbsp;</p>
<p><strong><span style="font-size: 12pt; font-family: 宋体">小结</span></strong><strong></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">讨论过托管映像文件的结构以及</span>IL<span style="font-family: 宋体">编译器生成这些文件的方式，我将小结一下</span>IL<span style="font-family: 宋体">编译器创建一个托管</span>PE<span style="font-family: 宋体">文件的步骤。</span>PE<span style="font-family: 宋体">文件的创建表现为以下</span>4<span style="font-family: 宋体">个步骤：</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">步骤</span>1</strong><strong><span style="font-family: 宋体">：初始化</span></strong></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">初始化内部缓冲器</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">在内存创建一个</span>PE<span style="font-family: 宋体">文件的空模板，包括</span>MS-DOS<span style="font-family: 宋体">头和</span>stub<span style="font-family: 宋体">、</span>PE<span style="font-family: 宋体">签名、</span>COFF<span style="font-family: 宋体">头和</span>PE<span style="font-family: 宋体">头。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">输入地址表和</span>CLR<span style="font-family: 宋体">头被分配在</span>.text<span style="font-family: 宋体">区段中。</span></p>
<p><strong><span style="font-family: 宋体">步骤</span>2</strong><strong><span style="font-family: 宋体">：源代码的语法分析</span></strong></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">元数据被收集在内部缓冲器中。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">方法体（</span>IL<span style="font-family: 宋体">代码和托管的异常处理表）被收集在内部缓冲器中。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">数据常量被发布到</span>.sdata<span style="font-family: 宋体">和</span>.tls<span style="font-family: 宋体">区段。</span></p>
<p><strong><span style="font-family: 宋体">步骤</span>3</strong><strong><span style="font-family: 宋体">：图像的生成</span></strong></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">为强签名在</span>.text<span style="font-family: 宋体">区段中分配空间。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">元数据被分析和重新整理。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">内部（到模块）的引用在</span>IL<span style="font-family: 宋体">代码中被处理。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">4.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">方法体被发布到</span>.text<span style="font-family: 宋体">区段。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">5.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>TLS<span style="font-family: 宋体">目录表被发布到</span>.sdata<span style="font-family: 宋体">区段。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">6.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">调试目录被发布到</span>.text<span style="font-family: 宋体">区段。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">7.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">为元数据在</span>.text<span style="font-family: 宋体">区段中分配空间。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">8.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">为内嵌的托管资源在</span>.text<span style="font-family: 宋体">区段中分配空间。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">9.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">非托管的导出</span>stub<span style="font-family: 宋体">被发布到</span>.text<span style="font-family: 宋体">区段。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">10.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>VTFixup<span style="font-family: 宋体">标被发布到</span>.text<span style="font-family: 宋体">区段。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">11.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>V-<span style="font-family: 宋体">表被发布到</span>. sdata<span style="font-family: 宋体">区段。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">12.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">非托管的导出表被发布到</span>. sdata<span style="font-family: 宋体">区段。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">13.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">元数据中最近的改变——映射字段的</span>RVA<span style="font-family: 宋体">被修复。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">14.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">元数据被发布在</span>.text<span style="font-family: 宋体">区段的预分配空间。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">15.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">托管的资源被发布在</span>.text<span style="font-family: 宋体">区段的预分配空间。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">16.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">运行时的开始</span>stub<span style="font-family: 宋体">被发布在</span>.text<span style="font-family: 宋体">区段</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">17.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">非托管资源被从</span>.res<span style="font-family: 宋体">文件中读取到，并被发布在</span>.rsrc<span style="font-family: 宋体">区段</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">18.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">必需的基本重定向被发布在</span>.reloc<span style="font-family: 宋体">区段</span></p>
<p><strong><span style="font-family: 宋体">步骤</span>4</strong><strong><span style="font-family: 宋体">：完成</span></strong></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">映像文件被写为一个磁盘文件。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">强签名过程被应用到文件，通过调用强名称工具的方式。</span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt">IL<span style="font-family: 宋体">编译器允许你在映像文件的头中显示地设置某个值，依靠源代码指令和编译器命令行选项，正如表</span>4-7<span style="font-family: 宋体">所示。在本章所讨论的所有情形中，命令行选项优先于相应的源代码指令。</span></p>
<p>&nbsp;&nbsp;</p>
<p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 41.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="55">
            <p><strong><span style="font-family: 宋体">头</span></strong></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="132">
            <p><strong><span style="font-family: 宋体">字段</span></strong></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 144pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="192">
            <p><strong><span style="font-family: 宋体">指令</span></strong></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 141.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="189">
            <p><strong><span style="font-family: 宋体">命令行选项</span></strong></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 41.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="55">
            <p>COFF</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="132">
            <p>Machine</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 144pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="192">
            <p>&nbsp;</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 141.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="189">
            <p>/ITANIUM, /X64(default is I386)</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 41.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="55">
            <p>PE</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="132">
            <p>Header type</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 144pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="192">
            <p>&nbsp;</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 141.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="189">
            <p>/PE64(default is PE32)</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 41.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="55">
            <p>PE</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="132">
            <p>ImageBase</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 144pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="192">
            <p>.imagebase &lt;integer value&gt;</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 141.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="189">
            <p>/BASE=&lt;integer value&gt;</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 41.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="55">
            <p>PE</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="132">
            <p>SizeOfStackReserve</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 144pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="192">
            <p>.stackreserve &lt;integer value&gt;</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 141.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="189">
            <p>/STACK=&lt;integer value&gt;</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 41.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="55">
            <p>PE</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="132">
            <p>FileAlignment</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 144pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="192">
            <p>.file alignment &lt;integer value&gt;</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 141.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="189">
            <p>/ALIGNMENT=&lt;integer value&gt;</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 41.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="55">
            <p>PE</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="132">
            <p>Subsystem</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 144pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="192">
            <p>.subsystem &lt;integer value&gt;</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 141.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="189">
            <p>/SUBSYSTEM=&lt;integer value&gt;</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 41.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="55">
            <p>CLR</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="132">
            <p>Flags</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 144pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="192">
            <p>.corflags &lt;integer value&gt;</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 141.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="189">
            <p>/FLAGS=&lt;integer value&gt;</p>
            </td>
        </tr>
    </table>
</p>
<p>&nbsp;&nbsp;</p>
<p>&nbsp;</p>
<p>Commit<span style="font-family: 宋体">翻译——提交？</span></p>
<p>Preferred<span style="font-family: 宋体">——首选的</span></p>
<p>take precedence of<span style="font-family: 宋体">——优先于</span></p>
<p>make nontrivial use of = <span style="font-family: 宋体">很需要使用</span></p>
<p>as sush <span style="font-family: 宋体">同样的</span></p>
<img src ="http://www.cnblogs.com/Jax/aggbug/1278153.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41940/" target="_blank">[新闻]惠普139亿美元完成对EDS的收购</a>]]></description></item><item><title>(翻译)《Expert .NET 2.0 IL Assembler》 第四章 托管可执行体文件的结构 4.2 CLR头（二） </title><link>http://www.cnblogs.com/Jax/archive/2008/08/27/1278151.html</link><dc:creator>包建强</dc:creator><author>包建强</author><pubDate>Wed, 27 Aug 2008 15:48:00 GMT</pubDate><guid>http://www.cnblogs.com/Jax/archive/2008/08/27/1278151.html</guid><wfw:comment>http://www.cnblogs.com/Jax/comments/1278151.html</wfw:comment><comments>http://www.cnblogs.com/Jax/archive/2008/08/27/1278151.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Jax/comments/commentRss/1278151.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Jax/services/trackbacks/1278151.html</trackback:ping><description><![CDATA[<p><a href="http://www.cnblogs.com/Jax/archive/2008/07/19/1246490.html">返回目录</a></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">重定位区段</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">映像文件的</span>.reloc<span style="font-family: 宋体">区段包括了</span>Fixup<span style="font-family: 宋体">表，它为映像文件中的所有修正保存了入口。</span>RVA<span style="font-family: 宋体">和</span>.reloc<span style="font-family: 宋体">区段的大小都由</span>PE<span style="font-family: 宋体">头的</span>Base Relocation<span style="font-family: 宋体">表目录定义。</span>Fixup<span style="font-family: 宋体">表由很多块修正组成，每一块将这些修正保存为一个</span>4KB<span style="font-family: 宋体">的页。这些块都是按</span>4<span style="font-family: 宋体">字节排列的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">每一个修正都描述了映像文件中特定地址的位置，以及当加载这个映像文件到内存的时候，</span>OS<span style="font-family: 宋体">加载器应该如何修改这个位置上的地址。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">每一个修正块开始于两个</span>4<span style="font-family: 宋体">字节的无符号整数：这个页的</span>RVA<span style="font-family: 宋体">包括了要修正的地址和这个块的大小。这个页的入口的修正包括直接位于它的后面。每个入口都有</span>16<span style="font-family: 宋体">位的宽度，包含了重定位的类型所需要的</span>4<span style="font-family: 宋体">个最重要的字节。剩下的</span>12<span style="font-family: 宋体">位保存了这个页中重定位地址的偏移量。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">为了重定位地址，</span>OS<span style="font-family: 宋体">的加载器计算出首选的基地址（</span>PE<span style="font-family: 宋体">头的</span>ImageBase<span style="font-family: 宋体">字段）和实际映像文件被加载的基地址之间的不同（</span>delta<span style="font-family: 宋体">）。这个</span>delta<span style="font-family: 宋体">接着根据重定位的类型被应用到地址上。一旦映像文件被加载到它首选的位置，就不会应用任何修正。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">下面的重定位类型定义于</span>Winnt.h<span style="font-family: 宋体">中：</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_ABSOLUTE (0)<span style="font-family: 宋体">：这个类型在映像文件中没有任何意义，修正在这里被跳过。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_HIGH (1)<span style="font-family: 宋体">：这个</span>delta<span style="font-family: 宋体">的</span>16<span style="font-family: 宋体">高位段被添加到偏移量上的</span>16<span style="font-family: 宋体">位字段上。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_LOW (2)<span style="font-family: 宋体">：这个</span>delta<span style="font-family: 宋体">的</span>16<span style="font-family: 宋体">低位段被添加到偏移量上的</span>16<span style="font-family: 宋体">位字段上。在这种情形中的</span>16<span style="font-family: 宋体">位字段是</span>32<span style="font-family: 宋体">位地址被重新部署的半数低位。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_HIGHLOW (3)<span style="font-family: 宋体">：这个</span>delta<span style="font-family: 宋体">被添加到偏移量上的</span>32<span style="font-family: 宋体">位字段上。对这个类型的重定位与</span>IMAGE_REL_BASED_HIGH<span style="font-family: 宋体">和</span>IMAGE_REL_BASED_LOW<span style="font-family: 宋体">这些重定位的位或运算是相等的，它是</span>32<span style="font-family: 宋体">位地址重定位的首选类型。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_HIGHADJ (4)<span style="font-family: 宋体">：这个</span>delta<span style="font-family: 宋体">的</span>16<span style="font-family: 宋体">高位段被添加到偏移量上的</span>16<span style="font-family: 宋体">位字段上。这个</span>16<span style="font-family: 宋体">位字段在这种情形中是重定位的</span>32<span style="font-family: 宋体">位地址的高位部分。这个地址的</span>16<span style="font-family: 宋体">低位存储在</span>16<span style="font-family: 宋体">位的在这个重定位之后的单词中。这个类型的修正占据了两个槽。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_MIPS_JMPADDR (5)<span style="font-family: 宋体">：</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_SECTION (6)<span style="font-family: 宋体">：保留的。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_REL32 (7)<span style="font-family: 宋体">：保留的。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_MIPS_JMPADDR16 (9)<span style="font-family: 宋体">：这个修正应用到</span>MIPS<span style="font-family: 宋体">的</span>jump<span style="font-family: 宋体">方法。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_IA64_IMM64 (9)<span style="font-family: 宋体">：与</span>IMAGE_REL_BASED_MIPS_JMPADDR16<span style="font-family: 宋体">相同。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_DIR64 (10)<span style="font-family: 宋体">：这个</span>delta<span style="font-family: 宋体">在偏移量上被添加到</span>64<span style="font-family: 宋体">位字段。</span></p>
<p style="text-indent: 21pt">IMAGE_REL_BASED_HIGH3ADJ (11)<span style="font-family: 宋体">：这个修正添加了这个</span>delta<span style="font-family: 宋体">的</span>16<span style="font-family: 宋体">高位段到偏移量上的</span>16<span style="font-family: 宋体">位字段上。这个</span>16<span style="font-family: 宋体">位字段是</span>48<span style="font-family: 宋体">高位地址的三分之一。这个地址的</span>32<span style="font-family: 宋体">位低位存储在</span>32<span style="font-family: 宋体">位两倍于这个单词中，紧跟在这个重定位中。这个类型的一个修正占据了</span>3<span style="font-family: 宋体">个槽。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">唯一的修正类型是</span>IMAGE_REL_BASED_HIGHLOW<span style="font-family: 宋体">，由</span>32<span style="font-family: 宋体">位可执行体中的已有的托管编译器发布。在</span>64<span style="font-family: 宋体">位可执行体中，则是</span>IMAGE_REL_BASED_DIR64</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一个</span>32<span style="font-family: 宋体">位的纯净</span>IL<span style="font-family: 宋体">的</span>PE<span style="font-family: 宋体">文件，在</span>.text<span style="font-family: 宋体">区段中只包括一个修正。这样做是为了</span>CLR<span style="font-family: 宋体">开始的</span>stub<span style="font-family: 宋体">，在一个纯净的</span>IL<span style="font-family: 宋体">映像文件中本地代码的唯一片段。这个修正是为了映像文件的</span>IAT<span style="font-family: 宋体">，包括了一个唯一的入口：</span>CLR<span style="font-family: 宋体">入口点。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一个</span>64<span style="font-family: 宋体">位的纯净</span>IL<span style="font-family: 宋体">的</span>PE<span style="font-family: 宋体">文件，在</span>X64<span style="font-family: 宋体">体系中有</span>1<span style="font-family: 宋体">个修正，在</span>Itanimu<span style="font-family: 宋体">体系中有</span>2<span style="font-family: 宋体">个修正（额外的那个修正是为了全局指针）。</span></p>
<p style="text-indent: 21pt">Windows XP<span style="font-family: 宋体">或者更新的版本，作为一个</span>CLR<span style="font-family: 宋体">天生载体的操作系统，既不需要</span>CLR<span style="font-family: 宋体">的开始</span>stub<span style="font-family: 宋体">，也不需要</span>IAT<span style="font-family: 宋体">来调用</span>CLR<span style="font-family: 宋体">。因此，如果</span>CLR<span style="font-family: 宋体">头的标记指出映像文件只是</span>IL<span style="font-family: 宋体">（</span>COMIMAGE_FLAGS_ILONLY<span style="font-family: 宋体">），操作系统就会完全地忽略这个</span>.reloc<span style="font-family: 宋体">区段。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这种优化对由</span>IL<span style="font-family: 宋体">编译器生成的一些映像文件开了一个冷笑话，这将生成纯净的</span>IL<span style="font-family: 宋体">映像文件但却需要重定向被执行——如果有任何数据定位于</span>TLS<span style="font-family: 宋体">或定义了</span>data on data<span style="font-family: 宋体">。当映像文件在</span>Windows XP<span style="font-family: 宋体">下被加载时，为了让这些重定位得到执行，</span>IL<span style="font-family: 宋体">编译器被迫作弊并设置</span>CLR<span style="font-family: 宋体">头的标记就好像映像文件包括内嵌的本地代码（</span>32<span style="font-family: 宋体">位目标平台上为</span>COMIMAGE_FLAGS_32BITREQUIRED<span style="font-family: 宋体">，没有适用于</span>64<span style="font-family: 宋体">位目标平台的值）。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">其他平台上并没有这些问题。生成了纯净</span>IL<span style="font-family: 宋体">映像文件的编译器（如</span>C#<span style="font-family: 宋体">或</span>VB.NET<span style="font-family: 宋体">）并没有定义基于</span>TLS<span style="font-family: 宋体">的数据或</span>data-on-data<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">正如</span>VC++<span style="font-family: 宋体">编译器和连接器生成混合代码的映像文件那样，这些映像文件的</span>.reloc<span style="font-family: 宋体">区段可以包括任意数量的重定位。但是混合代码的映像文件从来不携带仅有</span>IL<span style="font-family: 宋体">的</span>CLR<span style="font-family: 宋体">头标记，因此他们的重定位总是被执行。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">文本区段</span></strong></p>
<p style="text-indent: 21pt">PE<span style="font-family: 宋体">文件的文本区段是一个只读区段。在一个托管的</span>PE<span style="font-family: 宋体">文件中，它包括了元数据表、导出表、</span>CLR<span style="font-family: 宋体">头以及用于</span>CLR<span style="font-family: 宋体">的非托管的启动</span>stub<span style="font-family: 宋体">。在这个由</span>IL<span style="font-family: 宋体">编译器生成的映像文件中，这个区段还包括了托管资源、哈希强签名、调试数据以及非托管的导入型</span>stub<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">图</span>4-3<span style="font-family: 宋体">总结了由</span>IL<span style="font-family: 宋体">编译器生成的</span>.text<span style="font-family: 宋体">区段的通用结构。</span></p>
<p style="text-indent: 21pt">IL<span style="font-family: 宋体">编译器以一个特定的顺序发布数据到</span>.text<span style="font-family: 宋体">区段。当</span>PE<span style="font-family: 宋体">文件生成器在</span>IL<span style="font-family: 宋体">启动期间被初始化的时候，就会在</span>.text<span style="font-family: 宋体">区段为输入地址表（只携带一个单独的入口，作为</span>CLR<span style="font-family: 宋体">的入口点）和在本章前面章节描述的</span>CLR<span style="font-family: 宋体">头分配空间。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">当</span>IL<span style="font-family: 宋体">编译器解析源代码并在内存中形成元数据和</span>IL<span style="font-family: 宋体">结构体的时候，</span>.text<span style="font-family: 宋体">区段得到一个临时性的断点；直到解析完成并且</span>IL<span style="font-family: 宋体">编译器做好</span>PE<span style="font-family: 宋体">文件发布的准备时，才会发布上去。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">接下来是</span>IL<span style="font-family: 宋体">编译器，如果是这样被安排好的（通过在</span>.assembly<span style="font-family: 宋体">指令中指定公钥；参见第</span>6<span style="font-family: 宋体">章了解详细内容），为强签名在</span>.text<span style="font-family: 宋体">区段分配充分的空间。强签名是一个对主模块使用程序集发布者的私钥进行加密的哈希值。签名本身被发布到随后分配的空间中，作为主模块生成的最后一步。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">接下来进行到方法体这一步，包括了方法头、</span>IL<span style="font-family: 宋体">代码以及托管异常处理表（参见第</span>10<span style="font-family: 宋体">章了解详细内容）。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">图</span>4-3 <span style="font-family: 宋体">由</span>IL<span style="font-family: 宋体">编译器发布的</span>.text<span style="font-family: 宋体">区段的结构</span></p>
<p><span style="font-family: 宋体"><img height="548" alt="" src="http://www.cnblogs.com/images/cnblogs_com/jax/MSIL/4_3.gif" width="367" border="0" />&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在方法体被发布后，而且一旦你定制了包括调试信息的</span>PDB<span style="font-family: 宋体">文件的生成，</span>IL<span style="font-family: 宋体">编译器就发布调试目录入口以及包括了指向</span>PDB<span style="font-family: 宋体">文件路径的</span>CodeReview-style<span style="font-family: 宋体">头。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">接下来是元数据，在那之后会被完全定义的，就被发布到</span>.text<span style="font-family: 宋体">区段，紧跟在后面的是托管资源（如果有的话）。元数据格式会在下一章详细描述，而托管资源将会在本章后面的&#8220;资源&#8221;章节讨论。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在元数据和托管资源之后，非托管导出</span>stub<span style="font-family: 宋体">发布为那些托管的方法——被暴露为非托管的导出。第</span>18<span style="font-family: 宋体">章描述了导出托管方法为非托管的客户端。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">下一个发布到</span>.text<span style="font-family: 宋体">区段的项（如果存在），是本章前面描述的</span>V-<span style="font-family: 宋体">表的修正表。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">最后一个发布到</span>.text<span style="font-family: 宋体">区段的项，是</span>CLR<span style="font-family: 宋体">的非托管起始</span>stub<span style="font-family: 宋体">，它的</span>RVA<span style="font-family: 宋体">被分配到</span>PE<span style="font-family: 宋体">头的</span>AddressOfEntryPoint<span style="font-family: 宋体">字段。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">数据区段</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">由</span>IL<span style="font-family: 宋体">编译器生成的一个映像文件的数据区段（</span>.sdata<span style="font-family: 宋体">），是一个可读写的区段。它包括了数据常量、在&#8220;</span>V-<span style="font-family: 宋体">表&#8221;章节中描述的</span>V-<span style="font-family: 宋体">表、非托管导出表以及</span>TLS<span style="font-family: 宋体">的目录结构。声明为特定于线程的数据位于一个不同的区段，也就是</span>.tls<span style="font-family: 宋体">区段。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p><strong><span style="font-family: 宋体">数据常量</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">数据常量这个术语，可能有一些误解。数据常量位于一个可读写的区段中，肯定可以被覆写，因此从技术上讲，很难称其为常量。然而这个词语，涉及的是数据的用法而不是数据的本性。数据常量代表了静态字段直接的映射，并通常包括被映射字段初始化了的数据。（第一章描述了字段映射的特性。）</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">字段映射是一个便捷的方式来初始化任何带有</span>ANSI<span style="font-family: 宋体">字符串、</span>blob<span style="font-family: 宋体">或结构的静态字段。一个可选择的初始化静态字段的方法——也是一个以</span>CLR<span style="font-family: 宋体">形式的更传统的方法——将会通过执行类的构造函数中的代码显示地对其操作，正如第九章讨论的那样。但是这种可选择性更加单调乏味，因此没有人真的去责备编译器借助字段映射来初始化。</span>VC++<span style="font-family: 宋体">编译器映射了所有的全局字段，而不管它们是否将会被初始化。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">将静态字段映射到数据有其自身的需要注意的。映射到数据区段的字段，换句话说，就如同类型控制和垃圾收集那样，是</span>CLR<span style="font-family: 宋体">控制机制难以达到的，换句话说，对于自由访问和修改是广泛开放的。这就引起了加载器阻止特定的字段类型被映射；被映射的字段类型可能不包括指向对象、向量、数组或任何非公有的子结构的引用。如果类的构造函数被用为静态字段初始化，就不会有这样的问题发生。从哲学意义上讲，这是非常自然的：贯穿人类的历史，背离了正统，尽管是临时性的，也总是会带来一些不愉快的并发症。</span></p>
<p>&nbsp;</p>
<p><strong>V-</strong><strong><span style="font-family: 宋体">表</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">纯托管代码模块中的</span>V-<span style="font-family: 宋体">表用于将托管方法暴露给非托管代码来调用。</span>V-<span style="font-family: 宋体">表是由一些入口条目组成，每个入口条目又是由一个或多个槽位组成。这些入口和</span>V-<span style="font-family: 宋体">表的槽都定义在</span>V-<span style="font-family: 宋体">表的修正中——在前面&#8220;</span>VTableFixedup<span style="font-family: 宋体">字段&#8221;章节讨论。每个修正详细指明了数量和在每个入口中这些槽的宽度（</span>4<span style="font-family: 宋体">或</span>8<span style="font-family: 宋体">字节）。每个</span>V-<span style="font-family: 宋体">表的槽包含了相应方法的元数据符号，这将在执行期间被方法本身的地址或提供了非托管的方法入口的一个封送了</span>thunk<span style="font-family: 宋体">的地址所取代。随着这些修正在运行期间被执行，这个由托管的</span>PE<span style="font-family: 宋体">文件组成的</span>V-<span style="font-family: 宋体">表必须位于一个可读写的区段中。</span>IL<span style="font-family: 宋体">编译器将这个</span>V-<span style="font-family: 宋体">表放在了</span>.sdata<span style="font-family: 宋体">区段中，不像</span>VTFixup<span style="font-family: 宋体">表，后者位于</span>.text<span style="font-family: 宋体">区段中。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">非托管映像文件的</span>V-<span style="font-family: 宋体">表需要完全定义在链接期间，并只需要基本的由</span>OS<span style="font-family: 宋体">加载器执行的重定位修正。由于在执行期间没有生成对</span>V-<span style="font-family: 宋体">表的改变（正如用托管图像的地址代替方法符号），非托管的映像文件在只读区段中携带着它们的</span>V-<span style="font-family: 宋体">表。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">非托管导出表</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在非托管的映像文件中，这些非托管的导出表占据了一个独立的名为</span>.edata<span style="font-family: 宋体">区段。在由</span>IL<span style="font-family: 宋体">编译器生成的映像文件中，这些非托管导出表位于</span>.sdata<span style="font-family: 宋体">区段中，还附带上它所引用的</span>V-<span style="font-family: 宋体">表。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">非托管的导出表包括了有关方法的信息——非托管导出文件能够遍历动态链接。非托管的导出表不是一个单独的表，而是一组连续的</span>5<span style="font-family: 宋体">个表：</span>Export Directory<span style="font-family: 宋体">表，</span>Export Address<span style="font-family: 宋体">表，</span>Name Pointer<span style="font-family: 宋体">表，</span>Ordinal<span style="font-family: 宋体">表和</span>Export Name<span style="font-family: 宋体">表。图</span>4-4<span style="font-family: 宋体">显示了</span>YDD.DLL<span style="font-family: 宋体">模块的导出表之间的联系，它的函数暴露为</span>Yabba<span style="font-family: 宋体">，</span>Dabba<span style="font-family: 宋体">和</span>Doo<span style="font-family: 宋体">。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">图</span>4-4 <span style="font-family: 宋体">非托管表导出表的结构</span></p>
</span>
<p><span style="font-family: 宋体"><img height="367" alt="" src="http://www.cnblogs.com/images/cnblogs_com/jax/MSIL/4_4.gif" width="505" border="0" />&nbsp;</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">非托管的导出信息开始于</span><span lang="EN-US"><font face="Times New Roman">Export Directory</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表，它描述了导出信息的剩余部分。这是只有一个元素的表，包括了位置和其他导出表的大小。这个</span><span lang="EN-US"><font face="Times New Roman">Export Directory</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表的唯一一行的结构，定义在如下的</span><span lang="EN-US"><font face="Times New Roman">Winnt.h</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中：</span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;struct&nbsp;_IMAGE_EXPORT_DIRECTORY&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;Characteristics;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;TimeDateStamp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WORD&nbsp;&nbsp;&nbsp;&nbsp;MajorVersion;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WORD&nbsp;&nbsp;&nbsp;&nbsp;MinorVersion;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;Name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;Base;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;NumberOfFunctions;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;NumberOfNames;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;AddressOfFunctions;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;AddressOfNames;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;AddressOfNameOrdinals;<br />
}&nbsp;IMAGE_EXPORT_DIRECTORY,&nbsp;<br />
*PIMAGE_EXPORT_DIRECTORY;</span></div>
</span></span>
<p style="text-indent: 21pt"><span style="font-family: 宋体">简而言之，</span>_IMAGE_EXPORT_DIRECTORY<span style="font-family: 宋体">字段包括了以下部分：</span></p>
<p style="text-indent: 21pt">Characteristics<span style="font-family: 宋体">：保留的。这个字段应该被设置为</span>0<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt">TimeDateStamp<span style="font-family: 宋体">：导出数据生成的时间和日期。</span></p>
<p style="text-indent: 21pt">MajorVersion<span style="font-family: 宋体">：主版本号。这个字段和</span>MinorVersion<span style="font-family: 宋体">字段只用于信息；</span>IL<span style="font-family: 宋体">编译器并没有设置它们。</span></p>
<p style="text-indent: 21pt">MinorVersion<span style="font-family: 宋体">：次版本号。</span></p>
<p style="text-indent: 21pt">Name<span style="font-family: 宋体">：</span>ASCII<span style="font-family: 宋体">字符串的</span>RVA<span style="font-family: 宋体">，包括了导出模块的名称。</span></p>
<p style="text-indent: 21pt">Base<span style="font-family: 宋体">：顺序的基数（通常是</span>1<span style="font-family: 宋体">）。这是用来导出在映像文件表中的开始顺序的数字。</span></p>
<p style="text-indent: 21pt">NumberOfFunctions<span style="font-family: 宋体">：</span>Export Address<span style="font-family: 宋体">表中的入口数量。</span></p>
<p style="text-indent: 21pt">NumberOfNames<span style="font-family: 宋体">：</span>Export Name<span style="font-family: 宋体">表中的入口数量。</span></p>
<p style="text-indent: 21pt">AddressOfFunctions<span style="font-family: 宋体">：</span>Export Address<span style="font-family: 宋体">表中的</span>RVA<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt">AddressOfNames<span style="font-family: 宋体">：</span>Export Name<span style="font-family: 宋体">表中的</span>RVA<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt">AddressOfNameOrdinals<span style="font-family: 宋体">：</span>Name Pointer<span style="font-family: 宋体">表中的</span>RVA<span style="font-family: 宋体">。</span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt">Export Address<span style="font-family: 宋体">表包含了被导出为入口点的</span>RVA<span style="font-family: 宋体">。一个进入点的导出序号定义为它的在</span>Export Address<span style="font-family: 宋体">表中的基于</span>0<span style="font-family: 宋体">的索引加上基本序号（</span>IMAGE_EXPORT_DIRECTORY<span style="font-family: 宋体">结构的</span>Base<span style="font-family: 宋体">字段值）。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在托管的文件中，</span>Export Address<span style="font-family: 宋体">表不仅包括了属于导出进入点（方法）自身的</span>RVA<span style="font-family: 宋体">，还有非托管导出</span>stub<span style="font-family: 宋体">——拥有对这些进入点的方法。（参见本章前面介绍的&#8220;文本区段&#8221;）。导出</span>stub<span style="font-family: 宋体">，按照顺序，包括了对相应的</span>V-<span style="font-family: 宋体">表的槽的引用。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在一个</span>Export Address<span style="font-family: 宋体">表中的</span>RVA<span style="font-family: 宋体">，可以是一个</span>forwarder RVA<span style="font-family: 宋体">，识别了一个重导出的进入点——就是说，一个指向这个模块的入口从一个模块导入并导出为其自身。在这种情形中，这个</span>RVA<span style="font-family: 宋体">指向了一个包括了导入名称的</span>ASCII<span style="font-family: 宋体">字符串。导入名称可能是一个</span>DLL<span style="font-family: 宋体">名称和这个导入点（</span>SomeDLL.someFunc<span style="font-family: 宋体">）的名称或一个</span>DLL<span style="font-family: 宋体">名称和在这个</span>DLL<span style="font-family: 宋体">（</span>SomeDLL.#12<span style="font-family: 宋体">）中导入入口的序号。</span></p>
<p style="text-indent: 21pt">IL<span style="font-family: 宋体">编译器并不允许重导出，因此由这个编译器生成的一个映像文件的</span>Export Address<span style="font-family: 宋体">表的入口，总是表示了非托管导出</span>stub<span style="font-family: 宋体">的</span>RVA<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt">Export Name<span style="font-family: 宋体">表包括了以</span>0<span style="font-family: 宋体">结尾的</span>ASCII<span style="font-family: 宋体">字符串，表示了由这个模块导出的方法导出名称。严格的讲，</span>Export Name<span style="font-family: 宋体">表不仅是一个表，还是一系列以</span>0<span style="font-family: 宋体">结尾的字符串。</span>Export Name<span style="font-family: 宋体">表中的导出名称按照字母顺序排序，从而使按照名称的二分查找法的入口点变得便利。导出名称可能不同于声明在模块中的方法下的名称。如果一个导出方法是只按照序号导出的，可能根本没有导出名称。在这种情形中，它的序号并不包括在</span>Ordinal<span style="font-family: 宋体">表中。</span>IL<span style="font-family: 宋体">编译器不允许未命名的导出。</span></p>
<p style="text-indent: 21pt">Name Pointer<span style="font-family: 宋体">表包括了来自</span>Export Name<span style="font-family: 宋体">表的由</span>RVA<span style="font-family: 宋体">组成的导出名称。</span></p>
<p style="text-indent: 21pt">Ordinal<span style="font-family: 宋体">表包括了对</span>Export Address<span style="font-family: 宋体">表的</span>2<span style="font-family: 宋体">个字节的索引。</span>Name Pointer<span style="font-family: 宋体">表和</span>Ordinal<span style="font-family: 宋体">表构成了两个类似的数组，并作为一个直接查找表来操作，重新排列了入口以至于它们可以从词法上按名称排序。当一个入口根据名称被识别时，这个二分查找法在</span>Name Pointer<span style="font-family: 宋体">表中被引导。如果在</span>Name Pointer<span style="font-family: 宋体">表中发现被找到的入口和地址数字</span>N<span style="font-family: 宋体">的名称相匹配，这个入口的序号会被从</span>Ordinal<span style="font-family: 宋体">表中的元素数字</span>N<span style="font-family: 宋体">取出。通过这个序号，这个入口的地址可以从</span>Export Address<span style="font-family: 宋体">中重新得到。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">第</span>18<span style="font-family: 宋体">章检查了非托管的导出信息，以及将托管方法暴露为非托管导出的细节</span></p>
<p>&nbsp;</p>
<p><strong>TLS</strong></p>
<p style="text-indent: 21pt">ILAsm<span style="font-family: 宋体">和</span>VC++<span style="font-family: 宋体">允许你定义属于</span>TLS<span style="font-family: 宋体">的数据常量并映射静态字段到数据常量上。</span>TLS<span style="font-family: 宋体">是一个特殊的存储类，在这里，一个数据对象不仅是一个栈变量仍然还是本地化到每个隔离的线程。从而，每个线程可以为每一个这样的变量维护一个不同的值。</span></p>
<p style="text-indent: 21pt">TLS<span style="font-family: 宋体">数据在</span>TLS<span style="font-family: 宋体">目录中描述，</span>IL<span style="font-family: 宋体">编译器将其放置于</span>.sdata<span style="font-family: 宋体">区段中。用于</span>32<span style="font-family: 宋体">位映像文件的</span>TLS<span style="font-family: 宋体">目录结构定义在如下的</span>Winnt.h<span style="font-family: 宋体">中：</span><span style="font-family: 宋体"></p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;struct&nbsp;_IMAGE_TLS_DIRECTORY32&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;StartAddressOfRawData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;EndAddressOfRawData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;AddressOfIndex;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;AddressOfCallBacks;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;SizeOfZeroFill;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;Characteristics;<br />
}&nbsp;IMAGE_TLS_DIRECTORY32;</span></div>
</span>
<p style="text-indent: 21pt"><span style="font-family: 宋体">用于</span>64<span style="font-family: 宋体">位映像（</span>IMAGE_TLS_DIRECTORY64<span style="font-family: 宋体">）的</span>TLS<span style="font-family: 宋体">目录的结构是类似的，除了开头的</span>4<span style="font-family: 宋体">个字段是</span>8<span style="font-family: 宋体">字节的无符号整数（</span>ULONGLONG<span style="font-family: 宋体">）取代了</span>4<span style="font-family: 宋体">字节的无符号整数（</span>ULONG<span style="font-family: 宋体">）。这个结构的字段如下：</span></p>
<p style="text-indent: 21pt">StartAddressOfRawData<span style="font-family: 宋体">：</span>TLS<span style="font-family: 宋体">数据常量的虚地址（是</span>VA<span style="font-family: 宋体">而不是</span>RVA<span style="font-family: 宋体">）的开始部分。</span>TLS<span style="font-family: 宋体">数据常量加上未初始化的</span>TLS<span style="font-family: 宋体">数据一起形成了</span>TLS<span style="font-family: 宋体">模板。每当一个线程创建的时候，操作系统就会制作一个对</span>TLS<span style="font-family: 宋体">模板的复制，从而提供了每个带有&#8220;私有&#8221;数据常量和字段映射的线程。</span></p>
<p style="text-indent: 21pt">EndAddressOfRawData<span style="font-family: 宋体">：</span>TLS<span style="font-family: 宋体">数据常量的</span>VA<span style="font-family: 宋体">的结束部分。</span>TLS<span style="font-family: 宋体">数据的结束部分（如果有的话）以</span>0<span style="font-family: 宋体">填充。</span>IL<span style="font-family: 宋体">编译器允许未初始化的</span>TLS<span style="font-family: 宋体">数据，假定</span>TLS<span style="font-family: 宋体">数据常量代表全部的</span>TLS<span style="font-family: 宋体">模板，因此不会留下什么被</span>0<span style="font-family: 宋体">填充。</span></p>
<p style="text-indent: 21pt">AddressOfIndex<span style="font-family: 宋体">：</span>4<span style="font-family: 宋体">字节</span>TLS<span style="font-family: 宋体">索引的</span>VA<span style="font-family: 宋体">，位于普通的数据区段。</span>IL<span style="font-family: 宋体">编译器将</span>TLS<span style="font-family: 宋体">索引放入</span>.sdata<span style="font-family: 宋体">区段，直接位于</span>TLS<span style="font-family: 宋体">目录结构和回调函数指针数组休止符的后面。</span></p>
<p style="text-indent: 21pt">AddressOfCallBacks<span style="font-family: 宋体">：</span>TLS<span style="font-family: 宋体">回调函数指针的一个以</span>null<span style="font-family: 宋体">结尾的数组的</span>VA<span style="font-family: 宋体">。这个数组以</span>null<span style="font-family: 宋体">结尾，而结果这个字段并不是</span>null<span style="font-family: 宋体">值并且如果没有指出回调函数的话，就指向一个全部为</span>0<span style="font-family: 宋体">的指针。</span>IL<span style="font-family: 宋体">编译器并不支持回调函数，因此</span>TLS<span style="font-family: 宋体">回调函数指针的整个数组包括了一个</span>null<span style="font-family: 宋体">休止符。这个</span>null<span style="font-family: 宋体">休止符在</span>.sdata<span style="font-family: 宋体">区段中的</span>TLS<span style="font-family: 宋体">目录结构之后。</span></p>
<p style="text-indent: 21pt">SizeOfZeroFill<span style="font-family: 宋体">：</span>TLS<span style="font-family: 宋体">模板的未初始化部分的大小，当</span>TLS<span style="font-family: 宋体">模板的一份复制被创建的时候，以</span>0<span style="font-family: 宋体">填充。</span>IL<span style="font-family: 宋体">编译器将这个字段设置为</span>0<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt">Characteristics<span style="font-family: 宋体">：保留的。这个字段应该被设置为</span>0<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt">StartAddressOfRawData<span style="font-family: 宋体">，</span>EndAddressOfRawData<span style="font-family: 宋体">，</span>AddressOfIndex<span style="font-family: 宋体">，</span>AddressOfCallBacks<span style="font-family: 宋体">字段保存了</span>VA<span style="font-family: 宋体">而不是</span>RVA<span style="font-family: 宋体">，因此你需要在</span>.reloc<span style="font-family: 宋体">区段为它们定义基本的重定位。</span></p>
<p style="text-indent: 21pt">RVA<span style="font-family: 宋体">和</span>TLS<span style="font-family: 宋体">目录结构的大小存储在</span>PE<span style="font-family: 宋体">头中的第</span>10<span style="font-family: 宋体">个数据目录（</span>TLS<span style="font-family: 宋体">）中。</span>TLS<span style="font-family: 宋体">数据常量，构成了</span>TLS<span style="font-family: 宋体">模板，位于映像文件的</span>.tls<span style="font-family: 宋体">区段中。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">资源</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">你能够嵌入两种截然不同的资源到一个</span>PE<span style="font-family: 宋体">文件中：非托管的特定于平台的资源和托管的特定于</span>CLR<span style="font-family: 宋体">的资源。这两种资源，没有什么共同之处，位于托管映像文件的不同区段，并可以被不同组别的</span>API<span style="font-family: 宋体">访问。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">非托管的资源</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">非托管资源位于映像文件的</span>.rsrc<span style="font-family: 宋体">区段中。开始部分的</span>RVA<span style="font-family: 宋体">和内嵌的非托管资源大小，都表示在</span>PE<span style="font-family: 宋体">头的资源数据目录中。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">非托管资源是通过类型、名称和语言来索引的，它们是二进制的，以这三个特性以及上面的顺序进行分类。一系列资源目录表如下表示这个索引：每个目录表都紧跟着一个由目录入口组成的数组，它们包括了引用数字的整数（</span>ID<span style="font-family: 宋体">）或相应级别的名称（类型、名称和语言的级别）和下一级目录表的地址或数据描述（树的叶子节点）。由于使用了这三个索引特性，任何数据描述都可以通过分析至多三个目录表获取到。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在数据描述获取到之前，它的类型、名称和语言都可以从路径中得到，这个路径由搜索算法遍历以达到数据描述的位置。</span></p>
<p style="text-indent: 21pt">.rsrc<span style="font-family: 宋体">区段有以下结构：</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">资源目录表和入口：正如之前所描述的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">资源目录字符串：</span>Unicode<span style="font-family: 宋体">（</span>UTF-16<span style="font-family: 宋体">）字符串代表了通过目录入口寻址的字符串数据。这些字符串是以</span>2<span style="font-family: 宋体">字节排列的。每个字符串都在前面加上</span>2-<span style="font-family: 宋体">字节无符号整数以表示这个字符串的长度。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">资源数据描述：一组由目录入口记录的地址，包括了这个实际资源数据的大小和位置。</span></p>
<p><span style="font-family: 宋体">资源数据：处于自然状态的</span>undelimited<span style="font-family: 宋体">资源数据，由独立的资源数据组成，其地址和大小定义在数据描述的记录中。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一个资源目录表的结构定义在如下的</span>Winnt.h<span style="font-family: 宋体">中：</span></p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;struct&nbsp;_IMAGE_RESOURCE_DIRECTORY&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;Characteristics;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;TimeDateStamp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WORD&nbsp;&nbsp;&nbsp;&nbsp;MajorVersion;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WORD&nbsp;&nbsp;&nbsp;&nbsp;MinorVersion;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WORD&nbsp;&nbsp;&nbsp;&nbsp;NumberOfNamedEntries;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WORD&nbsp;&nbsp;&nbsp;&nbsp;NumberOfIdEntries;<br />
}&nbsp;IMAGE_RESOURCE_DIRECTORY,&nbsp;*PIMAGE_RESOURCE_DIRECTORY;</span></div>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据前面关于对非托管资源和资源目录表的构成的讨论，这些字段的角色应该是明显的。一个异常可能是</span><span lang="EN-US"><font face="Times New Roman">Characteristic</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">字段，这是受保护的并且应该被设置为</span><span lang="EN-US"><font face="Times New Roman">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">名称入口，使用字符串来识别类型、名称或语言，直接跟在资源目录表之后。在其之后，存储了</span><span lang="EN-US"><font face="Times New Roman">ID</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">入口。</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">资源目录入口（名称入口或</span><span lang="EN-US"><font face="Times New Roman">ID</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">入口）是一个</span><span lang="EN-US"><font face="Times New Roman">8</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位的结构，包括了两个</span><span lang="EN-US"><font face="Times New Roman">4</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位无符号整数，在</span><span lang="EN-US"><font face="Times New Roman">Winnt.h</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中定义如下：</span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;struct&nbsp;_IMAGE_RESOURCE_DIRECTORY_ENTRY&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;</span><span style="color: #ff00ff">NameOffset:</span><span style="color: #800080">31</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;</span><span style="color: #ff00ff">NameIsString:</span><span style="color: #800080">1</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;Name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WORD&nbsp;&nbsp;&nbsp;&nbsp;Id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;OffsetToData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;</span><span style="color: #ff00ff">OffsetToDirectory:</span><span style="color: #800080">31</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;</span><span style="color: #ff00ff">DataIsDirectory:</span><span style="color: #800080">1</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
}IMAGE_RESOURCE_DIRECTORY_ENTRY,&nbsp;*PIMAGE_RESOURCE_DIRECTORY_ENTRY;</span></div>
</span>
<p style="text-indent: 21pt"><span style="font-family: 宋体">如果第一个</span>4<span style="font-family: 宋体">位的组件的开始位被设置了，入口就是一个名称入口，并且剩下的</span>31<span style="font-family: 宋体">位代表了名称字符串的偏移量；否则，这个入口就是一个</span>ID<span style="font-family: 宋体">入口，并且它的</span>16<span style="font-family: 宋体">个不重要的位保存了</span>ID<span style="font-family: 宋体">值。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">如果第二个</span>4<span style="font-family: 宋体">位的组件的开始位被设置了，那么这个项，它的偏移量由剩下的</span>31<span style="font-family: 宋体">位所表示，是资源目录表的下一级别，否则它就是一个资源数据描述。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">资源数据描述是一个定义在如下</span>Winnt.h<span style="font-family: 宋体">中的</span>16<span style="font-family: 宋体">位结构：</span></p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;struct&nbsp;_IMAGE_RESOURCE_DATA_ENTRY&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;OffsetToData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;Size;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;CodePage;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;Reserved;<br />
}&nbsp;IMAGE_RESOURCE_DATA_ENTRY,&nbsp;*PIMAGE_RESOURCE_DATA_ENTRY;</span></div>
<p style="text-indent: 21pt">OffsetToData<span style="font-family: 宋体">和</span>Size<span style="font-family: 宋体">字段刻画了资源数据相应的</span>chunk<span style="font-family: 宋体">的特征，这些</span>chunk<span style="font-family: 宋体">组成了一个独立的资源。</span>OffsetToData<span style="font-family: 宋体">被详细指明相对于资源目录的起始位置。</span>CodePage<span style="font-family: 宋体">代码页的</span>ID<span style="font-family: 宋体">，用于对元数据中的代码点的值进行解码。通常这是</span>Unicode<span style="font-family: 宋体">的代码页。最后，不要在这里感到惊讶，</span>Reserved<span style="font-family: 宋体">字段是受保护的并且必须被设置为</span>0<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt">IL<span style="font-family: 宋体">编译器创建了</span>.rsrc<span style="font-family: 宋体">区段并内嵌了来自相应的</span>.res<span style="font-family: 宋体">文件的非托管资源——如果这个文件文件被详细指定在命令行选项。编译器只可以为每个模块内嵌一个非托管的资源文件。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">当</span>IL<span style="font-family: 宋体">反编译器分析一个托管的</span>PE<span style="font-family: 宋体">文件并找到这个</span>.rsrc<span style="font-family: 宋体">区段，它从这个这个区段中读取数据和它的结构，并发布包括了在</span>PE<span style="font-family: 宋体">文件中所有的非托管资源的</span>.res<span style="font-family: 宋体">文件。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">托管资源</span></strong></p>
<p style="text-indent: 21pt">CLR<span style="font-family: 宋体">头的</span>Resource<span style="font-family: 宋体">字段包括了</span>RVA<span style="font-family: 宋体">和内嵌在</span>PE<span style="font-family: 宋体">文件中的托管资源的大小。这并没有对</span>PE<span style="font-family: 宋体">头的</span>Resource<span style="font-family: 宋体">目录做些什么，但是它详细指定了</span>RVA<span style="font-family: 宋体">和非托管的特定于平台的资源的大小。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在由</span>IL<span style="font-family: 宋体">编译器创建的</span>PE<span style="font-family: 宋体">文件中，非托管资源位于映像文件的</span>.rsrc<span style="font-family: 宋体">区段中，反之托管资源位于</span>.text<span style="font-family: 宋体">区段中，和元数据、</span>IL<span style="font-family: 宋体">代码等等在一起。托管资源连续地存储在</span>.text<span style="font-family: 宋体">区段中。元数据携带着</span>ManifestResource<span style="font-family: 宋体">的记录，每一个对应着一个托管的资源，包括了托管资源的名称，以及在</span>CLR<span style="font-family: 宋体">头的</span>Resource<span style="font-family: 宋体">字段中详细指明的</span>RVA<span style="font-family: 宋体">的开始部分距离资源开始处的偏移量。在这个偏移量的位置上，一个</span>4<span style="font-family: 宋体">位的无符号整数指出了资源的字节长度。紧跟在后面的则是资源本身。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">当</span>IL<span style="font-family: 宋体">反编译器处理一个托管的映像文件并找到内嵌的托管资源，它将每个资源写到一个独立的文件中，并根据资源的名称来命名。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">当</span>IL<span style="font-family: 宋体">编译器创建一个</span>PE<span style="font-family: 宋体">文件时，它从文件中读取定义在源代码中的所有托管的内嵌的资源，根据资源的名称并将它们写到</span>.text<span style="font-family: 宋体">区段中，每一个都以它们特定的长度作为开始。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">作为一个练习，我提议你使用</span>IL<span style="font-family: 宋体">反编译器打开任何托管的可执行体（比方说，一个简单的示例），并选择</span>View/Headers<span style="font-family: 宋体">菜单进入点。你将会看到所有的头和它们的&#8220;</span>field<span style="font-family: 宋体">&#8221;字段。</span></p>
<p>&nbsp;</p>
<img src ="http://www.cnblogs.com/Jax/aggbug/1278151.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41940/" target="_blank">[新闻]惠普139亿美元完成对EDS的收购</a>]]></description></item><item><title>(翻译)《Expert .NET 2.0 IL Assembler》 第四章 托管可执行体文件的结构 4.2 CLR头（一） </title><link>http://www.cnblogs.com/Jax/archive/2008/08/27/1278148.html</link><dc:creator>包建强</dc:creator><author>包建强</author><pubDate>Wed, 27 Aug 2008 15:40:00 GMT</pubDate><guid>http://www.cnblogs.com/Jax/archive/2008/08/27/1278148.html</guid><wfw:comment>http://www.cnblogs.com/Jax/comments/1278148.html</wfw:comment><comments>http://www.cnblogs.com/Jax/archive/2008/08/27/1278148.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Jax/comments/commentRss/1278148.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Jax/services/trackbacks/1278148.html</trackback:ping><description><![CDATA[<p><a href="http://www.cnblogs.com/Jax/archive/2008/07/19/1246490.html">返回目录</a></p>
<p>&nbsp;</p>
<p><strong><span style="font-size: 12pt">CLR</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">头</span></strong><strong></strong></p>
<p style="text-indent: 21pt">PE<span style="font-family: 宋体">头的第</span>15<span style="font-family: 宋体">个目录入口包括了</span>RVA<span style="font-family: 宋体">和映像文件中的</span>CLR<span style="font-family: 宋体">头的大小。这个</span>CLR<span style="font-family: 宋体">头，包括了所有特定于</span>CLR<span style="font-family: 宋体">的数据入口和其他的信息，应该位于这个映像文件中的一段只读区段。</span>IL<span style="font-family: 宋体">编译器将</span>CLR<span style="font-family: 宋体">头放在了</span>.text<span style="font-family: 宋体">区段。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体">头的结构</span></strong></p>
<p style="text-indent: 21pt">CLR<span style="font-family: 宋体">头定义在</span>CorHdr.h<span style="font-family: 宋体">中——一个头文件被分配为</span>Microsoft .NET Framework SDK<span style="font-family: 宋体">的一部分，如下：</span></p>
<p style="text-indent: 21pt"></p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;struct&nbsp;IMAGE_COR20_HEADER<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cb;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;USHORT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MajorRuntimeVersion;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;USHORT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MinorRuntimeVersion;<br />
</span><span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</span><span style="color: #008000">&nbsp;Symbol&nbsp;table&nbsp;and&nbsp;startup&nbsp;information</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMAGE_DATA_DIRECTORY&nbsp;&nbsp;&nbsp;&nbsp;MetaData;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Flags;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EntryPointToken;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EntryPointRVA;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
</span><span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</span><span style="color: #008000">&nbsp;Binding&nbsp;information</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMAGE_DATA_DIRECTORY&nbsp;&nbsp;&nbsp;&nbsp;Resources;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMAGE_DATA_DIRECTORY&nbsp;&nbsp;&nbsp;&nbsp;StrongNameSignature;<br />
</span><span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</span><span style="color: #008000">&nbsp;Regular&nbsp;fixup&nbsp;and&nbsp;binding&nbsp;information</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMAGE_DATA_DIRECTORY&nbsp;&nbsp;&nbsp;&nbsp;CodeManagerTable;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMAGE_DATA_DIRECTORY&nbsp;&nbsp;&nbsp;&nbsp;VTableFixups;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMAGE_DATA_DIRECTORY&nbsp;&nbsp;&nbsp;&nbsp;ExportAddressTableJumps;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMAGE_DATA_DIRECTORY&nbsp;&nbsp;&nbsp;&nbsp;ManagedNativeHeader;<br />
}&nbsp;IMAGE_COR20_HEADER;</span></div>
<p style="text-indent: 21pt"><span style="font-family: 宋体">表</span>4-6<span style="font-family: 宋体">对这个头的字段提供了进一步的着眼。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">表</span>4-6 CLR<span style="font-family: 宋体">头的字段</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p><strong><span style="font-family: 宋体">偏移量</span></strong></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p><strong><span style="font-family: 宋体">大小</span></strong></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p><strong><span style="font-family: 宋体">字段名</span></strong></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p><strong><span style="font-family: 宋体">描述</span></strong></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>0</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>4</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>Cb</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p><span style="font-family: 宋体">头的字节大小。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>4</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>2</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>MajorRuntimeVersion</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p>CLR<span style="font-family: 宋体">需要运行程序的最小版本的主版本号。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>6</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>2</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>MinorRuntimeVersion</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p>CLR<span style="font-family: 宋体">需要运行程序的最小版本的次版本号。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>8</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>8</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>MetaData</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p>RVA<span style="font-family: 宋体">和元数据的大小。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>16</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>4</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>Flags</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p><span style="font-family: 宋体">二进制标记，在接下来的章节讨论。在</span>ILAsm<span style="font-family: 宋体">中，你可以通过显示地使用指令</span>.corflags &lt;integer value&gt;<span style="font-family: 宋体">和</span>/<span style="font-family: 宋体">或命令行选项</span>/FLAGS=&lt;integer value&gt;<span style="font-family: 宋体">详细指明这个值。这个命令行选项优先于指令。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>20</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>4</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>EntryPointToken/EntryPointRVA</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p><span style="font-family: 宋体">这个映像文件的入口点的元数据识别符（符号）；对于</span>DLL<span style="font-family: 宋体">映像而言可以是</span>0<span style="font-family: 宋体">。这个字段识别了属于这个模块的一个方法或包括这个入口点方法的一个模块。在</span>2.0<span style="font-family: 宋体">或更新的版本中，这个字段可能包括内嵌的本地入口点方法的</span>RVA</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>24</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>8</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>Resources</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p>RVA<span style="font-family: 宋体">和托管资源的大小。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>32</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>8</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>StrongNameSignature</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p>RVA<span style="font-family: 宋体">和用于这个</span>PE<span style="font-family: 宋体">文件的哈希数据的大小，由加载器在绑定和版本控制中使用。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>40</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>8</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>CodeManagerTable</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p>RVA<span style="font-family: 宋体">和代码管理表的大小。在现有的</span>CLR<span style="font-family: 宋体">发布版本中，这个字段是保留的，并被设置为</span>0<span style="font-family: 宋体">。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>48</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>8</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>VTableFixups</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p>RVA<span style="font-family: 宋体">和一个由虚拟表（</span>v-<span style="font-family: 宋体">表）修正组成的数组的字节大小。在当前托管的编译器中，只有</span>VC++<span style="font-family: 宋体">连接器和</span>IL<span style="font-family: 宋体">编译器能够生成这个数组。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>56</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>8</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>ExportAddressTableJumps</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p>RVA<span style="font-family: 宋体">和由</span>jump thunk<span style="font-family: 宋体">的地址组成的数组的大小。在托管的编译器中，只有</span>8.0<span style="font-family: 宋体">之前版本的</span>VC++<span style="font-family: 宋体">能够生成这种表，这将允许导出内嵌在托管</span>PE<span style="font-family: 宋体">文件中的非托管本地方法。在</span>CLR<span style="font-family: 宋体">的</span>2.0<span style="font-family: 宋体">版本中，这个入口是废弃的并且必须被设置为</span>0<span style="font-family: 宋体">。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 50.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="67">
            <p>64</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 36pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="48">
            <p>8</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="168">
            <p>ManagedNativeHeader</p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: #f0f0f0; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #f0f0f0; width: 213.7pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent" valign="top" width="285">
            <p><span style="font-family: 宋体">为预编译映像而保留的，被设置为</span>0<span style="font-family: 宋体">。</span></p>
            </td>
        </tr>
    </table>
<p>&nbsp;</p>
<p><strong>Flags</strong><strong><span style="font-family: 宋体">字段</span></strong></p>
<p style="text-indent: 21pt">CLR<span style="font-family: 宋体">头的</span>Flags<span style="font-family: 宋体">字段保存了下列位标志的位或运算：</span></p>
<p style="text-indent: 21pt">COMIMAGE_FLAGS_ILONLY (0x00000001)<span style="font-family: 宋体">：这个映像文件只包括</span>IL<span style="font-family: 宋体">代码，而没有内嵌的本地非托管代码——除开始的</span>stub<span style="font-family: 宋体">外（只是简单地执行一个到</span>CLR<span style="font-family: 宋体">进入点的跳转）。</span>CLR<span style="font-family: 宋体">——意识到操作系统（如</span>Windows XP<span style="font-family: 宋体">或更新的操作系统）忽略开始部分的</span>stub<span style="font-family: 宋体">并自动调用</span>CLR<span style="font-family: 宋体">，到目前为止，所有的实际意图都是为了这个文件可以被认为是纯净的</span>IL<span style="font-family: 宋体">。然而，在</span>Windows XP<span style="font-family: 宋体">或更新操作系统下运行的时候，设置这个标记会引起特定的问题。如果设置了这个标记，</span>Windows XP<span style="font-family: 宋体">或更新操作系统的加载器不仅忽略了开始部分的</span>stub<span style="font-family: 宋体">，还忽略了</span>.reloc<span style="font-family: 宋体">区段，在这种情形中后者将包括一个对</span>CLR<span style="font-family: 宋体">入口点的单一的重定位（或者说在特定于</span>IA64<span style="font-family: 宋体">映像中的单独的一对重定位）。然而，</span>.reloc<span style="font-family: 宋体">区段既可以包括</span>.tls<span style="font-family: 宋体">区段的开始和结束位置的重定位，还包括被称为</span>data on data<span style="font-family: 宋体">的重定向（就是说，数据常量指向其它的数据常量）。在这些现有的托管的编译器中，只有</span>VC++<span style="font-family: 宋体">和</span>IL<span style="font-family: 宋体">编译器可以生成这些项。</span>VC++<span style="font-family: 宋体">的</span>7.0<span style="font-family: 宋体">版本和</span>7.1<span style="font-family: 宋体">版本（对应</span>CLR<span style="font-family: 宋体">的</span>1.0<span style="font-family: 宋体">版本和</span>1.1<span style="font-family: 宋体">版本）并没有设置这个标记，因为他生成的映像文件从来不是纯净的</span>IL<span style="font-family: 宋体">。在</span>2.0<span style="font-family: 宋体">版本中，这种情形有了改变，而当前，</span>VC++<span style="font-family: 宋体">和</span>IL<span style="font-family: 宋体">编译器是唯一的两个能够生成纯净</span>IL<span style="font-family: 宋体">映像文件的工具，而这些图像需要在</span>.reloc<span style="font-family: 宋体">区段中额外的重定向。为了解决这个问题，如果发布的是基于</span>BLS<span style="font-family: 宋体">的数据或</span>data on data<span style="font-family: 宋体">，</span>IL<span style="font-family: 宋体">编译器就会清除这个标记；如果目标平台是</span>32<span style="font-family: 宋体">位的，</span>IL<span style="font-family: 宋体">编译器就会替代地设置这个</span>OMIMAGE_FLAGS_32BITREQUIRED<span style="font-family: 宋体">标记。</span></p>
<p style="text-indent: 21pt">COMIMAGE_FLAGS_32BITREQUIRED (0x00000002)<span style="font-family: 宋体">：映像文件只可以被加载进一个</span>32<span style="font-family: 宋体">位进程中。这个标记是单独设置的——当本地非托管代码内嵌在</span>PE<span style="font-family: 宋体">文件中，或者当</span>.reloc<span style="font-family: 宋体">区段包括了额外的重定向的时候，或者与</span>_ILONLY<span style="font-family: 宋体">联合起来被设置——当可执行体不仅包括额外的重定向而且在某些方面是以特定于</span>32<span style="font-family: 宋体">位的（例如，调用一个非托管</span>32<span style="font-family: 宋体">位特定的</span>API<span style="font-family: 宋体">或者使用</span>4<span style="font-family: 宋体">字节的整型来存储指针）。</span></p>
<p style="text-indent: 21pt">COMIMAGE_FLAGS_IL_LIBRARY (0x00000004)<span style="font-family: 宋体">：这个标记是废弃的并且不能被设置。使用</span>.corflags<span style="font-family: 宋体">指令设置它——正如</span>IL<span style="font-family: 宋体">编译器允许的，将会生成你的未加载的模块。</span></p>
<p style="text-indent: 21pt">COMIMAGE_FLAGS_STRONGNAMESIGNED (0x00000008)<span style="font-family: 宋体">：映像文件是受强签名保护的。强签名。这个强签名包括了公钥和哈希签名，并作为一个编译集同一性的一部分，伴随着这个编译集的名称、版本号以及文化信息。当这个强签名过程被应用到一个映像文件的时候，就会设置这个标记。没有编译器，包括</span>ILAsm<span style="font-family: 宋体">在内，可以显示地设置这个标记。</span></p>
<p style="text-indent: 21pt">COMIMAGE_FLAGS_NATIVE_ENTRYPOINT (0x00000010)<span style="font-family: 宋体">：执行体的进入点是一个非托管的方法。</span>CLR<span style="font-family: 宋体">头的</span>EntryPointToken/EntryPointRVA<span style="font-family: 宋体">字段包括了这个本地方法的</span>RVA<span style="font-family: 宋体">。这个标记是在</span>CLR 2.0<span style="font-family: 宋体">版本中引进的。</span></p>
<p style="text-indent: 21pt">COMIMAGE_FLAGS_TRACKDEBUGDATA (0x00010000)<span style="font-family: 宋体">：</span>CLR<span style="font-family: 宋体">加载器和</span>IL<span style="font-family: 宋体">编译器被要求对方法的调试信息进行跟踪。这个方法没有被使用。</span></p>
<p>&nbsp;</p>
<p><strong>EntryPointToken</strong><strong><span style="font-family: 宋体">字段</span></strong><strong></strong></p>
<p style="text-indent: 21pt">CLR<span style="font-family: 宋体">头的</span>EntryPointToken<span style="font-family: 宋体">字段包括了一个符号（元数据标志符）——一个方法定义（</span>MethodDef<span style="font-family: 宋体">）或一个文件引用（</span>File<span style="font-family: 宋体">）。</span>MethodDef<span style="font-family: 宋体">符号将定义在模块（一个托管的</span>PE<span style="font-family: 宋体">文件）中的方法识别为入口点方法。</span>File<span style="font-family: 宋体">记号只用在一种情形中：在多模块编译集的主模块的</span>CLR<span style="font-family: 宋体">头中，当进入点方法定义在这个编译集的另一个模块中（由文件引用识别）。在这种情形中，这个由文件引用识别的模块包括了在它所在的</span>CLR<span style="font-family: 宋体">头的</span>EntryPointToken<span style="font-family: 宋体">字段中相应的</span>MethodDef<span style="font-family: 宋体">记号。</span></p>
<p style="text-indent: 21pt">EntryPointToken<span style="font-family: 宋体">必须在可以运行的执行体（</span>EXE<span style="font-family: 宋体">文件）中详细指明。例如，如果源代码没有定义入口点，</span>IL<span style="font-family: 宋体">编译器甚至都不会尝试生成一个</span>EXE<span style="font-family: 宋体">文件。</span>CLR<span style="font-family: 宋体">加载器利用了入口点方法的签名上的局限性：这个方法必须返回一个有符号或无符号的</span>4<span style="font-family: 宋体">字节的整数或者</span>void<span style="font-family: 宋体">，而且它至多必须有一个</span>string<span style="font-family: 宋体">或</span>string[]<span style="font-family: 宋体">（</span>string<span style="font-family: 宋体">向量）类型的参数。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">没有这些不能运行的可执行体（</span>DLL<span style="font-family: 宋体">文件），这将是一个不一样的故事。纯</span>IL<span style="font-family: 宋体">的</span>DLL<span style="font-family: 宋体">并不需要定义了的入口点方法，并且在它们的</span>CLR<span style="font-family: 宋体">头中的</span>EntryPointToken<span style="font-family: 宋体">字段必需被设置为</span>0<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">混合代码的</span>DLL<span style="font-family: 宋体">——包括了</span>IL<span style="font-family: 宋体">和内嵌的非托管代码——由</span>VC++<span style="font-family: 宋体">编译器和链接器生成的，必须在这个</span>DLL<span style="font-family: 宋体">被调用时直接运行非托管本地函数</span>DllMain<span style="font-family: 宋体">，从而为非托管的本地</span>DLL<span style="font-family: 宋体">组件执行必要的初始化。这个非托管方法的签名必须是如下这样的：</span></p>
<p style="text-indent: 21pt">int DllMain(HINSTANCE, DWORD, void *);</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">为了对托管代码和</span>CLR<span style="font-family: 宋体">可见，</span>DllMain<span style="font-family: 宋体">函数必须被声明为一个对内嵌的本地方法的平台调用（本地</span>P/Invoke<span style="font-family: 宋体">，也被称为</span>IJW<span style="font-family: 宋体">——</span>It Just Works<span style="font-family: 宋体">）。参见</span>18<span style="font-family: 宋体">章获取关于托管和非托管代码互操作的更多细节。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">从</span>2.0<span style="font-family: 宋体">版本开始，你可以详细指明非托管的入口点方法而不用本地平台调用。既然这样，由</span>OMIMAGE_FLAGS_NATIVE_ENTRYPOINT<span style="font-family: 宋体">设定标记指定，这个</span>EntryPointRVA<span style="font-family: 宋体">字段（别名为</span>EntryPointToken<span style="font-family: 宋体">）包括了本地入口点方法的</span>RVA<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这个被</span>CLR<span style="font-family: 宋体">头的</span>EntryPointToken/EntryPointRVA<span style="font-family: 宋体">字段指向的方法并没有对</span>PE<span style="font-family: 宋体">头指向的</span>AddressOfEntryPoint<span style="font-family: 宋体">方法做些什么。</span>AddressOfEntryPoint<span style="font-family: 宋体">总是指向</span>CLR<span style="font-family: 宋体">调用</span>stub<span style="font-family: 宋体">，这对于</span>CLR<span style="font-family: 宋体">是不可见的，不在元数据中反映出来并因此而没有一个符号。</span></p>
<p>&nbsp;</p>
<p><strong>VTableFixups</strong><strong><span style="font-family: 宋体">字段</span></strong></p>
<p style="text-indent: 21pt">CLR<span style="font-family: 宋体">头的</span>VTableFixups<span style="font-family: 宋体">字段是一个数据目录，包括了</span>RVA<span style="font-family: 宋体">和映像文件的</span>V-<span style="font-family: 宋体">表的修正表的大小。托管和非托管方法使用了不同的数据格式，因此当一个托管方法必须被非托管代码调用时，</span>CLR<span style="font-family: 宋体">就会为其创建一个封装的</span>thunk<span style="font-family: 宋体">，这将执行数据转换，而这个</span>thunk<span style="font-family: 宋体">的地址就被放置于相应的地址表中。如果托管方法是被内嵌在当前托管</span>PE<span style="font-family: 宋体">文件中的非托管代码调用的，这个</span>thunk<span style="font-family: 宋体">地址会进入这个文件的</span>V-<span style="font-family: 宋体">表。如果托管方法导出为非托管的，并且在这个托管</span>PE<span style="font-family: 宋体">文件外的任何地方使用，相应的</span>v-<span style="font-family: 宋体">表入口地址必须也进入导出型地址表。在加载的时候（也就是在磁盘的映像文件中），这个</span>V-<span style="font-family: 宋体">表的入口包括了相应的方法符号。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这些</span>V-<span style="font-family: 宋体">表的修正代表了创建这些</span>thunk<span style="font-family: 宋体">所必需的</span>CLR<span style="font-family: 宋体">初始信息。</span>V-<span style="font-family: 宋体">表的修正定义在下面的</span>CorHdr.h<span style="font-family: 宋体">中：</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;struct&nbsp;_IMAGE_COR_VTABLEFIXUP&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RVA;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;USHORT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Count;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;USHORT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type;&nbsp;<br />
}&nbsp;IMAGE_COR_VTABLEFIXUP;</span></div>
<p><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在这个定义中，</span>RVA<span style="font-family: 宋体">指向了</span>V-<span style="font-family: 宋体">表的槽的位置，这个槽包括了方法的符号。</span>Count<span style="font-family: 宋体">详细指出了槽中入口的数量，</span>1<span style="font-family: 宋体">或者更多，例如，对同一个方法的多种实现是存在的，相互覆盖。</span>Type<span style="font-family: 宋体">是以下标记的位或运算，为</span>CLR<span style="font-family: 宋体">提供了关于槽的信息以及使用它能做些什么：</span></p>
<p style="text-indent: 21pt">COR_VTABLE_32BIT (0x01)<span style="font-family: 宋体">：每个入口都是</span>32<span style="font-family: 宋体">位宽的。</span></p>
<p style="text-indent: 21pt">COR_VTABLE_64BIT (0x02)<span style="font-family: 宋体">：每个入口都是</span>64<span style="font-family: 宋体">位宽的。</span></p>
<p style="text-indent: 21pt">COR_VTABLE_FROM_UNMANAGED (0x04)<span style="font-family: 宋体">：由</span>CLR<span style="font-family: 宋体">创建的</span>thunk<span style="font-family: 宋体">必须提供托管和非托管代码间的数据封送。</span></p>
<p style="text-indent: 21pt">COR_VTABLE_CALL_MOST_DERIVED (0x10)<span style="font-family: 宋体">：这个标志当前并不使用。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">显然，头两个标记是互相排斥的。</span>V-<span style="font-family: 宋体">表的这些槽必须是一个紧跟着另一个——就是说，</span>V-<span style="font-family: 宋体">表必须是连续的。</span></p>
<p style="text-indent: 21pt">V-<span style="font-family: 宋体">表位于一个可读写的区段，因为它应该在图像被加载进内存后安排处理。相反，非托管图像中的</span>V-<span style="font-family: 宋体">表位于一个只读区段内。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在现有的托管编译器中，只有</span>VC++<span style="font-family: 宋体">和</span>IL<span style="font-family: 宋体">编译器可以定义</span>V-<span style="font-family: 宋体">表和它的修正。</span></p>
<p>&nbsp;</p>
<p><strong>StrongNameSignature</strong><strong><span style="font-family: 宋体">字段</span></strong></p>
<p style="text-indent: 21pt">CLR<span style="font-family: 宋体">头的</span>StrongNameSignature<span style="font-family: 宋体">字段包括了</span>RVA<span style="font-family: 宋体">和哈希强签名的大小，这将由</span>CLR<span style="font-family: 宋体">使用来确定映像文件的真实性。在映像文件被创建之后，使用由映像文件制造者提供的私钥对其进行哈希处理，而结果哈希块被写入到在映像文件中分配的空间。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">如果即使连映像文件的一个单字节也是后期修改的，真实性检查就会失败，而且映像文件也不会被加载。强签名并不会经历一个反复的过程；如果你使用</span>IL<span style="font-family: 宋体">反编译器反编译一个强名称模块，接着重新编译它，这个模块必须重新进行强名称签名。</span></p>
<p style="text-indent: 21pt">IL<span style="font-family: 宋体">编译器将强名称签名放进映像文件的</span>.text<span style="font-family: 宋体">区段中。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
</span>
<img src ="http://www.cnblogs.com/Jax/aggbug/1278148.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41940/" target="_blank">[新闻]惠普139亿美元完成对EDS的收购</a>]]></description></item><item><title>(翻译)《Expert .NET 2.0 IL Assembler》 第五章 元数据表的组织 5.5 小结</title><link>http://www.cnblogs.com/Jax/archive/2008/08/26/1276379.html</link><dc:creator>包建强</dc:creator><author>包建强</author><pubDate>Tue, 26 Aug 2008 01:23:00 GMT</pubDate><guid>http://www.cnblogs.com/Jax/archive/2008/08/26/1276379.html</guid><wfw:comment>http://www.cnblogs.com/Jax/comments/1276379.html</wfw:comment><comments>http://www.cnblogs.com/Jax/archive/2008/08/26/1276379.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Jax/comments/commentRss/1276379.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Jax/services/trackbacks/1276379.html</trackback:ping><description><![CDATA[<p><a href="http://www.cnblogs.com/Jax/archive/2008/07/19/1246490.html">返回目录</a></p>
<p>&nbsp;</p>
<p><strong><span style="font-size: 12pt; font-family: 宋体">小结</span></strong><strong></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">既然你已经了解元数据原则上是如何被组织的，你要准备好检测这些特定的元数据项和表示它们的表。所有进一步的考虑都将集中在</span>4<span style="font-family: 宋体">个元数据流上——</span>#Strings<span style="font-family: 宋体">、</span>#Blob<span style="font-family: 宋体">、</span>#US<span style="font-family: 宋体">和</span>#~<span style="font-family: 宋体">——因为</span>#GUID<span style="font-family: 宋体">只在一个元数据表中被引用到（</span>Module<span style="font-family: 宋体">表），而</span>#-<span style="font-family: 宋体">流（未优化的元数据）则从来不会被</span>ILAsm<span style="font-family: 宋体">编译器发布。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里对一些人有一些建议，他们想知道这是否一个好的主意——在细微操作元数据的借口下，欺骗元数据头从而有权访问超越元数据之上的数据：忘记他！</span>CLR<span style="font-family: 宋体">加载器在分析元数据头的一致性和元数据本身时有安全保障。如果侦测到不一致性，加载器就拒绝打开这个元数据流。胡乱地修补这个元数据头并不会导致这个模块错误的或不可预计的行为；代替的，它会这段时期生成不可加载的模块。</span></p>
<p>&nbsp;</p>
<p>一些翻译笔记:&nbsp;</p>
<p>quit stalling<span style="font-family: Arial">! </span><span style="font-family: 宋体">不要拖延时间</span></p>
<p><span style="font-family: Arial">It would be tempting to do </span><span style="font-family: 宋体">（去做某事）非常诱人，有诱惑力</span></p>
<p><span style="font-family: Arial">in minute detail: </span><span style="font-family: 宋体">细枝末节</span></p>
<p><span style="font-family: Arial">emission</span><span style="font-family: 宋体">翻译？？？</span></p>
<p><span style="font-family: Arial">mutually exclusive </span><span style="font-family: 宋体">互斥的</span></p>
<p><span style="font-family: 宋体">翻译的有问题，</span><span style="font-family: Arial">bit</span><span style="font-family: 宋体">和</span><span style="font-family: Arial">byte</span><span style="font-family: 宋体">混淆了</span></p>
<p><span style="font-family: Arial">Schema </span><span style="font-family: 宋体">翻译为规格</span></p>
<p><span style="font-family: Arial">Stand-alone</span><span style="font-family: 宋体">的翻译</span> <span style="font-family: 宋体">独立的</span></p>
<p>per se <span style="font-family: 宋体">本身</span> <span style="font-family: 宋体">本质上</span></p>
<p>Edit-and-Continue</p><img src ="http://www.cnblogs.com/Jax/aggbug/1276379.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41939/" target="_blank">[新闻]搜狗五笔输入法发布</a>]]></description></item><item><title>(翻译)《Expert .NET 2.0 IL Assembler》 第五章 元数据表的组织 5.4 元数据和验证</title><link>http://www.cnblogs.com/Jax/archive/2008/08/26/1276375.html</link><dc:creator>包建强</dc:creator><author>包建强</author><pubDate>Tue, 26 Aug 2008 01:22:00 GMT</pubDate><guid>http://www.cnblogs.com/Jax/archive/2008/08/26/1276375.html</guid><wfw:comment>http://www.cnblogs.com/Jax/comments/1276375.html</wfw:comment><comments>http://www.cnblogs.com/Jax/archive/2008/08/26/1276375.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Jax/comments/commentRss/1276375.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Jax/services/trackbacks/1276375.html</trackback:ping><description><![CDATA[<p><a href="http://www.cnblogs.com/Jax/archive/2008/07/19/1246490.html">返回目录</a></p>
<p>&nbsp;</p>
<p><strong><span style="font-size: 12pt; font-family: 宋体">元数据和验证</span></strong><strong></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">然而，这个&#8220;好的暗示&#8221;，仅仅是一个暗示。在前述的部分提供了关于你可以从一个列的确定的类型引用哪些表的信息。这并不意味着你应该引用所有你能够引用的表。在表</span>5-10<span style="font-family: 宋体">中列出的一些群组的符号类型比在</span>CLR<span style="font-family: 宋体">现有的发布版本中实际上可接受的要更加广阔。例如，</span>MemberRefParent<span style="font-family: 宋体">群组，描述了能够包含</span>MemberRef<span style="font-family: 宋体">记录的父级别的表，包括</span>TypeDef<span style="font-family: 宋体">表。但是这个元数据发布</span>API<span style="font-family: 宋体">不会接受</span>TypeDef<span style="font-family: 宋体">符号作为</span>MemberRef<span style="font-family: 宋体">的父级别符号；并且即使这样的元数据不知何故还是发布出来了，加载器将会忽略它。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">元数据发布</span>API<span style="font-family: 宋体">提供了非常少的安全保证（它们中的大多数是相当琐碎的）直到元数据有效性被涉及。元数据是一个极其复杂的系统，并且是文字上的数以百计的需要被强制执行的有效性规则。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">高级别的语言编译器，如</span>VB.NET<span style="font-family: 宋体">或</span>C#<span style="font-family: 宋体">，对元数据发布提供了一个重要级别的保护，因为它们防止了来自程序员的确切的元数据规格说明和发布。这种高级别语言是概念取代的和基于概念的，并且这是编译器的职责来把语言概念转换为元数据结构和</span>IL<span style="font-family: 宋体">代码构造，因此一个编译器可以被建造用来发布有效<span style="color: red">的结构和构造（好吧，或多或少。）</span>另一方面，</span>ILAsm<span style="font-family: 宋体">，就像其它的编译器，是一个面向平台的语言并允许程序员生成巨大的范围的元数据结构和</span>IL<span style="font-family: 宋体">构造，其中只有小部分代表着一个有效的子集。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">考虑到这种的艰难的情形，我们需要依赖于外部的有效性和验证性工具（说到有效性和验证不是在同义反复的练习——在</span>CLR<span style="font-family: 宋体">术语中，有效性经常应用于元数据，验证性择应用于</span>IL<span style="font-family: 宋体">代码。）一个这样的工具就是</span>CLR<span style="font-family: 宋体">本身。加载器依靠很多有效性工具来测试元数据，尤其是那些可以破坏系统的侵害。负责</span>JIT<span style="font-family: 宋体">编译器的运行时子系统执行</span>IL<span style="font-family: 宋体">代码的验证。这些工程被称为&#8220;运行时有效性和验证&#8221;。</span></p>
<p style="text-indent: 21pt">PEVerify<span style="font-family: 宋体">，一个独立的包括在</span>.NET Framework SDK<span style="font-family: 宋体">中的工具，提供了更彻底的有效性和验证。</span>PEVerify<span style="font-family: 宋体">使用了两种独立的子系统，</span>MDValidator<span style="font-family: 宋体">和</span>ILVerifier<span style="font-family: 宋体">。</span>MDValidator<span style="font-family: 宋体">也可以在</span>IL<span style="font-family: 宋体">反编译器中被调用。</span></p>
<p><span style="font-family: 宋体">