第二章PE文件结构解析.pptx
《第二章PE文件结构解析.pptx》由会员分享,可在线阅读,更多相关《第二章PE文件结构解析.pptx(75页珍藏版)》请在冰点文库上搜索。
病毒原理及防范病毒原理及防范PEPE型病毒型病毒主讲:
林春蔷主讲:
林春蔷职称:
讲师职称:
讲师成都信息工程学院信息对抗教研室成都信息工程学院信息对抗教研室通过一个实例改变程序的执行流程,从而加深大家对PE文件格式的理解。
深度解析深度解析PEPE文件格式文件格式WinhexWinhexLordPELordPEOllyICEOllyICE工具PEPE文件结构文件结构zzzzzzzzz为什么要重点学习这种文件格式?
portableportableexecutableexecutable可移植可执行跨Win32Win32平台的文件格式所有Win32Win32执行体(exeexe、dlldll、kernelkernelmodedriversmodedrivers)本讲的内容提纲本讲的内容提纲1.PE文件格式总体结构2.MS-DOSMZ文件头+DOSStub3.PE文件头4.节表5.节MZ文件头:
DOSMZHEADERDOS插桩程序:
DOSStubIMAGE_SECTION_HEADERIMAGE_SECTION_HEADERIMAGE_SECTION_HEADERIMAGE_SECTION_HEADER.text.data.edata.reloc.COFF行号COFF符号表CodeView调试信息PE文件标志:
“PE00”映像文件头:
IMAGE_FILE_HEADER可选映像头:
IMAGE_OPTIONAL_HEADER32数据目录表:
IMAGE_DATA_DIRECTORYDOS头PE文件头节表(SectionTable)节(Section)调试信息文件头文件尾hello-2.5.exePEPE文件格式总体结构文件格式总体结构“PE00”?
23年6月25日第8页MSDOSHeader所有MS-DOS兼容的可执行文件都将这个值设为0x5A4D(MZ)4字节文件偏移地址定位PE头部MS-DOSMZheaderMS-DOSMZheaderMS-DOS头部占据了PE文件的头64个字节(4*16=64)USHORTe_magic;/魔数魔数=MZ=MZMZMZ文件格式创始人,微软资深工程师文件格式创始人,微软资深工程师MarkZbikowskiMarkZbikowski的缩写的缩写LONGe_lfanew;/e_lfanewe_lfanew成员用于定位成员用于定位PEPE头。
头。
该字段位于该字段位于3CH3CH处,该位置给出了处,该位置给出了PEPE文件头部的开始位置。
文件头部的开始位置。
在本例中,在本例中,PEPE文件头部开始位置为文件头部开始位置为0B0H0B0H。
字串字串“PE00PE00”SignatureSignature一dword类型,值为50h,45h,00h,00h(PE00)。
本域为PE标记,我们可以此识别给定文件是否为有效PE文件。
这个字串在文件中的位置(e_lfanew)可以在DOS程序头中找到它的指针,它占用四个字节,位于文件开始偏移3CH字节中。
魔术数字定位PE头部PE文件标志“PE00”“PE00”魔术数字魔术数字魔术数字映像文件头(映像文件头(0x140x14)该结构域包含了关于PE文件物理分布的信息,比如节数目、文件执行机器等。
它实际上是结构IMAGE_FILE_HEADERIMAGE_FILE_HEADER的简称。
23年6月25日第14页WORDMachine;该程序要执行的环境及平台WORDNumberOfSections;文件中节的个数DWORDTimeDateStamp;文件建立的时间DWORDPointerToSymbolTable;COFF符号表的偏移DWORDNumberOfSymbols;符号数目WORDSizeOfOptionalHeader;可选头的长度WORDCharacteristics;文件属性标志集合PE头部1:
映像文件头可选映像头可选映像头(P80)(P80)可选映像头中的一些关键字段可选映像头中的一些关键字段11名字描述AddressOfEntryPoint*PE装载器准备运行的PE文件的第一个指令的RVA。
若要改变整个执行的流程,可以将该值指定到新的RVA,这样新RVA处的指令首先被执行。
(病毒感染中通用关键字段)ImageBasePE文件的优先装载地址。
比如,如果该值是400000h,PE装载器将尝试把文件装到虚拟地址空间的400000h处。
若该地址区域已被其他模块占用,那PE装载器会选用其他空闲地址。
SectionAlignment内存中节对齐的粒度。
FileAlignment文件中节对齐的粒度。
可选映像头中的一些关键字段可选映像头中的一些关键字段22名字描述MajorSubsystemVersionMinorSubsystemVersionwin32子系统版本。
若PE文件是专门为Win32设计的,该子系统版本必定是4.0否则对话框不会有3维立体感。
SizeOfImage内存中整个PE映像体的尺寸。
SizeOfHeaders所有头+节表的大小。
可以以此值作为PE文件第一节的文件偏移量。
SubsystemNT用来识别PE文件属于哪个子系统。
DataDirectory一个IMAGE_DATA_DIRECTORY结构数组。
每个结构给出一个重要数据结构的RVA,比如引入地址表等。
RVA:
RelativeVirtualAddress,表示相对虚拟地址。
它是相对内存中ImageBase的偏移位置。
VA:
VirtualAddress,表示虚拟地址,即装载到内存中之后的位置。
(VA=ImageBase+RVA)举例说明,如果PE文件装入内存空间的400000h处,且进程从虚拟地址401000h开始执行,我们可以说进程执行起始地址在RVA1000h。
每个RVA都是相对于模块的起始VA的。
几个常用术语几个常用术语几个常用术语几个常用术语对齐内存中节对齐的粒度文件中节对齐的粒度问题1:
桶的容量为100升,现有367升水,请问需要使用多少个桶?
问题2:
代码节的代码实际长度为0x46字节,文件中节对齐粒度为0x200,内存中节对齐粒度为0x1000字节,请问代码节在文件和内存中分别占用多少字节?
为什么PE文件中有很多“00”字节?
DataDirectoryDataDirectory数据目录数据目录一个IMAGE_DATA_DIRECTORY数组,里面放的是这个可执行文件的一些重要部分的RVA和尺寸,目的是使可执行文件的装入更快,数组的项数由上一个域给出。
IMAGE_DATA_DIRECTORY包含有两个域,如下:
IMAGE_DATA_DIRECTORYVitualAddressDD?
SizeDD?
IMAGE_DATA_DIRECTORYENDS3.4hello-2.5.exe3.4hello-2.5.exe的的IATIAT与引入与引入表表节表节表节表其实就是紧挨着PEheader的一结构数组。
该数组成员的数目由Fileheader(IMAGE_FILE_HEIMAGE_FILE_HEADERADER)结构中NumberOfSectionsNumberOfSections域的域值来决定。
节表结构又命名为IMAGE_SECTION_HEADERIMAGE_SECTION_HEADER(每个结构占用28H)。
结构中放的是一个节的信息,如名字、地址、长度、属性等。
23年6月25日第25页节表UCHARName8;/UCHARName8;/节名unionunionULONGPhysicalAddress;/OBJULONGPhysicalAddress;/OBJ文件中表示本节物理地址ULONGULONGVirtualSize;/EXEVirtualSize;/EXE文件中表示节的实际字节数Misc;Misc;ULONGVirtualAddress;/ULONGVirtualAddress;/本节的RVARVAULONGSizeOfRawData;/ULONGSizeOfRawData;/本节在文件中的尺寸ULONGPointerToRawData;/ULONGPointerToRawData;/本节在文件中的偏移地址ULONGPointerToRelocations;/OBJULONGPointerToRelocations;/OBJ文件中表示本节重定位信/息的偏移,EXEEXE文件中无意义ULONGPointerToLinenumbers;/ULONGPointerToLinenumbers;/行号偏移USHORTNumberOfRelocations;/USHORTNumberOfRelocations;/重定位项的数目USHORTNumberOfLinenumbers;/USHORTNumberOfLinenumbers;/本节在行号表中的行号数目ULONGCharacteristics;/ULONGCharacteristics;/节属性代码SectionAlignmentSectionAlignmentFileAlignmentFileAlignment23年6月25日第27页如:
80000000H就表示这段内存是可写的,40000000H就表示这段内存是可读的一个节可包含多个属性,对应位为1表示有此属性如果期望一个节的数据可读可写,则它的属性代码应该是:
?
节的属性节的属性代表了该节所在内存区块的权限,其中每一位都代表了一种权限或属性的启开和关闭:
属性为:
60000020H,请问是什么节?
属性为:
C0000040H,请问是什么节?
请问病毒代码会为自己设置什么样的属性值?
QuestionQuestion23年6月25日第29页PEPE装载器的工作流程装载器的工作流程装载器如何把一个节映射到内存中?
获取文件节的数目(NumberOfSections)定位节表(SizeOfHeaders)获得该节在磁盘上的存储位置及大小(PointerToRawData,SizeOfRawData)把该节映射进内存(VirtualAddress,ImageBase)设置该节的属性(Characteristics)节节“节(Section)”跟在节表之后,一般PE文件都有几个“节”。
比较常见的有:
代码节已初始化的数据节未初始化的数据节引入函数节引出函数节资源节代码节代码节代码节代码节代码节一般名为.text或CODE,该节含有程序的可执行代码。
每个PE文件应该都有代码节已初始化的数据节已初始化的数据节这个节一般取名为.data或DATA已初始化的数据节中放的是在编译时刻就已确定的数据。
如HelloWorld中的字符串“HelloWorld!
”。
.data.data节节未初始化的数据节未初始化的数据节这个节的名称一般叫.bbs。
这个节里放有未初始化的全局变量和静态变量。
例如staticintk;“该节的PointerToRawData为0,表明其内容不在文件内,特征位IMAGE_SCN_CNT_UNINITIALIZED_DATA指明所有内容必须在加载时间置0。
这意味着有节头,但没有节在文件内,该节被加载器创建,并且包含全0字节。
其长度是SizeOfUninitializedData.典型名字如.bss,BSS。
引入函数节引入函数节这个节一般名为.rdata,也叫引入函数节。
一个引入函数是被某模块调用的但又不在调用者模块中的函数它可以用来从其它(系统或第三方写的)DLL中引入函数,例如user32.dll、gdi32.dll等。
IATIAT(IMPORTAddressTableIMPORTAddressTable)一系列DWORD的数组在文件中时,每个双字中存放着对应引入函数的函数名字符串的RVA在内存中时,每个双字中存放着对应引入函数的地址。
请问:
ExitProcess函数的地址可能在不同的操作系统中各不相同,但为什么我们写的程序可以在不同的系统中正常运行?
IATIAT(IMPORTAddressTablIMPORTAddressTablee)IMPORTDirectoryTableIMPORTDirectoryTable(核心)(核心)输入目录是一个IMAGE_IMPORT_DESCRIPTORs数组,每个DLL都使用一个元素,该列表中止于一个全0的数组元素。
一个一个IMAGE_IMPORT_DESCRIPTORIMAGE_IMPORT_DESCRIPTOR是一个具有如下元素的结构:
IMAGE_IMPORT_DESCRIPTORSTRUCTunionCharacteristicsdd?
OriginalFirstThunkdd?
/指向引入函数名列表或序号列表EndsTimeDateStampdd?
ForwarderChaindd?
Name1dd?
/指向dll函数名FirstThunkdd?
/指向IAT表IMAGE_IMPORT_DESCRIPTORENDSIMPORTDirectoryTableIMPORTDirectoryTableIMPORTNameTableIMPORTNameTableDataData最高位:
为11时,表示通过序号引入函数为00时,表示通过函数名引入IMPORTHints/Names&DLLnamesIMPORTHints/Names&DLLnamesIMPORTHints/Names&DLLnamesIMPORTHints/Names&DLLnames分分解说明解说明kernel32.dll为dll文件名8000为Hints,ExitProcess为引入函数名user32.dll为dll文件名6202为Hints,wsprintfA为引入函数名9D01为Hints,MessageBoxA为引入函数名在文件中的引入表在文件中的引入表IMAGE_IMPORT_DESCRIPTORIMAGE_IMPORT_BY_NAMEOriginalFirstThunkTimeDatestampForwardChainNameFirstThunkIMAGE_THUNK_DATAIMAGE_THUNK_DATA01函数123函数2IMAGE_THUNK_DATAIMAGE_THUNK_DATAKERNEL32.DLL在内存中的引入表在内存中的引入表IMAGE_IMPORT_DESCRIPTORIMAGE_IMPORT_BY_NAMEOriginalFirstThunkTimeDatestampForwardChainNameFirstThunkIMAGE_THUNK_DATAIMAGE_THUNK_DATA01函数123函数2IMAGE_THUNK_DATAIMAGE_THUNK_DATAKERNEL32.DLL函数1地址函数2地址23年6月25日第49页23年6月25日第50页什么是引入函数?
这些函数一般从哪里引入?
为什么要设计引入函数节?
目的何在?
复习复习ExitProcess7081CDDAMessageBoxA77D504EAwsprintfA77D1A8AD引出函数节引出函数节引出函数节一般名为.edata,这是本文件向其他程序提供调用函数的列表所在的“索引”及具体代码实现。
(这个节一般用在DLL中,EXE也可以有这个节,但通常很少使用)我们主要分析其“索引”部分。
通过该“索引”,可以找到对应函数的具体地址。
引出函数节引出函数节1(00H)Characteristics4一般为02(04H)TimeDateStamp4文件生成时间3(08H)MajorVersion2主版本号4(0AH)MinorVersion2次版本号5(0CH)Name4指向DLL的名字6(10H)Base4开始的序列号7(14H)NumberOfFunctions4AddressOfFunctions数组的项数8(18H)NumberOfNames4AddressOfNames数组的项数9(1CH)AddressOfFunctions4指向函数地址数组10(20H)AddressOfNames4指向“函数名所在地址”数组11(24H)AddressOfNameOrdinals4指向“函数索引序列号”数组Kernel32.dllKernel32.dll的引出函数节的引出函数节寻找寻找ExitProcessExitProcess地址地址1.首先从AddressOfNames指向的指针数组中找到“ExitProcess”字符串,并记下该数组序号x2.然后从AddressofNameOrinals指向的数组中,定位第x项成员,得到一个序号yy为ExitProcess函数地址在AddressOfFunction中的索引号。
3.从AddressOfFunction指向的数组中定位第y项,获得ExitProcess的RVA函数地址1.1.寻找寻找ExitProcessExitProcess地址:
地址:
首先搜索首先搜索NameTableNameTable,x=?
x=?
x=00B7x=00B72.2.然后从然后从AddressofNameOrinalsAddressofNameOrinals指向指向的数组中,定位第的数组中,定位第xx项成员,获得项成员,获得y=y=?
00B600B63.3.从从AddressTableAddressTable获取获取ExitProcessExitProcess的的函数地址函数地址(RVA=001CDDA)(RVA=001CDDA)y=00B600B6,为何这里是00B700B7项?
=PEViewPEView定位数组成员从11开始,而不是00获取的获取的ExitProcessExitProcess地址是否正确地址是否正确?
23年6月25日第61页构建构建PEPE中的引入信息中的引入信息PE加载器是如何正确的填充了FirstThunk指向的函数地址?
23年6月25日第62页对于每个DLL的IMAGE_IMPORT_DESCRIPTOR:
1.通过OriginalFirstThunk指向的INT得到函数名列表。
2.对每个函数名:
从DLLEXPORT匹配名称,查得地址3.把函数地址填到FirstThunk对应的字段。
23年6月25日第63页首先打开一个名为example.exe的程序(PE文件)实验后的效果test.exe实例:
如何改变程序(实例:
如何改变程序(.exe.exe)的执行流程)的执行流程ABCWinhexWinhex是一款以1616进制编辑器为核心,主要用于各种文件操作的高级工具。
LordPELordPE,是一款功能强大的PEPE文件分析、修改、脱壳软件。
OllyICEOllyICE反汇编工具,主要用于动态追踪、调试、逆向等领域。
WinhexWinhex需要的工具需要的工具LordPELordPEOllyICOllyICE最后用LordPE修改AddressOfEntryPoint,使其指向新加入的节。
用OllyICE对新加入的节添加弹出对话框的代码。
通过Winhex修改文件大小。
通过LordPE加入一个新节,并修改NumberOfSection+1。
用LordPE查看example.exe相关信息。
设计思路设计思路用用LordPELordPE打开打开example.exeexample.exeSectionAlignmentSectionAlignmentFileAlignmentFileAlignment添加一个新节添加一个新节节的数目节的数目什?
为么报错添加的节超出的文件的范围,必须用Winhex加大节(增加节的字节数)。
具体操作WinhexWinhex应用应用到00404000h处添加代码push0;逆序压栈push00404030;标题push00404044;提示信息push0callMessageBoxA;调用Messagebox函数jmp00401000;跳转到修改前程序的入口地址用用OllyICEOllyICE对新加的节添加代码对新加的节添加代码通过本次课学习,希望大家加深对PE文件格式的理解。
Winhex、LordPE、OllyICE实用性高,功能强大,希望大家课后花时间去熟悉它们。
死记硬背不如动手实践。
本次课小结本次课小结谢谢!