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

📄 lion-petut-c05.htm

📁 在DOS下编程因为实模式的限制
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<html>

<head>
<meta http-equiv="Content-Type"
content="text/html; charset=gb_2312-80">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Iczelion的PE教程5: Section Table(节表)</title>
</head>

<body bgcolor="#003366" text="#FFFFFF" link="#FFFFCC"
vlink="#FFCCCC" alink="#CCFFCC">

<h1 align="center"><font color="#FFFFCC">PE教程5: Section Table(节表)</font></h1>

<p><font size="2">请下载 </font><a href="files/PE-tut05.zip"><font
size="2">范例</font></a><font size="2">。</font></p>

<h3>理论<font face="MS Sans Serif">:</font></h3>

<p><font size="2">到本课为止,我们已经学了许多关于
</font><font size="2" face="MS Sans Serif">DOS header </font><font
size="2">和 </font><font size="2" face="MS Sans Serif">PE header
</font><font size="2">的知识。接下来就该轮到 </font><font
size="2" face="MS Sans Serif">section table</font><font size="2">(节表)了。节表其实就是紧挨着
</font><font size="2" face="MS Sans Serif">PE header </font><font
size="2">的一结构数组。该数组成员的数目由 </font><font
size="2" face="MS Sans Serif">file header (</font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_FILE_HEADER</b></font><font
size="2" face="MS Sans Serif">) </font><font size="2">结构中 </font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>NumberOfSections</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">域的域值来决定。节表结构又命名为
</font><font color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_SECTION_HEADER</b></font><font
size="2">。</font></p>

<p><font size="2" face="MS Sans Serif"><b>IMAGE_SIZEOF_SHORT_NAME
equ 8 </b></font></p>

<p><font size="2" face="MS Sans Serif"><b>IMAGE_SECTION_HEADER
STRUCT <br>
&nbsp;&nbsp;&nbsp;Name1 db IMAGE_SIZEOF_SHORT_NAME dup(?) <br>
&nbsp;&nbsp;&nbsp;union Misc <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PhysicalAddress dd ? <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VirtualSize dd ? <br>
&nbsp;&nbsp;&nbsp;ends <br>
&nbsp;&nbsp;&nbsp;VirtualAddress dd ? <br>
&nbsp;&nbsp;&nbsp;SizeOfRawData dd ? <br>
&nbsp;&nbsp;&nbsp;PointerToRawData dd ? <br>
&nbsp;&nbsp;&nbsp;PointerToRelocations dd ? <br>
&nbsp;&nbsp;&nbsp;PointerToLinenumbers dd ? </b></font><font
size="2"><b>哦<br>
</b></font><font size="2" face="MS Sans Serif"><b>&nbsp;&nbsp;&nbsp;NumberOfRelocations
dw ? <br>
&nbsp;&nbsp;&nbsp;NumberOfLinenumbers dw ? <br>
&nbsp;&nbsp;&nbsp;Characteristics dd ? <br>
IMAGE_SECTION_HEADER ENDS </b></font></p>

<p><font size="2">同样,不是所有成员都是很有用的,我们只关心那些真正重要的。</font></p>

