邱元陽(yáng)
編者按:新的一年,“高手論技”繼續(xù)伴隨大家前行,身處一線的你,就那些技術(shù)上最常遇到的故障、最需要解決的難題、最成熟的應(yīng)用……都可以在此暢所欲言,各抒己見(jiàn)。是繼續(xù)圍觀還是現(xiàn)身說(shuō)法,新浪微群http://q.t.sina.com.cn/264976,期待您的共同參與。
“可逆”是要考量條件和智慧的,勇往直前時(shí)勇氣是必不可少的,追根溯源卻更需要耐心。生活如此,反編譯亦如此,但如果有好工具相助,必會(huì)輕松清除很多障礙。平日里,將圖片中的文字提取出來(lái)、將“借用”的.swf文件稍作修改……想必很多老師都不可避免會(huì)遇到這種情況。在此,主持人和嘉賓將用兩期來(lái)探討反編譯的技巧,當(dāng)然技術(shù)的探討終歸是要落實(shí)到行動(dòng)上的,反編譯須遵循道德約束,僅為便利我們的學(xué)習(xí)、教學(xué)或工作開展,請(qǐng)勿作他用。
在軟件技術(shù)的學(xué)習(xí)過(guò)程中,逆向工程(Reverse Engineering)似乎是一個(gè)有些敏感的詞語(yǔ)。一方面,通過(guò)逆向工程,我們可以分析和學(xué)習(xí)別人程序的設(shè)計(jì)思想、軟件架構(gòu)等,提高自己的技術(shù)水平;另一方面,也可通過(guò)逆向工程,分析和察看別人程序的核心算法、加密手段等,甚至對(duì)程序進(jìn)行修改和移植。
反編譯是逆向工程的一種,同樣處于亦正亦邪的邊緣。對(duì)學(xué)習(xí)者而言,需要利用反編譯來(lái)學(xué)習(xí)、分析和借用別人的源程序;對(duì)開發(fā)者而言,卻忌諱別人通過(guò)反編譯來(lái)偷窺、修改和剽竊自己的勞動(dòng)成果。
● 霧里看花:亦正亦邪反編譯
由于編譯(Compile)過(guò)程是利用編譯程序從高級(jí)語(yǔ)言編寫的源程序來(lái)產(chǎn)生目標(biāo)程序,因而凡是從編譯后的目標(biāo)程序(可執(zhí)行文件或?qū)S酶袷降奈募﹣?lái)得到源程序的過(guò)程,都被認(rèn)為是反編譯(Decompile)。
從編譯原理上看,編譯程序把一個(gè)源程序翻譯成目標(biāo)程序要經(jīng)過(guò)五個(gè)階段:詞法分析、語(yǔ)法分析、語(yǔ)義檢查和中間代碼生成、代碼優(yōu)化、目標(biāo)代碼生成。而反編譯要逆向進(jìn)行這個(gè)過(guò)程,難度顯然要大很多,即使是編譯程序,一般也沒(méi)有反編譯能力。
然而對(duì)反編譯的需求,卻大有市場(chǎng),不僅僅是開發(fā)者,一些應(yīng)用人員,由于某些特殊需要,也對(duì)反編譯情有獨(dú)鐘。這些特殊的需要中,也包括不便明說(shuō)的原因,道德的與不道德的,合法的與非法的,一起構(gòu)成了反編譯的動(dòng)機(jī)和來(lái)源。
工具與用途的關(guān)系,總是可以進(jìn)行辯證和辯論的。反編譯不僅是工具,也是技術(shù),正也好,邪也罷,蘊(yùn)含在其中的智慧和智力結(jié)晶,仍值得熱愛(ài)技術(shù)的人們?nèi)ャ@研。
借用一句話:“逆向工程可能會(huì)被誤認(rèn)為是對(duì)知識(shí)產(chǎn)權(quán)的嚴(yán)重侵害,但是在實(shí)際應(yīng)用上,反而可能會(huì)保護(hù)知識(shí)產(chǎn)權(quán)所有者。例如,在集成電路領(lǐng)域,如果懷疑某公司侵犯知識(shí)產(chǎn)權(quán),可以用逆向工程技術(shù)來(lái)尋找證據(jù)。”
● 它山之石:程序語(yǔ)言的反編譯
在高級(jí)語(yǔ)言出現(xiàn)之前,程序都是使用匯編語(yǔ)言來(lái)編寫的,為了得到匯編程序的源代碼,出現(xiàn)了反匯編技術(shù)。高級(jí)語(yǔ)言出現(xiàn)后,有了編譯過(guò)程,相應(yīng)的也就有了反編譯技術(shù)。但是不管哪種語(yǔ)言編寫的程序,最終都是翻譯成機(jī)器語(yǔ)言來(lái)執(zhí)行,因而反匯編技術(shù)是可以通用于各種語(yǔ)言所編寫的程序的。反匯編的工具軟件有W32DASM、IDA Pro等。
但是,由于對(duì)機(jī)器語(yǔ)言進(jìn)行反匯編的結(jié)果,可讀性較差,因而人們轉(zhuǎn)而根據(jù)目標(biāo)可執(zhí)行程序的開發(fā)語(yǔ)言針對(duì)性地進(jìn)行反編譯,得到相應(yīng)的高級(jí)語(yǔ)言源代碼。
1.VB程序的反編譯
VBExplorer、VB反編譯精靈和VBRezQ等都能對(duì)VB編寫的程序進(jìn)行反編譯,但是不要對(duì)它們企求太高,大多時(shí)候并不能完全反編譯出原來(lái)的代碼,只能作為輔助性工具來(lái)用,協(xié)助你重建窗體和項(xiàng)目文件,還原部分源代碼。即便是效果較好的VBRezQ,對(duì)于稍微復(fù)雜一些的VB程序,要想反編譯得到完整的源碼也是勉為其難。
2.Dephi程序的反編譯
DeDe被認(rèn)為是非常好用的Delphi反編譯軟件。它可得到所有的目標(biāo)dfm文件,甚至可以創(chuàng)建一個(gè)帶有所有的dfm、pas、dpr文件的Delphi工程的文件夾。
MRipper可以反編譯任何Delphi可執(zhí)行文件,并可從Delphi應(yīng)用程序中提取cursors、icons、dfm文件、pas文件和其他資源。得到的pas文件不包含事件過(guò)程執(zhí)行,還不能算是原味的源程序。
此外,還有DfmExplorer、Revendepro等Delphi的反編譯工具。
3.C++程序的反編譯
在傳統(tǒng)C++語(yǔ)言的開發(fā)環(huán)境中,是直接將其編譯為機(jī)器指令的,因此對(duì)C++的反編譯就很困難,最多是反匯編到匯編代碼。
但是使用微軟為.net平臺(tái)擴(kuò)展的C++/CLI語(yǔ)言,編譯之后的是.net平臺(tái)的IL語(yǔ)言,通過(guò)簡(jiǎn)單的反匯編就可以得到幾乎原樣的源代碼,如在VS2008下開發(fā)的Windows桌面程序,就可以用Reflector反編譯出源代碼。
此外,在.net 1.1時(shí)期,還有一種所謂的托管C++語(yǔ)言,它是在.net的虛擬機(jī)里運(yùn)行的,可以反編譯出托管代碼。
雖然不能直接反編譯得到C++程序的源碼,卻還是有工具可能幫助查看和分析C++程序。PE Explorer就是一款功能強(qiáng)大的可視化Delphi、C++、VB程序解析器,并且是一種集成化環(huán)境,捆綁了UPX的脫殼插件、掃描器和反匯編器,具備反匯編能力和PE文件頭編輯功能,可以更容易地分析源代碼,查看、替換和修復(fù)損壞了的資源。
4.JAVA程序的反編譯
對(duì)Java的反編譯比較常見(jiàn),也比較完全,將.class文件反編譯成.java文件也是有可能的。常用的Java反編譯工具有JAD(Joint Application Development)、Java Decompiler、JDEC、Java204等。
5.其他程序的反編譯
例如,C#程序的反編譯器Reflector,易語(yǔ)言程序的反編譯器E-Code Explorer,C語(yǔ)言程序的反編譯器Exe2C、ExeToC,.net程序的反編譯器.net Reflector等。
為了防止被反編譯,有些軟件的可執(zhí)行文件在編譯完成后會(huì)使用加殼工具進(jìn)行加殼,甚至使用多個(gè)工具進(jìn)行多重加殼。這些程序需要正確脫殼之后才能正常反編譯。
要脫殼就需要先查殼。著名的查殼工具PEiD幾乎可以偵測(cè)出所有的殼,數(shù)量已超過(guò)470種,還可識(shí)別出EXE文件是用什么語(yǔ)言編寫的(如圖1)。
需要說(shuō)明的是,由于反編譯工具的不同,以及對(duì)編譯環(huán)境判斷的失誤,甚至脫殼過(guò)程的錯(cuò)誤,對(duì)高級(jí)語(yǔ)言的反編譯,得到的源代碼可能與原作者的代碼差別極大,可讀性很差,雖然可能它們的執(zhí)行結(jié)果是一樣的。
● 擺脫束縛:電子文檔的反編譯
電子文檔的傳播,極大地方便了數(shù)字閱讀和學(xué)習(xí)。然而美中不足的是,排版美觀的電子文檔,有時(shí)候卻無(wú)法讓我們?cè)倮?。一方面,是文檔所有者對(duì)自己版權(quán)的保護(hù);另一方面,一些電子文檔格式本身的特點(diǎn)也決定了它不能夠進(jìn)行再編輯。
大多數(shù)情況下,電子文檔中的文字等資源是允許被復(fù)制使用的,但有時(shí)也會(huì)設(shè)定為不允許復(fù)制,更不用說(shuō)連內(nèi)容和形式一起重新利用了。然而在很多時(shí)候,我們卻需要還原這些文檔的原有格式,以便重新編輯或者按自己的需要進(jìn)行打印,這時(shí)候,就需要對(duì)這些電子文檔進(jìn)行反編譯。
常用的電子文檔的傳播格式有DOC、PDF、CHM以及一些專用的電子雜志的格式。這些格式的電子文檔(或電子圖書)以PDF格式最為常見(jiàn)。由于PDF是一種大眾化的文件格式,生成PDF格式文件的軟件非常多,無(wú)法確定原始的源文件格式,因而對(duì)PDF文件的反編譯,其實(shí)就是對(duì)它進(jìn)行格式轉(zhuǎn)換,如將它轉(zhuǎn)換成Word的DOC格式。針對(duì)PDF的格式轉(zhuǎn)換軟件很多,效果較好的有AnyBizSoft PDF Converter等。
另外有些文檔被制作成了CHM的幫助文件的格式,這些格式中的文本和圖像等對(duì)象本身是可以復(fù)制的,但由于CHM通常是由HTML文件來(lái)制作生成的,在HTML代碼中可能禁止了復(fù)制功能,所以有時(shí)也需要對(duì)CHM文件進(jìn)行反編譯。這類軟件有ChmDecompiler、CHM電子書反編譯精靈等。HTML Help WorkShop、CHM制作精靈則兼有編譯和反編譯的功能。
其實(shí)Windows中自帶的CHM文件瀏覽工具h(yuǎn)h.exe也具有反編譯CHM文件的功能,需要在命令提示符下帶參數(shù)運(yùn)行。為了方便,可以把反編譯的命令和參數(shù)寫在一個(gè)批處理文件中,利用拖放來(lái)實(shí)現(xiàn)反編譯過(guò)程:
@echo off
set filePath=%1%
for %%i in (%filePath%) do (
set folder=%%~di%%~pi
set fileName=%%~ni
)
set dir=%folder%%fileName%
md %dir%>nul 2>nul
start %windir%\hh.exe -decompile %dir% %filePath%
echo 反編譯完成,文件保存在%dir%下
pause>nul
把上述內(nèi)容保存在一個(gè).bat文件中,把要反編譯的CHM文件拖到這個(gè)bat文件上——見(jiàn)證奇跡的時(shí)刻到了!原來(lái)CHM文件所在位置多出一個(gè)同名的文件夾,里面是已經(jīng)反編譯出來(lái)的HTML文件。這可是系統(tǒng)自帶的免費(fèi)CHM文件反編譯工具哦!
還有一些文檔被編譯成了專用電子雜志的格式,這些格式需要用專門的閱讀器來(lái)打開,有些甚至直接就是EXE可執(zhí)行文件的格式。這些電子雜志格式的文檔,設(shè)計(jì)美觀,操作方便,內(nèi)容豐富,功能強(qiáng)大,其中常常包含有動(dòng)畫、音頻等多媒體內(nèi)容,要對(duì)它們進(jìn)行反編譯難度較大。有一款綜合性電子雜志解包工具pkZine(原名unZineMaker),可用于解析各類流行電子雜志制作軟件生成的EXE文件,從雜志中提取各種原始素材,如文字、SWF動(dòng)畫、JPG圖片等。pkZine目前支持解析ZineMaker、IE Book超級(jí)精靈、Flash、Director、SWFKit、諾杰數(shù)碼精靈、中國(guó)麥客、雅致打包工具等近20種軟件生成的EXE文件(如圖2)。
特別地,有些文檔被制作成了SWF格式的Flash文件,可使用Flash Paper虛擬打印得到的SWF文檔。SWF的反編譯會(huì)在下面講到。
● 心照不宣:Flash的反編譯
對(duì)Flash文件的反編譯也許是我們最熟悉的反編譯工作了。由于眾多的課件作品都是Flash格式的,很多教師需要把這些SWF文件反編譯成FLA文件,再進(jìn)行修改,重新制作成Flash運(yùn)行文件,其目的不言自明。當(dāng)然,F(xiàn)lash反編譯工具的開發(fā)目的,決不僅僅是為了讓人去篡改Flash作品,更多的是為了提取其中的資源,以及學(xué)習(xí)其中的代碼。
最強(qiáng)大的Flash反編譯工具應(yīng)該非Action Script Viewer(簡(jiǎn)稱ASV)莫屬。ASV是一個(gè)商業(yè)SWF反編譯工具,是同類產(chǎn)品中AS代碼反編譯效果最好、FLA工程重建成功率最高的軟件。目前最新版本是ASV2013,支持AS1、AS2、AS3,可以支持Flash1.0~18(Adobe Flash CS6)所有版本的SWF文件,反編譯出的代碼準(zhǔn)確性好,支持反編譯各種加密SWF,支持SWF轉(zhuǎn)FLA,完美重現(xiàn)文件結(jié)構(gòu)和腳本代碼(如圖3)。
教師們?cè)趯W(xué)校經(jīng)常用的Flash反編譯工具應(yīng)該是碩思閃客精靈(Sothink SWF Decompiler)了,其方便而強(qiáng)大的SWF反編譯功能在教師群體中有著極佳的口碑,不僅能解析SWF,提取其中的資源文件,也能將SWF文件還原為FLA文件,方便重新修改。只是重建FLA文件的效果要差些,會(huì)生成非常多的圖層,對(duì)有些高版本的SWF甚至無(wú)法重建正確的FLA文件,AS代碼的反編譯能力也差一些。
實(shí)際上,如果僅僅是修改SWF文件,使用碩思閃客之錘(Sothink SWF Quicker)要更方便一些。閃客之錘是一款功能強(qiáng)大的SWF編輯修改工具,雖然不能反編譯出FLA文件,卻能夠直接修改SWF文件,包括其中的AS代碼都能直接修改,而且成功率很高,對(duì)教師修改Flash課件而言更具實(shí)用性(如圖4)。類似的軟件還有SWiX Free等。
另外,由于有些Flash文件被打包成了EXE文件,有時(shí)需要先把它們還原為SWF文件才能進(jìn)一步進(jìn)行反編譯(閃客精靈等支持直接反編譯EXE文件),這類工具軟件也很多,如exe2swf等。
● 時(shí)尚潮流:安卓應(yīng)用的反編譯
Android(安卓)系統(tǒng)已然成為當(dāng)前最流行的智能終端的操作系統(tǒng),從手機(jī)、多媒體播放器、平板電腦,到網(wǎng)絡(luò)機(jī)頂盒、智能電視,無(wú)處不見(jiàn)Android系統(tǒng)身影,其應(yīng)用程序也非常豐富。
Android應(yīng)用程序的擴(kuò)展名是.apk,這其實(shí)是打包后的文件,我們都知道它們是用Java開發(fā)的。試著把這些.apk應(yīng)用程序的擴(kuò)展名改為.zip或.rar,會(huì)發(fā)現(xiàn)可以直接使用WinRAR之類的壓縮軟件打開(不改擴(kuò)展名也可以打開,只是沒(méi)有關(guān)聯(lián)而已),里面是很多分門別類的文件(如圖5)。因此,Android應(yīng)用程序的反編譯,就是針對(duì).apk文件里面這些文件的反編譯。
解開.apk文件后,可以看到里面有一個(gè)classes.dex和一些.xml文件,以及其他一些文件。在apk文件包中,res這個(gè)目錄下是資源文件,可以直接提取出來(lái);META-INF目錄下是簽名文件,用于確保壓縮包的完整性;AndroidManifest.xml文件是編譯后的配置文件,用于聲明程序中所包含的activity、service以及程序權(quán)限;resources.arsc是編譯后的資源說(shuō)明文件。
.apk中的classes.dex就是主程序文件,它是.java文件編譯后再通過(guò)dx工具打包生成的,用來(lái)在Android的dalvik虛擬機(jī)上運(yùn)行。要得到它打包前的Java源程序,需要用到一些反編譯工具,最常用的是dex2jar和jd-gui這兩個(gè)工具。dex2jar用來(lái)把dex文件轉(zhuǎn)換成jar文件,jd-gui則可以把轉(zhuǎn)換得到的jar文件反編譯成Java源文件。
為了反編譯方便,使用dex2jar時(shí),可以把classes.dex復(fù)制到dex2jar.bat所在的目錄夾,并在命令提示符下轉(zhuǎn)到這個(gè)目錄,輸入命令“dex2jar.bat classes.dex”,即生成classes.dex.dex2jar.jar文件。這個(gè)jar文件即可以用jd-gui直接打開查看,保存所有文件,即生成一個(gè)包含所有源代碼文件壓縮包。
如果要直接反編譯.apk文件,可以使用另一個(gè)工具Apktool,這是谷歌官方提供的命令行apk編譯、反編譯工具。把.apk文件復(fù)制到軟件所在目錄下(方便起見(jiàn),最好都置于C盤根目錄),并在命令提示符下轉(zhuǎn)到這個(gè)目錄,輸入命令“apktool d C:/xxx.apk C:/xxxx”,即可把xxx.apk文件釋放到xxxx這個(gè)路徑下。Apktool還有重編譯的功能,可以重新生成.apk文件,這使它成為很受歡迎的Android反編譯工具。
需要說(shuō)明的是,用WinRAR等壓縮軟件雖然可以查看和解壓縮.apk文件,但是其中的xml是經(jīng)過(guò)優(yōu)化的,不能直接查看,否則只會(huì)看到一堆亂碼。用AXMLPrinter2.jar這個(gè)工具,可以反編譯.xml文件。用baksmali.jar這個(gè)工具,也能反編譯classex.dex文件。但是它們都需要用JDK來(lái)搭建Java運(yùn)行環(huán)境,適合Java開發(fā)人員使用。
編譯和反編譯是互逆的過(guò)程,但二者并非一種對(duì)抗關(guān)系。雖然有時(shí)反編譯會(huì)有悖于著作權(quán)保護(hù),但是只要我們以正常的心態(tài)來(lái)正確使用,不突破道德和法律的底線,仍會(huì)對(duì)自己和他人有益。很多時(shí)候,文檔編譯的目的不再是版權(quán)的保護(hù),而是運(yùn)行的需要和規(guī)范,包括微軟軟件在內(nèi)的很多編譯軟件自帶了反編譯功能,如Windows軟件開發(fā)工具包中的Dumpbin就是一個(gè)例證。