当前位置: 首页 > news >正文

【转】Android 防破解技术简介

http://www.cnblogs.com/likeandroid/p/4888808.html

Android 防破解技术简介

这几年随着互联网的不断发展,Android App 也越来越多!但是随之而来的问题也越来越多,这其中比较令人头疼的问题就是:有些不法分子利用反编译技术破解 App,修改代码,之后再重新编译上传到应用商店!到时候,如果用户下载了这些应用,就可能造成个人信息或者金钱的丢失!所以,作为开发者的我们,有必要学习一些防止被破解的技术手段了!

简介

现在想要破解一个 App, 大多数都是遵循着以下的几个步骤:

  • 反编译 App
  • 查看 App 源代码并修改
  • 动态调试(有可能存在而已,毕竟修改源码之后也是要调试的,哈)
  • 重新编译 App
  • 上传破解的 App 到商店中

目前来讲大多数的破解只存在一二两步中,但是后面的几个步骤还是会有人弄的,所以我们不能掉以轻心呀!当然最后一步我们姑且不谈了!下面我就来一个一个的介绍防止这些步骤的方法!

防止反编译 App

目前来说,大多数人用的反编译工具都是:jdax,dex2jar,jd-gui等工具,但是对于我们来说有个好消息就是 这些工具很多都是开源的,我们可以在 Github 上找到这些工具的源码,我们可以通过阅读这些源码,从而找出防止他们反编译的方法,也就是让他在反编译你的 App 的时候,让他们的软件崩溃!对于这个我们可以忽略,因为去阅读这些代码并理解他们,是一项比较耗时的工作甚至有可能都读不通他们的程序,所以我们尽量把经历放在下面的几个步骤上!

防止查看源代码

其实并不能真正的做到防止别人查看我们的源代码,我们只是通过代码混淆的技术来使别人在查阅我们的源代码时变得更加的困难而已。在 Android 中我们可以使用 ProGuard 来混淆我们的代码。在这里先说明一下代码混淆的优缺点:
优点:

  1. 增加别人破解 app 的难度
  2. 压缩、优化、删除代码
  3. 通过删除代码功能实现的特殊作用

缺点:

  1. 增加我们自己的调试难度(相信混效过代码的同学都知道,在混淆之后,app会出各种错误)
  2. 反射方面的问题(就是找不到对应的类)

对于第一个缺点的问题的解决方案是:保存 mappinp.txt 这个保存映射关系的文件,当 app 在混淆运行之后可能出现的问题,可以根据这个映射关系来快速定位出 bug 所在的位置!对于第二个缺点的问题的解决方案是:不混淆该类,如果不知道是哪个类那只能运行的时候调试了!
接下来简要介绍一下 ProGuard 的常用语法:

-libraryjars class_path 应用的依赖包,如android-support-v4
-keep [,modifier,...] class_specification 不混淆某些类
-keepclassmembers [,modifier,...] class_specification 不混淆类的成员
-keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员
-keepnames class_specification 不混淆类及其成员名 -keepclassmembernames class_specification 不混淆类的成员名 -keepclasseswithmembernames class_specification 不混淆类及其成员名 -assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等 -dontwarn [class_filter] 不提示warnning

在这里在给出 android 中标准的 proguard.cfg 文件内容

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -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 com.android.vending.licensing.ILicensingService -keepclasseswithmembernames class * { native <methods>; } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } 

大家可以依据此模版在进行增删改查。另外,我还可以通过代码混淆来控制是否打印日志输出:

   -assumenosideeffects class android.util.Log {
    public static *** d(...); public static *** v(...); }

在我写此文章是,有些牛逼的公司已经可以进行资源文件名的混淆了,这样就更加增大了代码阅读难度了!在这里给出该文章:美团Android资源混淆保护实践

防止动态调试

所谓的动态调试就是使用 检测调试器

检测调试器

这个检测很简单:就是当我们的软件检测到连接到调试器的时候,就终止程序!
首先,我们在 AndroidManifest.xml 中的 Application 标签中添加 android:debuggable="false" 这个属性,使程序不可调试,如果有人想调试,必定要修改这个值,之后我们只要在代码中添加下面短代码来检测该值是否变改变过,如果改变过就停止程序。

if((getApplicationInfo().flags &= 
                 ApplicationInfo.FLAG_DEBUGGABL)!=0){
   android.os.Process.killProcess(android.os.Process.myPid());
}

这样就可以解决这个问题了

防止重新编译

代码在上传的时候是需要对 app 进行的签名的,而每个签名文件只有 app 开发者才有,所以我们可以根据签名的内容来进行对比。但是签名的文件过长不利于对比,我们用见面签名内容的 hashCode 来比较。获取这个值的代码:

   public int getsignature(String packageName) { try { android.content.pm.Signature[] signatures= getPackageManager().getPackageInfo(packageName.toString(), PackageManager.GET_SIGNATURES).signatures; return signatures[0].hashCode(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return 0; } }

我们只要在本地打包之后获取到这个值,之后在每次程序运行的时候,在获取签名的 hashCode 的来与我们之前在本地打包的值进行比较就行了!如果不同就直接关闭程序就行了!

NDK保护

就是关键代码使用 C/C++ 代码来写,没有研究过

加壳

在现有的代码外加一层 C/C++ 代码来保护,也没有研究过

参考资料

  • Android 软件安全与逆向分析

相关文章:

  • Go 环境变量
  • 使用LocalBroadcastManager
  • exif信息对照
  • 前端学习笔记--9/5~13/5 Ajax, jQuery
  • 【COCOS2DX-LUA 脚本开发之二】LUA语言基础
  • OC语言大总结(下)
  • Lucene5学习之使用MMSeg4j分词器
  • PostgreSQL 9.6 攻克金融级多副本可靠性问题
  • 1.3 中国云创行业地图
  • cacti系列之安装篇 LNMP+cacti+spine (一)
  • 华为S5700实现两个VLAN间不通信的ACL策略
  • Appstore热搜的五款外包应用!
  • Ubuntu安装配置串口通讯工具minicomcutecom
  • 关于前端复用的实践
  • 51nod 1043 幸运号码
  • ➹使用webpack配置多页面应用(MPA)
  • AWS实战 - 利用IAM对S3做访问控制
  • ES2017异步函数现已正式可用
  • idea + plantuml 画流程图
  • in typeof instanceof ===这些运算符有什么作用
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript创建对象的四种方式
  • Material Design
  • Swoft 源码剖析 - 代码自动更新机制
  • VUE es6技巧写法(持续更新中~~~)
  • vue-loader 源码解析系列之 selector
  • Webpack 4x 之路 ( 四 )
  • 从0到1:PostCSS 插件开发最佳实践
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 简单实现一个textarea自适应高度
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 聊聊redis的数据结构的应用
  • 如何合理的规划jvm性能调优
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 一、python与pycharm的安装
  • 一些css基础学习笔记
  • 赢得Docker挑战最佳实践
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #stm32驱动外设模块总结w5500模块
  • $jQuery 重写Alert样式方法
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (LeetCode 49)Anagrams
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (十三)Flask之特殊装饰器详解
  • (一)基于IDEA的JAVA基础10
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)人的集合论——移山之道
  • (状压dp)uva 10817 Headmaster's Headache
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'