Google

星期三, 一月 23, 2008

PE Format(6)

上一页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 下一页

  试举一例,假若你已知道执行开始处位于RVA0x1560地址处,并且想从那里开始的代码处反汇编。
为了从文件中找到这个地址,你得先查明在RAM(内存)中各节是按照4096字节对齐的,并且“.code”节是从RVA0x1000地址处开始,有16384字节长;然后你才知道RVA0x1560地址位于此节的偏移量0x560处。你还要查明在文件中那节是按512字节边界对齐,且“.code”节在文件中从偏移量0x800处开始,然后你就知道在文件中代码的执行开始处就在0x800+0x560=0xd60字节处。

  然后你反汇编它并发现访问一个变量的线性地址位于0x1051d0处。二进制文件的线性地址在装入时将被重定位,并常被假定使用的是优先载入地址。因为你已查明优先载入地址为 0x100000,因此我们可开始处理RVA0x51d0了。因数据节开始于RVA0x5000处,且有2048字节长,所以它处于数据节中。又因数据节在文件中开始于偏移量0x4800处,所以该变量就可以在文件中的0x4800+0x51d0-0x5000=0x49d0处找到。

  六、可选头(OptionalHeader)

  ----------------------------

  紧跟在文件头后面的就是IMAGE_OPTIONAL_HEADER(尽管它名叫“可选头”,它却一直都在那里)。它包含有怎样去准确处理PE文件的信息。我们也将从头至尾的介绍其成员。

  1)第一个16位的word单元叫“Magic(魔数)”,就我目前所观察过的PE文件而言,它的值总是0x010b。

  2-3)下面2个字节是创建此文件的链接器的版本(‘MajorLinkerVersion’,“链接器主版本号”和 ‘MinorLinkerVersion’,“链接器小版本号”)。这两个值又是不可靠的,并不能总是正确地反映链接器的版本号。(有好几个链接器根本就不设置这个值。)况且,你可想象一下,你连使用的是“什么”链接器都不知道,知道它的版本号又有什么作用呢?

  4-6)下面3个longword(每个32位)分别用来设定可执行代码的大小(“SizeOfCode”)、已初始化数据的大小(“SizeOfInitializedData”,所谓的“数据段”)、以及未初始化数据的大小(“SizeOfUninitializedData”,所谓的“bss段”)。这些值也是不可靠的(例如:数据段实际上可能会被编译器或者链接器分成好几段),并且你可以通过查看可选头后面的各个“节”来获得更准确的大小。

  7)下一个32位值是RVA。这个RVA是代码入口点的偏移量(‘AddressOfEntryPoint’,“入口点地址”)。执行将从这里开始,它可以是:例如DLL文件的LibMain()的地址,或者一个程序的开始代码(这里相应的叫main())的地址,或者驱动程序的DriverEntry()的地址。如果你敢于“手工”装载映象文件,那么在你完成所有的修正和重定位后,你可以从这个地址开始执行你的进程。

标签: , ,

0 条评论:

发表评论

<< 主页

辽ICP备05003652号
流风洄雪听天籁,轻云蔽日看落花

Powered by Blogger