劉彥宇,唐運樂
(北海藝術設計職業學院 現代教育技術中心,廣西 北海 536000)
現有的軟件逆向工程分析方法主要有4種:詞法分析和語法分析;程序切片;動態分析;圖形化方法[1]。在對現有源代碼進行分析的過程中,首先想到的便是圖形化建模方法,使用Rational Rose、Visio、Rigio、StarUML等,進行逆向建模,即通過對源代碼的自動分析,提取出代碼各個層次上各類元素的相關信息,分析它們間的相互關系并生成多種類型的模型描述文檔[1-4]。但由于程序開發本身的復雜性,以及這些分析工具關注重點所限,分析結果往往和預期相差很遠,像Visio逆向生成的類模型文檔,只包含了類的描述信息,缺少更多的類結構信息。這就需要開發人員在使用輔助工具的基礎上,更多的人為參與代碼分析。
為了幫助開發者快速地閱讀理解程序源代碼,本文針對Java語言,以基于實體關系的C++元模型[5]為基礎,擴展了一種支持Java源代碼逆向建模的關系模型,按照關系模型設計代碼數據庫。
目前,現有逆向建模方法大致為,通過抽取源代碼信息,存入設計的表或數據庫中,再通過一些輔助工具或數據庫應用程序對抽取的信息進行模型描述[2-3,6-7]。這種方法在將抽取信息存入數據庫時所要設計的接口程序相對復雜。而基于實體關系的C++元模型可以很好的完成結構化分析及細粒度搜索,同時它還可以平衡粒度尺寸及分析局限。本文在原有模型的基礎上進行關系模型設計,擴展了兩方面內容。第一,針對業界大量使用的Java語言,擴展了特定語言的元模型。采用Java1.5的特性,通過這些特性可以有效控制元模型的復雜度,同時與Java語言中的文法概念相匹配后,便可以很容易的對抽取信息進行分類處理,簡化接口程序。第二,擴展實體類型和關系類型,支持細粒度分析。
整個逆向建模過程如圖1所示,分三個步驟:第一,抽取源代碼信息,采用Eclipse AST對源代碼進行解析;第二,存儲到代碼數據庫;第三,生成模型描述文檔、進行代碼信息檢索。
將代碼中的信息抽象為實體、關系,并且將它們與源程序使用的程序設計語言的文法概念相匹配,之后,便很容易對各種信息進行分類處理。
實體可以與源代碼中的顯式聲明一致,例如Class、Interface、Method等,也可以與Array、Primitive這類Java類型一致。解析過程中如果實體類型無法描述,可以使用UNKNOWN代替。表1列出了全部實體類型,這些類型遵循Java語言規范(JLS)中定義的標準含義。

圖1 Java源代碼逆向建模過程

表1 實體類型
關系代表兩實體之間的依賴特性,因此所有關系都是從源實體到目標實體的二元關系。程序在檢查過程中發現源實體,源實體相對較小并且包含有關系的觸發代碼。目標實體則不同,它可以是關系涉及的本地實體,也可以是涉及到的Java標準庫或者其他外部的JAR。表2列出了完整的關系類型。

表2 關系類型
擴展后的關系模型如圖2所示,由工程(Project)、文件(File)、實體(Entity)、關系(Relation)、注釋(Comment)五個部分組成。

圖2 擴展后的關系模型
首先,為每個逆向建模的工程,建立一個Project模型元素。由于每個工程中含有Java源文件、JAR文件、類文件,因此建立File模型元素來代表三種類型文件。源文件及類文件通過它們內部的多個Entity模型元素聯系起來,而且在這些源實體及目標實體之間形成Relation模型元素。另一方面,將Java工程打包生成的JAR文件,則包含全部Entity模型元素和Relation模型元素。對擴展后的關系模型元素的詳細描述如下。


