文件格式内容详细PPT课件_第1页
文件格式内容详细PPT课件_第2页
文件格式内容详细PPT课件_第3页
文件格式内容详细PPT课件_第4页
文件格式内容详细PPT课件_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 安装在硬盘上的程序没运行-静态 加载到内存-动态第1页/共49页MZ文件格式-Mark Zbikowski .EXE文件由三部分构成:文件头、重定位表和二进制代码 允许代码、数据、堆栈分别处于不同的段,每一段都可以是64KB.偏移偏移大小大小(字节字节)描述描述002EXE文件类型标记:文件类型标记: 4D5Ah(ASCII字符字符MZ)022文件最后一个扇区的字节数文件最后一个扇区的字节数042文件的总扇区文件的总扇区(页页)数数文件的大小文件的大小=(总扇区数总扇区数-1)512+最后一个扇区的字节数最后一个扇区的字节数062重定位项的个数重定位项的个数082EXE文件头的大小文件头的大

2、小(16字节的倍数字节的倍数)0A2最小分配数最小分配数(16字节的倍数字节的倍数)0C2最大分配数最大分配数(16字节的倍数字节的倍数)0E2初始化堆栈段初始化堆栈段(SS初值初值)102初始化堆栈指针初始化堆栈指针(SP初值初值)122补码校验和补码校验和142初始代码段指针初始代码段指针(IP初值初值)162初始代码段段地址初始代码段段地址(CS初值初值)182定位表的偏移地址定位表的偏移地址(第一个重定位项的偏移量第一个重定位项的偏移量)1A2连接程序产生的覆盖号连接程序产生的覆盖号确定MZ文件的大小以大小为512B的页为存储单位确定代码的开始处执行代码的入口地址重定位表的指针链表比如

3、调用C的库函数加载EXE文件第2页/共49页调用C的库函数程序编译后: 0000:0000 9A78563412 call far 1234:5678 程序加载器的重定位工作,就是将程序中需要重定位的地方,都加上程序的加载地址。 这个程序被加载到了内存中的1111段处。那么完成重定位后,代码应该是这样: 1111:0000 9A78564523 call far 2345:5678 第3页/共49页NE文件格式 NE是New Excutable的缩写,是16位Windows可执行文件的标准格式,这种格式基本上没用了 NE在MZ文件头之后添加了一个以“NE”开始的文件头第4页/共49页PE文件格

4、式 Win32可执行文件,如*.EXE、*.DLL、*.OCX等,都是PE格式 PE的意思就是Portable Executable(可移植、可执行),它是Win32可执行文件的标准格式 由于大量的EXE文件被执行,且传播的可能性最大,因此,Win32病毒感染文件时,基本上都会将EXE文件作为目标计算机病毒也是程序或者程序代码,而且也是可执行的,否则无法感染、破坏、隐藏等,其病毒文件也是遵循PE的格式结构。第5页/共49页PE文件格式 一般来说,病毒往往先于HOST程序获得控制权。运行Win32病毒的一般流程示意如下: 用户点击或系统自动运行HOST程序; 装载HOST程序到内存; 通过PE文

5、件中的AddressOfEntryPoint+ImageBase,定位第一条语句的位置(程序入口); 从第一条语句开始执行(这时执行的其实是病毒代码); 病毒主体代码执行完毕,将控制权交给HOST程序原来的入口代码; HOST程序继续执行。 问题在于:计算机病毒怎会在HOST程序之前执行?第6页/共49页PE文件格式MZ文件头:DOS MZ HEADERDOS插桩程序:DOS StubIMAGE_SECTION_HEADERIMAGE_SECTION_HEADERIMAGE_SECTION_HEADERIMAGE_SECTION_HEADER.text.data.edata.reloc.COF

6、F行号COFF符号表Code View调试信息PE文件标志:“PE00”映像文件头:IMAGE_FILE_HEADER可选映像头:IMAGE_OPTIONAL_HEADER32数据目录表:IMAGE_DATA_DIRECTORYDOS头PE文件头节表(Section Table)节(Section)调试信息文件头文件尾PE文件格式可看作为逻辑磁盘Boot扇区各种文件文件目录有了DOS头,程序在DOS下执行,DOS就能识别这是个有效的执行体。DOS Stub是有效的DOS的可执行的代码,因而在不支持PE文件格式DOS下运行,它调用中断21H的功能9显示This program cannot be

