已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Windows下病毒原理研究第一章 概述1.引言随着计算机技术的发展,计算机病毒也越来越多,并且所使用的技术也各不相同。并且由于现在盗版风行,使得病毒的传染范围也越来越广,我敢肯定每一个计算机用户都有过感染病毒的经历。虽然我们都对病毒深恶痛绝,但知道病毒破坏、传染原理的人却并不多。本文就以Windows下最常见的感染PE(Portable Executable)格式文件的病毒为研究对象,来探索病毒的原理,以提高大家对病毒的认识。本文的目的并不是要教会大家如何编写病毒,而是要通过介绍病毒的原理,为大家对反病毒研究提供一个切入点。并且病毒的编写一般都利用了一些比较高级的编程原理,我们也能从中学到很多知识。因此,病毒原理研究也是一个很有很有意义的课题。这也正是我们大学所学知识和综合能力接受考验的时候,我们将尽我们的最大努力,运用所学的基础知识做好这个课题。2.研究方法计算机科学是一门实践性很强的科学,因此,我们就以编写一个“类病毒“程序来检验我们的研究成果,根据程序功能的要求,编程语言可以采用汇编或Vc等高级语言。但因为程序涉及较多的低层操作,使用高级语言会带来很多不便。所以程序采用32位的全386保护模式汇编代码,具有较高的执行效率和十分灵活的使用机制。由于汇编语言的限制,设计界面和较复杂的程序并不是它的强项。所以本程序除了必要的提示和指示以外,没有较为漂亮和友好的界面。但程序的效率较高,速度很快,生成的执行代码量也很小,发挥了汇编语言在低层操作中的优势。程序使用的是Microsoft公司的Masm宏汇编编译器和连结器。生成的是Windows的可执行文件,程序能在Windows 98/2000下使用。3.期望研究成果所生成的程序应该有基本的病毒原理,能够较好的演示病毒的发作效果,当然,我们这里只是研究原理,所以程序应该没有任何破坏性。第二章 PE文件格式一览及预备知识PE 的意思就是 Portable Executable(可移植的执行体)。它是 Win32环境自身所带的执行体文件格式。它的一些特性继承自 Unix的 Coff (common object file format)文件格式。portable executable(可移植的执行体)意味着此文件格式是跨win32平台的 : 即使Windows运行在非Intel的CPU上,任何win32平台的PE装载器都能识别和使用该文件格式。当然,移植到不同的CPU上PE执行体必然得有一些改变。所有 win32执行体 (除了VxD和16位的Dll)都使用PE文件格式,包括NT的内核模式驱动程序(kernel mode drivers)。PE格式将在所有基于Win32的系统中扮演重要的角色。如果你用过Win32或Windows NT和Windows 95,你就已经在使用PE文件了。因而研究PE文件格式给了我们洞悉Windows结构和病毒原理的良机。操作系统的可执行文件的格式从多种意义上讲是操作系统本身执行机制的反映。虽然研究可执行文件格式并非是一个程序员的首要任务,但这种工作能积累大量的知识。而且PE非常普遍,应该引起大家的重视。我们现在应该好好研究就这种新的文件格式及在操作系统中的作用众所周知,Windows NT继承了VAX、VMS及UNIX的某些思想,因为许多Windows NT的创始者在来Microsoft之前都设计并编写过上述平台。但设计Windows NT时,他们借助了以前编写的并经过测试的工具以减少项目设计的启动时间,这是很自然的。他们的这些工具所产生或使用的可执行文件和目标文件格式称为COFF(Common Object File Format)。COFF格式本身是一个很好的起点,但需要予以充分的扩充以适应现代操作系统(Windows NT、Windows 95)的需要。其结果就产生了PE格式。之所以称为“Portable”,是因为Windows NT在各种平台(X86、MIPS、Alpha等等)上都是用同样的执行格式。当然,在CPU指令的二进制译码等方面会存在差异,但最重要的是系统的装载器和编程工具无需对任何一种新出现的CPU进行重写。Microsoft为了将精力集中在Windows NT上,使之最快速的发展起来,放弃了现存的32位工具及文件格式。比如,在Windows NT出现之前,16位Windows的虚拟设备驱动程序使用的是32位的文件格式LE格式。更重要的是OBJ格式的改变:在Windows NT的C编译器之前,所有的Microsoft编译器使用的都是Intel的OMF(Object Module Format)规范。在前面讲过,基于Win32的Microsoft编译器生成的是COFF格式的目标文件。一些Microsoft的竞争者,如Borland及Symantec继续使用Intel的OMF格式,放弃了COFF格式。其结果是OBJs和LIBs必须针对编译器发送不同的版本。以前,PE格式在Winnt.h头文件中由不甚精确的描述,在一节叫“Image Format”的小节中,该节为大家给出了大家熟知的DOS MZ格式和Windows 3.1的NE格式文件头,之后就是PE文件的新内容。Winnt.h提供了PE文件中要使用的原始数据结构,但有关结构和标记含义的注释很有限,要深入理解PE格式,这些还远远不够。Microsoft在98年推出的Visual Studio 6.0中的MSDN(Microsoft Developer Network)Library Visual Studio 6.0光盘为我们提供了Microsoft的大量资料,其中包含了较为详尽的关于PE可执行文件的信息。我们还从互联网上面找到了有关PE文件格式的专门文章。这对我们深入理解PE文件,以至后续章节的关于PE文件的操作及我们的外壳程序的“装配”都提供了比较大的帮助。21 Win32及PE的基本概念PE文件框架结构:CodeView Debug InformationCOFF SymblsCOFF Line Numbers.relocSection(块).idata.edata.data.textSection Table(块表)Image_optional_header(可选部首Data DirectoryIMAGE_FILE_HEADERPE标识“PE00”DOS部首Offset 0DOS_HEADER“MZ”图2-1我们将用“Module”这一术语来表示已装入内存的可执行文件或DLL的代码、数据及资源。除了程序中直接用到的代码和数据以外,一个Module也指Windows中用于判断代码及数据在内存中位置的支撑数据结构。在16位Windows中,支撑数据结构在Module Database中(Hmodule指向这个段)。而在32位Windows中,这些数据结构放在了PE部首中。对于PE文件,首先应该知道,磁盘中的执行文件与其被Windows装载程序装入后的Module看起来非常相似。Windows装载程序把磁盘文件编程实际执行代码的中作相当简单,装载程序使用文件内存映象机制将磁盘文件映射到虚拟地址空间。打个比方,PE文件象一个活动地房子,装载时只需将某个块放在某个地方,在把它和其它部分拧好即可(比如说,把它和DLL连结在一起)。加载PE文件格式的DLL同样的简单。一旦Module被装入,在Windows中就同其它已经装入的文件一样了。这种方式与16位的Windows 3.1明显的不同。16位的NE格式文件装载程序读取部分磁盘文件,并生成一个完全不同的数据结构,在内存中建立Module。当代码或数据需要装入时,装载程序必须从全局内存中分配出一块,查找原始数据在文件的什么地方,找到位置后再读取原始的数据,最后再进行一些修整。还有,每一个16位的Module要负责记住现在使用的所有selector(段选择符),该selector表示该段是否已经被抛弃等等。对于Win32,某Module中的代码、数据、资源、输入表、输出表及其他有用的数据结构等使用的内存都放在一个连续的内存块中,编程人员只要知道装载程序文件映像到内存后的地址即可。通过映像后面的各种指针可以轻易找到Module中所有内容。我们还应该熟悉Win32中的“相对虚拟地址”(Relative Virual Address,RVA)这个名词。PE文件中的许多项都是以RVA方式指定的,RVA就是某个项相对于文件映象地址的偏移。例如:装载程序将一个PE文件装入到虚拟地址空间中,从10000h开始的内存中,如果PE中某个表在映像中的起始地址是10464h,那么该表的RVA就是464h。将RVA装换为可用的指针,只要将RVA的值加上Module的基址即可。基地址是指装入到内存中的EXE或DLL程序的开始地址,它是Win32中的一个重要概念。为了方便起见,Windows NT或Windows 95将Module的基地址作为Module的实例句柄Instance Handle(Hinstance)。在Win32中称基地址为Hintance,似乎有些混淆,因为Instance Handle一词来源于16为的Windows 3.1,其中每一个执行实例都有自己的数据段,依此来互相区分,这就是Instance Handle的来历。在Win32中,以为不存在共享地址空间,所以已用程序无需加以区别。当然,Win16和Win32中的Hinstance还有些联系:在Win32中可以直接调用GetModuleHandle以取得指向DLL的指针,通过指针访问该DLL Module的内容。我们还需要知道PE文件中“section”(块)。在PE文件中section大致相当于NE格式中的段或资源。块中包含代码或数据,与段不同的是,块没有大小限制,是一个连续内存块。有些块中包含程序中声明及直接使用的代码和数据,而另外一些数据块由连接器或库管理程序产生,包含对操作系统极其重要的信息。有人把section称为object,但object具有太多的意义。2.2 PE 部首象其他可执行文件一样,PE文件也由一个部首信息的集合,描述了文件的基本内容。这个部首包含了诸如代码和数据的地址、长度及该文件适合何种操作系统、堆栈初始大小及其它一些重要信息。PE文件部首并不是在文件的最开始部分,最开始第几百个字节是MS-DOS stub(WINSTUB),这个极小的DOS程序显示“This program cannot be run in MS-DOS mode”之类的信息,提示用户应在Win32的环境中运行。PE部首的起始地址隐含在MS-DOS部首中。在Winnt.h头文件中包含了DOS stub的结构定义。E_lfanew字段就是真正PE部首的相对偏移(或RVA),要得到内存中的PE部首指针,只需要用基址加上e-lfanew即可。PNTHeader=dosHeader+dosHeader-e_lfanew;得到了PE部首的文件指针后,我们来看看PE部首的汇编结构定义。;*PE文件头结构定义;*IMAGE_NT_HEADERS STRUC;-PE文件标识PESignature DD ?; 4 ;PE文件标识PE;-PE文件头Machine DW ?; 6NumberOfSections DW ?; 8 ; 块数目TimeDateStamp DD ?; 12; 文件时间PointerToSymbolTable DD ?; 16NumberOfSymbols DD ?; 20;符号表中符号个数SizeOfOptionalHeader DW ?; 22; 可选部首长度 Characteristics DW ?; 24; 信息标志 ;-可选部首Magic DW ? ; 26;标志字(总是010bh)MajorLinkerVersion DB ? ; 27; 连接器版本号MinorLinkerVersion DB ? ; 28SizeOfCode DD ? ; 32; 代码段大小SizeOfInitializedData DD ? ; 36;已初始化数据块大小SizeOfUninitializedData DD ? ;40; 未初始化数据块大小AddressOfEntryPoint DD ? ; 44; 程序起始RVABaseOfCode DD ? ; 48; 代码段起始RVABaseOfData DD ? ; 52; 数据段起始RVAImageBase DD ? ; 56; 装入基址RVASectionAlignment DD ? ; 60; 块对齐FileAlignment DD ? ; 64; 文件块对齐MajorOperatingSystemVersion DW ? ; 66;所需操作系统版本号MinorOperatingSystemVersion DW ? ; 68MajorImageVersion DW ? ; 70;用户自定义版本号MinorImageVersion DW ? ; 72MajorSubsystemVersion DW ? ; 74; 所需子系统版本号MinorSubsystemVersion DW ? ; 76Win32VersionValue DD ? ; 80; 保留SizeOfImage DD ? ; 84; 文件各部分总长 SizeOfHeaders DD ? ; 88; 部首及块表大小 CheckSum DD ? ; 92; 累加和Subsystem DW ? ; 94DllCharacteristics DW ? ; 96SizeOfStackReserve DD ? ; 100SizeOfStackCommit DD ? ; 104SizeOfHeapReserve DD ? ; 108SizeOfHeapCommit DD ? ; 112LoaderFlags DD ? ; 116NumberOfRvaAndSizes DD ? ; 120DataDirectory IMAGE_DATA_DIRECTORY 16 DUP ();目录表IMAGE_NT_HEADERS ENDS标志项由“PE00”的ASCII文本构成。如果根据DOS部首中的e_lfanew找到的是标志“NE”,而不是“PE00”,说明该文件是Windows 3.1的NE格式。同样,如果是“LE”,即是指出该程序是Windows 3.1的设备驱动程序,“LX”标志是OS/2的执行文件。接下来就是PE文件的文件头。为了简明起见,我们只介绍和我们的“装配”程序有关的结构项目。u NumberOfSections DW ?文件中块的数目u SizeOfOptionalHeader DW ?可选部首长度,在OBJs中,该字段为0。在执行文件中,是指IMAGE_OPTIONAL_HEADER结构的长度。u SizeOfCode DD ? 代码段大小 所有Code Section总共的大小(只入不舍)。通常情况下,多数文件只有一个Code Section,所以这个字段和.text section的大小匹配。u SizeOfInitializedData DD ? 已初始化数据块大小估计是指由已初始化的数据构成地块的大小(不包括代码段)。但它似乎与文件中的实际情况不一致u SizeOfUninitializedData DD ? 未初始化数据块大小块的大小,装载程序要在虚拟地址空间中为这些块约定空间。这些块在磁盘文件中不占空间,如同“UninitializedData”这一术语,这些块在程序开始运行时没有指定值。未初始化数据通常是在.bbs块中。u AddressOfEntryPoint DD ? 程序起始RVA程序开始执行的地址。这是一个RVA(相对虚拟地址),通常能在.text中找到。u BaseOfCode DD ? 代码段起始RVA文件的Code Section开始的RVA。在内存中,Code Section通常是在PE部首之后、Date Section之前。在Microsoft连结器生成的执行文件中,RVA通常是1000h;Borland的Tlink32是将Image Base加上第一个Code Section的RVA,并将结果存入该字段。u BaseOfData DD ? 数据段起始RVA文件Date Section开始的RVA。Date Section 通常是在内存的末尾,即PE部首和Code Section之后。u ImageBase DD ? 装入基址RVA当连结器生成一个可执行文件时,假定文件是被直接映像到指定的内存地址中。把这个地址就存放在本字段中,以允许连结器优化装载地址。如果文件真的被装入这个地址,在运行之前就不需作变动了。在Windows NT中,缺省的值是10000h;对于DLLs,缺省值为400000h。在Windows 95中,10000h不能用来装入32位的执行文件,因为该地址处于所有进程共享的线性地址区域,因此Microsoft将Win32可执行文件的缺省基地址改变为400000h。连结时假定为10000h的老程序在Windows 95中装入时,用的时间要长一些,因为程序需要被重定位。u SectionAlignment DD ? 块对齐当装入内存时,每个块的起始虚拟地址都要保证是本字段的倍数。为了分页的目的,这个缺省的块对齐值是1000h(4K字节)。u FileAlignment DD ? 文件块对齐在PE文件中,组成块的原始数据必须保证从本字段的倍数地址开始。缺省值是200h字节,这是为了保证块总是从磁盘的扇区开始(也是200h字节)。这个字段的功能等价与NE格式文件中的段/资源对齐因子。PE文件不象NE格式中的段那样有数以百计的块,所以因为对齐而浪费的空间很小。u SizeOfImage DD ? 文件各部分总长 似乎是装载程序应该保证的装入文件各部分的总长。它是指装入文件从Image Base到最后一个块的大小。最后一个块根据对其大小往上取整。u SizeOfHeaders DD ? 部首及块表大小PE部首及Section Table(块表)的大小。部首之后就是块的原始数据。u DataDirectory IMAGE_DATA_DIRECTORY 16 DUP () 目录表初始化组项目包括起始RVA和执行文件的重要部分的长度。数组末尾的一些项基本上是没有用的。数组的第一项总是Exported Function Table(输出表)的地址及长度(如果有的话)。第二个项是Import Table(输入表)的地址和长度,目录表汇编结构定义:IMAGE_DATA_DIRECTORY STRUC VirtualAddress DD ?;RVA地址 Size DD ?;长度IMAGE_DATA_DIRECTORY ENDS2.3 块表在PE部首与原始数据之间存在一个块表,块表包含每个块在映像中的信息。块在映像中是按起始地址(RVA)来排列的,而不是按字母表顺序。下表给出了IMAGE_SECTION_HEADER的格式。有趣的是,PE格式的块信息中没有我们在NE结构中很熟悉的信息,比如装载属性(PRELOAD)。NE文件允许指定段在模块装入时的预装载属性,这就给程序的人工装载提供可条件。而Windows 95不支持该功能,所以给我们目标文件的完全加密设置了巨大的障碍。另外,PE格式中也没有页表说明。因为它保证一个块的数据是连续的存放在文件中的,这是PE文件的出奇简洁的地方。PE格式文件的一个重大的改变是,任何偏移地址都是直接给出的。在NE格式重,几乎所有的地址都是类似磁盘中扇区值的形式标识的,需要先乘以对齐因子;极个别的情况是以相对于NE部首的偏移值给出的。因为NE部首并不是在文件的最开始,所以需要先找到部首的偏移。总之,PE格式比NE、LE、LX等格式都要简单得多。IMAGE_SECTION_HEADER STRUC Name DB 8 DUP (0); 块名 SVirtualSize DD ?; 该段真实长度 SVirtualAddress DD ?; 该块的RVA SizeOfRawData DD ?; 该块物理长度 PointerToRawData DD ?; 该块物理偏移 PointerToRelocations DD 0; 重定位的偏移 PointerToLinenumbers DD 0; 行号表的偏移 NumberOfRelocations DW 0; 重定位项数目 NumberOfLinenumbers DW 0; 行号表的数目 SFlags DD ?; 块属性 IMAGE_SECTION_HEADER ENDS我们还是只介绍有关外壳程序“装配”的字段。u Name DB 8 DUP (0)块名这是一个8位ANSI名(不是UNICODE内码),用来定义块名。多数块名以一个“.”开始(如.text)。尽管许多PE文档都认为实际上并不是要求的。值得注意的是,如果块名超过8个字节,则没有最后的终止标志“NULL”字节。u SVirtualSize DD ?; 该块真实长度这一字段是该块的真实长度,和SizeOfRawData不一样,是块对齐前的长度。u SVirtualAddress DD ?; 该块的RVA在可执行文件中,这一字段包含装入该块的RVA地址。要计算出一个给定块在内存中的起始地址,应将该块的VirtualAddress加上文件映像的基地址。在Microsoft工具中,第一个块的缺省RVA为1000h。在OBJs中,该字段没有意义,并被设为0。u SizeOfRawData DD ?; 该块物理长度在可执行文件中,给字段包含了经过FileAlignment调整后地块的长度。例如,指定FileAlignment的大小为200h,如果VirtualSize中块的长度为35ah字节,这一块应保存的长度为400h字节。u PointerToRawData DD ?; 该块物理偏移程序经编译或汇编后生成的原始数据,这个字段用于给出原始数据的文件中的偏移。如果程序自装载PE或COFF文件(而不是由操作系统装入),这一字段比VirtualAddress还重要。在这种状态下,必须完全使用线性映像方法装入文件,所以需要在该偏移处找到块的数据,而不是VirtualAddress字段中的RVA地址。u SFlags DD ?; 块属性 该字段是一组指出块属性(如代码/数据/可读/可写等等)的标志。比较重要的标志如下:00000020h该块包含代码,通常与可执行标志(10000000h)一起设置。00000040h该块包含已初始化的数据。00000080h该块包含未初始化的数据。02000000h该块可被丢弃,因为它一旦被装入后,进程就不再需要它了。常见的可丢弃的是.reloc(重定位块)10000000h 该块为共享块20000000h该块可以执行。通常当00000020h标志被设置时,该标志也被设置。40000000h 该块可读。可执行文件中的块总是设置该标志。80000000h该块可写。如果可执行文件没有设置该标志,装载程序就会将内存映像页标记为可读或可执行。在我们的程序中,由于一些关键的块需要加密,所以我们在加密这些块时,要把他们的块属性加上可读可写属性,以便外壳程序解密还原时的读写操作。2.4 各种块的描述由于我们的程序需要对某些关键的块进行处理。所以我们有必要了解各执行文件中经常遇到的各种常见块。2.4.1 .text.text是在编译或汇编结束时产生的一种块。它的内容全是指令代码,PE文件是运行在32位方式下,不受16位段的约束,所以不必要将不同文件产生的代码在分成分离的块。连结器把所有目标文件的.text块连结成一个大的.text块。如果使用的是Borland C+,其编译器将产生的代码存于名为CODE的区域中,其连接器连结的结果使代码块的名称不是.text而是CODE。2.4.2 .data如同.text是默认的代码块一样,.data是初始化的数据块。这些数据包括编译时被初始化的globle和static变量,也包括字符串。连接器将OBJs及LIBs文件的.data结合成一个大的.data。local变量以放在一个线性的堆栈中,不占.data和.bbs的空间。和.text一样,数据块是以明文的形式存放在文件中的2.4.3 .idata.idata包含其他外来DLL的函数及数据信息。该块功能于NE文件的模块引用表类似,关键的差异在于PE文件中的每一个输入函数都明确的列于该块中,要在NE格式中找到相同的信息,必须从各个段的重定位数据中查找。2.4.4 .rsrc.rsrc包含模块的全部资源。如图标、菜单、位图等等。该资源结构复杂,不便直接加密和装入。2.4.5 .reloc.reloc保存基地址重定位表。当装载程序不能按连结器所指定的地址装载文件时,需要对指令或已初始化的变量进行调整,基地址重定位表包含了调整所需的数据。如果转载程序能够正常装载文件,它就忽略.reloc中的重定位数据。2.4.6 .edata.edata是该PE文件输出函数和数据的列表,以供其他模块引用。它与NE文件中的入口表、驻留名表及非驻留名表综合功能相似。PE格式文件没有必要输出一个函数,所以通常只是在DLL文件中才可以见到.edata块。有些PE可执行文件有.edata块,因为可能它需要输出函数。2.4.7 .tlsTLS的意思是“thread local storage”(线程局部存储器),它与Win32的TlsAlloc系列功能有关。它的装入机制和使用方法都不太清楚。2.4.8 .rdata.rdata块通常是在.data或.bss中间,但程序中很少用到该块中的数据。至少有两种情况下要用到.rdata。一是在Microsoft的连结器产生的EXE文件中,用于存放调试目录。二是就是用于存放说明字符串。如果程序的DEF文件中指定了DESCRIPTION,则字符串就会出现在.rdata中。2.4.9 其他常见块其他常见块包括了:.debug$s、.debug$t、.drective、.crt、.bss等等。他们在程序中很少用到。2.5 PE文件的IMPORT在调用外部DLL时,CALL指令实际上是被转化成EXE文件.text块中的Jmp dword ptr xxxxxxxx指令(如果使用的是Borland C+,则在.icode块中)。Jmp指令要跳转到的地方才是真正的目的地址。装载程序判定目标函数的地址并将该函数插补到执行文件的映像中,所需要的信息都是放在PE文件的.idata中,也就是Import块。.idata块以一个IMAGE_IMPORT_DESCRIPTOR数组开始。每一个被PE文件隐式连结进来的DLL都有一个IMAGE_IMPORT_DESCRIPTOR。在这个数组中,没有字段指出该结构数组的项数,但它的最后一个单元是NULL,可以由此计数算出该数组的项数。IMAGE_IMPORT_DESCRIPTOR的格式如下:u Dword Characteristics该字段是一个指针数组的RVA偏移。其中每一个指针都指向一个IMAGE_IMPORT_BY_NAME结构u Dword TimeDateStamp时间及日期标志,可以忽略。u Dword ForwarderChain正向链结索引。我们的资料中没有函数正向链结的格式,也没有这一样的例子。u Dword Name以NULL结尾的ASCII字符的RVA地址,该字符串包含输入的DLL名,比如“Kernel32.dll”或“USER32.DLL”。u PIMAGE_THUNK_DATA FirstThunk该字段是在Image_thunk_data联合结构中的RVA偏移。大多数情况下,Image_thunk_data是指IMAGE_IMPORT_BY_NAME结构的指针。如果不是一个指针的话,那它就是该功能在DLL中的序号。IMAGE_IMPORT_DESCRIPTOR重要的部分有输入的DLL名字及两个IMAGE_IMPORT_BY_NAME指针数组。在执行文件中,这两个指针数组彼此平行,末尾都是以Null表示数组的结束。下图给出了这种关系的图形描述。Import Address TableHintName Array44GetMessageIMAGE_IMPORT_DESCRIPTOR72LoadIconTranslateMessage19Characteristics(hint name)“User32.dll”95TimeDateStamp该部分由PE装入器填写IsWIndowsForwarderChainImport DLL NameFirstThunk图4-2为什么由两个并行的指针数组指向IMAGE_IMPORT_BY_NAME结构呢?第一个Characteristics是单独的一项,而且不可改写,它有时被称为提示名表(Hint Name Table)。第二个数组(FirstThunk所指)是由PE装入器重写的。装载程序迭代搜索数组中的每一个指针,找到每一个IMAGE_IMPORT_BY_NAME结构所指的输入函数的地址,然后装载器找到程序的地址改写IMAGE_IMPORT_BY_NAME指针。Jmp dword ptr xxxxxxxx中的xxxxxxxx是指First Thunk数组中的一个入口。因为它被称为输入地址表(Import Address Table)。2.6 PE格式小结讲到这里,凡是涉及我们的装配程序的结构就已经讲解完毕了。象Export(输出函数)、资源块、Base Relocations(重定位)等等都没作介绍,如果有兴趣可以查阅有关资料。可以看出,PE文件比起传统的DOS的MZ格式的可执行文件要复杂得多,功能和性能得到了巨大的扩充和增强,这都是由新型操作系统的机制所决定的。但它又在功能增强的基础上,比Windows 3.1的NE格式文件简单了许多,这充分说明了PE文件格式既功能强大又具有较为简洁的结构和优异的装入效率及性能。PE文件必将成为未来Microsoft公司系列操作系统下的主流执行文件格式。在下一章节中我们将切入我们的程序,运用我们在上几章介绍的知识具体的解决问题。第三章 代码编写代码主要流程:首先,打开一个文件,判断是否有效PE文件,我们可以通过两步来验证,首先判断MAGE_DOS_HEADER.- e_magic,如是”MZ”,则可以通过IMAGE_DOS_HEADER.- e_lfanew得到PE Header的偏移量,然后将指针移到此偏移所指位置,然后取得PE Heade的第一个双字节,该双字与IMAGE_NT_SIGNATURE比对,符合则认为PE header有效。得到有效的PE文件后,就可以通过IMAGE_FILE_HEADER STRUCT-SizeOfOptionalHeader来得到optional header的指针,optional header 结构里最重要的就是AddressOfEntryPoint,他标识了整个程序的第一个指令的RAV,因为我们要改变整个程序的执行顺序,所以就必须把这个值指定到新的RAV,先执行我们自己的程序段,执行完后通过一个无条件转移,跳转到原来程序的入口地址,这样我们就实现了在原程序执行之前运行我们自己的程序。 核心代码:;包含文件.386 .model flat,stdcall option casemap:none ;includeinclude masm32includewindows.inc include masm32includekernel32.inc include masm32includecomdlg32.inc include masm32includeuser32.inc includelib masm32libuser32.lib includelib masm32libkernel32.lib includelib masm32libcomdlg32.lib;错误处理结构SEH struct PrevLink dd ? CurrentHandler dd ? SafeOffset dd ? PrevEsp dd ? PrevEbp dd ? SEH ends;打开文件mov of
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 纸箱设计与生产规范手册
- 医疗健康产业风险管理手册
- 2025中国检验认证集团云南有限公司财务中心招聘2人笔试历年常考点试题专练附带答案详解
- 金融创新与风险管理手册
- 学生行为规范与心理健康手册
- 网站运营与优化手册
- 2026年宁德市蕉城区临海工业园区开发有限公司招聘项目工程部经理1人备考题库有答案详解
- 2026国家纳米科学中心刘晶课题组招聘1人备考题库附答案详解
- 2026中国农业大学后勤保障处东区物业服务部合同聘用制人员招聘1人备考题库附答案详解
- 2026贵州贵阳农垦品牌运营管理有限公司诚聘健康顾问24人备考题库含答案详解(能力提升)
- 网络综合布线进线间子系统概述
- 耳穴压豆完整版本
- 2024贵州贵阳中考物理试题及答案 2024年中考物理试卷
- 特发性肺纤维化急性加重AEIPF诊治指南
- DB11-T 1938-2021 引调水隧洞监测技术导则
- WB/T 1045-2012驶入式货架
- GB/T 4295-2019碳化钨粉
- 文化管理学自考复习资料自考
- 三年级下册《对鲜花》音乐教案冯雨婷
- 使用拐杖操作流程及评分标准
- 基金会财务报表审计指引
评论
0/150
提交评论