关于pe中的入口点和跳转问题

pe里面的入口点和跳转问题。在我一开始学习pe的时候曾经就被这两个问题困惑过,可能很多朋友在学习的过程中也会遇到,所以我想在这里把这两个问题说清楚一点。没什么技术含量大牛飘过啦。

大家知道pe的入口点是在IMAGE_FILE_HEADER里面AddressOfEntryPoint指定的。其实这个说得挺清楚的,是address而不是offset,当然指的是内存里面的地址。那为什么会搞错呢?因为我用vb和vc++分别编译了一个简单的程序李测试,这时候我发现只要入口点的内存地址-映像基址=文件中的偏移量(因为OD载入厚就停留在入口点的),所以我误以为AddressOfEntryPoint就是一个文件偏移值,结果在写一个文件感染的程序的时候就只能感染这两个文件,其他像windows计算器还有资源管理器都出错。于是我就开始摸索,发现计算器的入口点减去映像基址并不等于入口点在文件里面的偏移,所以程序根本跳转不到我想要的地方。那我就纳闷了,装载器怎么找到要执行的地方呢?后来我又看到内存里面的入口点地址-映像基址就=AddressOfEntryPoint,于是我就想是不是AddressOfEntryPoint指的就是这个。我把入口点的地址放到oc转化器里面转换得到文件中的偏移,这个地方的数据果然和内存里面的是一样的。

所以结论就是:内存中程序开始执行的地址=映像基址+AddressOfEntryPoint,而在文件中偏移为AddressOfEntryPoint的地方不一定是程序的入口点数据。因为windows的pe文件是有对齐的,在很多时候文件对齐和内存对齐是不一样的,AddressOfEntryPoint要经过一定的转换才能得到offset。为什么上面用vb和vc++编译出来的程序刚好一样呢?因为这两个程序的文件对齐系数和内存对齐系数刚好是一样的,而且代码段刚好都在第一个节。

接着说说跳转问题

简单说跳转有远跳和近跳,对应的机器码分别为e9,和eb。不管是那种跳转,本质就是对eip的一个操作,加多少或减多少。但直接add eip,10是不允许的。当开始执行一条指令的时候eip自动指向下一条指令的地址,所以在我们执行jmp语句的时候eip就已经指向下一条语句的地址了,所以要jmp的距离是下一条指令的地址与目标指令地址的距离而不是本条jmp语句的地址和目标指令地址的距离。

EB FE就是不断地循环这句jmp而不是忘前面跳。

好了,就说这么多了。

文章来自: 本站原创
Tags:
评论: 0 | 查看次数: 12149