Chinaunix首页 | 论坛 | 博客
  • 博客访问: 347576
  • 博文数量: 93
  • 博客积分: 2322
  • 博客等级: 大尉
  • 技术积分: 1600
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-27 10:23
文章分类

全部博文(93)

文章存档

2018年(12)

2012年(81)

分类: Windows平台

2018-01-13 22:31:16

一、基础知识
(1)EXE和DLL文件之间的区别完全是语义上的,因为他们使用完全相同的PE格式。而唯一的区别就是用一个字段标识出这个文件是EXE还是DLL。

(2)64位Windows只是对PE格式做了一些简单的修饰,新格式叫PE32+。并没有任何新的结构加进去,改变的只是简单的将32位字段扩展成64位。(windows NT架构的可执行文件的格式就是PE格式)

(3)PE格式定义的主要地方位于我们的头文件winnt.h,这个头文件中几乎能找到关于PE文件的所有定义

(4)PE文件中的数据结构一般都有32位和64位之分,一般在名称上会表现出来:例如IMAGE_NT_HEADERS32 或 IMAGE_NT_HEADER64

(5)PE文件框架结构图:

 


(6)PE 文件和内存映像的关系


二、PE的基本概念
(1)PE文件使用的是一个平面地址空间(线性的),所有代码和数据都被合并在一起,组成一个很大的结构。文件的内容被分割为不同的区块,块中包含代码或数据。各个区块按页边界来对齐,区块没有大小限制,是一个连续的结构。此外,每个块有自己在内存中的一套属性,比如说这个区块是否包含代码、是否只读或可读/写等。

(2)认识PE文件不是作为单一内存映射文件被装入内存是很重要的。

(3)Windows加载器(又称PE装载器)遍历PE文件并决定文件的哪一部分被映射(比如说调试信息是不会被映射的,我们调试的时候才会用到).这种映射方式是将文件较高的偏移位置映射到较高的内存地址中(反之低的就到低的)。

(4)当磁盘文件一旦被装入内存中,磁盘上的数据结构布局和内存中的数据结构布局是一致的。

(5)这样如果知道在磁盘的数据结构中寻找一些内容,那么几乎都能在被装入到内存映射文件中找到相同的信息。但数据之间的相对位置可能改变(只是按比例变大变小了),其某项的偏移地址可能区别于原始的偏移位置,不管怎样,所有表现出来的信息都允许从磁盘文件偏移到内存偏移的转换。

(6)PE文件磁盘与内存映像结构图:清晰的反应了映射到内存中结构布局是一致的,只是数据之间的相对位置发生了改变(按比例变大变小了)。

 
三、PE相关名词解释
(1)基地址(ImageBase):文件执行时将被映射到指定内存地址中(加载文件会先加载到内存中,也就是映射了)的起始地址被称为模块句柄,这个初始内存地址也称为基地址。这个值是由PE文件本身设定的。(按照默认设置,用Visual C++建立的EXE文件基地址是00400000h,DLL文件基地址是10000000h。但是,这个值可以自己在编译器设定的。)
获取基地址的函数:HMODULE GetModuleHandle(LPCTSTR lpModuleName)        //HMODULE 返回值,也就是我们获取到的句柄。LPCTSTR指针指向lpModuleName(想要获取的句柄的模块)

(2)虚拟地址(Virtual Address, VA)
由于Windows程序运行在保护模式下,所以应用程序访问存储器所使用的逻辑地址称为虚拟地址(因为他不是真正的物理地址,真正的物理地址被windows老大妈的保护机制保护起来),又称为内存偏移地址(Memory Offset)。

(3)相对虚拟地址(RVA(RelativeVirtualAddress)):某一个虚拟地址相对于基地址的偏移。例如:基地址为:00400000h,虚拟地址为:00410000h,那么相对虚拟地址就是:10000h。

(4)文件偏移地址(File Offset)
当PE文件储存在磁盘上的时候,某个数据的位置相对于文件头的偏移量,叫做偏移地址。文件偏移地址从PE文件的第一个字节开始计数,起始值为0。


阅读(2545) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~