<table border="1" cellpadding="2">
    <tr>
        <th bgcolor="#006666"><font size="2" face="MS Sans Serif"><b>Field</b></font></th>
        <th bgcolor="#006666"><font size="2" face="MS Sans Serif">Meanings</font></th>
    </tr>
    <tr>
        <td align="center" bgcolor="#003333"><font size="2"
        face="MS Sans Serif"><b>Name1</b></font></td>
        <td align="center" bgcolor="#003333"><font size="2">事实上本域的名称是</font><font
        size="2" face="MS Sans Serif">&quot;name&quot;</font><font
        size="2">,只是</font><font size="2"
        face="MS Sans Serif">&quot;name&quot;</font><font
        size="2">已被</font><font size="2" face="MS Sans Serif">MASM</font><font
        size="2">用作关键字,所以我们只能用</font><font
        size="2" face="MS Sans Serif">&quot;Name1&quot;</font><font
        size="2">代替。这儿的节名长不超过</font><font
        size="2" face="MS Sans Serif">8</font><font size="2">字节。记住节名仅仅是个标记而已,我们选择任何名字甚至空着也行,注意这里不用</font><font
        size="2" face="MS Sans Serif">null</font><font size="2">结束。命名</font><font
        color="#FF0000" size="2"><b>不是</b></font><font
        size="2">一个</font><font size="2" face="MS Sans Serif">ASCIIZ</font><font
        size="2">字符串,所以不用</font><font size="2"
        face="MS Sans Serif">null</font><font size="2">结尾。</font></td>
    </tr>
    <tr>
        <td align="center" bgcolor="#003333"><font size="2"
        face="MS Sans Serif"><b>VirtualAddress</b></font></td>
        <td align="center" bgcolor="#003333"><font size="2">本节的</font><font
        size="2" face="MS Sans Serif">RVA</font><font size="2">(相对虚拟地址)。</font><font
        size="2" face="MS Sans Serif">PE</font><font size="2">装载器将节映射至内存时会读取本值,因此如果域值是</font><font
        size="2" face="MS Sans Serif">1000h</font><font size="2">,而</font><font
        size="2" face="MS Sans Serif">PE</font><font size="2">文件装在地址</font><font
        size="2" face="MS Sans Serif">400000h</font><font
        size="2">处,那么本节就被载到</font><font
        size="2" face="MS Sans Serif">401000h</font><font
        size="2">。</font></td>
    </tr>
    <tr>
        <td align="center" bgcolor="#003333"><font size="2"
        face="MS Sans Serif"><b>SizeOfRawData</b></font></td>
        <td align="center" bgcolor="#003333"><font size="2">经过文件对齐处理后节尺寸,</font><font
        size="2" face="MS Sans Serif">PE</font><font size="2">装载器提取本域值了解需映射入内存的节字节数。(译者注</font><font
        size="2" face="MS Sans Serif">: </font><font size="2">假设一个文件的文件对齐尺寸是</font><font
        size="2" face="MS Sans Serif">0x200</font><font size="2">,如果前面的</font><font
        size="2" face="MS Sans Serif"><b>&nbsp;VirtualSize</b></font><font
        size="2">域指示本节长度是</font><font size="2"
        face="MS Sans Serif">0x388</font><font size="2">字节,则本域值为</font><font
        size="2" face="MS Sans Serif">0x400</font><font size="2">,表示本节是</font><font
        size="2" face="MS Sans Serif">0x400</font><font size="2">字节长)。</font></td>
    </tr>
    <tr>
        <td align="center" bgcolor="#003333"><font size="2"
        face="MS Sans Serif"><b>PointerToRawData</b></font></td>
        <td align="center" bgcolor="#003333"><font size="2">这是节基于文件的偏移量,</font><font
        size="2" face="MS Sans Serif">PE</font><font size="2">装载器通过本域值找到节数据在文件中的位置。</font></td>
    </tr>
    <tr>
        <td align="center" bgcolor="#003333"><font size="2"
        face="MS Sans Serif"><b>Characteristics</b></font></td>
        <td align="center" bgcolor="#003333"><font size="2">包含标记以指示节属性,比如节是否含有可执行代码、初始化数据、未初始数据,是否可写、可读等。</font></td>
    </tr>
</table>

<p><font size="2">现在我们已知晓 </font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_SECTION_HEADER</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构,再来模拟一下
</font><font size="2" face="MS Sans Serif">PE</font><font
size="2">装载器的工作吧</font><font size="2"
face="MS Sans Serif">:</font></p>