7、 run in DOS mode 每种文件有不同属性,如只读、系统、隐藏、文档等。节的划分是基于各种数据的共同属性,而不是逻辑概念。PE文件中的数/代码拥有相同的属性,就能被列入同一节。因而节名仅仅是个名称而已,为了识别。真正理解节,要靠节的属性设置第7页/共49页PE文件结构文件结构第8页/共49页PE文件格式 相对虚拟地址 (Relative Virtual Addresses,RVA) 相对虚拟地址是一个相对于PE文件映射到内存的基地址的偏移量 不能映射的数据.reloc.data.textDOS头节表PE头.reloc.data.textDOS头节表PE头文件头文件尾磁盘中的PE文件映

8、射到内存中文件偏移地址基地址(ImageBase)某一虚拟地址(VA)相对虚拟地址(RVA)0X004000000X15600X00401560第9页/共49页PE文件格式MS-DOS头(64字节) USHORT(双字节无符号数)typedef struct _IMAGE_DOS_HEADER / DOStypedef struct _IMAGE_DOS_HEADER / DOS的.EXE.EXE头部 USHORT e_magic; / USHORT e_magic; / 魔术数字 USHORT e_cblp; / USHORT e_cblp; / 文件最后页的字节数 USHORT e_cp;

9、 / USHORT e_cp; / 文件页数 USHORT e_crlc; / USHORT e_crlc; / 重定向元素个数 USHORT e_cparhdr; / USHORT e_cparhdr; / 头部尺寸,以段落为单位 USHORT e_minalloc; / USHORT e_minalloc; / 所需的最小附加段 USHORT e_maxalloc; / USHORT e_maxalloc; / 所需的最大附加段 USHORT e_ss; / USHORT e_ss; / 初始的SSSS值( (相对偏移量) ) USHORT e_sp; / USHORT e_sp; / 初

10、始的SPSP值 USHORT e_csum; / USHORT e_csum; / 校验和 USHORT e_ip; / USHORT e_ip; / 初始的IPIP值 USHORT e_cs; / USHORT e_cs; / 初始的CSCS值( (相对偏移量) ) USHORT e_lfarlc; / USHORT e_lfarlc; / 重分配表文件地址 USHORT e_ovno; / USHORT e_ovno; / 覆盖号 USHORT e_res4; / USHORT e_res4; / 保留字 USHORT e_oemid; / OEMUSHORT e_oemid; / OEM

11、标识符( (相对e_oeminfo)e_oeminfo) USHORT e_oeminfo; / OEM USHORT e_oeminfo; / OEM信息 USHORT e_res210; / USHORT e_res210; / 保留字 LONG e_lfanew;LONG e_lfanew; / / 新EXEEXE头部的文件地址 IMAGE_DOS_HEADER, IMAGE_DOS_HEADER, * *PIMAGE_DOS_HEADER;PIMAGE_DOS_HEADER;MZPE头位置PE装载器跳过DOS Stub定位到PE文件头第10页/共49页PE文件格式 DOS头与DOS插桩

12、程序 PE结构中紧随MZ文件头之后的DOS插桩程序(DOS Stub) 可以通过IMAGE_DOS_HEADER结构来识别一个合法的DOS头 可以通过该结构的e_lfanew(偏移60,32bits)成员来找到PE开始的标志0 x00004550(“PE00”) 病毒通过“MZ”、“PE”这两个标志,初步判断当前程序是否是目标文件PE文件。如果要精确校验指定文件是否为一有效PE文件,则可以检验PE文件格式里的各个数据结构,或者仅校验一些关键数据结构。大多数情况下,没有必要校验文件里的每一个数据结构,只要一些关键数据结构有效,就可以认为是有效的PE文件第11页/共49页PE文件格式 PE文件头

13、紧接着DOS Stub的是PE header PE header是IMAGE_NT_HEADERS的简称,即NT映像头(PE文件头),存放PE整个文件信息分布的重要字段,包含了许多PE装载器用到的重要域。执行体在支持PE文件结构的操作系统中执行时 PE装载器将从DOS MZ header中找到PE header的起始偏移量,从而跳过DOS Stub直接定位到真正的文件头PE header第12页/共49页PE文件格式 PE文件头的结构 字符串“PE00”(Signature)(4H字节) IMAGE_NT_HEADERS STRUCT IMAGE_NT_HEADERS STRUCT Signa

