我们知道,利用 apktool 可以将 apk 反编译为 smali 文件,利用 dex2jar 也可以将 apk 反编译为 jar 文件。这样的话,破解者就可以根据关键代码(比如资源文件中的字符串),修改代码,然后再利用 apktool 重新编译,并运行 signapk.bat 重新签名打包为己所用,而你辛辛苦苦几个月的努力一下回到解放前!

最近看过《Android 软件安全与逆向分析》之后,又有了不少收获。

那么,怎样防止破解呢?其实之前介绍的利用 proguard 进行代码混淆就是一种方式,它可以有效增加利用 dex2jar 反编译后破解的难度。另外,也可以通过检测调试器、模拟器、签名的 hash 值和 classes.dex 文件的 crc 值来确定确认 apk 文件的完整性。

检测调试器

我们发布时将 AndroidManifest.xml 文件中 application 标签的 android:debuggable 属性设为 false ,程序运行时再去检测:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  1. public void checkDebug(){
  2. if((getApplicationInfo().flags&=ApplicationInfo.FLAG_DEBUGGABLE)!=0){
  3. android.os.Process.killProcess(android.os.Process.myPid());
  4. }
  5. }

此外,Android SDK 还提供了一个专门检测 debugger 是否连接的方法:

  1. 1
  1. android.os.Debug.isDebuggerConnected();

这样就不用在 AndroidManifest.xml 里配置字段了。

检测模拟器

通过 dab shell getprop 可以发现模拟器客真机这几个属性不一致:

  • ro.product.model : 模拟器中为 sdk ,真机中为具体型号;

  • ro.build.tags : 模拟器中为 test-keys ,真机中为 release-keys ;

  • ro.kernel.qemu : 模拟器中为 1 ,真机中不存在;

下面以第三个字段为例做检测:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  1. public boolean isRunningInEmulator(){
  2. boolean qemuKernel=false;
  3. Process process=null;
  4. DataOutpusStream os=null;
  5. try{
  6. process=Runtime.getRuntime().exec("get prop ro.kernel.qemu");
  7. os=new DataOutputStream(process.getOutputStream());
  8. BufferedReader in=new BufferedReader(
  9. new InputStreamReader(process.getInputStream(), "GBK"));
  10. os.writeBytes("exit\n");
  11. os.flush();
  12. process.waitFor();
  13. qemuKernel=(Integer.valueOf(in.readLine())==1);
  14. }catch(Exception e){
  15. e.printStackTrace();
  16. }finally{
  17. try{
  18. if(os!=null){
  19. os.close();
  20. }
  21. }catch(Exception e){
  22. e.printStackTrace();
  23. }
  24. }
  25. return qemuKernel;
  26. }

检查签名的 hash 值

Android 的 PackageManager 类提供了读取签名信息方法:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  1. public int getSignature(Context context, String packageName){
  2. PackageManager pm=context.getPackageManager();
  3. PackageInfo pi=null;
  4. int sig=0;
  5. try{
  6. pi=pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
  7. Signature[] s=pi.signatures;
  8. sig=s[0].hashCode();
  9. }catch(Exception e){
  10. sig=0;
  11. e.printStackTrace();
  12. }
  13. return sig;
  14. }

打包发布前我们将这个 hash 值保存在 server 端,程序运行时再去比对。

检查 classes.dex 文件 CRC 值

apk 文件本质上是 zip 压缩文件,而 Android SDK 自带了读取 zip 压缩包 CRC 值的 API :

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  1. public long getDexCrc(Context context){
  2. long crc=0;
  3. ZipFile zf;
  4. try{
  5. zf=new ZipFile(context.getApplicationContext().getPackageCodePath());
  6. ZipEntry ze=zf.getEntry("classes.dex");
  7. crc=ze.getCrc();
  8. }catch(Exception e){
  9. e.printStackTrace();
  10. }
  11. return crc;
  12. }

打包发布前我们也可以将这个 crc 值保存在 server 端,程序运行时再去比对。

将以上几种方式结合起来,就可以大大增强 apk 文件的破解难度。

最后,网上有些大神说还可以通过对 apktool 和 dex2jar 等反编译工具进行压力测试,以得到错误信息,而这些工具是开源的,这样我们就可以顺藤摸瓜地找到这些工具本身的漏洞,进而在我们的代码中加以利用,达到釜底抽薪的作用。例如对 dex2jar 运行这个批处理:

  1. 1
  1. for %%i in (*.apk) do dex2jar %%i

这种思路理论上是行得通的,但我没有亲测过,这里就不再多说了。

