1. 程式人生 > >Android實用技能:你應該掌握的APK反編譯技巧以及重新打包釋出

Android實用技能:你應該掌握的APK反編譯技巧以及重新打包釋出

需要的工具

1,apktool: 反編譯獲取資原始檔的工具,包括圖片資源和佈局檔案等的獲取
下載地址:https://bitbucket.org/iBotPeaches/apktool/downloads
2,dex2jar:反編譯獲取原始碼的工具,將classes.dex 轉化為jar檔案
下載地址:https://sourceforge.net/projects/dex2jar/files/
3,jd-gui:jar檔案原始碼檢視工具
下載地址:http://jd.benow.ca/

這裡提供一個我自己的下載地址:同時包含上面三個工具的壓縮包

為了方便進行反編譯,我們將上述下載好的3個工具統一放到一個資料夾中,並將相應的zip解壓縮,如下:
在這裡插入圖片描述

使用apktool反編譯apk得到圖片、XML配置、語言資源等檔案

1,進入CMD命令列,切換到上述的3個工具的所在目錄,如:E:\AndroidDevelopTool\Android反編譯工具包:
在這裡插入圖片描述
使用如下的命令執行apktool_2.0.1.jar反編譯MMTS-release-1.0.2.apk

java -jar apktool_2.0.1.jar d -f E:\AndroidDevelopTool\Android反編譯工具包\測試apk\MMTS-release-1.0.2.apk -o MMTS

上面命令的含義為:啟動apktool_2.0.1.jar將位於【E:\AndroidDevelopTool\Android反編譯工具包\測試apk\】目錄下的"MMTS-release-1.0.2.apk"這個apk反編譯,然後將反編譯生成的檔案存放到當前目錄(apktool_2.0.1.jar所在的目錄,也就是"E:\AndroidDevelopTool\Android反編譯工具包"目錄)下的一個【MMTS】資料夾中,這個資料夾MMTS的名字可以自定義。
如下圖:
在這裡插入圖片描述


反編譯成功後,會在當前目錄(E:\AndroidDevelopTool\Android反編譯工具包)下生成一個MMTS資料夾,開啟MMTS裡面就有反編譯後生成的檔案,如下圖所示:
在這裡插入圖片描述
開啟MMTS資料夾,就可以看到反編譯後的生成的檔案,如下圖所示:
在這裡插入圖片描述

使用dex2jar反編譯apk得到Java原始碼

1,將要反編譯的APK字尾名改為.rar或者 .zip,並解壓,得到其中的classes.dex檔案。
2,將獲取到的classes.dex放到之前解壓出來的工具【dex2jar-2.0】資料夾內,如下圖所示:
在這裡插入圖片描述
3,在命令列下定位到dex2jar.bat所在目錄,輸入"d2j-dex2jar classes.dex",效果如下:
在這裡插入圖片描述


4,命令執行完成之後,在當前目錄下就可以看到生成的Jar檔案了,如下圖所示:
在這裡插入圖片描述
5,啟動原始碼檢視工具【jd-gui】:
在這裡插入圖片描述
6,將生成的classes-dex2jar.jar檔案直接拖進jd-gui就可以看到原始碼了,如下圖所示:
在這裡插入圖片描述
注意:JD-GUI雖然可以將class反編譯成java原始碼,但是對於一些被混淆過的class,反編譯的效果就不是那麼理想了,被混淆過的class反編譯後的效果圖(類檔名稱以及裡面的方法名稱都會以a,b,c…之類的樣式命名):
在這裡插入圖片描述

重新打包

對於反編譯出來的資料夾我們是可以進行重新打包釋出的,但是這種破解別人應用的做法是很不道德的,漢化的方式其實就是將一個APK進行反編譯,然後翻譯其中的資源再重新打包,那麼如何重新打包呢?
這裡我們自己新建一個應用,然後簽名打包,命名為Demo.apk,執行效果如下:
在這裡插入圖片描述
可以看到這個應用很簡單,就是在主介面上有一個按鈕,然後點選該按鈕彈出一個Toast提示:“you clicked button”。
接下來我們就演示下如何對這個apk進行反編譯後重新打包。

