PE格式文件的代码注入.docx
《PE格式文件的代码注入.docx》由会员分享,可在线阅读,更多相关《PE格式文件的代码注入.docx(84页珍藏版)》请在冰豆网上搜索。
PE格式文件的代码注入
PE格式文件的代码注入
(一) 2008-11-2401:
05
分类:
PE结构
字号:
大大 中中 小小
本文演示了在不需要重新编译源代码的情况下,怎样向WindowsPE(PortableExecutable)格式的文件(包括EXE、DLL、OCX)中注入自己的代码。
程序如图:
前言
或许,你想了解一个病毒程序是怎样把自身注入到一个正常的PE文件中的,又或者是,你为了保护某种数据而加密自己的PE文件,从而想实现一个打包或保护程序;而本文的目的,就是为了向大家展示,通常的EXE工具或某种恶意程序,是怎样实现上述目的的。
可以基于本文中的代码创建一个你自己的EXE修改器,如果运用得当,它可以是一个EXE保护程序,相反的话,也可能发展成某种病毒。
不管怎样,本文写作的意图是前者,对于任何不适当的用法,本文作者概不负责。
首要条件
对于阅读本文,不存在任何特定强制性的先决条件——即基础知识,如果你对调试器或者PE文件格式非常熟悉,可以跳过下面的两节,而这两节是为不具备调试器或PE文件格式知识的读者准备的。
PE文件格式
PE文件格式被定义用于在Windows操作系统上执行代码或存储运行程序所需的基本数据,例如:
常量、变量、引入库的链接、资源数据等等,其由MS-DOS文件头信息、WindowsNT文件信息、节头部及节映像等组成,见表1。
MS-DOS头部数据
MS-DOS头部数据让人回想起最初在Windows操作系统上部署程序的那些日子,那些在如WindowsNT3.51这类系统上部署程序的日子——这里是说,Win3.1、Win95、Win98不是开发所需的理想操作系统。
这些MS-DOS数据的功能就是在你运行一个可执行文件时,调用一个函数显示出“ThisprogramcannotberuninMS-DOSmode”或者“ThisprogramcanberunonlyinWindowsmode”,或者当你想在MS-DOS6.0中运行一个Windows的EXE文件时,显示出一些类似的信息,所以这些数据是被保留在代码中以作提示之用,但其中最让人感兴趣的还是数据中的“MZ”,不管你相不相信,它是微软的一个程序员“MarkZbikowski”的首字母缩写。
对本文来说,MS-DOS头部数据中,只有PE标志的偏移量最重要,可据此来找出WindowsNT信息数据的实际位置。
在此,建议读者先看一下表1,再查看一下VC7PlatformSDKinclude目录中,或VC98include目录中的头文件中的IMAGE_DOS_HEADER结构。
typedefstruct_IMAGE_DOS_HEADER{//DOS.EXE头"MZ"
WORD e_magic; //神奇数字
WORD e_cblp; //文件尾页的字节数
WORD e_cp; //文件页数
WORD e_crlc; //重定位信息
WORD e_cparhdr; //段落中头部信息的大小
WORD e_minalloc; //所需的最小额外段
WORD e_maxalloc; //所需的最大额外段
WORD e_ss; //初始(相对)SS值
WORD e_sp; //初始SP值
WORD e_csum; //校验和
WORD e_ip; //初始IP值
WORD e_cs; //初始(相对)CS值
WORD e_lfarlc; //重定位表的文件地址
WORD e_ovno; //覆盖数
WORD e_res[4]; //保留字数
WORD e_oemid; //OEM标识符(为e_oeminfo准备)
WORD e_oeminfo; //OEM信息;e_oemid详细说明
WORD e_res2[10]; //保留字数
LONG e_lfanew; //新exe头中文件的地址
}IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
结构中e_lfanew代表了WindowsNT数据位置的偏移量。
以下程序演示了如何从一个EXE文件中获取相关的头部信息。
请留心观察,这些例子对全文来说,都是很重要的。
MS-DOS头信息
IMAGE_DOS_
HEADER
DOSEXESignature
00000000 ASCII"MZ"
00000002 DW0090
00000004 DW0003
00000006 DW0000
00000008 DW0004
0000000A DW0000
0000000C DWFFFF
0000000E DW0000
00000010 DW00B8
00000012 DW0000
00000014 DW0000
00000016 DW0000
00000018 DW0040
0000001A DW0000
0000001C DB00
…
…
0000003B DB00
0000003C DD000000F0
DOS_PartPag
DOS_PageCnt
DOS_ReloCnt
DOS_HdrSize
DOS_MinMem
DOS_MaxMem
DOS_ReloSS
DOS_ExeSP
DOS_ChkSum
DOS_ExeIPP
DOS_ReloCS
DOS_TablOff
DOS_Overlay
…
Reservedwords
…
OffsettoPEsignature
MS-DOSStub
程序
00000040
º
.´.Í!
¸LÍ!
Thisprogramcanno
00000060 tberuninDOSmode....$.......
WindowsNT信息
IMAGE_
NT_HEADERS
Signature
PEsignature(PE)
000000F0 ASCII"PE"
IMAGE_
FILE_HEADER
Machine
000000F4 DW014C
000000F6 DW0003
000000F8 DD3B7D8410
000000FC DD00000000
00000100 DD00000000
00000104 DW00E0
00000106 DW010F
NumberOfSections
TimeDateStamp
PointerToSymbolTable
NumberOfSymbols
SizeOfOptionalHeader
Characteristics
IMAGE_
OPTIONAL_
HEADER32
MagicNumber
00000108 DW010B
0000010A DB07
0000010B DB00
0000010C DD00012800
00000110 DD00009C00
00000114 DD00000000
00000118 DD00012475
0000011C DD00001000
00000120 DD00014000
00000124 DD01000000
00000128 DD00001000
0000012C DD00000200
00000130 DW0005
00000132 DW0001
00000134 DW0005
00000136 DW0001
00000138 DW0004
0000013A DW0000
0000013C DD00000000
00000140 DD0001F000
00000144 DD00000400
00000148 DD0001D7FC
0000014C DW0002
0000014E DW8000
00000150 DD00040000
00000154 DD00001000
00000158 DD00100000
0000015C DD00001000
00000160 DD00000000
00000164 DD00000010
MajorLinkerVersion
MinorLinkerVersion
SizeOfCode
SizeOfInitializedData
SizeOfUninitializedData
AddressOfEntryPoint
BaseOfCode
BaseOfData
ImageBase
SectionAlignment
FileAlignment
MajorOSVersion
MinorOSVersion
MajorImageVersion
MinorImageVersion
MajorSubsystemVersion
MinorSubsystemVersion
Reserved
SizeOfImage
SizeOfHeaders
CheckSum
Subsystem
DLLCharacteristics
SizeOfStackReserve
SizeOfStackCommit
SizeOfHeapReserve
SizeOfHeapCommit
LoaderFlags
NumberOfRvaAndSizes
IMAGE_
DATA_DIRECTORY[16]
ExportTable
ImportTable
ResourceTable
ExceptionTable
CertificateFile
RelocationTable
DebugData
ArchitectureData
GlobalPtr
TLSTable
LoadConfigTable
BoundImportTable
ImportAddressTable
DelayImportDescriptor
COM+RuntimeHeader
Reserved
节信息
IMAGE_
SECTION_
HEADER[0]
Name[8]
000001E8 ASCII".text"
000001F0 DD000126B0
000001F4 DD00001000
000001F8 DD00012800
000001FC DD00000400
00000200 DD00000000
00000204 DD00000000
00000208 DW0000
0000020A DW0000
0000020C DD60000020
CODE|EXECUTE|READ
VirtualSize
VirtualAddress
SizeOfRawData
PointerToRawData
PointerToRelocations
PointerToLineNumbers
NumberOfRelocations
NumberOfLineNumbers
Characteristics
…
…
…
IMAGE_
SECTION_
HEADER[n]
00000210 ASCII".data";SECTION
00000218 DD0000101C;VirtualSize=0x101C
0000021C DD00014000;VirtualAddress=0x14000
00000220 DD00000A00;SizeOfRawData=0xA00
00000224 DD00012C00;PointerToRawData=0x12C00
00000228 DD00000000;PointerToRelocations=0x0
0000022C DD00000000;PointerToLineNumbers=0x0
00000230 DW0000 ;NumberOfRelocations=0x0
00000232 DW0000 ;NumberOfLineNumbers=0x0
00000234 DDC0000040;Characteristics=
INITIALIZED_DATA|READ|WRITE
00000238 ASCII".rsrc";SECTION
00000240 DD00008960;VirtualSize=0x8960
00000244 DD00016000;VirtualAddress=0x16000
00000248 DD00008A00;SizeOfRawData=0x8A00
0000024C DD00013600;PointerToRawData=0x13600
00000250 DD00000000;PointerToRelocations=0x0
00000254 DD00000000;PointerToLineNumbers=0x0
00000258 DW0000 ;NumberOfRelocations=0x0
0000025A DW0000 ;NumberOfLineNumbers=0x0
0000025C DD40000040;Characteristics=
INITIALIZED_DATA|READ
SECTION[0]
00000400 EA22DD77D723DD77 ê"Ýw×#Ýw
00000408 9A18DD7700000000 ?
Ýw....
00000410 2E1EC777831DC777 .?
Çw?
Çw
00000418 FF1EC77700000000 ÿ?
Çw....
00000420 939FE777D805E877 “?
çwØèw
00000428 FDA5E777ADA9E977 ý¥çw©éw
00000430 A336E7770338E777 £6çw8çw
00000438 41E3E677608DE777 Aãæw`?
çw
00000440 E61BE6772B2AE777 ææw+*çw
00000448 7A17E67779C8E677 zæwyÈæw
00000450 141BE777C130E777 çwÁ0çw
…
…
…
…
SECTION[n]
…
0001BF00 63002E0063006800 c...c.h.
0001BF08 6D000A0043006100 m...C.a.
0001BF10 6C00630075006C00 l.c.u.l.
0001BF18 610074006F007200 a.t.o.r.
0001BF20 11004E006F007400 .N.o.t.
0001BF28 200045006E006F00 .E.n.o.
0001BF30 7500670068002000 u.g.h..
0001BF38 4D0065006D006F00 M.e.m.o.
0001BF40 7200790000000000 r.y.....
0001BF48 0000000000000000 ........
0001BF50 0000000000000000 ........
0001BF58 0000000000000000 ........
0001BF60 0000000000000000 ........
0001BF68 0000000000000000 ........
0001BF70 0000000000000000 ........
0001BF78 0000000000000000 ........
表1:
PE文件格式结构
WindowsNT信息数据
正如前一部分所提到的,MS-DOS头数据结构中,e_lfanew代表了WindowsNT头数据位置的偏移量。
因此,如果假定pMem是指向特定PE文件内存空间起始点的指针,那么以下代码就可以获得MS-DOS头与WindowsNT头。
IMAGE_DOS_HEADER image_dos_header;
IMAGE_NT_HEADERS image_nt_headers;
PCHARpMem;
…
memcpy(&image_dos_header,pMem,
sizeof(IMAGE_DOS_HEADER));
memcpy(&image_nt_headers,
pMem+image_dos_header.e_lfanew,
sizeof(IMAGE_NT_HEADERS));
取得PE文件的头部信息,看起来似乎很简单,不过还是推荐查阅一下MSDN中IMAGE_NT_HEADERS的结构定义,以领会NT头部映像中究竟包含了什么,以用于支持在Windows系列操作系统中运行代码。
现在,你应该对WindowsNT头部结构非常熟悉了吧,它由PE标志、文件头信息、可选头信息组成;另外别忘了,要看一下它们在MSDN中的注释。
以下是IMAGE_NT_HEADERS的大体结构:
FileHeader->NumberOfSections
OptionalHeader->AddressOfEntryPoint
OptionalHeader->ImageBase
OptionalHeader->SectionAlignment
OptionalHeader->FileAlignment
OptionalHeader->SizeOfImage
OptionalHeader->
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]->VirtualAddress
OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]->Size
由上,可清楚地看到,当Windows操作系统分配虚拟内存空间时,这些值和它们所扮演的角色的主要作用,在此不便赘述,MSDN中的注释已经非常详细。
不过,对于PE头部的数据节,或OptionalHeader->DataDirectory[],也必须作一个简短的介绍。
当你在WindowsNT数据信息中查看OptionalHeader时,将会发现,在OptionalHeader的结尾处,有16个索引说明,并且包括相关的虚拟地址和大小。
文件中也清楚地说明了这些。
#defineIMAGE_DIRECTORY_ENTRY_EXPORT 0 //ExportDirectory
#defineIMAGE_DIRECTORY_ENTRY_IMPORT 1 //ImportDirectory
#defineIMAGE_DIRECTORY_ENTRY_RESOURCE 2 //ResourceDirectory
#defineIMAGE_DIRECTORY_ENTRY_EXCEPTION 3 //ExceptionDirectory
#defineIMAGE_DIRECTORY_ENTRY_SECURITY 4 //SecurityDirectory
#defineIMAGE_DIRECTORY_ENTRY_BASERELOC 5 //BaseRelocationTable
#defineIMAGE_DIRECTORY_ENTRY_DEBUG 6 //DebugDirectory
#defineIMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 //ArchitectureSpecificData
#defineIMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 //RVAofGP
#defineIMAGE_DIRECTORY_ENTRY_TLS 9 //TLSDirectory
#defineIMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10//LoadConfigurationDirectory
#defineIMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11//BoundImportDirectoryinheaders
#defineIMAGE_DIRECTORY_ENTRY_IAT 12 //ImportAddressTable
#defineIMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 //DelayLoadImportDescriptors
#defineIMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14//COMRuntimedescriptor
注意,此处最后一个,也就是第15个,是否会被用于PE64(Windowsx64可