软件体系结构在软件逆向工程中的应用---毕业论文

软件体系结构在软件逆向工程中的应用---毕业论文

ID:15003113

大小:788.50 KB

页数:51页

时间:2018-07-31

上传者:xinshengwencai
软件体系结构在软件逆向工程中的应用---毕业论文_第1页
软件体系结构在软件逆向工程中的应用---毕业论文_第2页
软件体系结构在软件逆向工程中的应用---毕业论文_第3页
软件体系结构在软件逆向工程中的应用---毕业论文_第4页
软件体系结构在软件逆向工程中的应用---毕业论文_第5页
资源描述:

《软件体系结构在软件逆向工程中的应用---毕业论文》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库

本科毕业论文软件体系结构在软件逆向工程中的应用SoftwareArchitectureinSoftwareReverseEngineering姓名:学号:学 院:软件学院系:软件工程专业:软件工程年级:指导教师: 年月 摘要摘 要随着软件产业的进一步发展,网络安全和企业软件技术竞争越来越受到人们关注,逆向工程被引入软件工程。然而,当前行业业务复杂,软件规模也随之扩大,软件代码疾速膨胀,相对应的汇编代码更是无法计算,如何分析一个大规模的软件已经成为许多逆向工作者最头疼的问题。软件逆向工程是一个从产品-代码-设计的过程,如果掌握了软件的体系结构,将软件体系结构应用在软件逆向工程中,在进行逆向分析工作时就有规律可循,从而能够实现在短时间内从海量代码中找出自己所关心的技术细节,这就可以大大的缩短分析时间和任务工作量。面向过程开发与面向对象开发一直是软件产业中应用最为广泛的开发模式。本文就这两种典型的开发模式,结合实际例子,运用软件体系结构知识,分别进行了详细的分析。在基于面向过程开发的软件分析中,选取了备受IT界关注的网络安全领域—病毒技术作为范例,另外一个示例是以事件驱动为架构的基于Win32开发的小型桌面应用程序分析。说到面向对象,以类为核心,就不得不提起最经典的类库。在面向对象开发的软件的逆向分析这部分,集中分析了微软类库MFC框架下的一些规律。从而总结出了几个不同领域,不同框架下的软件的逆向分析的规律,并提出了下一步展望。关键词:软件体系结构;逆向工程;反汇编技术I 摘要AbstractWiththedevelopmentofsoftwareindustry,thecompetitionofnetworksecurityandenterprisesoftwaretechnologyweremoreandmoreconcernedabout,reverseengineeringwasintroducedtothesoftwareindustry.Butthebusinessofcurrentsoftwareindustryisverycomplicated,thecodeisveryhugeandthecorrespondingassemblycodeisnowimpossibletocalculate.Asaresult,howtoanalyzeaverylargescalesoftwareisbecomingamosttroublesomeproblemtothesoftwarereverseengineer.SoftwareReverseEngineeringisaprocessformproducttocodeandthentodesign.Ifyoumasterthesoftwarearchitecture,anduseitinthesoftwarereverseengineering,youwillhaverulestofollowintheanalysis,findouttheconcernstechnologydetailsfromthemassivecodeinashorttime,soitcangreatlyshortentheanalysistimeandtaskworkload.Process-orientedandobject-orienteddevelopmentmodelhavebeenthemostwidelyusedinsoftwareindustry.Thisdissertationfocusesonthetwotypicaldevelopmentmodels,withpracticalexamplesandtheknowledgeofsoftwarearchitecture,carriedoutadetailedanalysisofeachexample.Itakethenetworksecurity-virustechnologyasanexamplefortheprocess-orienteddevelopmentprocesswhichisconcernedmuchbytheITindustry.AnotherexampleisasmalldesktopapplicationwhichisdevelopedbyeventdrivenandbasedonWin32framework.Speakingofobject-oriented,withclassasthecore,wehavetobringtheclassicclasslibrary.Inobject-orientedsoftwaredevelopmentreverse,thisdissertationconcentratesontheMicrosoftMFCframework,andfindoutsomerules.Thusthisdissertationconcludesseveralregularpatternsofreverseanalysisatdifferentdomains,andcomesupwiththeexpectationinthenextstep.Keywords:SoftwareArchitecture;ReverseEngineering;DisassemblyTechnologyI 目录目 录第一章 绪论11.1引言11.2论文组织结构2第二章 软件体系结构风格和软件逆向工程概述32.1软件体系结构风格概述32.1.1数据流风格32.1.2调用/返回风格42.1.3虚拟机风格52.1.4数据仓库风格52.1.5独立组件风格62.2软件逆向工程相关概述72.2.1软件逆向分析的各个阶段72.2.2反汇编技术及其在软件开发中的应用92.2.3IDAPro工具介绍10第三章 软件体系结构在逆向工程中的应用一123.1过程恢复技术123.1.1函数的识别(开始和结束)123.1.2函数的参数123.1.3函数返回值143.2计算机病毒143.2.1病毒的体系结构143.2.2病毒技术提取与总结153.2.3软件体系结构对病毒分析的指导意义203.3事件驱动应用程序203.3.1事件驱动应用程序的体系结构21III 目录3.3.2事件驱动系统实例分析21第四章 软件体系结构在逆向工程中的应用二274.1基于类的软件分析概况274.2基于类的分析294.2.1识别类294.2.2识别对象314.2.3识别类与类之间的关系324.3基于类的软件的实例分析—HttpSniffer36第五章 总结与展望415.1论文总结415.2工作展望41参考文献42致 谢43III ContentsContentsChapter1Introduction11.1Introduction11.2StructureofthisDissertation2Chapter2OverviewofSAStyleandSoftwareReverseEngineering32.1SoftwareArchitectureStylesOverview32.1.1DataFlowStyle32.1.2CallBackStyle42.1.3VirtualMachineStyle52.1.4DataWarehouseStyle52.1.5IndependentComponentStyle62.2Overviewofsoftwarereverseengineering72.2.1StagesofSoftwareReverseAnalysis72.2.2DisassembleandDisassembleTechnologyinSoftwareDevelopment92.2.3IntroductionofIDAPro10Chapter3SoftwareArchitectureinReverseEngineeringPart1123.1ProcessRecoveryTechnology123.1.1IdentifyFunctions123.1.2Parameters123.1.3ReturnValues133.2ComputerVirus143.2.1ArchitectureofVirus143.2.2VirusTechnologyExtractionandSummarization153.2.3TheSignificanceofSAinAnalysisVirus203.3Event-drivenApplication213.3.1ArchitectureofEvent-drivenApplication213.3.2AnExampleofevent-drivensystem21V ContentsChapter4SoftwareArchitectureinReverseEngineeringPart2274.1OverviewofAnalysisonClass-BasedSoftware274.2Class-BasedAnalysis294.2.1IdentifyClasses294.2.2IdentifyObjects314.2.3IdentifytheRelationshipbetweenClasses324.3AnalysisofClass-basedCase—HttpSniffer35Chapter5ConclusionsandFutureWorks415.1ConclusionsofthisDissertation415.2FutureWorks41References42Acknowledgements43V 第一章 绪论第一章 绪论1.1引言逆向工程这一术语最早来源于机械工程领域。随着软件工程技术的发展、软件市场的竞争越来越大、软件遗产系统越来越多,逆向工程被引入软件工程领域。软件逆向工程是指“分析目标系统以便识别系统的部件及其关系,并用另外一种形式或在更高的抽象层次表示系统的过程”。软件逆向工程分为两类:第一类是从已知软件系统的完整代码出发,生成对应系统的结构以及相关设计原理和算法思想的文档。第二类是从没有源代码的程序出发,生成对应的源程序、系统结构以及相关设计原理和算法思想的文档。然而实际上,很多人都不愿意把源码公布出来,真正有意义的软件逆向工作就是指从没有源码的产品中经过逆向生成源程序,得到产品的设计思想[1]。在为解决从需求到实现之间的转换问题,从实际上提高软件质量时,软件体系结构概念产生了。软件体系结构试图在软件需求与软件设计之间架起一座桥梁,着重解决软件系统的结构和需求向实现平坦地过渡的问题。本质上,软件体系结构是对软件需求的一种抽象解决方案。这样,在引入了体系结构之后,软件系统的开发变为“问题定义→软件需求→软件体系结构→软件设计→软件实现”的过程[2]。逆向工程在软件行业中的典型应用是开发有竞争力的软件产品,由于逆向工程是一个非常复杂的过程,所以在软件行业中的应用并不普遍。当前行业业务复杂,软件规模也随之扩大,软件代码疾速膨胀,相对应的汇编代码更是无法计算,如何分析一个大规模的软件已经成为许多软件逆向工作者最头疼的问题。软件逆向工程是一个从产品-代码-设计的过程。好的软件产品,必然是合理的应用了软件体系结构进行设计的,所以掌握了软件的体系结构,将软件体系结构知识应用在软件逆向工程中,在进行逆向分析工作时就有规律可循,从而实现在短时间内从海量代码中找出自己所关心的技术细节。41 第一章 绪论1.2论文组织结构本论文共分为五章。论文首先论述了软件逆向工程在软件工程中重要地位,介绍了软件体系结构在实现需求到设计的转换、提高软件质量问题方面的作用,然后根据二者的关系得出将软件体系结构应用在逆向工程中的意义。在这个基础上提出了论文的背景、目标和研究价值,引出了论文所作的主要工作内容。紧接着论文概述了论文调研中所需要用到的相关技术,并通过基于过程开发的病毒程序和事件响应系统,基于面向对象的软件开发的实际例子进行逆向分析,详细介绍及展示了如何将软件体系结构应用在软件逆向分析中。论文具体安排如下:第一章,论文首先论述了软件逆向工程在软件工程中重要地位,介绍了软件体系结构在实现需求到设计的转换、提高软件质量问题方面的作用,然后根据二者的关系得出将软件体系结构应用在逆向工程中的意义。从而提出了毕业论文的背景、目标和研究价值。  第二章,对软件体系结构风格和软件逆向工程相关知识的介绍。第三章,详细介绍了基于独立组件风格的逆向分析,结合面向过程开发的病毒和事件驱动系统实例进行逆向分析。第四章,详细介绍了基于调用返回风格的逆向分析,结合面向对象开发的软件实例进行逆向分析。第五章,最后论文总结了毕业论文所作的工作,并作了下一步展望。41 第二章 软件体系结构风格和软件逆向工程概述第二章 软件体系结构风格和软件逆向工程概述2.1软件体系结构风格概述软件技术的快速发展使得今天的软件开发越来越工程化,与之相应的工程技术也日趋成熟。软件体系结构作为一门新兴的学科,通过提升软件复用粒度,改进软件工程化的程度。软件体系结构定义了软件或计算系统的结构,它包括软件的构件、构件的外部可见属性以及它们之间的关系。下面对5种常见的体系结构风格进行简单的分析概述[3][4]。2.1.1数据流风格数据流是一种将数据从输入端显式的输送到输出端的体系结构风格。数据流风格的构件是数据的处理单元,连接件是连接处理单元的通道。数据流体系结构风格是由数据驱动的,数据在按照一定顺序排列好的构件上有序的流动。当有数据流经构件时,控制被激活。构件之间不共享任何状态信息,即一个构件不知道上一个构件对数据进行了什么处理。数据流风格包括批处理、管道过滤器、任务处理三种体系结构。管道过滤器包括管道和过滤器两种构件。过滤器用于增量式的处理数据,它们之间不共享,数据在过滤器中以流到流的形式传输。管道用于连接过滤器,它是单方向的。当数据到来时,管道过滤器开始工作,直到数据传输完毕。1.数据流的优点:(1)构件之间不共享状态,降低了构件的复杂性;(2)支持构件复用;(3)支持并发执行;(4)系统易于维护。2.数据流的缺点:(1)不适合交互式系统;(2)需要处理同步问题;(3)解析输入输出的数据,增加了系统的复杂性;41 第二章 软件体系结构风格和软件逆向工程概述(4)处理相关数据流可能会产生同步问题。2.1.2调用/返回风格调用/返回结构是基于模块间的显式调用形成的体系结构风格。这种风格的构件是组成系统的模块、层或者对象,连接件是构件之间的调用关系。调用返回风格的构件对外界隐藏了它的内部信息。这些信息包括:数据的表示、物理设备的属性、事件模型的实现、支持策略的机制。通过隐藏信息,构件之间可以独立的改变内部系统的细节。构件之间通过调用接口进行协同工作,这些接口代表了构件可以为外界提供服务,调用者构件不必关心被调用的构件是如何实现的。调用/返回风格包括主、子调用,抽象数据类型(面向对象)和层次体系结构。主、子调用基于确定的使用关系。它只具有单一的控制线程。子过程的聚集称为模块,模块是一段代码、一个编译单元或者一个工作单元。在主子调用风格中,子过程的正确性依赖于子过程所调用的子过程的正确性。抽象数据类型对外界隐藏了自身的数据,它体现了面向对象的要求。面向对象要求构件要具有封装性、继承性、多态性。随着面向对象的发展,出现了设计模式。通过设计模式我们可以很容易的管理、重用与维护对象。1.调用/返回的优点:(1)允许将一个复杂的问题分解为一系列增量的过程;(2)支持构件的复用;(3)支持信息隐藏、多态、封装、继承、动态绑定等优点;(4)系统功能容易增强。2.调用/返回的缺点:(1)主过程实现的正确性依赖于子过程实现的正确性;(2)在层次结构中会产生效率问题;(3)不易界定层次间的划分;(4)部件接口的修改导致了必须修改所有调用它的接口。41 第二章 软件体系结构风格和软件逆向工程概述2.1.3虚拟机风格   虚拟机是一层软件,其它软件可以在它之上运行,看起来就好像在另一台机器上运行一样。虚拟机的构件包括:用于保存输入数据的部件;虚拟机执行引擎;用于保存当前虚拟机状态的部件;用于保存当前虚拟机执行状态的部件。虚拟机的连接件包括过程调用和直接存储访问。虚拟机是一个软件层,它屏蔽了底层硬件的异构性,可以让不同的软件在它之上运行,就好像在另一台机器上运行一样。它就好像一台计算机,有输入、输出,工作过程也像一台计算机。它将虚拟机的指令映射到机器指令集上。虚拟机风格包括解释器与基于规则的体系结构。解释器用以建立一种虚拟机以弥合程序的语义与作为计算引擎的硬件的间隙。它的构件包括:正在被解释的程序;执行引擎;被解释的程序的状态;执行引擎的当前状态。1.虚拟机的优点:(1)可以实现非本机平台的功能;(2)有助于程序的可移植性和程序设计语言的跨平台能力;(3)能够安全的进行“灾难模式”的模拟;(4)具有很强的适应性。2.虚拟机的缺点:(1)额外的间接层次带来了系统性能的下降;(2)比编译系统的执行速度要慢;(3)额外软件层的正确性需要进行验证。2.1.4数据仓库风格数据仓库是一种以数据为中心的体系结构风格,它用于收集、管理和维护大量的复杂数据。这种风格的构件包括用于表示当前数据状态的中心数据结构和在数据中心存储的数据上进行操作的独立部件的集合。连接件是独立部件对中心数据结构的访问。数据仓库风格最主要的特征就是以数据为中心,包括一个中央的数据结构以及访问这个结构的操作部件。操作部件之间是独立的。41 第二章 软件体系结构风格和软件逆向工程概述数据仓库风格包括数据库体系结构和黑板体系结构。数据库体系结构是由输入事物选择进行何种处理,并把执行结果作为当前状态存储到中央数据结构中。它是固有的可以体现数据仓库风格的一种体系结构。数据库体系结构中的中央数据结构是被动的。1.数据仓库的优点:(1)适合管理大量的信息数据;(2)适合添加独立的操作部件,便于扩展操作;(3)适合于复杂的逻辑系统;(4)黑板系统更容易处理事物间的协作,系统更加灵活。2.数据仓库的缺点:(1)不同的操作对于共享数据结构要达成一致,修改比较困难;(2)需要一定的同步/加锁机制保证数据结构的完整性和一致性,增加了系统的复杂性。2.1.5独立组件风格独立组件风格的构件是处理过程或者是对象,连接件是事件绑定或者消息传递。它包括事件处理体系结构和通讯处理体系结构。事件体系结构主要处理隐式调用,它定义一组事件以及事件处理过程,构件之间通过不同的事件处理过程进行交互。事件也可以与事件进行绑定。通讯处理体系结构由一组过程组成。每个过程拥有自己的地址空间,它可以看成一个虚拟的处理器。消息之间通过消息传递进行交互。消息传递的类型可以是同步的、异步的、点对点的、或者是基于某种协议的点对点调用。1.独立组件的优点:(1)可重用性强;(2)容易实现系统的维护、使用和改进;(3)容易实现事件处理过程的并行运行。2.独立组件的缺点:(1)无控制部件;(2)需要全局的结构管理隐式事件绑定;41 第二章 软件体系结构风格和软件逆向工程概述(3)事件绑定可能无法在其它的运行时机制的环境中运行。2.2软件逆向工程相关概述软件逆向分析是一系列对运行在机器之上的低级代码进行等价的提升和抽象,最终得到更加容易被人所理解的表现形式的过程。简言之,软件逆向分析的目的就在于从目标软件中找出设计思想。软件逆向分析具有很高的实用价值,包括反编译系统的开发、程序的理解和维护、代码变换系统的正确性验证、恶意代码检测等。软件技术是当前最为复杂,但也是最吸引人的技术之一,软件逆向分析就是关于如何打开一个软件的“黑盒子”,并且探个究竟的过程[6]。2.2.1软件逆向分析的各个阶段图2.1显示了常见软件逆向分析的各个阶段,包括文件装载、指令解码、语义映射、相关图构造、过程分析、类型分析、结果输出7个阶段。一般来说,软件逆向分析的过程根据其不同的目的可以选取若干个阶段来完成。由图2.1中可以发现,逆向分析的各个阶段并不是一个严格的直线过程,而是存在着一些并行的模块,并且需要通过循环执行分析过程针对某些特殊问题进行分析和恢复。下面对这7个阶段做简要的介绍。图2.1逆向分析的各个阶段41 第二章 软件体系结构风格和软件逆向工程概述1.文件装载文件装载主要完成读入目标文件,并进行与目标文件相关的一些初步分析,包括文件格式解析、文件信息搜集、文件性质判定等。可执行文件常见格式有PE(PortableExecutable)格式和ELF(ExecutableandLinkableFormat)格式。PE可执行文件格式主要应用在Windows操作系统之上,而ELF格式是Linux操作系统上的主流可执行文件格式。通过文件装载阶段的操作,可以分析出文件执行的入口地址,初步分析文件的数据段和代码段信息,以及文件运行所依赖的其他文件信息等。2.指令解码根据目标体系结构的指令编码规则,对目标文件中使用的指令进行解释、识别和翻译。根据逆向分析的目的和手段,可以将目标指令映射为汇编指令,也可以映射为某种中间表示形式。3.语义映射语义映射就是将二进制指令的执行效果,通过语义描述的方法表示出来,并加以记录。通常有两种方法:直接代码实现和使用语义描述语言进行描述。4.相关图构造常见的图包括控制流图、调用图、依赖图等,在此基础上可以完成控制流分析、数据流分析、依赖分析等操作,从而进一步对程序进行切片等高级操作。5.过程分析经过编译器翻译后的程序大多是面向过程式的,过程分析阶段的主要目标就是将目标文件中的过程信息恢复出来,包括过程边界分析、过程名、参数列表和返回值信息。6.类型分析类型分析阶段的目标在于正确反映原程序中各个存储单元所携带的类型信息。该分析主要有两种方式:基于指令语义的方式和基于过程式分析的方式。基于指令语义的方式根据具体指令的执行方式完成类型定义及转换操作,实现起来比较简单但无法反映程序指令上下文之间的联系。基于过程式分析的方式则是将所有的数据类型进行概括和归纳,并制订相应的类型推导规则,可以充分利用程序上下文的信息,对目标存储单元的类型进行推导。41 第二章 软件体系结构风格和软件逆向工程概述7.结果输出结果输出是逆向分析的最终阶段,该阶段决定了如何将分析结果有效的呈现在操作人员面前。2.2.2反汇编技术及其在软件开发中的应用从对目标文件的执行角度来看,反汇编分为静态反汇编和动态反汇编。前者是指将二进制目标文件根据对应的指令系统转换为相应的可读的汇编语句,但是并不执行这段程序;后者主要是指要跟踪执行目标文件,具体地反映出程序的运行情况。静态反汇编的优点之一是能够一次对整个文件进行处理,而动态反汇编只能处理程序中被执行到的部分;另一个优点是静态反汇编的时间与文件的长度成正比,而动态反汇编的时间与被执行到的指令数成正比。静态反汇编是指在对可执行代码进行反汇编的过程中,不执行相关代码,通过对代码的静态分析得到汇编程序,从而获得程序功能的方法,在本论文的研究中,使用的就是静态反汇编的方法。1.反汇编算法流程:对于静态反汇编,通常采用的算法有两种:线性扫描和递归扫描。(1)线性扫描算法:线性扫描算法从输入程序的第一个可执行字节开始进行反汇编,并简单地向后扫描至整个代码段,反汇编出遇到的每条指令。优点是能够完全覆盖程序的所有代码段,缺点是当代码中含有数据时容易导致反汇编错误。(2)递归扫描算法:递归的反汇编扫描策略是以程序静态控制流程为基础,通过对可执行代码的扫描来获得比较准确的反汇编结果。在这种策略中,每一条改变程序流程的指令是反汇编扫描的关键点,当扫描到这些指令时,以它们跳转或调用的目标地址作为某一个新程序段的起始;而程序返回类指令等表示程序结束的指令是反汇编器扫描的另一个关键点,当扫描到这类指令时表示当前正在扫描的是程序段的结束。通过使用这样的策略,可以有效地跳过嵌入在程序段中的数据以及无效代码。2.反汇编技术在软件开发中的应用:反汇编技术作为软件逆向工程的重要组成部分,在当今软件开发中有着十分广泛的应用:41 第二章 软件体系结构风格和软件逆向工程概述(1)通过使用包括反汇编在内的软件逆向工程对现有软件进行分析,充分利用其有用的模块,可以加快软件开发的进度,并减小出错的可能。(2)通过利用包括反汇编在内的软件逆向工程对原有遗产系统进行分析,根据当前工作的需求对系统进行修改和完善,使其能够适应实际工作的需要并充分利用其中有用资源,是解决遗产系统问题的一个十分有效的途径。(3)通过利用包括反汇编在内的软件逆向工程对一些比较成功的商业软件进行分析,获得软件的设计思想以及设计方法,对于打破软件垄断,特别是对于繁荣发展我国民族软件有着至关重要的意义。(4)反汇编技术可以为计算机的“灾难性事故”中所造成的资料丢失进行恢复工作;分析某些被怀疑的未知的逻辑炸弹;分析计算机病毒或者某些恶意代码;为编译器和优化工具分析工作等提供良好的技术支持。(5)军事方面,反汇编技术可以用于密码机的解剖工作中。利用反汇编技术对密码机中所使用的加密程序进行分析,可以获得密码机所使用的加密算法,为加密军事情报的解密工作提供重要的保证[6][7][8]。2.2.3IDAPro工具介绍IDAPro是DataRescue公司出品的一款交互式反汇编工具,它功能强大,操作复杂,要完全掌握它,需要很多知识。IDA最主要的特点是交互式和多处理器。操作者可以通过对IDA的交互指导IDA更好的反汇编,IDA并不自动的解决程序中的问题,但它会按照用户的指令找到可疑之处,用户的工作是通知IDA怎样去作。比如人工置顶的编译器类型,对变量名,结构定义,数组等定义。这样的交互能力在反汇编大型软件的时候显得尤为重要,多处理器特点是指IDA支持常见处理器平台上的软件产品[7]。IDA打开文件分自动和手工两种模式,默认是自动模式,手工模式可以自由选择需要加载的区段。IDA装载PE文件时候,是按照区块来装载的。IDA反汇编的时间和程序的大小以及复杂程度有关。此过程分为两个阶段,第一阶段是将程序的代码和数据分开,然后为各个函数标志并作参数调用分析跳转,调用等指令关系并给标签赋值等。在第二阶段,如果IDA识别出文件和编译类型,就装载对应的编译器特征文件然后给各个函数赋名。41 第二章 软件体系结构风格和软件逆向工程概述IDA在提供专业的反汇编能力的同时,也提供了很多优秀的辅助功能,如制作流程图和动态调试。IDAPro是目前最好的反汇编器。它改变了人们反汇编的方法,它更像一个智能的反汇编工具。IDA对程序的代码进行反汇编开始,然后分析程序的流程,变量和函数调用,IDA很难使用,并且需要有关程序行为的高级知识,但它的技术层次反应了逆向工程真正的本质特征。IDA提供了操作程序特征的完整API调用,因此用户能定性分析。对于WindowsSDK开发的程序,用IDA配合一般都能逆出源代码,特别是X-RaysDecompiler插件的出现,使得源代码获得更是轻而易举。IDA也不是十分完美,最大的缺陷是其反汇编的速度,由于各种高级功能的引进,IDA在反汇编速度上落后于其他大多数反汇编工具。另一个缺陷来源于界面,由于IDA强大的交互性,导致IDA的界面过于专业,大量的窗口、反汇编术语可能导致初级用户无所适从,但反过来说,这样的用户界面,又再次加强了IDA在专业领域的地位[8]。41 第三章 软件体系结构在逆向工程中的应用一第三章 软件体系结构在逆向工程中的应用一3.1过程恢复技术程序是由不同的函数组成的,因此逆向分析中将重点放在函数的识别以及参数的传递上是明智的,这样可以将注意力集中在某一段代码上。函数是一个程序模块,用来实现一个特定的功能。一个函数有如下几个部分:函数名,入口参数,返回值,函数功能。3.1.1函数的识别(开始和结束)程序中通过调用程序调用函数,而在函数执行完后又返回调用程序继续执行。调用函数的代码保存了一个返回地址,并连同参数一起传递给被调用的函数。有多种方法实现这个功能,在绝大多数情况下,编译器都使用CALL和RET指令来调用函数和返回调用位置。3.1.2函数的参数函数传递参数有三种方式:堆栈方式、寄存器方式以及通过全局变量进行隐含参数的传递。如果参数是通过堆栈传递的,就需要定义参数在堆栈中的顺序,并约定函数被调用后,由谁来平衡堆栈。如果参数是通过寄存器传递的,就要确定参数存放在哪个寄存器中。1.利用堆栈传递参数堆栈是一种“后进先出”的存储区,栈顶指针ESP指向堆栈中第一个可用的数据项。调用函数时,调用者依次把参数压栈,然后调用函数,函数被调用以后,在堆栈中取得数据,并进行计算。函数计算结束以后,或者调用者,或者函数本身修改堆栈,使堆栈恢复平衡。41 第三章 软件体系结构在逆向工程中的应用一在参数传递中,有两个很重要的问题必须得到明确说明:当参数多于一个时,按照什么顺序把参数压入堆栈?函数结束后,由谁来平衡堆栈?这些都必须有个约定,这种在程序设计语言中为了实现函数调用而建立的协议称为调用约定(CallingConvention)。这种协议规定了函数中的参数传送方式、参数是否可变和由谁来处理堆栈等问题。不同的语言定义了不同的调用约定,见表3-1;常用的函数调用约定见表3-2。表3-1 调用方式之间的差异CSysCallStdCallBasicFortranPascal参数入栈顺序右→左右→左右→左左→右左→右左→右恢复栈平衡操作的位置母函数子函数子函数子函数子函数子函数表3-2 函数调用约定调用约定的声明参数入栈顺序恢复栈平衡的位置__cdecl右→左母函数__fastcall右→左子函数__stdcall右→左子函数如果要明确使用某一种调用约定,只需要在函数前加上调用约定的声明即可,否则默认情况下,VC会使用__stdcall的调用方式[9]。2.利用寄存器传递参数寄存器传递参数的方式并没有一个标准,所有与平台相关的方法都是由编译器开发人员制定的。尽管没有统一的标准,但绝大多数编译器提供商都在不对兼容性声明的情况下,遵循相应的规范,即__fastcall规范。__fastcall,顾名思义,特点就是快,因为它是靠寄存器来传递参数的。另一个调用规范thiscall也用到了寄存器传递参数。thiscall是C++中的非静态类成员函数的默认调用约定,对象的每个函数隐含接收this参数。采用thiscall约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,只是另外通过ecx寄存器传送一个额外的参数this指针。41 第三章 软件体系结构在逆向工程中的应用一3.1.3函数返回值函数被调用执行完后将向调用者返回一个或多个执行结果,称为函数返回值。返回值最常见的方法是用return操作符,其它的还有通过参数按传引用方式返回值,通过全局变量返回值等。1.用return操作符返回值一般情况下,函数的返回值放在eax寄存器中返回,如果处理结果超过了eax寄存器容量,其高32位就会放到edx寄存器中。2.通过参数按传引用方式返回值给函数传递参数的方式有两种,即传值和传引用。传值调用时是建立参数的一份拷贝并把它传给调用函数,在调用函数中修改参数值的拷贝不影响原始的变量值。传引用调用允许调用函数修改原始变量的值。在调用某个函数时,当把变量的地址传递给函数时,可以在函数中用间接引用运算符修改调用函数中内存单元中的该变量的值。3.2计算机病毒随着互联网发展,计算机病毒技术也不断迅速发展,病毒数量和类型都在不断增多。计算机病毒的定义也不再像以前那样狭隘,现在的病毒结合各类技术入侵计算机,常见的病毒种类很多,如蠕虫、木马、后门、恶意脚本、RootKit、流氓软件、间谍软件、广告软件、黑客工具等。可以简单的说,凡是带有恶意目的的程序都是计算机病毒[9]。3.2.1病毒的体系结构病毒越来越猖狂,并且正在以几何的速度递增,传统方式的杀毒已经力不从心,急需寻找发现新的技术。想要更有效的方式查杀病毒,就要对病毒本身做深入的剖析,图3.1是一个病毒经过IDA反汇编后,生成的函数调用关系图:               41 第三章 软件体系结构在逆向工程中的应用一图3.1病毒程序函数调用关系图在图3.1中,绿色代表程序执行入口,粉色代表系统API,黑色代表用户自定义函数。可以看出,病毒程序有一个入口,start函数,该函数又在其内部调用了若干个函数,这些函数通过调用一些系统API或者自定义函数来实现自身功能,而这些函数通过消息机制来进行交互,且彼此之间不直接相互控制,从而实现整个病毒所需要的功能。独立组件风格的体系结构由很多独立的通过消息交互的过程或者对象组成,这种软件体系结构通过对各自部分计算的解耦操作来达到易更改的目的。它们之间相互传输数据,但是不直接控制双方。而病毒正是使用了独立组件风格的体系结构,将大的系统分解为很多独立的构件,这些构件通过消息的交互进行相互传输数据,但彼此之间不直接相互控制。这样的设计模式也正符合了病毒自身的特点的要求,病毒自身需要网络传播速度快,这对自身大小会有严格限制(通常小于200KB)。使用独立组件风格能实现事件处理过程的并行性,同时能使系统容易改进和扩展。3.2.2病毒技术提取与总结41 第三章 软件体系结构在逆向工程中的应用一在基于过程开发的病毒的逆向分析过程中,切入点是start函数,并且牢牢把握start函数主线,自顶向下,逐级细致方法进行分析,进而进行技术提取与总结。以下是利用IDA反汇编工具,经过人工分析提取出来的一般病毒技术。1.检测虚拟机病毒程序会检测自身的程序是否运行在虚拟机的环境中,如果检测出是在虚机中的话,病毒可以选择退出进程,从而达到自身保护的目的。其代码如图3.2所示:  图3.2 检测虚拟机2.自启动注册表自启动是在注册表中修改或添加相关的自启动键值,而且这些键值的数据一般都修改为要实现自启动程序的文件名。在〔运行〕对话框中输入“msconfig”命令,单击确定按钮,即可打开〔系统配置实用程序〕对话框。在〔系统配置实用程序〕对话框中显示的启动程序都是通过加载注册表来实现自启动的,所以注册表启动没有太强的隐蔽性,可通过加载一些不常见的注册表键值来实现自启动,以增强病毒的隐蔽性。其代码如图3.3所示:41 第三章 软件体系结构在逆向工程中的应用一图3.3 注册表自启动3.文件生成技术病毒为了实现自身的隐藏封包会将几个文件打包成一个文件,在运行的时候再将其释放。该项技术的实质是在编译时先把多个文件整合成一个文件,运行后释放原来整合的文件到相应的目录中,最后程序才执行自身功能[10]。(1)资源法生成文件:把DLL文件作为资源和EXE一起编译,编译完成后,DLL文件就会以PE资源的形式包含在EXE文件中。在EXE运行之前,先把资源导出为文件,然后再调用DLL文件。其代码如图3.4所示:图3.4资源法生成文件41 第三章 软件体系结构在逆向工程中的应用一(2)附加文件法生成文件:附加文件法是在EXE文件尾部写入DLL文件的数据,当EXE运行时就创建一个DLL文件,读取自身文件尾部的DLL内容,并把这部分数据写入要创建的DLL文件中。其代码如图3.5所示:图3.5附加文件法生成文件4.下载文件黑客在入侵过程中会上传一些文件,有时文件上传会成为入侵成功的关键,而http下载功能则能很好实现文件上传,而且一般防火墙不会拦截http数据包,所以现在很多病毒都有http下载功能。其代码如图3.6所示:图3.6下载文件41 第三章 软件体系结构在逆向工程中的应用一5.提升权限有时候需要对一些进程进行相关的修改操作,但用Administrator帐号对一个系统安全进程执行写操作还是会遇到“访问拒绝”的错误,因为默认的情况下进程的一些访问权限是没有被使能(Enabled)的,所以首先要使能这些权限然后就可以获得任意进程的句柄,并且指定所有的访问权。其代码如图3.7所示:图3.7提升权限6.修改起始页如今的病毒已经不再那么“单纯”,往往背后蕴藏着巨大的商业利益,修改主页,用户每次启动浏览器后,就会打开指定的网页,从中网站可以收取广告费用或者进一步挂马[11]。其代码如图3.8所示:图3.8 修改起始页41 第三章 软件体系结构在逆向工程中的应用一7.发送数据发送数据,几乎是常见病毒所必备的模块,只有利用该功能,才能将窃取的有用数据发送到黑客指定的地址空间,该过程通常会采用TCP协议[12]。其代码如图3.9所示:图3.9 发送数据3.2.3软件体系结构对病毒分析的指导意义出于网络传播速度考虑,病毒对自身大小有严格限制,而正是这样大小的限制,决定了病毒设计的体系结构特点。综上,共两个特点,一是开发的模式属于面向过程开发,二是功能模块化比较清晰。针对这样体系结构的病毒,在分析的时候应该把握这样的原则,以Start即程序入口为主线,将Start函数内调用的其他过程作为新的起始点,进行自顶向下,逐级求精的分析策略,逐步分析各个模块的功能。在分析各个模块时,依据其调用的API和堆栈信息,来确定整个过程的功能和参数调用的情况。3.3事件驱动应用程序41 第三章 软件体系结构在逆向工程中的应用一在事件驱动的应用程序中,代码不是按照预定的路径执行-而是在响应不同的事件时执行不同的代码片段。事件可以由用户操作触发、也可以由来自操作系统或其它应用程序的消息触发、甚至由应用程序本身的消息触发。这些事件的顺序决定了代码执行的顺序,因此应用程序每次运行时所经过的代码的路径都是不同的。事件驱动系统是由多个子系统构成,主要分为管理系统和操作系统。在事件驱动系统中,有一个主系统来对外部事件进行响应并进行任务的调配,有若干个子系统来完成特定的功能,子系统之间需要相互合作来完成最终的目的。任何事件驱动系统的组成都有事件系统和处理机制,并通过此机制与外界进行通信。3.3.1事件驱动应用程序的体系结构Windows应用程序是以消息为基础,以事件为驱动的应用程序。应用程序会不断的等待操作系统发送给自身的消息,然后利用一个while循环,依据不同的消息进行相应的处理[13]。事件系统风格是独立组件风格的一个子风格。其中的每一个独立组件在它们的相关环境中声明它们希望共享的数据,这个环境便是未指定的参与项。事件系统会充分利用消息管理器在消息传递到消息管理器的时候来管理组件之间的交互,和调用组件。组件会注册它们希望提供或者希望收到的信息的类型。3.3.2事件驱动系统实例分析1. 基于Win32框架的事件驱动模型分析利用VisualStudio2005自动生成一个基于Win32框架的模板程序。将这个程序编译保存下来的EXE文件在IDA中进行反汇编分析,根据函数入口WinMain()我们可以很快在汇编代码界面中找到程序的入口。程序的基本框架如图3.10所示:41 第三章 软件体系结构在逆向工程中的应用一图3.10 程序基本框架程序的主入口是WinMain(),而处理消息的场所是窗口函数,操作系统通过该函数来处理各种消息。在窗口函数的内部,存在一个代码段相对比较长的switch语句,该switch语句针对不同的消息进行相应的处理。当windows向程序发送消息时,它会调用窗口函数,窗口函数的参数精确地描述了windows发送的消息。窗口函数代码如图3.11所示:41 第三章 软件体系结构在逆向工程中的应用一图3.11 窗口函数1.实例分析-BootFlashDosBootFlashDos是一个把U盘格式化为DOS启动盘的小工具,它是基于事件驱动开发的应用程序。BootFlashDos的主界面如图3.12所示:41 第三章 软件体系结构在逆向工程中的应用一图3.12 BootFlashDos主界面将BootFlashDos.exe在IDAPro中打开,在IDAPro的视图窗口中,生动的体现出了当前函数由一个块到另一个块的控制流程。该图形视图提供添加注释的功能,经过对整个流程的分析后,把可以识别的块注释起来,就得到了视图如图3.13所示:41 第三章 软件体系结构在逆向工程中的应用一图3.13 图形视图  在图3.12中,可以清晰的得到整个程序的消息控制流程、函数调用情况以及函数何时返回的信息。WM_COMMAND在以下一些条件下都会产生command消息:点击菜单、点击加速键、点击子窗口按钮、点击工具栏按钮等。WM_COMMAND消息中有两个参数:wparam、lparam,它们的定义如下:(1)wParam高两个字节通知码;(2)wParam低两字节命令ID;41 第三章 软件体系结构在逆向工程中的应用一(3)lParam发送命令消息的子窗体句柄。对于菜单和加速键来说,lParam为0,只有控件此项才非0。命令ID也就是资源脚本中定义的菜单项的命令ID或者加速键的命令ID,菜单的通知码为0,加速键的通知码为1。3. 核心功能流程图在独立组件体系结构风格的指导下,首先找到WainMain(),然后在消息循环中,计算控件按钮ID,能迅速定位关键代码段,从而完成了核心功能的流程图绘制。如图3.14就是得到的核心功能流程图:图3.14 核心功能流程图41 第四章 软件体系结构在逆向工程中的应用二第四章软件体系结构在逆向工程中的应用二4.1基于类的软件分析概况面向对象是当前计算机界关心的重点。面向对象的概念和应用最早出现于程序设计和软件开发,现在扩展到很宽的范围。数据库系统、交互界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。在程序设计中,“面向对象”专指采用抽象、封装、继承、多态等设计方法。先来看一副图:图4.1为一款网络嗅探小软件,在IDA中函数的情况如下:程序中充斥着大量的未识别函数(系统库和自定义函数)。41 第四章 软件体系结构在逆向工程中的应用二图4.1IDA中函数窗口在面向过程的软件设计中,函数过程是软件设计的重点。相应的,在基于面向过程的软件逆向工程中,逆向的目标重点放在了对函数过程的把握上。在面向对象的软件设计中,功能的具体实现已经不是软件设计的重点,取而代之的是类的设计。换而言之,面向对象的软件设计的核心是类的设计。在基于面向对象的软件逆向工程中,面对数以万计甚至动则几兆的汇编代码中,逆向的重点,也需要进行适当的调整。过程的具体实现已经不再是重点,对类的把握显得尤为重要。41 第四章 软件体系结构在逆向工程中的应用二4.2基于类的分析深入理解C++面向对象方式开发的软件的反汇编,能从一个二进制可执行文件中识别出C++程序的结构,并且能标识出各个主要的类,以及这些类之间的关系是非常重要的。为了能做到这一点,逆向工程分析人员就必须要:(1)能识别出这些类(2)能识别出这些类之间的关系(3)能识别出类中的各个成员4.2.1识别类要识别出类的成员及类与类之间的关系,首先要把各个类给识别出来,所以先来识别类及其构造函数。可以通过下列特征从一个可执行文件中把类和它的构造函数识别出来:1.大量的使用ECX寄存器(作为this指针)应该首先注意到的是在反汇编代码中会大量出现使用ECX寄存器(来传递this指针)的情况。如图4.2,在给ECX寄存器赋值之后,马上调用了一个函数。图4.2 ECX寄存器使用举例1另外,在函数中可能会经常看到ECX寄存器还没有初始化就直接被使用的情况,如图4.3。这时基本上就可以猜出来:这个函数应该就是某个类的成员函数。41 第四章 软件体系结构在逆向工程中的应用二图4.3 ECX寄存器使用举例22.调用约定这一点与类的识别有关,类的成员函数在被调用时基本上是把函数的参数压入栈中,而使用ECX传递this指针。如下面这个例子,在为类新建了一个对象之后,new返回的指针(该指针指向分配给对象的地址)EAX的值马上被传给了ECX,然后就调用了构造函数[14]。另外,有时还会遇到一些间接函数调用,这很可能是调用类的虚函数,当然,在静态分析的情况下(即不是在调试器中进行动态分析)如果不是事先明确的知道这个虚函数是哪个类的,要深入跟踪这个虚函数还是很困难的。下面是对一个类的实例分析。注意指向虚函数表的指针(vfptr)是被添加在最前面的,而在虚函数表里面,各个虚函数是按照其声明的顺序排列的。41 第四章 软件体系结构在逆向工程中的应用二图4.4 虚函数表派生类将每个基类都嵌入了自身,而且每个基类还都保留有自己的虚函数表。第一个基类的虚函数表是被派生类共享的,派生类的虚函数将会被列在基类虚函数表的后面。4.2.2识别对象识别构造函数和析构函数。为了能从二进制可执行文件中把类识别出来,必须先要理解这些类的实例——对象是怎样被创建的。因为这个创建过程在汇编级别上具体是怎样实现的会给在反汇编时如何识别这些类提供依据(1)全局对象。全局对象顾名思义就是那些被声明为全局变量的对象。这些对象的内存空间是在编译时就被分配好了的,它们位于可执行文件的数据段中。这些对象的构造函数是在这个程序启动之后,main()函数被调用之前被调用执行的,而它们的析构函数则是在程序退出(exit)时被调用的。一般来讲,如果发现一个函数调用时,传入的this指针(一般是使用ecx寄存器)是指向一个全局变量的话,基本可以确定,这是一个全局对象,而要找到这个全局对象的构造函数和析构函数,一般要借助于交叉引用(cross-references)的功能。观察所有使用指向这个全局对象的函数的位置,如果某个函数位于程序的入口点(entrypoint)和main()41 第四章 软件体系结构在逆向工程中的应用二函数之间,那么它就很有可能就是这个对象的构造函数。(2)局部对象。同全局对象,局部对象就是被声明为局部变量的对象。这些对象的作用域起始于该对象被声明的地方,结束于声明该对象的模块退出之时(比如函数结尾或者分支结束的地方,下面例子里就是在一个if语句块结束的地方调用析构函数的)。局部对象在内存中是位于栈(stack)里的。它们的构造函数在该对象声明的地方被调用,而在对象离开其作用域时调用对象的析构函数。局部对象的构造函数还是比较容易识别的,如果发现一个函数调用,传递过去的this指针竟然是指向了栈中一个未被初始化过的变量的话,基本上可以确定这个函数是一个对象的构造函数,同时也就发现了一个对象。析构函数一般则是与构造函数位于同一个模块(也就是声明该对象的模块)的最后一个使用指向该对象的this指针的函数。(3)动态分配的对象。这种对象是指那些通过new操作符动态创建的对象。实际上new操作符会转变成两个函数调用:一个new()函数的调用再紧接着一个构造函数的调用。new()函数是用来在堆中为对象分配空间的(对象的大小通过参数传递给new()函数),然后把新分配的地址放在EAX寄存器中返回出来。然后这个地址就被当作this指针传递给构造函数。同样delete操作符也会转变成两个函数调用,先调用析构函数,然后接着调用free()函数回收空间。4.2.3识别类与类之间的关系RTTI运行时类型信息(Run-TimeTypeInformation)。程序能够使用基类的指针或者引用来检查这些指针和引用所指定的对象的实际派生类型。RTTI提供了以下两个非常有用的操作符:(1)typeid操作符,返回指针和引用所指的实际类型;(2)dynamic_cast操作符,将基类类型的指针或引用安全地转化为派生类型的指针或引用。41 第四章 软件体系结构在逆向工程中的应用二在C++中存在虚函数,也就存在了多态性,对于多态性的对象,在程序编译时可能出现无法确定对象类型的情况。当类中含有虚函数时,其基类的指针就可以指向任何派生类的对象,这时就有可能不知道基类指针到底是指向哪个对象的情况,类型的确定要在运行时利用运行时的类型标识做出。为了获得一个对象的类型功能可以使用typeid,该函数返回对一个type_info类对象的引用[15]。这两个操作符来实现这一机制。这两个操作符在实现时需要获得相关类的类名,类的层次等相关信息。为了实现RTTI,编译器在编译完了的二进制可执行文件中加入一些结构体,这些结构体包含了代码中关于类(特别是多态类)的信息。这些结构体是:1.RTTICompleteObjectLocator这个结构体包含了2个指针,一个指向实际的类信息,另一个指向类的继承关系信息。如下表4-1所示。表4-1结构体RTTICompleteObjectLocatorOffsetTNameDescription0x00DWsignatureAlways00x04DWOffsetOffsetofvftablewithintheclass0x08DWcdoffset-0x0CDWpTypeDescriptorClassInformation0x10DWpClassHierarchyClassHierarchyInformation在内存中虚函数表上面一个DWORD就是指向RTTICompleteObjectLocator结构体的指针。下面是一个RTTICompleteObjectLocator结构的实例分析:图4.5 RTTICompleteObjectLocator结构体2.TypeDescriptor在RTTICompleteObjectLocator结构体中,第四个DWORD域里是一个指向本类的TypeDescriptor结构体的指针。TypeDescriptor这个结构体中记录了这个类的类名。如下表4-2所示。41 第四章 软件体系结构在逆向工程中的应用二表4-2 结构体TypeDescriptorOffsetTypeNameDescription0x00DWpVFTableType_info’svftable0x04DWspare?0x08SZnameClassname下面是TypeDescriptor的一个实例:图4.6 TypeDescriptor结构体3.RTTIClassHierarchyDescriptorRTTIClassHierarchyDescriptor记录了类的继承信息,包括基类的数量,以及一个RTTIBaseClassDescriptor数组,RTTIBaseClassDescriptor下面详细讨论,现在只先说一点,就是RTTIBaseClassDescriptor最终将指向当前各个基类的TypeDescriptor。如表4-3所示:表4-3 结构体RTTIClassHierarchyDescriptorOffsetTypeNameDescription0x00DWsignature00x04DWattributes0x08DWnumBaseClassesNumofbaseclasses0x0CDWpBaseClassArrayArrayofbaseclass下面是RTTIClassHierarchyDescriptor的一个实例:41 第四章 软件体系结构在逆向工程中的应用二图4.7 RTTIClassHierarchyDescriptor结构体从图4.7可以看到它有五个基类,其派生层次为:CObject->CCmdTarget->CWnd->CDialog->CHTTPDlg,这些基类都是RTTIBaseClassDescriptor指针数组。4.RTTIBaseClassDescriptor这个结构体包含了关于基类的有关信息。它包括一个指向基类的TypeDescriptor的指针和一个指向基类的RTTIClassHierarchyDescriptor的指针。RTTIBaseClassDescriptor的结构如下:表4-4 结构体RTTIBaseClassDescriptorOffsetTypeNameDescription0x00DWpTypeDescriptorpTypeDescriptorofthisbaseclass0x04DWnumContainedBasesNumberofdirectbasesofthisbaseclass0x08DWPMD.mdispvftableoffset0x0CDWPMD.pdispvbtableoffset0x10DWPMD.vdispDisplacementofthebaseclassvftablepointerinsidethevbtable0x14DWattributes?0x18DWpClassDescriptorRTTIClassHierarchyDescriptorofthisbaseclass下面是一个RTTIBaseClassDescriptor结构的分析实例:41 第四章 软件体系结构在逆向工程中的应用二图4.8 RTTIBaseClassDescriptor结构体4.3基于类的软件的实例分析—HttpSniffer本实例是基于对话框窗体的分析,在MFC中,创建一个对话框会用到的类是CDialog,CDialog有以下图4.9所示两种构造函数形式:图4.9 CDialog两种构造函数形式本实例中,CDialog使用构造函数的是图4.9中所示的第二种形式,第一个参数是对话框的ID,第二个参数是父类窗口的句柄。在PEExplorer(PEExplorer是一款强大的查看和编辑PE资源的工具)中,查看到该程序的主窗体资源的ID是102,在IDA中定位到该构造函数,在该构造函数所在的函数体中,有一个偏移地址指向虚函数表。图4.10即是对话框主体虚函数表:41 第四章 软件体系结构在逆向工程中的应用二图4.10 对话框主体虚函数表首先确定类名,在虚函数表的上一行,是一个地址,该地址指向一个RTTI_Complete_Object_Locator结构体,这个结构体的第三个成员又是一个地址,该地址指向另一个结构体,RTTI_Type_Descriptor,该结构体的第三个成员即是对类的名字的描述,我们就可以通过这个描述来确定类的名字。调试进程窗口的资源ID是129,根据同样的方法,可以定位到该类的虚函数表,如图4.11所示:41 第四章 软件体系结构在逆向工程中的应用二图4.11调试进程窗口虚函数表在MFC中引用了消息映射的概念。当调用函数处理消息时候,就可以调用消息映射表中对应的消息处理函数。寻找消息映射表,在CCmdTarget::GetTypeLib()下面通常是基于CDialog类派生的对话框子类的成员函数GetMessageMap,双击进入新的函数GetThisMessage(),41 第四章 软件体系结构在逆向工程中的应用二在新的偏移地址中,继续跟入,第一个成员是GetBaseMessage(),第二个成员是一个偏移地址,该地址指向一个以NULL结尾的消息映射表的首地址。此消息映射表由若干个AFX_MSGMAP_ENTRY结构体构成。AFX_MSGMAP_ENTRY的结构如图4.12所示:图4.12 AFX_MSGMAP_ENTRY结构体第一个成员nMessage表示消息的类型,第三个成员nID表示控件的ID,第六个成员pfn指向消息处理函数。在IDA中定义该结构体,并在对应的数据段声明AFX_MSGMAP_ENTRY。图4.13是主对话框对应的消息映射表:图4.13主对话框对应的消息映射表41 第四章 软件体系结构在逆向工程中的应用二图4.14是调试对话框对应的消息映射表:图4.14调试对话框对应的消息映射表本章小结,在面向对象开发的软件工程中,类的设计是整个软件开发的核心,在面向对象的逆向工程中,识别类是整个软件逆向的核心。从主观上,对于所有代码进行重新分析是没有必要的,客观上,也没有如此大的精力去关注在每个细节上。文章先阐述了逆向分析类的理论,之后结合具体实例,详细分析了如何分析一个基于类开发的软件。定位虚函数表是关键。根据RTTI相关结构体确定类名,根据MFC的消息机制,找到消息映射表,确定事件的响应函数。至于这个响应函数是如何实现的,可以参考第三章基于独立组件风格的分析对所关心的响应函数的实现细节进行详细的分析。41 第五章 总结与展望第五章 总结与展望5.1论文总结有时出于行业的需要,有时出于企业产品的竞争,或是对无法找到源码的程序进行维护,我们不得不对二进制进行逆向。然而当前行业业务复杂,软件规模也随之扩大,软件代码疾速膨胀,相对应的汇编代码更是无法计算,如何分析一个大规模的软件已经成为许多逆向工作者最头疼的问题。本文简单的介绍了常见的软件体系结构,重点分析了基于过程和基于对象开发的软件的两种不同模式下,结合具体实例,运用软件体系结构知识,快速高效的进行分析。在基于过程的软件开发过程中,软件设计的重点是函数,实现了每个函数,整个软件也就实现了,在这样的体系结构下,逆向工程的工作重点就是组成软件的每个过程。在基于类的软件开发中,工作重心转移到类的设计上,这样的体系结构下,逆向的工作重点已经不再是功能的具体实现,而是类。识别类的关键,是虚函数表及其对应的消息事件。可见,逆向工程和正向工程是对立统一的关系。正向工程是从设计—代码—产品,而逆向工程是从产品—代码—设计。基于一定的软件体系结构设计的软件是更加健壮更易于维护的,基于软件体系结构而进行的逆向工程是快捷高效的,这主要体现在对模块的把握,对类的把握,对软件架构的把握,是对代码定位的把握,即在海量代码中,迅速而又全面的找到自己所关心的技术细节。5.2工作展望由于时间和个人能力有限,本论文只研究了两种风格的软件体系结构在逆向工程中的应用。下一步研究,可以找出软件体系结构各个不同风格的典型例子,将这些实例在IDAPro中逐个进行逆向分析,找出其关键特征,最后总结出常见的不同软件体系结构风格的软件系统在逆向分析中的规律。随着软件体系结构的深入研究,逆向工程也会逐渐走入系统化、科学化、理论化,二者的联系会越来越紧密。41 第五章 总结与展望参考文献[1][美]EldadEilam,ElliotChikofsky..逆向工程揭秘[M].北京:电子工业出版社,2007.[2]张友生.软件体系结构[M].北京:清华大学出版社,2004.[3]刘志都,仵峰.软件体系结构风格简析[J].福建电脑,2007,第4期:61-62.[4]万建成,卢雷.软件体系结构的原理、组成与应用[M].北京:科学出版社,2002.[5]段钢.加密与解密第三版[M].北京:电子工业出版社,2008.[6]赵荣彩,庞建民,张靖博.反编译技术与软件逆向分析[M].北京:国防工业出版社,2009.[7][美]ChrisEagle.IDAPro权威指南[M].北京:人民邮电出版社,2010.f[8][美]KrisKaspersky.黑客反汇编揭秘[M].北京:电子工业出版社,2004.[9]傅建明,彭国军,张焕国.计算机病毒分析与对抗第二版[M].武汉:武汉大学出版社,2009.[10]刘颖东.揭秘数据解密的关键技术[M].北京:人民邮电出版社,2009.[11]武新华,陈艳艳,王英英.矛与盾黑客攻防与脚本编程[M].北京:机械工业出版社,2010.[12]黑客防线编辑部.黑客防线[M].北京:人民邮电出版社,2009.[13]王艳平.Windows程序设计第二版[M].北京:人民邮电出版社,2008.[14]明日科技.MFC程序开发参考大全[M].北京:人民邮电出版社,2007.[15]张静盛.Windows编程循序渐进[M].北京:机械工业出版社,2009.41 致 谢致 谢岁月匆匆,又是一年凤凰花开的季节,我们就要毕业了!回顾大学生涯,虽然时间很短暂,但是经过4年的学习和磨练,我们都成长了,无论是在专业方面还是为人处事方面,都得到了非常大的提高。在此论文即将完成之际,我衷心地感谢所有曾经帮助过我的人们。首先,感谢我的导师教授。王老师在学术方面敏锐的洞察力和严谨的学术态度使我受益良多。在整个毕设过程中,王老师经常关注我的毕设进度,认真的进行指导和帮助。王老师对我严格的要求和细心的指点使我能顺利克服种种困难并最终顺利完成毕业论文。感谢厦门大学所有老师,你们无私敬业的高尚情操和温文儒雅的学者风范,深深地感染着我们每一位同学;对你们对待学生如父辈如兄长般的关怀,使我们在学校里仍然感受着家一般的温暖。感谢我所有的同学和亲友们,感谢你们在学习和生活上给予我关心和帮助。最后,“谁言寸草心,报得三春晖”,仅以此文作为微薄的礼物奉献给我的父母亲和哥哥,以感谢他们的养育之恩。43

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