14、ture dd ? Signature dd ? FileHeader IMAGE_FILE_HEADER FileHeader IMAGE_FILE_HEADER OptionalHeader IMAGE_OPTIONAL_HEADER32OptionalHeader IMAGE_OPTIONAL_HEADER32IMAGE_NT_HEADERS ENDSIMAGE_NT_HEADERS ENDS检验PE文件的有效性?首先检验文件头部第一个字的值是否等于 IMAGE_DOS_SIGNATURE,是则 DOS MZ header 有效。一旦证明文件的 DOS header 有效后,就可用e_l

15、fanew来定位 PE header 了。比较 PE header 的第一个字的值是否等于 IMAGE_NT_HEADER。如果前后两个值都匹配,那我们就认为该文件是一个有效的PE文件。第13页/共49页typedef struct _IMAGE_FILE_HEADER typedef struct _IMAGE_FILE_HEADER WORD WORD MachineMachine; / 0 x04; / 0 x04,该程序要执行的环境及平台 WORD WORD NumberOfSectionsNumberOfSections; / 0 x06; / 0 x06,文件中节的个数 DWORD

16、 TimeDateStamp; / 0 x08DWORD TimeDateStamp; / 0 x08,文件建立的时间 DWORD PointerToSymbolTable; / 0 x0cDWORD PointerToSymbolTable; / 0 x0c,COFFCOFF符号表的偏移 DWORD NumberOfSymbols; / 0 x10DWORD NumberOfSymbols; / 0 x10,符号数目 WORD WORD SizeOfOptionalHeaderSizeOfOptionalHeader; / 0 x14; / 0 x14,可选头的长度 WORD WORD Ch

17、aracteristicsCharacteristics; / 0 x16; / 0 x16,标志集合 IMAGE_FILE_HEADER, IMAGE_FILE_HEADER, * *PIMAGE_FILE_HEADER;PIMAGE_FILE_HEADER;每个节表28H字节病毒感兴趣的地方,添加一个新节IMAGE_NT_HEADERS STRUCT IMAGE_NT_HEADERS STRUCT Signature dd ? Signature dd ? FileHeader IMAGE_FILE_HEADER FileHeader IMAGE_FILE_HEADER OptionalH

18、eader IMAGE_OPTIONAL_HEADER32OptionalHeader IMAGE_OPTIONAL_HEADER32IMAGE_NT_HEADERS ENDSIMAGE_NT_HEADERS ENDSPE文件头的结构-映像文件头-NT映像头的主要部分,包含有PE文件的基本信息关于PE文件物理分布的基本信息关于文件信息的标记,比如文件是 exe还是 dllPE文件逻辑分布的信息第14页/共49页PE文件格式 紧跟映像文件头后面的是可选映像头-是必须的!typedef struct _IMAGE_OPTIONAL_HEADER typedef struct _IMAGE_OPTI

19、ONAL_HEADER / / 标准域: : / / WORD Magic; / 0 x18 WORD Magic; / 0 x18,一般是0 x010B0 x010B BYTE MajorLinkerVersion; / 0 x1a BYTE MajorLinkerVersion; / 0 x1a,链接器的主/ /次版本号, BYTE MinorLinkerVersion; / 0 x1bBYTE MinorLinkerVersion; / 0 x1b,这两个值都不可靠 DWORD DWORD SizeOfCodeSizeOfCode; / 0 x1c; / 0 x1c,可执行代码的长度 D

20、WORD SizeOfInitializedData; / 0 x20DWORD SizeOfInitializedData; / 0 x20,初始化数据的长度( (数据节) ) DWORD SizeOfUninitializedData; / 0 x24 DWORD SizeOfUninitializedData; / 0 x24,未初始化数据的长度(bss(bss节) ) DWORD DWORD AddressOfEntryPointAddressOfEntryPoint;/ 0 x28;/ 0 x28,代码的入口RVARVA地址,程序从这开始执行 DWORD BaseOfCode; /

21、0 x2cDWORD BaseOfCode; / 0 x2c,可执行代码起始位置,意义不大 DWORD BaseOfData; / 0 x30DWORD BaseOfData; / 0 x30,初始化数据起始位置,意义不大 / NT / NT 附加域: : / / DWORD DWORD ImageBaseImageBase; / 0 x34; / 0 x34,载入程序首选的VAVA地址 DWORD DWORD SectionAlignmentSectionAlignment; / 0 x38; / 0 x38,加载后节在内存中的对齐方式- -节的大小 DWORD DWORD FileAlig

