1. PE结构1

Portable Executable file format

从命名上看,微软想让PE文件可移植。

 

 

 

 

注意,虽然IMAGE_OPTIONAL_HEADER结构体总大小0xE0字节,但IMAGE_OPTIONAL_HEADER结构体的最后是数组,数组中究竟有几个元素,可以手动修改。

所以是exe的中IMAGE_OPTIONAL_HEADER究竟占多少字节,是由IMAGE_FILE_HEADER结构体中的WORD SizeOfOptionalHeader字段决定的。大小可以小于0xE0,也可以大于0xE0。例如改为F0,然后增加0x10字节,再删除无关位置的0x10字节,依然可运行。

 

IMAGE_OPTIONAL_HEADER中的

    DWORD   SizeOfCode;

    DWORD   SizeOfInitializedData;

DWORD   SizeOfUninitializedData;

以及

DWORD   BaseOfCode;

DWORD   BaseOfData;

是说明性自字段,可以自由更改。如果3改成0x0CCCCCCC之类的能成功分配内存大小的数值,OD会当成代码真有这么大,分析时很慢。如果数值太大,不能分配这么大的内存,OD会采用其他方案。

 

 

文件地址FA

虚拟地址VA

相对虚拟地址RVA,是相对于模块基址的偏移

 

DWORD AddressOfEntryPoint是相对虚拟地址RVA,相对于image base。将其改为2,启动后可执行IMAGE_DOS_HEADER里的代码,但修改后的程序在win10上无法启动,XP上可以运行,但可能要改内存保护属性。

 

DWORD ImageBase是首选装载地址,可以改,但对内存进行绝对访问的代码也要修复。

 

 

 

typedef struct _IMAGE_OPTIONAL_HEADER {

    //

    // Standard fields.

    //

 

    WORD    Magic;

    BYTE    MajorLinkerVersion;             //可以改

    BYTE    MinorLinkerVersion;             //可以改

    DWORD   SizeOfCode;                     //说明性

    DWORD   SizeOfInitializedData;          //说明性

    DWORD   SizeOfUninitializedData;        //说明性

    DWORD   AddressOfEntryPoint;            //RVA

    DWORD   BaseOfCode;                     //说明性

    DWORD   BaseOfData;                     //说明性

 

    //

    // NT additional fields.

    //

 

    DWORD   ImageBase;                      //首选装载地址,可以改,但对内存进行绝对访问的代码也要修复

    DWORD   SectionAlignment;               //加载到内存中节的对齐值

    DWORD   FileAlignment;                  //文件对齐值

    WORD    MajorOperatingSystemVersion;    //说明性

    WORD    MinorOperatingSystemVersion;    //说明性

    WORD    MajorImageVersion;              //说明性

    WORD    MinorImageVersion;              //说明性

    WORD    MajorSubsystemVersion;          //Subsystem的版本,后面字段还有类型

    WORD    MinorSubsystemVersion;          //说明性

    DWORD   Win32VersionValue;              //MSDN说保留成员,必须为0win10xp测试也不行,老师的xp可以

    DWORD   SizeOfImage;                    //加载到内存后占多少字节,必须是SectionAlignment的倍数,随便改会错

    DWORD   SizeOfHeaders;                  //所有头部的大小(文件中),例如0x400

    DWORD   CheckSum;                       //驱动,系统关键dll会做检测,普通PE不检测

    WORD    Subsystem;                      //链接时指定的子系统GUICUINATIVE等,改后可改窗口程序为控制台

    WORD    DllCharacteristics;             //针对所有PE文件的,例如IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE

    DWORD   SizeOfStackReserve;             //栈保留内存,可以改,数值要在正常范围

    DWORD   SizeOfStackCommit;              //栈提交内存,可以改,数值要在正常范围

    DWORD   SizeOfHeapReserve;              //堆保留内存,可以改,数值要在正常范围

    DWORD   SizeOfHeapCommit;               //栈提交内存,可以改,数值要在正常范围

    DWORD   LoaderFlags;                    //MSDN说该成员已过时

    DWORD   NumberOfRvaAndSizes;            //目录条目数

    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

posted @ 2020-11-03 21:04  八转达人  阅读(93)  评论(0编辑  收藏  举报