第六章
引言:
可执行文件格式是操作系统本身执行进制的反映,虽然研究可执行文件格式并不是程序员的首要任务,但这想种工作能够积累大量的知识,有助于对操作系统的深刻理解,掌握可执行文件的数据结构,也是研究软件安全的必须课。
我们为什么要学习PE?
了解可执行文件结构,更方便的了解操作系统。
结构体sizeof什么才是正确的学习方法?
本章节主要是记结构体,然后要写程序,如果没写程序,是永远学不懂的。
本章必须要掌握的知识点:
1. PE头结构。
2. 文件和内存的对齐方式。
3. 添加节,扩大节,合并节。
4. 导入表,导出表,重定位表。
5. IAT表。
6.1 PE
本节主要内容:
掌握IMAGE_DOS_HEADER、IMAGE_FILE_HEADER、IMAGE_OPTIONAL_HEADER结构。
老唐语录:
今天我们开始讲PE。
1.用OD随便打开一个进程,或者打开一个记事本,看一下它的内存分布(0-2G)。大家都抄过CR3,也应该知道内存分布了。2G以上的大部分都一样。然后点击查看选项,选
择内存,也就是说这个CR3里面有哪些部分构成。
如图6-1所示:
图6-1
我们只看地址,大小,访问,初始访问,如果没有学页的话,你根本看不懂,页怎么会有属性呢?等等一系列问题都出来了,当然我们学过就知道了,觉得理所当然。
我们看2G空间,前64K和后64K都是空的,不可访问的。
可以看里面的内容双击就可以了如图6-2所示:
图6-2
可以选择查看方式,数据或者反汇编以及文本等等,2G以下在3环都可以看到的。
你会发现有些块是有名字的,比如:.text .data 等等。
我们在查看里面看一下执行模块和内存对一下有什么区别?如图6-3所示:
图6-3
学过API就知道啦,页的属性是可以改变的,有一个API (VirtualProtect)可以改变页的属性。
模块列表和内存列表的区别:
1. 内存列表是相同属性放在一起,模块列表是很多块放在一起了,也就是说当模块里面没有的那些内存都是用virtualAlloc分配的,如果说是有模块的那段内存都是在磁盘上有对应的EXE的。
2. 有模块就是有对应的EXE。
3. 一个EXE 在磁盘中叫做文件,在内存中叫模块。
4每个模块都有一个格式就是一个结构体,windows把它叫做PE。
练习:
用winhex分别打开不同的文件格式
比如: .exe .txt .doc .jpg .ink .htm .dll .pdf  等等打开10个看看前四个字节是什么,写在纸上。
1. 在winhex里面鼠标拖动最后面看下多大,然后在磁盘上看下这个文件多大
如图6-4所示:
图6-4
如图6-5所示:
图6-5
我们发现一样大.
大家发现没有,相同的文件前面几个字节是一样的。
.doc .mp3 .jpg .dll 等等都是有文件格式的,我们只需要记.exe文件格式,因为.exe文件是可执行文件格式,其他的文件是不可执行的,不能在CPU上运行的,每一种操作系统它最重要的格式就是它的可执行文件格式,因为操作系统就是为了支持这些文件而生成的,内核里面有很多机制,也是配合这种文件格式设计的。换句话说,这种文件格式也是适合操作系统设计的。
比如: PE 它是windows下的文件格式,是MZ打头的(4D5A)只有两个字节,后面很大一片就是对这个结构体的管理,比如:声音在什么位置,图像在什么位置,文字在什么位置,在前面这一片都是有记录的,也就是说,前面开头不只是标志而已,前面这一片是一个结构体。
不同的文件有不同的结构体,我们只需要学习windows下.exe文件格式。
那前面这个结构体是什么了?这个结构体头文件有定义。
练习:
在VC6中输入#include "winnt.h" 在上面点右键打开就行了
然后搜索 IMAGE_DOS_HEADER 或者在程序里面输入IMAGE_DOS_HEADER 按F12进去
typedef struct _IMAGE_DOS_HEADER {
WORD  e_magic;
WORD  e_cblp;
WORD  e_cp;
WORD  e_crlc;
WORD  e_cparhdr;
WORD  e_minalloc;
WORD  e_maxalloc;
WORD  e_ss;
WORD  e_sp;
WORD  e_csum;
WORD  e_ip;
WORD  e_cs;
WORD  e_lfarlc;
WORD  e_ovno;
WORD  e_res[4];
WORD  e_oemid;
WORD  e_oeminfo;
WORD  e_res2[10];
LONG  e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
可以用winhex打开这个文件,对着这个结构体拆分,写出他们的数值。
比如:e_magic 的值是多少,写在纸上。
备注:这个结构体里面的每个成员都要背。
我们看最后一个成员 e_lfanew (新的文件位置)用winhex看下一这个成员在什么
地方(0x3c)在看里面的值指向的是哪个位置(0xE0)我们看一下0xE0的位置(备注:我打开的是记事本)(000000E0 455000000 (PE)),所以把这个文件格式叫做PE。
紧接着PE后面又是一个结构体,那么这个结构在哪里了?那个结构叫做IAMGE_FILE_HEADER 同样的在VC6中F12进去。
typedef struct _IMAGE_FILE_HEADER
{
WORD    Machine;
WORD    NumberOfSections;
DWORD  TimeDateStamp;
DWORD  PointerToSymbolTable;
DWORD  NumberOfSymbols;
WORD    SizeOfOptionalHeader;
WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
备注:有的东西我说一遍,你没记住也没用,所以说要先记住,我再说一遍,才能印象深刻。
紧接着在IAMGE_FILE_HEADER 后面又是一个结构体,那个结构叫做
IMAGE_OPTIONAL_HEADER  (F12进去)
typedef struct _IMAGE_OPTIONAL_HEADER
{
WORD    Magic;
BYTE    MajorLinkerVersion;
BYTE    MinorLinkerVersion;
DWORD  SizeOfCode;
DWORD  SizeOfInitializedData;
DWORD  SizeOfUninitializedData;
DWORD  AddressOfEntryPoint;
DWORD  BaseOfCode;
DWORD  BaseOfData;
DWORD  ImageBase;