22、nmentFileAlignment; / 0 x3c; / 0 x3c,节在文件中的对齐方式- -节的大小( (待续) )首选不是必须,如果该值为400000H,但是被其他模块占用,PE装载器会选择其他空闲地址。内存中节对齐的粒度。该值为4096-1000H,那么每节的起始地址必须是4096倍数。若第一节从401000H开始,大小为10字节,那么下一节从什么地方开始?文件中节对齐的粒度。该值为512-200H,那么每节的起始地址必须是512倍数。若第一节从200H开始,大小为10字节,那么下一节从什么地方开始?运行PE文件的第一条指令的RVA。进程从虚址VA401000H开始执行,那么该值为

23、多少?病毒感兴趣!-指向病毒体代码PE文件逻辑分布的信息第15页/共49页PE文件格式(续前) WORD MajorOperatingSystemVersion; / 0 x3eWORD MajorOperatingSystemVersion; / 0 x3e,操作系统主/ /次版本, WORD MinorOperatingSystemVersion; / 0 x40WORD MinorOperatingSystemVersion; / 0 x40,LoaderLoader并没有用这两个值 WORD MajorImageVersion; / 0 x42WORD MajorImageVersio

24、n; / 0 x42,可执行文件主/ /次版本 WORD MinorImageVersion; / 0 x44WORD MinorImageVersion; / 0 x44 WORD MajorSubsystemVersion; / 0 x46 WORD MajorSubsystemVersion; / 0 x46,子系统版本号 WORD MinorSubsystemVersion; / 0 x48WORD MinorSubsystemVersion; / 0 x48 DWORD Win32VersionValue; / 0 x4c DWORD Win32VersionValue; / 0 x

25、4c,Win32Win32版本,一般是0 0 DWORD DWORD SizeOfImageSizeOfImage; / 0 x50; / 0 x50,程序调入后占用内存大小( (字节) ) DWORD DWORD SizeOfHeadersSizeOfHeaders; / 0 x54; / 0 x54,文件头的长度之和 DWORD DWORD CheckSumCheckSum; / 0 x58; / 0 x58,校验和 WORD WORD SubsystemSubsystem; / 0 x5c; / 0 x5c,可执行文件的子系统GUIGUI或CUICUI WORD DllCharacter

26、istics; / 0 x5e WORD DllCharacteristics; / 0 x5e,何时DllMainDllMain被调用,一般为0 0 DWORD SizeOfStackReserve; / 0 x60 DWORD SizeOfStackReserve; / 0 x60,初始化线程时保留的堆栈大小 DWORD SizeOfStackCommit; / 0 x64DWORD SizeOfStackCommit; / 0 x64,初始化线程时提交的堆栈大小 DWORD SizeOfHeapReserve; / 0 x68DWORD SizeOfHeapReserve; / 0 x6

27、8,进程初始化时保留的堆大小 DWORD SizeOfHeapCommit; / 0 x6cDWORD SizeOfHeapCommit; / 0 x6c,进程初始化时提交的堆大小 DWORD LoaderFlags; / 0 x70DWORD LoaderFlags; / 0 x70,装载标志,与调试相关 DWORD NumberOfRvaAndSizes; / 0 x74DWORD NumberOfRvaAndSizes; / 0 x74,数据目录的项数,一般是1616 IMAGE_DATA_DIRECTORY DataDirectoryIMAGE_NUMBEROF_DIRECTORY_E

28、NTRIES; IMAGE_DATA_DIRECTORY DataDirectoryIMAGE_NUMBEROF_DIRECTORY_ENTRIES; IMAGE_OPTIONAL_HEADER, IMAGE_OPTIONAL_HEADER, * *PIMAGE_OPTIONAL_HEADER;PIMAGE_OPTIONAL_HEADER;第16页/共49页DataDirectory:数据目录表 typedef struct _IMAGE_DATA_DIRECTORY DWORD VirtualAddress; DWORD Size; IMAGE_DATA_DIRECTORY, *PIMAGE

