PE文件格式详解,第三讲,可选头文件格式,以及节表           PE文件格式详解,第三讲,可选头文件格式,以及节表

一丶可选头结构以及作用

 

复制代码
 
 

typedef struct _IMAGE_OPTIONAL_HEADER {


    WORD    Magic;                  /*机器型号,判断是PE是32位还是64位*/
    BYTE    MajorLinkerVersion;          /*连接器版本号高版本*/
    BYTE    MinorLinkerVersion;          /*连接器版本号低版本,组合起来就是 5.12 其中5是高版本,C是低版本*/
    DWORD   SizeOfCode;               /*代码节的总大小(512为一个磁盘扇区)*/
    DWORD   SizeOfInitializedData;        /*初始化数据的节的总大小,也就是.data*/
    DWORD   SizeOfUninitializedData;       /*未初始化数据的节的大小,也就是 .data ? */
    DWORD   AddressOfEntryPoint;          /*程序执行入口(OEP) RVA(相对偏移)*/
    DWORD   BaseOfCode;               /*代码的节的起始RVA(相对偏移)也就是代码区的偏移,偏移+模块首地址定位代码区*/
    DWORD   BaseOfData;               /*数据结的起始偏移(RVA),同上*/
    DWORD   ImageBase;               /*程序的建议模块基址(意思就是说作参考用的,模块地址在哪里)*/
DWORD SectionAlignment;           /*内存中的节对齐*/ DWORD FileAlignment;             /*文件中的节对齐*/ WORD MajorOperatingSystemVersion;    /*操作系统版本号高位*/ WORD MinorOperatingSystemVersion;    /*操作系统版本号低位*/ WORD MajorImageVersion;          /*PE版本号高位*/ WORD MinorImageVersion;          /*PE版本号低位*/ WORD MajorSubsystemVersion;        /*子系统版本号高位*/ WORD MinorSubsystemVersion;        /*子系统版本号低位*/ DWORD Win32VersionValue;          /*32位系统版本号值,注意只能修改为4 5 6表示操作系统支持nt4.0 以上,5的话依次类推*/ DWORD SizeOfImage;             /*整个程序在内存中占用的空间(PE映尺寸)*/ DWORD SizeOfHeaders;            /*所有头(头的结构体大小)+节表的大小*/ DWORD CheckSum;               /*校验和,对于驱动程序,可能会使用*/ WORD Subsystem;              /*文件的子系统 :重要*/ WORD DllCharacteristics;         /*DLL文件属性,也可以成为特性,可能DLL文件可以当做驱动程序使用*/ DWORD SizeOfStackReserve;        /*预留的栈的大小*/ DWORD SizeOfStackCommit;         /*立即申请的栈的大小(分页为单位)*/ DWORD SizeOfHeapReserve;        /*预留的堆空间大小*/ DWORD SizeOfHeapCommit;         /*立即申请的堆的空间的大小*/ DWORD LoaderFlags;            /*与调试有关*/ DWORD NumberOfRvaAndSizes;       /*下面的成员,数据目录结构的项目数量*/ IMAGE_DATA_DIRECTORY DataDirectory[16];/*数据目录,默认16个,16是宏,这里方便直接写成16*/ } IMAGE_OPTIONAL_HEADER32,
*PIMAGE_OPTIONAL_HEADER32;
复制代码

需要注意的成员:

1.PE类型

这个有宏定义了

#define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b    /*32位PE*/
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b    /*64位PE*/
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC       0x107    /*其它,单片机*/

 

2丶.OEP,程序执行入口位置.

我们利用昨天写的程序,可以完成一个反调试.

思路:

1.修改OEP偏移,置为0位置处(也就是MZ的位置)

2.在MZ位置后面添加我们自己的代码

3.添加完成之后,继续跳到以前OEP的位置.

 

首先,看PE文件的值,OEP的偏移位置是00001008偏移,那么OD调试,看下位置在哪里.

我们知道了入口偏移是00401008位置,那么我们就知道了模块首地址是00400000

公式  00401008 - 1008 = 00400000  因为我们知道1008是相对于模块地址来的所以可以求出模块地址,我们跳转过去

可以看出,前边正好是4D5A,那么我们可以修改一下,添加自己的代码,首先4D5A正好是汇编代码

那么我们可以去平栈,然后跳转到我们以前的OEP位置.

修改成下边那样

 

首先,我们以前讲DOS头的时候说过,如果这个EXE文件运行在32位系统下,那么DOS头中就地一个和最后一个成员有用,那么后面我们随便修改.

上面代码很简单,首先栈平衡,然后跳转到我们以前代码执行位置.

文件中(PE)我们把后面的二进制都修改为我们的代码

入后偏移(RVA)修改为0000000

运行我们的程序,和调试我们的程序

运行程序:

可以正常运行

调试程序:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值