<ol>
    <li><font size="2">读取 </font><font color="#CCFFCC"
        size="2" face="MS Sans Serif"><b>IMAGE_FILE_HEADER</b></font><font
        size="2" face="MS Sans Serif"> </font><font size="2">的 </font><font
        color="#FFFFCC" size="2" face="MS Sans Serif"><b>NumberOfSections</b></font><font
        size="2">域,知道文件的节数目。</font></li>
    <li><font color="#CCFFCC" size="2" face="MS Sans Serif"><b>SizeOfHeaders</b></font><font
        size="2" face="MS Sans Serif"> </font><font size="2">域值作为节表的文件偏移量,并以此定位节表。</font></li>
    <li><font size="2">遍历整个结构数组检查各成员值。</font></li>
    <li><font size="2">对于每个结构,我们读取</font><font
        color="#FFFFCC" size="2" face="MS Sans Serif"><b>PointerToRawData</b></font><font
        size="2">域值并定位到该文件偏移量。然后再读取</font><font
        color="#FFFFCC" size="2" face="MS Sans Serif"><b>SizeOfRawData</b></font><font
        size="2">域值来决定映射内存的字节数。将</font><font
        color="#FFFFCC" size="2" face="MS Sans Serif"><b>VirtualAddress</b></font><font
        size="2">域值加上</font><font color="#FFFFCC"
        size="2" face="MS Sans Serif"><b>ImageBase</b></font><font
        size="2">域值等于节起始的虚拟地址。然后就准备把节映射进内存,并根据</font><font
        color="#FFFFCC" size="2" face="MS Sans Serif"><b>Characteristics</b></font><font
        size="2">域值设置属性。</font></li>
    <li><font size="2">遍历整个数组,直至所有节都已处理完毕。</font></li>
</ol>

<p><font size="2">注意我们并没有使用节名</font><font
size="2" face="MS Sans Serif">: </font><font size="2">这其实并不重要。</font></p>

<h3>示例<font face="Arial, Helvetica, sans-serif">:</font></h3>

<p><font size="2">本例程打开一</font><font size="2"
face="MS Sans Serif">PE</font><font size="2">文件遍历其节表,并在列表框控件显示各节的信息。</font></p>

<p><font face="Fixedsys">.386 <br>
.model flat,stdcall <br>
option casemap:none <br>
include \masm32\include\windows.inc <br>
include \masm32\include\kernel32.inc <br>
include \masm32\include\comdlg32.inc <br>
include \masm32\include\user32.inc <br>
include \masm32\include\comctl32.inc <br>
includelib \masm32\lib\comctl32.lib <br>
includelib \masm32\lib\user32.lib <br>
includelib \masm32\lib\kernel32.lib <br>
includelib \masm32\lib\comdlg32.lib <br>
<br>
IDD_SECTIONTABLE equ 104 <br>
IDC_SECTIONLIST equ 1001 <br>
<br>
SEH struct </font></p>

<p><font face="Fixedsys"><br>
PrevLink dd ? ; the address of the previous seh structure <br>
CurrentHandler dd ? ; the address of the new exception handler <br>
SafeOffset dd ? ; The offset where it's safe to continue
execution <br>
PrevEsp dd ? ; the old value in esp <br>
PrevEbp dd ? ; The old value in ebp <br>
SEH ends <br>
<br>
.data <br>
AppName db &quot;PE tutorial no.5&quot;,0 <br>
ofn OPENFILENAME <> <br>
FilterString db &quot;Executable Files (*.exe,
*.dll)&quot;,0,&quot;*.exe;*.dll&quot;,0 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
db &quot;All Files&quot;,0,&quot;*.*&quot;,0,0 <br>
FileOpenError db &quot;Cannot open the file for reading&quot;,0 <br>
FileOpenMappingError db &quot;Cannot open the file for memory
mapping&quot;,0 <br>
FileMappingError db &quot;Cannot map the file into memory&quot;,0
<br>
FileInValidPE db &quot;This file is not a valid PE&quot;,0 <br>
template db &quot;%08lx&quot;,0 <br>
SectionName db &quot;Section&quot;,0 <br>
VirtualSize db &quot;V.Size&quot;,0 <br>
VirtualAddress db &quot;V.Address&quot;,0 <br>
SizeOfRawData db &quot;Raw Size&quot;,0 <br>
RawOffset db &quot;Raw Offset&quot;,0 <br>
Characteristics db &quot;Characteristics&quot;,0 <br>
<br>
.data? <br>
hInstance dd ? <br>
buffer db 512 dup(?) <br>
hFile dd ? <br>
hMapping dd ? <br>
pMapping dd ? <br>
ValidPE dd ? <br>
NumberOfSections dd ? <br>
<br>
.code <br>
start proc <br>

⌨️ 快捷键说明

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