29、_DATA_DIRECTORY; 是一个IMAGE_DATA_DIRECTORY结构数组,有16个这样的元素。 数据目录表-每个结构给出一个重要数据结构的起始RVA和大小信息。 节表可以看作是PE文件各节的根目录的话,也可以认为 data directory 是存储在这些节里的逻辑元素的根目录。第17页/共49页 什么重要数据结构? 如:导入目录-导入函数(引入函数 import) 一个引入函数是被某模块调用但又不在调用模块中的函数,位于一个或者更多的DLL里,因而要保留一些函数信息,包括函数名及其驻留的DLL名。 怎么样获得PE文件中重要数据结构?第18页/共49页怎么样获得PE文件中重要数

30、据结构?从 DOS header 定位到 PE header从 optional header 读取 data directory 的地址。IMAGE_DATA_DIRECTORY 结构尺寸乘上找寻结构的索引号: 寻import symbols的位置信息,必须用IMAGE_DATA_DIRECTORY 结构尺寸(8 bytes)乘上1(import symbols在data directory中的索引号)。将上面的结果加上data directory地址,就得到包含所查询数据结构信息的 IMAGE_DATA_DIRECTORY 结构项。第19页/共49页PE文件格式 节表是紧挨着NT映像头的一

31、结构数组,其成员的数目由映像文件头中NumberOfSections决定#define IMAGE_SIZEOF_SHORT_NAME 8#define IMAGE_SIZEOF_SHORT_NAME 8typedef struct _IMAGE_SECTION_HEADER typedef struct _IMAGE_SECTION_HEADER UCHAR NameIMAGE_SIZEOF_SHORT_NAME; / UCHAR NameIMAGE_SIZEOF_SHORT_NAME; / 节名 union union ULONG PhysicalAddress; / OBJ ULONG

32、PhysicalAddress; / OBJ文件中表示本节物理地址 ULONG ULONG VirtualSizeVirtualSize; / EXE; / EXE文件中表示节的实际字节数 Misc; Misc; ULONG ULONG VirtualAddressVirtualAddress; / ; / 本节的RVARVA ULONG SizeOfRawData; / ULONG SizeOfRawData; / 本节经过文件对齐后的尺寸 ULONG PointerToRawData; / ULONG PointerToRawData; / 本节原始数据在文件中的位置 ULONG Poin

33、terToRelocations; / OBJULONG PointerToRelocations; / OBJ文件中表示本节重定位信 / / 息的偏移,EXEEXE文件中无意义 ULONG PointerToLinenumbers; / ULONG PointerToLinenumbers; / 行号偏移 USHORT NumberOfRelocations; / USHORT NumberOfRelocations; / 本节需重定位的数目 USHORT NumberOfLinenumbers; / USHORT NumberOfLinenumbers; / 本节在行号表中的行号数目 UL

34、ONG Characteristics; / ULONG Characteristics; / 节属性 IMAGE_SECTION_HEADER, IMAGE_SECTION_HEADER, * *PIMAGE_SECTION_HEADER;PIMAGE_SECTION_HEADER;本节的实际字节数 如388H字节本节的相对虚拟地址 如为1000H,而PE文件装载地址400000H,?经过文件对齐后的节尺寸;若对齐粒度为200H,那么该值为? 病毒喜欢这里PE装载器通过本域找到节的位置第20页/共49页PE文件格式 代码节的属性一般是60000020H,即“可执行”、“可读”和“节中包含代码

35、” 数据节的属性一般是C0000040H,即“可读”、“可写”和“包含已初始化数据” 病毒在添加新节时,都会将新添加的节的属性设置为可读、可写、可执行NumberOfSections知道有几个节SizeOfHeaders知道节表在什么地方开始遍历节表,PointerToRawData知道节在文件中偏移量SizeOfRawData来决定映射内存的字节数VirtualAddress加上ImageBase知道节的起始虚拟地址第21页/共49页PE文件格式 节 PE文件的真正内容划分成块,称之为Section(节),紧跟在节表之后 每个节是一块拥有共同属性的数据,比如代码/数据、读/写等 可以把PE文

36、件想象成一逻辑磁盘,PE header是磁盘的Boot扇区,节表就是根目录,而Section就是各种文件,每种文件自然就有不同属性如只读、系统、隐藏、文档等等 节的划分是基于各组数据的共同属性而不是逻辑概念如果PE文件中的数据/代码拥有相同属性,它们就能被归入同一节中 节名称仅仅是个区别不同节的符号而已,类似“data”、“code”的命名只为了便于识别,惟有节的属性设置决定了节的特性和功能 第22页/共49页PE文件格式 代码节.text Windows NT默认的做法是将所有的可执行代码组成了一个单独的节,名为“.text”或“.code” 引入函数节.idata 包含有从其它DLL中引入

