正是由於反編譯這麼簡單,若是不加保護,咱們的勞動成果就會被輕易盜取。php
市面上比較經常使用的反編譯工具備:dex2jar,jd-gui,apktool,IDA等等。html
這裏我簡單的說一下dex2jar這個經常使用反編譯工具的使用。java
在下載到了dex2jar和jd-gui這兩個工具以後。android
1.將要反編譯的APK後綴名改成.rar或 .zip,並解壓安全
-------------------------------------------------------------app
2.獲得其中的classes.dex文件(它就是java文件編譯再經過dx工具打包而成的),將獲取到的classes.dex放到以前解壓出來的工具dex2jar-0.0.9.15 文件夾內ide
-------------------------------------------------------------函數
3.在命令行下定位到dex2jar.bat所在目錄,輸入dex2jar.bat classes.dex。工具
效果以下:學習
在該目錄下會生成一個classes_dex2jar.jar的文件,而後打開工具jd-gui文件夾裏的jd-gui.exe,以後用該工具打開以前生成的classes_dex2jar.jar文件,即可以看到源碼了,效果以下:
被混淆過的效果圖(類文件名稱以及裏面的方法名稱都會以a,b,c....之類的樣式命名):
沒有通過處理或者只是簡單的混淆過的APP其代碼的反編譯的比較容易的。你的代碼通過上面那三步已經暴露出來了。
在下面提供的更多的途徑來給各位學習反編譯。
更多反編譯的教程:
-------------------------------------------------------------
[size=21.3333339691162px]
apktool反編譯工具使用教程:
http://www.apkbus.com/forum.php?mod=viewthread&tid=60541&highlight=反編譯
-------------------------------------------------------------
反編譯與防止反編譯:
http://www.apkbus.com/forum.php?mod=viewthread&tid=183482&highlight=%E5%8F%8D%E7%BC%96%E8%AF%91
-------------------------------------------------------------
黑馬Android視頻教程——119_應用程序的反編譯:
http://www.apkbus.com/forum.php?mod=viewthread&tid=130649&highlight=%E5%8F%8D%E7%BC%96%E8%AF%91
怎樣防止應用被破解?
在知道了這麼容易就能夠破解我苦心經營的APP時,個人心是崩潰的。這個時候我要聽專家的,我還認真的記錄了下來,看看專家怎麼說。
從上圖咱們能夠看到,如今的防止反編譯的手段已經發展到了資本主義了。
下面一一列舉了各類對抗反編譯的手段,但願對你們有所幫助。
(一)基礎手段--混淆代碼
代碼混淆技術基本原理是使反編譯工具反編譯出來的代碼人難以閱讀,從而達到防止被逆向破解的目的。簡單的理解就是把原來的類名、方法名、字段名、參數名、變量名等,用無心義的字符序列來替換。變成相似abc這樣的無命名規則的字符,增長閱讀難度。
步驟:
-------------------------------------------------------------
1.找到或者建立一個proguard-project.txt文件
-------------------------------------------------------------
2.在proguard-project.txt添加混淆的申明
a) 申明外包jar包(申明的外面jar不會被混淆)
例如:-libraryjars libs/abc.jar
b) 將你不須要混淆的部分申明進來(由於有些類通過混淆會致使程序編譯不經過)
如系統組件和API的類:
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.**
c) -dontwarn 缺省proguard 會檢查每個引用是否正確,可是第三方庫裏面每每有些不會用到的類,沒有正確引用。若是不配置的話,系統就會報錯。
例如:-dontwarn android.support.**
d) -keepclassmembers 指定的類成員被保留。
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
e) -keepclasseswithmembers 指定的類和類成員被保留,假如指定的類成員存在的話。
例如:
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-------------------------------------------------------------
3.以上工做完成,混淆工做就完成了一大半了,最後須要作的就是在project.properties文件中加上你的混淆文件申明瞭,以下:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-------------------------------------------------------------
4.最後一步,打簽名包測試
(二)簽名自校驗
簡單的理解,簽名就是標明一個APP是否是官方正版發行的標記。發現一個APP跟你的同樣卻沒法覆蓋安裝,就是簽名不一致的緣故。也能夠理解爲你的APP已經被破解並從新打包了。
那麼如何獲取到APK文件的公鑰信息呢?由於Android系統安裝程序確定會獲取APK信息進行比對,因此咱們能夠經過Android源碼得到一些思路和幫助。
源碼中有一個隱藏的類用於APK包的解析。這個類叫PackageParser,路徑爲frameworks\base\core\java\android\content\pm\PackageParser.java。當咱們須要獲取APK包的相關信息時,能夠直接使用這個類,下面代碼就是一個例子函數:
代碼:
private PackageInfo parsePackage(String archiveFilePath, int flags){ PackageParser packageParser = new PackageParser(archiveFilePath); DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); final File sourceFile = new File(archiveFilePath); PackageParser.Package pkg = packageParser.parsePackage( sourceFile, archiveFilePath, metrics, 0); if (pkg == null) { return null; } packageParser.collectCertificates(pkg, 0); return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0); }
其中參數archiveFilePath指定APK文件路徑;flags需設置PackageManager.GET_SIGNATURES位,以保證返回證書籤名信息。
具體如何經過PackageParser獲取簽名信息在此處不作詳述,具體代碼請參考PackageParser中的public boolean collectCertificates(Package pkg, int flags)和private Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer)方法。至於如何在Android應用開發中使用隱藏的類及方法,能夠參看個人這篇文章: 《Android應用開發中如何使用隱藏API》 。
緊接着,咱們就能夠經過packageInfo.signatures來訪問到APK的簽名信息。還須要說明的是 Android中Signature和Java中Certificate的對應關係。它們的關係以下面代碼所示:
代碼:
pkg.mSignatures = new Signature[certs.length]; for (int i=0; i<N; i++) { pkg.mSignatures = new Signature( certs.getEncoded()); }
也就是說signature = new Signature(certificate.getEncoded()); certificate證書中包含了公鑰和證書的其餘基本信息。公鑰不一樣,證書確定互不相同。咱們能夠經過certificate的getPublicKey方法獲取公鑰信息。因此比對簽名證書本質上就是比對公鑰信息。
OK,獲取到APK簽名證書以後,就剩下比對了。這個簡單,功能函數以下所示:
代碼:
private boolean IsSignaturesSame(Signature[] s1, Signature[] s2) { if (s1 == null) { return false; } if (s2 == null) { return false; } HashSet<Signature> set1 = new HashSet<Signature>(); for (Signature sig : s1) { set1.add(sig); } HashSet<Signature> set2 = new HashSet<Signature>(); for (Signature sig : s2) { set2.add(sig); } // Make sure s2 contains all signatures in s1. if (set1.equals(set2)) { return true; } return false; }
在程序運行時,自我進行簽名比對。比對樣本能夠存放在APK包內,也可存放於雲端。缺點是程序被破解時,自檢測功能一樣可能遭到破壞,使其失效。
(三)源程序使用C層編寫
將核心代碼使用C/C++編寫而後編譯成爲.so文件,這種方式的代碼保護性是比Java代碼提高了很多。使用工具反編譯以後的是彙編語言,不過對於熟悉彙編語言的高手來講破解也是極可能的。
對於如何編譯成so文件你們能夠參考下面的文檔:
http://www.apkbus.com/forum.php?mod=viewthread&tid=240211&highlight=NDK%E7%BC%96%E8%AF%91
在瞭解了比較經常使用的技術以後咱們來看看專家推薦的比較高新的對抗技術有哪些
(四)DEX文件隱藏(加殼技術)
加殼技術原理:
所謂apk的加殼技術和pc exe的加殼原理同樣,就是在程序的外面再包裹上另一段代碼,保護裏面的代碼不被非法修改或反編譯,在程序運行的時候優先取得程序的控制權作一些咱們本身想作的工做。
加殼做用:
加殼的程序能夠有效阻止對程序的反彙編分析,以達到它不可告人的目的。這種技術也經常使用來保護軟件版權,防止被軟件破解。
你們能夠參考下面的文章:
http://www.apkbus.com/forum.php?mod=viewthread&tid=240207&extra=
http://www.apkbus.com/forum.php?mod=viewthread&tid=240662&highlight=so
(五)利用反編譯工具漏洞
1、對抗JD-GUI原理
一般在對apk進行反編譯的時候用到的最多的兩個工具就是apk-tool和dex2jar。利用這兩個工具將apk首先反編譯成classes.dex而後再將classes.dex反編譯成jar文件或者將apk直接反編譯成jar文件;獲得jar文件之後就能夠利用JD-GUI將獲得的jar文件打開就能夠直接查看apk的java源碼了。咱們花了那麼大心思寫的程序就這麼容易被別人拿到源碼是否是很不甘心,如今我就告訴你對抗JD-GUI查看源碼的方法。咱們在用JD-GUI查看源碼時有時有些函數的根本看不到直接提示error錯誤,咱們就利用這點來保護咱們的apk。原來JD-GUI在將通過混淆處理的jar裏面的class字節碼文件轉成java文件時,遇到函數中根本走不到的分支的特殊實現時就會提示函數error。這時咱們只要查看這些提示error的文件或者函數對應的源碼是有什麼語句引發的,將這些語句加到咱們的源碼中就能夠防止利用JD-GUI去查看咱們的apk源碼了。
2、原理實現
(1)假如咱們的apk onCreate的函數實現以下:
<font style=
"color:rgb(51, 51, 51)"
><font face=
"微軟雅黑"
><font style=
"font-size:16px"
>[url=home.php?mod=space&uid=
389554
]
@Override
[/url]
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); }</font></font></font>
(2)將咱們的apk通過混淆處理後通過簽名導出咱們的apk,咱們用dex2jar工具將咱們的apk轉換成jar文件
(3)用JD-GUI打開咱們的jar文件就能夠看到咱們的apk onCreate函數的源碼了。以下:
(4)這時咱們在apk onCreate函數裏面加上不可能的特殊分支語句,代碼以下:
<font style="color:rgb(51, 51, 51)"><font face="微軟雅黑"><font style="font-size:16px">@Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); switch ( ) { case : JSONObject jsoObj; String date= null ; String second= null ; try { jsoObj= new JSONObject(); date=jsoObj.getString( "date" ); second=jsoObj.getString( "second" ); } catch (JSONException e) { e.printStackTrace(); } test.settime(date,second); break ; }
class
test
{
public
static
void
settime(String a,String b){}
}
(5)咱們用(2)中一樣的方法將apk轉成jar文件,而後用JD-GUI打開會看到提示error錯誤。以下:
根據上面的講述相信你們對對抗JD-GUI的方法有了必定的瞭解,我只是舉了其中的一個方法,之因此說是特殊的分支語句是由於不是全部的分支語句均可以讓JD-GUI提示error。
(六)運行時修改Dalvik指令
咱們知道apk生成後全部的java生成的class文件都被dx命令整合成了一個classes.dex文件,當apk運行時dalvik虛擬機加載classes.dex文件而且用dexopt命令進行進一步的優化成odex文件。咱們的方法就是在這個過程當中修改dalvik指令來達到咱們的目的。
你們能夠參考下面的文章:
http://www.apkbus.com/forum.php?mod=viewthread&tid=240208&extra=
快捷的APK反逆向解決方案
在瞭解上面這麼多的反逆向方法以後,咱們要保護本身的APP要付出的時間和技術成本看起來仍是很高的,這時候若是有一些產品或者工具能夠幫咱們完成這些工做。那麼這方面的成本就低不少了,而目前市面上的確有很多這樣的服務。
360加固寶
http://jiagu.360.cn/protect/welcome/
阿里聚安全
愛加密
網址百度收
梆梆加固
百度雲加固
騰訊雲加固