正是由于反编译这么简单,若是不加保护,咱们的劳动成果就会被轻易盗取。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/
阿里聚安全
爱加密
网址百度收
梆梆加固
百度云加固
腾讯云加固