1,首先我們使用apktool工具反編譯apk,獲取到如下的目錄:
在這裡插入圖片描述
其中,original資料夾下存放的是未經反編譯過、原始的AndroidManifest.xml檔案,res資料夾下存放的是反編譯出來的所有資源,smali資料夾下存放的是反編譯出來的所有程式碼,AndroidManifest.xml則是經過反編譯還原後的manifest檔案。這裡值得一提的是smali資料夾,如果你進入到這個資料夾中你會發現它的目錄結構和我們原始碼中src的目錄結構是幾乎一樣的,主要的區別就是所有的java檔案都變成了smali檔案。smali檔案其實也是真正的原始碼,只不過它的語法和java完全不同,它有點類似於彙編的語法,是Android虛擬機器所使用的暫存器語言,語法結構大概如下所示:
在這裡插入圖片描述
看上去有點暈頭轉向是嗎?但是如果你一旦能夠看得懂smali檔案的話,那麼你就可以做很恐怖的事情了——你可以隨意修改應用程式內的邏輯,將其進行破解!
不過我對這種黑技術並沒有什麼太大的興趣,因此我也沒有去做具體研究,但即使是這樣,也已經可以對程式的邏輯做一定程度的修改了。比如說當我們點選按鈕時會彈出you clicked button這樣一句Toast,邏輯是寫在MainActivity按鈕點選事件的匿名類當中的,因此這段程式碼反編譯之後一定就會在MainActivity$1.smali這個檔案當中,讓我們開啟瞧一瞧,部分程式碼如下所示:
在這裡插入圖片描述
雖說多數的程式碼我是看不懂的,但其中第47行實在太明顯了,Toast顯示的內容不就是在這裡定義的麼,那麼如果我們想把Demo程式hack掉,就可以將這段字串給改掉,比如說我把它改成Your app is been hacked。
關於smali的語法,網上的資料也非常多,如果你對這門技術十分感興趣的話可以直接上網去搜,這裡我只是簡單介紹一下,就不再深入講解相關知識了。
改了一處程式碼後我們再來改一處資源吧,比如這裡想要把Demo的應用圖示給換掉,那麼首先我們要準備好一張新的圖片,如下圖所示:
在這裡插入圖片描述
然後從AndroidManifest.xml檔案中可以看出,應用圖示使用的是ic_launcher.png這張圖片,那麼我們將上面籃球這張圖片命名成ic_launcher.png,然後拷貝到所有以res/mipmap開頭的資料夾當中完成替換操作。
在做了兩處改動之後,我們現在來把反編譯後的Demo資料夾重新打包成APK吧,其實非常簡單,只需要在cmd中執行如下命令:

apktool b Demo -o New_Demo.apk

這裡的Demo資料夾對應上面的MMTS資料夾。

其中b是build的意思,表示我們要將Demo資料夾打包成APK檔案,-o用於指定新生成的APK檔名,這裡新的檔案叫作New_Demo.apk。執行結果如下圖所示:
在這裡插入圖片描述
現在你會發現在同級目錄下面生成了一個新的APK檔案:
在這裡插入圖片描述
不過不要高興得太早了,目前這個New_Demo.apk還是不能安裝的,因為它還沒有進行簽名。那麼如果這是別人的程式的話,我們從哪兒能拿到它原來的簽名檔案呢?很顯然,這是根本沒有辦法拿到的,因此我們只能拿自己的簽名檔案來對這個APK檔案重新進行簽名,但同時也表明我們重新打包出來的軟體就是個十足的盜版軟體。這裡大家學學技術就好了,希望不要有任何人去做什麼壞事情。
那麼這裡我就用一個之前生成好的簽名檔案了,使用Android Studio或者Eclipse都可以非常簡單地生成一個簽名檔案。
有了簽名檔案之後在cmd中執行簽名命令就可以進行簽名了,命令格式如下:

手動簽名:(JDK8版本下進行手動簽名的完整命令)
jarsigner  -keystore yiyou.jks(簽名檔案) -storepass tingxue666(金鑰)  -signedjar 22.apk(已簽名apk) 11.apk(未簽名apk) yiyou(別名) 
-digestalg SHA1 -sigalg MD5withRSA -tsa http://timestamp.digicert.com

其中jarsigner命令檔案是存放在jdk的bin目錄下的,需要將bin目錄配置在系統的環境變數當中才可以在任何位置執行此命令。
簽名之後的APK檔案現在已經可以安裝到手機上了,不過在此之前Android還極度建議我們對簽名後的APK檔案進行一次對齊操作,因為這樣可以使得我們的程式在Android系統中執行得更快。對齊操作使用的是zipalign工具,該工具存放於/build-tools/目錄下,將這個目錄配置到系統環境變數當中就可以在任何位置執行此命令了。命令格式如下:

// zipalign -v 4 22.apk(需優化的apk) 33.apk(優化後生成的apk)
zipalign -v 4 New_Demo.apk New_Demo_aligned.apk

執行這段命令之後就會生成一個New_Demo_aligned.apk檔案,如下所示:
在這裡插入圖片描述
這個New_Demo_aligned.apk就是我們重新打包簽名對齊後的檔案了,現在把它安裝到手機上,效果如下圖所示:
在這裡插入圖片描述
可以看到,應用圖示已經成功改成了籃球,另外點選按鈕後彈出的Toast的提示也變成了我們修改後的文字,說明重新打包操作確實已經成功了。