?? lion-petut-c05.htm
字號:
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=gb_2312-80">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Iczelion的PE教程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>
Name1 db IMAGE_SIZEOF_SHORT_NAME dup(?) <br>
union Misc <br>
PhysicalAddress dd ? <br>
VirtualSize dd ? <br>
ends <br>
VirtualAddress dd ? <br>
SizeOfRawData dd ? <br>
PointerToRawData dd ? <br>
PointerToRelocations dd ? <br>
PointerToLinenumbers dd ? </b></font><font
size="2"><b>哦<br>
</b></font><font size="2" face="MS Sans Serif"><b> NumberOfRelocations
dw ? <br>
NumberOfLinenumbers dw ? <br>
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">"name"</font><font
size="2">,只是</font><font size="2"
face="MS Sans Serif">"name"</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">"Name1"</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> 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 "PE tutorial no.5",0 <br>
ofn OPENFILENAME <> <br>
FilterString db "Executable Files (*.exe,
*.dll)",0,"*.exe;*.dll",0 <br>
db "All Files",0,"*.*",0,0 <br>
FileOpenError db "Cannot open the file for reading",0 <br>
FileOpenMappingError db "Cannot open the file for memory
mapping",0 <br>
FileMappingError db "Cannot map the file into memory",0
<br>
FileInValidPE db "This file is not a valid PE",0 <br>
template db "%08lx",0 <br>
SectionName db "Section",0 <br>
VirtualSize db "V.Size",0 <br>
VirtualAddress db "V.Address",0 <br>
SizeOfRawData db "Raw Size",0 <br>
RawOffset db "Raw Offset",0 <br>
Characteristics db "Characteristics",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 + -