自己构建PE文件.docx
《自己构建PE文件.docx》由会员分享,可在线阅读,更多相关《自己构建PE文件.docx(22页珍藏版)》请在冰点文库上搜索。
自己构建PE文件
自己构建PE文件
现在我将演示一个简单且具有一般性的标准PE文件(畸形的PE将来做壳开发的时候再做研究,现在我们只关心标准PE)的构造过程。
为简单起见,我们只关心必不可缺的结构和成员(eg。
),其他成员一律定义为0,具体含义请自己参考微软官方提供的PECOFF规范(英文)。
个人认为PE文件结构的结构太复杂成员太多,这样才比较容易接受。
首先还是老生常谈的PE的结构,如下图所示:
各部分名称
大小
简单描述
DOS头部
40h(64)
DOS头结构
P
E
头
Signature
04h(4)
PE头标志
IMAGE_FILE_HEADER
14h(20)
一个struct
IMAGE_OPTIONAL_HEADER
e0h(224)
一个struct
IMAGE_SECTION_HEADER(3个)
28h*3=78h
(40*3=120)
Section段头,一般有好多个,这里我们只有3个,其实完全可以把所以的东西都放在一个段里,只是这样不善于管理。
.text
200h(512)
一般存储汇编机器码
.rdata
200h(512)
存储输入表、输出表、IAT、资源等等信息
.data
200h(512)
一般存储const字符串等
1.DOS头
typedefstruct_IMAGE_DOS_HEADER{//DOS.EXEheader
WORDe_magic;//Magicnumber
WORDe_cblp;//Bytesonlastpageoffile
WORDe_cp;//Pagesinfile
WORDe_crlc;//Relocations
WORDe_cparhdr;//Sizeofheaderinparagraphs
WORDe_minalloc;//Minimumextraparagraphsneeded
WORDe_maxalloc;//Maximumextraparagraphsneeded
WORDe_ss;//Initial(relative)SSvalue
WORDe_sp;//InitialSPvalue
WORDe_csum;//Checksum
WORDe_ip;//InitialIPvalue
WORDe_cs;//Initial(relative)CSvalue
WORDe_lfarlc;//Fileaddressofrelocationtable
WORDe_ovno;//Overlaynumber
WORDe_res[4];//Reservedwords
WORDe_oemid;//OEMidentifier(fore_oeminfo)
WORDe_oeminfo;//OEMinformation;e_oemidspecific
WORDe_res2[10];//Reservedwords
LONGe_lfanew;//Fileaddressofnewexeheader
}IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
我们只关心第一个和最后一个这2个变量
e_magic(WORD)必须等于0x5A4D。
e_lfanew(LONG)是PE头的文件偏移(文件偏移就是指从文件开始处到目标位置的偏移量)。
因为我们将要构造的PE的PE头就是DOS头下面,所以e_lfanew值就是本结构的大小为0x00000040。
2.PE头
分为以下3个部分
(1)Signature必须是0x00004550
(2)IMAGE_FILE_HEADER是一个结构体,具体如下
typedefstruct_IMAGE_FILE_HEADER{
WORDMachine;
WORDNumberOfSections;
DWORDTimeDateStamp;
DWORDPointerToSymbolTable;
DWORDNumberOfSymbols;
WORDSizeOfOptionalHeader;
WORDCharacteristics;
}IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER;
我们只关心一下3个变量
Machine标识目标机器的类型,我们置0x014c表示Intel386或后续兼容的处理器
NumberOfSectionssection段的个数我们这里是0x03个
SizeOfOptionalHeaderPE可选头大小,也就是下面一个struct的大小0x00e0
Characteristics标识文件的属性信息,eg(文件是exe还是dll,大小端模式等等)0x010f查了一下用VC6生成的exe的属性就是它了这里借来用用
(3)IMAGE_OPTIONAL_HEADER
typedefstruct_IMAGE_OPTIONAL_HEADER{
WORDMagic;
BYTEMajorLinkerVersion;
BYTEMinorLinkerVersion;
DWORDSizeOfCode;
DWORDSizeOfInitializedData;
DWORDSizeOfUninitializedData;
DWORDAddressOfEntryPoint;
DWORDBaseOfCode;
DWORDBaseOfData;
//
//NTadditionalfields.
//
DWORDImageBase;
DWORDSectionAlignment;
DWORDFileAlignment;
WORDMajorOperatingSystemVersion;
WORDMinorOperatingSystemVersion;
WORDMajorImageVersion;
WORDMinorImageVersion;
WORDMajorSubsystemVersion;
WORDMinorSubsystemVersion;
DWORDWin32VersionValue;
DWORDSizeOfImage;
DWORDSizeOfHeaders;
DWORDCheckSum;
WORDSubsystem;
WORDDllCharacteristics;
DWORDSizeOfStackReserve;
DWORDSizeOfStackCommit;
DWORDSizeOfHeapReserve;
DWORDSizeOfHeapCommit;
DWORDLoaderFlags;
DWORDNumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORYDataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32;
只关心以下几个成员
Magic0x010b表示普通的可执行文件,0x0107表示ROM文件0x020b表示PE32+可执行文件(支持64位地址)
AddressOfEntryPoint程序的入口点0x00001000text段头部映射到内存后的首地址的偏移,这里牵扯到后面讲到的文件对齐和内存对齐
ImageBase文件装载到优先PE的基址,通常是0x00400000如果此地址被占用了PE装载器会选取其他空闲基址,此值必须是64K的整数倍
SectionAlignment内存对齐(内存中各个段开始地址必须为此值的整数倍),必须比下一个变量(文件对齐)大。
Windows管理内存采用分页管理的方式,一般此值为页大小,为4K,因此此值一般为0x00001000
FileAlignment文件对齐(文件中各个段的文件偏移地址必须为此值的整数倍),一般设定为0x200
MajorSubsystemVersion表示子系统主版本.win32程序必须为0x04
SizeOfImage表示内存镜像大小必须为内存对齐的整数倍这里(文件头+3个段,各占0x1000)一共是0x00004000,这里一定要理解文件偏移和RVA的概念,相关参考连接:
SizeOfHeaders表示文件中“PE头”(除去section段的所有的字节)所占大小,可作为第一个section段的文件偏移。
大小为40h+4h+14h+e0h+28h*3=1b0h,文件对齐是200h,因此它的值是0x00000200
SubsystemNT子系统,可能是以下的值
Constant
Value
Description
IMAGE_SUBSYSTEM_UNKNOWN
0
未知系统
IMAGE_SUBSYSTEM_NATIVE
1
系统和内核程序
IMAGE_SUBSYSTEM_WINDOWS_GUI
2
Win32GUI子系统
IMAGE_SUBSYSTEM_WINDOWS_CUI
3
Win32console子系统
IMAGE_SUBSYSTEM_POSIX_CUI
7
OS/2 console子系统
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
9
WindowsCE子系统
IMAGE_SUBSYSTEM_EFI_APPLICATION
10
AnExtensibleFirmwareInterface(EFI)application(可扩展固件接口应用程序)
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
11
AnEFIdriverwithbootservices
可扩展固件接口驱动启动服务
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
12
AnEFIdriverwithrun-timeservices
IMAGE_SUBSYSTEM_EFI_ROM
13
AnEFIROMimage
IMAGE_SUBSYSTEM_XBOX
14
XBOX
2和3都是合法的值,如果选3会出现一个熟悉的控制台
NumberOfRvaAndSizes此成员表示下面一个成员(下面一个成员是一个数组)的数组成员个数通常是0x00000010(16)个成员
DataDirectory是一个下面类型的数组,各个元素的意义如下图
typedefstruct_IMAGE_DATA_DIRECTORY{
DWORDVirtualAddress;
DWORDSize;
}IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
这里我们只关心第二个元素,即导入表。
DataDirectory[1].Size=0;//这个大小先弄个0放这里,讲完.rdata再回头来改
DataDirectory[1].VirtualAddress=0x00002000;//.rdata段首地址
3.IMAGE_SECTION_HEADER,本PE文件中有3个section段
typedefstruct_IMAGE_SECTION_HEADER{
BYTEName[8];
union{
DWORDPhysicalAddress;
DWORDVirtualSize;
}Misc;
DWORDVirtualAddress;
DWORDSizeOfRawData;
DWORDPointerToRawData;
DWORDPointerToRelocations;
DWORDPointerToLinenumbers;
WORDNumberOfRelocations;
WORDNumberOfLinenumbers;
DWORDCharacteristics;
}IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
Namesection段的名字,随便起名,可以为空。
这里分别取.text.rdata.data
Misc.VirtualSize实际的被使用的区块的大小,(.text)段的内容是指令机器码,我们只实际写如本节的代码如下(xx表示一个未知的字节,后面再来更新)
汇编指令
机器码
Push0
Push0x0040xxxx
Push0x0040xxxx
Push0
CallMessageBox
Push0
CallExitProcess
6A00
68xxxx0400
68xxxx0400
6A00
FF15xxxxxxxx
6A00
Ff15xxxxxxxx
一共是0x1c(28)个字节另外.data节是字符串信息假定是0x40字节.rdata先不管
VirtualAddress该块装载到内存的RVA这里应该分别是0x000010000x000020000x00003000
SizeOfRawData该块在文件中占用的字节数3个段都是0x200(因为文件对齐是0x200,即使本模块中有用的字节数为0x1a(26)个字节,也需要占用0x200的文件空间)
PointerToRawData该块在的文件偏移也就是前面说的IMAGE_OPTIONAL_HEADER.SizeOfHeaders成员的概念分别是0x2000x4000x600
Characteristics块属性具体含义看下表.我们分别取
.text0x60000020=IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ|IMAGE_SCN_CNT_CODE即可执行可读包含可执行代码
.rdata40000040=IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_MEM_READ即包括初始化数据可读
.dataC0000040=IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_UNINITIALIZED_DATA即可读可写包含初始化数据
Flag
Value
Description
0x00000000
Reservedforfutureuse.
0x00000001
Reservedforfutureuse.
0x00000002
Reservedforfutureuse.
0x00000004
Reservedforfutureuse.
IMAGE_SCN_TYPE_NO_PAD
0x00000008
Thesectionshouldnotbepaddedtothenextboundary.ThisflagisobsoleteandisreplacedbyIMAGE_SCN_ALIGN_1BYTES.Thisisvalidonlyforobjectfiles.
0x00000010
Reservedforfutureuse.
IMAGE_SCN_CNT_CODE
0x00000020
Thesectioncontainsexecutablecode.
IMAGE_SCN_CNT_INITIALIZED_DATA
0x00000040
Thesectioncontainsinitializeddata.
IMAGE_SCN_CNT_UNINITIALIZED_DATA
0x00000080
Thesectioncontainsuninitializeddata.
IMAGE_SCN_LNK_OTHER
0x00000100
Reservedforfutureuse.
IMAGE_SCN_LNK_INFO
0x00000200
Thesectioncontainscommentsorotherinformation.The.drectvesectionhasthistype.Thisisvalidforobjectfilesonly.
0x00000400
Reservedforfutureuse.
IMAGE_SCN_LNK_REMOVE
0x00000800
Thesectionwillnotbecomepartoftheimage.Thisisvalidonlyforobjectfiles.
IMAGE_SCN_LNK_COMDAT
0x00001000
ThesectioncontainsCOMDATdata.Formoreinformation,seesection5.5.6,“COMDATSections(ObjectOnly).”Thisisvalidonlyforobjectfiles.
IMAGE_SCN_GPREL
0x00008000
Thesectioncontainsdatareferencedthroughtheglobalpointer(GP).
IMAGE_SCN_MEM_PURGEABLE
0x00020000
Reservedforfutureuse.
IMAGE_SCN_MEM_16BIT
0x00020000
Reservedforfutureuse.
IMAGE_SCN_MEM_LOCKED
0x00040000
Reservedforfutureuse.
IMAGE_SCN_MEM_PRELOAD
0x00080000
Reservedforfutureuse.
IMAGE_SCN_ALIGN_1BYTES
0x00100000
Aligndataona1-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_2BYTES
0x00200000
Aligndataona2-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_4BYTES
0x00300000
Aligndataona4-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_8BYTES
0x00400000
Aligndataonan8-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_16BYTES
0x00500000
Aligndataona16-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_32BYTES
0x00600000
Aligndataona32-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_64BYTES
0x00700000
Aligndataona64-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_128BYTES
0x00800000
Aligndataona128-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_256BYTES
0x00900000
Aligndataona256-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_512BYTES
0x00A00000
Aligndataona512-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_1024BYTES
0x00B00000
Aligndataona1024-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_2048BYTES
0x00C00000
Aligndataona2048-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_4096BYTES
0x00D00000
Aligndataona4096-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_ALIGN_8192BYTES
0x00E00000
Aligndataonan8192-byteboundary.Validonlyforobjectfiles.
IMAGE_SCN_LNK_NRELOC_OVFL
0x01000000
Thesectioncontainsextendedrelocations.
IMAGE_SCN_MEM_DISCARDABLE
0x02000000
Thesectioncanbediscardedasneeded.
IMAGE_SCN_MEM_NOT_CACHED
0x04000000
Thesectioncannotbecached.
IMAGE_SCN_MEM_NOT_PAGED
0x08000000
Thesectionisnotpageable.
IMAGE_SCN_MEM_SHARED
0x10000000
Thesectioncanbesharedinmemory.
IMAGE_SCN_MEM_EXECUTE
0x20000000
Thesectioncanbeexecutedascode.
IMAGE_SCN_MEM_READ
0x40000000
Thesectioncanberead.
IMAGE_SCN_MEM_WRI