-----根据自己的理解和《0day安全》总结下
pe(可执行文件)常见的便是 .exe和 .dll文件
可执行文件中不光有机器代码,还有可以帮助我们定位的字符串,菜单,图标这些。PE格式规定了所有的这些信息在文件中应该如何组织。当文件载入的时候,操作系统会按照PE文件格式的规定去相应的地方准确定位各种类型的资源,并分别装入内存的不同区域。
PE文件格式
pe文件有着我们常说的数据节。
.text 编译器产生,存放着二进制代码,我们反编译调试一般都是在这里。
.data 初始化的数据块,储存着宏定义,全局变量,静态变量这些。
.idata 可执行文件的动态链接库
.rsrc 存放着程序的图标,菜单这些。可以改着玩。
(ps:当然这都是正常情况下,当作者不想让我们看到程序里面的内容,便会加壳。这些东西并不会影响程序的执行,但会pe文件变得非常难受,给反编译,调试造成很大的难度。而且更有一些会把关键函数放到服务器上,用户拿到的仅仅只是交互的东西。这样破解难度会更大。)
虚拟内存
windows上的内存分为物理内存,和虚拟内存。物理内存这内核级别的东西我就不了解了,ring0层,目前只知道使用icesoft进行调试。这个调试器很霸道,使用的时候会独占cpu,还能更改内核的东西。我之前好奇用了一下,很开心,电脑蓝屏没商量。
虚拟内存是我们用户看到的级别,我们调试器看到的便是虚拟内存。比如说电脑的内存是4GB,但可能内存条只有512MB。这用到的便是内存管理器,具体到怎么实现的,可以看看那些算法,听名字都头疼。
但是我们让每个进程都相信自己有壳4GB的运行空间,但应该没几个进程上来就用这么多。所以内存管理器给的便是“虚拟地址”,进程们都认为这些地址是可以访问的。
《0day安全》有很形象的描述
如果我们把这看成银行,那么就很好理解了。
---进程相当于储户
---内存管理器相当于银行
---物理内存相当于钞票
---虚拟内存相当于存款
当进程不需要内存的时候那些内存可以分给其它进程,相当于存在银行中。银行等着其它需要内存的人来取走。那些虚拟地址就相当于钞票上的编号,我们只要去的现金就好。并不会对上面的号码有什么感想。我们实际物理地址远小于虚拟地址之和,相对的银行也不会有那么多钱让所有用户来同时去。当两者往往都会正常运行着。
PE文件与虚拟内存的映射
我们调试的时候会经常说到文件地址这些,对于我们来说不存在可能这个说法,只能准确的找到位置才能到达控制,破解的目的。
VA:虚拟内存地址,也就是我们ida看到的那些地址
既然物理和虚拟之间存在着映射,我们便需要在PE文件中找到文件地址。
===文件偏移地址 File Offset
数据在PE文件中的地址叫文件偏移地址
===装载基址 Image Base
PE装入内存时的基地址,默认情况下EXE内存的基地址是0x00400000,DLL文件是0X10000000
===虚拟内存地址 Virtual Address,VA
PE文件中的指令被装入内存后的地址
===相对虚拟地址 Relative Virtual Address,RVA
虚拟内存地址,映射基址,相对虚拟内存地址三者关系
VA=Image+RVA
![](https://img.haomeiwen.com/i9266414/f90c0f373138ef0a.png)
文件偏移是相对于文件从0字节开始的偏移,RVA是相对于装载基址0x00400000处的偏移。
注意:pe文件中的数据是按照磁盘标准,以0x200(512)字节为基本单位。如果数据节不足则用00补全,内存中则是按照0x1000(1024)为基本单位。
使用PE Editor,dependencly可以查看各个字节。根据公式,我们可以计算文件中的偏移位置,在文件中直接进行更改或者pwn。
现在遇到了需要许多计算地址的ctf,先把这些基本的搞清楚。
网友评论