37、的函数 该节开始是一个成员为IMAGE_IMPORT_DESCRIPTOR结构的结构数组,也叫引入表,数据目录表表项结构成员VirtualAddress包含引入表地址 引入函数节可能被病毒用来直接获取API函数地址第23页/共49页Windows NT进程的地址空间操作系统使用不可读写(2GB)用于防止跨用户/系统边界传输数据不可读写(64KB)进程私有空间128KB2GB用户捕捉NULL指针用不可读写(64KB)FFFFFFFFH80000000H7FFFFFFFH7FFF0000H7FFFEFFFH00010000H0000FFFFH00000000H进程需要用到的DLL都会载入自己的私用

38、地址空间那么如何找到DLL中的函数呢?第24页/共49页对WIN32API函数GetMessage的调用USER32.DLL一个程序调用外部DLL中的函数时并不直接调用那个DLL中的函数。相反,CALL指令转到了同一个.text节中的JMP DWORD PTR XXXXXXXX类型的指令。这种JMP指令查找并且将控制权转移到的地址是实际的目标地址。PE文件的.idata节包含了加载器用以确定目标函数的地址并且在可执行映像中修正它们所需的信息。第25页/共49页引入表 import table Data Directory数组第二项的VirtualAddress包含引入表地址。 引入表实际上是一

39、个 IMAGE_IMPORT_DESCRIPTOR 结构数组。 每个结构包含PE文件引入函数的一个相关DLL的信息。 比如,如果该PE文件从10个不同的DLL中引入函数,那么这个数组就有10个成员。该数组以一个全0的成员结尾。第26页/共49页引入表 import tabletypedef struct _IMAGE_IMPORT_DESCRIPTOR union DWORD Characteristics; / 0 for terminating null import descriptor 别名DWORD OriginalFirstThunk; / RVA to original unbo

40、und IAT (指向IMAGE_THUNK_DATA结构数组的RVA);DWORD TimeDateStamp; / 0 if not bound,/ -1 if bound, and real datetime stamp/ in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)/ O.W. date/time stamp of DLL bound to (Old BIND)DWORD ForwarderChain; / -1 if no forwardersDWORD Name; / RVA,指向字符串,是这个可执行文件的名字。指向名字的指针 例

41、如“kernel32.dllDWORD FirstThunk; / RVA to IAT (if bound this IAT has actual addresses)(指向IMAGE_THUNK_DATA结构数组的RVA) IMAGE_IMPORT_DESCRIPTOR;第27页/共49页 OriginalFirstThunk FirstThunk都指向谁?第28页/共49页IMAGE_THUNK_DATA是什么?typedef struct _IMAGE_THUNK_DATA32 union DWORD ForwarderString; / 一个RVA地址,指向forwarder str

42、ing DWORD Function; / PDWORD,被导入的函数的入口地址DWORD Ordinal; / 该函数的序数DWORD AddressOfData; / 一个RVA地址,指向IMAGE_IMPORT_BY_NAME u1; IMAGE_THUNK_DATA32; DWORD联合体数据结构Ordinal和 AddressOfData当这个DWORD数据的最高位为1的时候,代表函数以序号的方式导入,Ordinal的低31位就是输入函数在其DLL内的 导出序号。当这个DWORD的数据最高位为0的时候,代表函数以字符串方式导入。AddressOfData就是一个指向用来导入函数名称的

43、 IMAGE_IMPORT_BY_NAME的数据结构的RVA。第29页/共49页 OriginalFirstThunk FirstThunk都指向谁?都指向谁?第30页/共49页IMAGE_IMPORT_BY_NAMEtypedef struct _IMAGE_IMPORT_BY_NAME WORD Hint;/ 函数输出序号 BYTE Name11;/输出函数名称 IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME序号 函数名 44GetMessage第31页/共49页 OriginalFirstThunk FirstThunk都指向谁?都指向谁?44Ge