Android 程序的反破解技术的更多相关文章

  1. Android程序的反破解技术

    Android 程序的破解一般步骤如下:反编译.静态分析.动态调试.重编译.我们可以从这几个步骤着手反破解 反编译 我们可以查找反编译器的漏洞,从而使反编译器无法正确解析APK文件 静态分析 对jav ...

  2. android apk 防止反编译技术第四篇-对抗JD-GUI

    又到周末一个人侘在家里无事可干,这就是程序员的悲哀啊.好了我们利用周末的时间继续介绍android apk防止反编译技术的另一种方法.前三篇我们讲了加壳技术(http://my.oschina.net ...

  3. 转: android apk 防止反编译技术(1~5连载)

    转: android apk 防止反编译技术 做android framework方面的工作将近三年的时间了,现在公司让做一下android apk安全方面的研究,于是最近就在网上找大量的资料来学习. ...

  4. android apk 防止反编译技术第一篇-加壳技术

    做android framework方面的工作将近三年的时间了,现在公司让做一下android apk安全方面的研究,于是最近就在网上找大量的资料来学习.现在将最近学习成果做一下整理总结.学习的这些成 ...

  5. android apk 防止反编译技术第二篇-运行时修改字节码

    上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...

  6. android apk 防止反编译技术第三篇-加密

    上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...

  7. android apk 防止反编译技术第二篇-运行时修改Dalvik指令

    上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...

  8. Android程序的反编译对抗研究

    转自: http://www.freebuf.com/tools/76884.html 一.前言 对抗反编译是指让apk文件或者dex文件无法正常通过反编译工具,而且有可能导致工具异常或者崩溃,如ap ...

  9. Android程序apk反编译破解方法

    简短不割了,我们直接奔主题吧. 把apktool-install-windows-r05-ibot文件里的两个文件剪切到apktool1.5.1目录. 新建一个文件夹把需要破解的apk应用程序放进去. ...

随机推荐

  1. mysql 排序后获得某行的位置

    假设有test表,下图为表机构和数据,score表示积分.现在要查询积分排名为第几的id?? 查询语句 select id,score,(@rowno:=@rowno+1) as rowno from ...

  2. MySQL 索引 总结

    1.索引的种类(六种) 普通索引,唯一索引,全文索引,单列索引,多列索引,空间索引 2.优缺点及注意事项 优点:有了索引,对于记录数量很多的表,可以提高查询速度. 缺点:索引是占用空间的,索引会影响u ...

  3. Codeforces Round #371 (Div. 2) C 大模拟

    http://codeforces.com/contest/714/problem/C 题目大意:有t个询问,每个询问有三种操作 ①加入一个数值为a[i]的数字 ②消除一个数值为a[i]的数字 ③给一 ...

  4. 熟练使用NTFS的文件链接技术

    硬链接和软链接介绍: 硬连接指向的是i节点(iNode),而软连接指向的是路径(Path) ,又称符号链接.硬链接可理解为对i节点的引用,最初的文件名与所有的硬链接地位是对等的,比如为文件a建立了硬链 ...

  5. CREATE SCHEMA

    CREATE SCHEMA 创建一个架构,即命名空间,在这个空间中可以进一步定义包含表.视图和权限定义等对象. 语法 CREATE SCHEMA AUTHORIZATION owner    [ &l ...

  6. 收缩sql server数据库日志

    项目中,可能数据库(sql server数据库)日志太多,占了很多磁盘空间,可以通过收缩数据库日志,减少日志文件大小. 下面以Northwind数据库为例: 1.把数据库的恢复模式设置为“简单模式”: ...

  7. 【转】configure/make/make install的使用说明

    这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装步骤. ./configure是用来检测你的安装平台的目标特征的.比如它会检测你是不是有CC或GCC,并不是需要CC或GCC ...

  8. MYSQL和ORACLE的触发器与存储过程语法差异

    整改了一番脚本,遇到了一些两种数据库之间的差异,记录一下: 触发器: 差异 MYSQL ORACLE 说明 创建语句不同 create trigger `AA` BEFORE INSERT on `B ...

  9. IIS访问PHP文件时,弹出用户名和密码提示框的解决方法

    找了一圈,以下的方法解决了IIS访问PHP弹用户名和密码提示框问题. 解决方法:给PHP安装目录everyone读取权限 这样不知道会不会出现安全问题,请大家谨慎.

  10. cfdiv2/c/找规律

    题目连接 £:若n<4,NO: £:若n==4,特判,n==5,特判. £:若n>=6,用2-4组成24,1和5和6组成零,即可. #include <set> #includ ...