將抽取的源代碼信息存儲到代碼數據庫后,就可以通過數據庫查詢語句得到程序相關信息。同時,通過開發相應的數據庫應用程序,將源代碼信息轉換為更高層次的抽象視圖,以適當的形式生成模型描述文檔。
另一方面,由于關系數據庫無法對存儲在庫中字段內容進行檢索和分析,因此并未在數據庫中存儲詳細代碼數據,而是采用代碼數據庫+Lucene[7-8]的模式,設計信息檢索部分。從代碼數據庫中讀取數據來建立Lucene索引,將Lucene定義的索引文檔(document)與數據庫中的一個實體記錄匹配。Lucene中,文檔又是一些域(field)的序列,而域又是一些項(term)的序列,這里項就是最基本的檢索單元,是從一個實體的各部分中提取出來的字串。將代碼數據庫與Lucene結合既實現了全文檢索,又可以利用數據庫做復雜分析,實現模型描述文檔的建立。
擴展后的關系模型支持源代碼的細粒度分析,生成的各層次元素復雜,適合局部源代碼建模,基于此開發的逆向建模工具與同類工具相比,具有一定特色。
實驗過程中,采用這種方法對開源項目面向對象數據庫db4o(for Java,version 8.0)的源代碼進行了局部的模型描述,分別對db4o內核的File Header(數據字典加載)、FreeSpace(空閑空間分配)、Internal Ids(分配對象OID)、Get(根據 OID 獲取對象數據)、Set(對象存儲)[9]等5個方面進行類模型描述。由于缺乏對比逆向建模細粒度分析優劣的基準測試及數據集,這里使用模型描述中獲得的實體數量作為評測參數。圖3顯示了基于擴展關系模型開發的逆向建模工具與Rational Rose、StarUML兩款工具在模型描述中獲得實體數量的對比。
結果顯示,由于分析粒度的不同,加之本文擴展了實體及關系類型(不再只是類、字段、方法等顯式實體),在對db4o五個類模型描述中,基于文中方法的工具在細粒度分析上要明顯優于其他兩款工具。
另一方面,通過代碼數據庫+Lucene的模式,可以提高源代碼分析的速度,同時為簡單時序分析提供可能性。圖4,5是代碼數據庫+Lucene,結合人為分析得到的db4o對象存儲的序列圖。

圖3 模型中獲得的實體數量對比

在對實際項目進行源代碼分析的過程中,可以采用粗粒度與細粒度分析相結合的方式,利用粗粒度分析項目整體概況,利用細粒度分析局部信息。但由于程序開發本身的復雜性及眾多的設計模式,要更有效的表現設計思想及設計邏輯,減少人為參與代碼分析,還需要更具體的分析與匹配。
[1]Francoise Balmas,Kostas Kontogiannis.Introduction to the special issue on software analysis,evolution and reengineering[J].Science of Computer Programming,2006,60(2):117 -120.
[2]彭四偉,朱群雄.基于源代碼分析的逆向建模[J].計算機應用研究,2006,23(7):52-54.
[3]Alexandru Telea,Heorhiy Byelas,Lucian Voinea.A Framework for Reverse Engineering Large C++Code Bases[J].Electronic Notes in Theoretical Computer Science,2009,233(3):143 -159.
[4]H Byelas,A Telea.Visualization of areas of interest in software architecture diagrams[A].SoftVis’06 Proceedings of the 2006 ACM symposium on Software visualization[C].New York:ACM Press,2006:20 -28.
[5]Yih - Farn Chen,Emden R Gansner,Eleftherios Koutsofios.A C++Data Model Supporting Reachability Analysis and Dead Code Detection[J].IEEE Transactions on Software Engineering,1998,24(9):682 -694.
[6]馬戀.基于關系數據庫的程序逆向分析架構研究[D].長沙:長沙理工大學,2007.
[7]Erik Linstead,Sushil Bajracharya,Trung Ngo.Sourcerer:mining and searching internet- scale software repositories[J].Data Mining and Knowledge Discovery,2009,18(2):300 -336.
[8]佚名.Lucene web site[CP/DK].http://lucene.apache.org,2012.
[9]佚名.Db4o web site[CP/DK].http://www.db 4o.com,2012.