44、tMessage第32页/共49页装载器首先读入IMAGE_IMPORT_DESCRIPTOR,获得需要加载的动态库User32.DLL。 第33页/共49页输入函数名称表输入函数名称表 (INT)和输入函数地址表和输入函数地址表(IAT)。这里这两个表所指向的是同一个这里这两个表所指向的是同一个IMAGE_IMPORT_BY_NAME数据结构的数据结构的RVA。 第34页/共49页根据根据IMAGE_IMPORT_BY_NAME的序号或名称到导入的的序号或名称到导入的DLL(user32.dll)函数导出表中函数导出表中获取导入函数的地址。获取导入函数的地址。然后把这个地址替换掉然后把这个地

45、址替换掉FirstThunk所指向的函数输入地址表中的数据。所指向的函数输入地址表中的数据。 0 x77879426第35页/共49页一个程序调用外部DLL中的函数时并不直接调用那个DLL中的函数。相反,CALL指令转到了同一个.text节中的JMP DWORD PTR XXXXXXXX类型的指令。第36页/共49页IMAGE_IMPORT_BY_NAME为什么会有两个并列的指向IMAGE_IMPORT_BY_NAME结构的指针数组呢?第一个数组(由Characteristics域指向的那一个)总是保留原样,系统并不修改。第二个数组(由FirstThunk域指向的那一个)要被PE加载器修改。改

46、成引入函数真实地址 IMAGE_THUNK_DATA结构数组address第37页/共49页IMAGE_IMPORT_BY_NAMEIMAGE_THUNK_DATA结构数组addressPE 文件从 kernel32.dll 中引入 10 个函数,那么 IMAGE_IMPORT_DESCRIPTOR 结构的 Name 域包含指向字符串 “kernel32.dll” 的 RVA ,同时每个 IMAGE_THUNK_DATA 数组有 10 个元素。第38页/共49页IMAGE_IMPORT_BY_NAME加载器首先查找这个数组中每个指针所指向的IMAGE_IMPORT_BY_NAME结构所代表的函

47、数的地址。然后它用找到的这个函数地址来覆盖数组中相应的指向IMAGE_IMPORT_BY_NAME结构的指针。而JMP DWORD PTR XXXXXXXX这条指令中的XXXXXXXX部分就是这个FirstThunk数组中的某个元素的值。由于被加载器覆盖的这个指针数组最终保存的是导入函数的地址,因此它被称为导入地址表(Import Address Table,IAT)。IMAGE_THUNK_DATA结构数组address第39页/共49页PE装载器如何找到DLL提供的函数的地址?第40页/共49页PE文件格式 引出函数节.edata 引出函数节是本文件向其他程序提供的可调用函数列表 这个节一

48、般用在DLL中,EXE文件中也可以有这个节,但通常很少使用 当PE装载器执行一个程序,它将相关DLLs都装入该进程的地址空间。然后根据主程序的引入函数信息,查找相关DLLs中的真实函数地址来修正主程序。PE装载器搜寻的是DLLs中的引出函数。 第41页/共49页 DLL/EXE要引出一个函数给其他DLL/EXE使用,有两种实现方法 通过函数名引出 通过函数名引出或者仅仅通过序数引出。比如某个DLL要引出名为GetSysConfig的函数,如果它以函数名引出,那么其他DLLs/EXEs若要调用这个函数,必须通过函数名-GetSysConfig。 仅仅通过序数引出 什么是序数呢? 序数是唯一指定D

49、LL中某个函数的16位数字,在所指向的DLL里是独一无二的。例如在上例中,DLL可以选择通过序数引出,假设是16,那么其他DLLs/EXEs若要调用这个函数必须以该值作为GetProcAddress调用参数。这就是所谓的仅仅靠序数引出。 引出函数节对病毒来说,非常重要的第42页/共49页PE文件格式 引出函数节的开始,是一个IMAGE_EXPORT_DIRECTORY结构typedef struct _IMAGE_EXPORT_DIRECTORY typedef struct _IMAGE_EXPORT_DIRECTORY DWORD Characteristics; / DWORD Char

50、acteristics; / 一般为0 0 DWORD TimeDateStamp; / DWORD TimeDateStamp; / 文件生成时间 WORD MajorVersion; / WORD MajorVersion; / 主版本号 WORD MinorVersion; / WORD MinorVersion; / 次版本号 DWORD Name; / DWORD Name; / 指向DLLDLL的名字 DWORD Base; / DWORD Base; / 基数,加上序数就是函数地址数组的索引值 DWORD NumberOfFunctions; / AddressOfFunction

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论