二进制文件概述

一 PE 文件格式

PE(Portable Executable) : Win32 平台下可执行文件遵守的数据格式

PE 文件格式把可执行文件分成若干个数据节,不同的资源被存放在不同的节中.一个典型的PE文件中包含的 "节" 如下:

.text : 由编译器产生, 存放着二进制的机器码,也是我们反汇编和调试的对象

.data : 初始化的数据库, 如 宏定义, 全局变量 , 静态变量等

.idata : 可执行文件所使用的动态链接库等外来函数与文件的信息

.rsrc : 存放程序的资源,如 图标 , 菜单等

 

二 虚拟内存

Windows 的内存可以被分为两个层面 : 物理内存 和 虚拟内存

物理内存 : 需要进入 windows 内核级别 ring 0 才能看到

虚拟内存 : 我们用调试器看到的内存地址都是 虚拟地址

每个进程都会以为自己有 4GB 的虚拟地址

三 PE文件与虚拟内存之间的映射

文件偏移地址(File Offset) : 数据在 PE 文件中的地址叫文件偏移地址,个人认为叫做文件地址更加准确.这是文件在磁盘上存放时相对于文件开头的偏移

装载基址(Image Base) : PE 装入内存时的基地址 , 默认情况下 , EXE 文件在内存中的基地址是 0x00400000 , DLL 文件是 0x10000000 . 这些位置可以通过修改编译器选项更改

虚拟内存地址(Virtual Address - VA) : PE 文件中的指令被装入内存后的地址

相对虚拟地址(Relative Virtual Address-RVA) : 相对虚拟地址是内存地址相对于映射基址的偏移量

虚拟内存地址 , 映射基址 , 相对虚拟内存地址   三者之间有如下的关系:

VA(虚拟内存地址) = Image Base(装载基址) + RVA(相对虚拟地址)

(1) PE 文件中的数据按照磁盘数据标准存放,以 0x200 字节为基本单位进行组织,当一个数据节(section)不足 0x200 个字节时,剩余的字节自动填充 0 , 大于 0x200 字节时,会自动扩成 0x200 个字节(=0x400) 继续存放,因此 PE 数据节的大小永远是 0x200 的倍数

(2) 当代码装入内存以后, 将按照内存数据标准存放,并以 0x1000 字节为基本单位进行组织

文件偏移地址 = 虚拟内存地址(VA) - 装载基址(Image Base) - 节偏移 = RAV - 节偏移

例如:在调试的时候遇到虚拟内存中 0x00404141 处的一条指令,那么要换算处这条指令在文件中的偏移量

[文件偏移量 = 0x00404141 - 0x00400000 - (0x1000 - 0x400) = 0x3541]

你可能感兴趣的:(二进制)