Android 实现代码混淆的实例

Android 实现代码混淆的实例

1、简介

代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。

混淆的目的是为了加大反编译的成本,但是并不能彻底防止反编译。

2、如何开启混淆

通常我们需要找到项目路径下app目录下的build.gradle文件,找到minifyEnabled这个配置,然后设置为true即可,如下:

release {
  minifyEnabled true
  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

3、proguard又是什么呢

这是java官网给出的定义:

ProGuard is a free Java Class file shrinker, optimizer, obfuscator,
and preverifier. It detects and removes unused classes, fields, methods,
 and attributes. It optimizes bytecode and removes unused instructions.
It renames the remaining classes, fields, and methods using short meaningless names.
Finally, it preverifies the processed code for Java 6 or higher, or for Java Micro Edition.

作用:

  • proguard是一个集文件压缩,优化,混淆和校验等功能的工具
  • 检测并删除无用的类,变量,方法和属性
  • 优化字节码并删除无用的指令
  • 通过将类名,变量名和方法名重命名为无意义的名称实现混淆效果
  • 还校验处理后的代码

4、常见语句

-optimizationpasses 5

代码混淆压缩笔记,在0~7之间

-dontusemixedcaseclassnames

混淆后类名都小写

-dontskipnonpubliclibraryclasses

不去忽略非公共的库的类

-dontskipnonpubliclibraryclassmembers

不去忽略非公共的库的类的成员

-dontpreverify

不做预校验的操作

-verbose
-printmapping proguardMapping.txt

生成原类名和混淆后的类名的映射文件

-optimizations !code/simplification/cast,!field/*,!class/merging/*

指定混淆时采用的算法

-keepattributes *Annotation*,InnerClasses

注解不混淆

-keepattributes Signature

泛型不混淆

-keepattributes SourceFile,LineNumberTable

抛出异常时保留代码行号

用的最多的指令

-keep class XXXX

保留类名不变,也就是类名不混淆,而类中的成员名不保证。当然也可以是继承XXX类的所有类名不混淆

-keepclasseswithmembers class XXXX

保留类名和成员名,当然也可以是类中特定方法

5、哪些不混淆

  • 反射中使用的元素
  • 与网络请求相关实体类
  • 使用注解的元素
  • 四大组件
  • WebView中与JS交互的类
  • 枚举 等

6、混淆文件编写

按照以上的规则和基本语句,我们将混淆文件分为两个区域:

定制化区域:分为实体类、第三方、js相关、反射相关,应按项目真实情况进行编写,具体会在稍后提到;

基本不动区直接复制即可。

#-------------------------------------------定制化区域----------------------------------------------
#---------------------------------1.实体类---------------------------------

#---------------------------------2.第三方包-------------------------------

#---------------------------------3.与js互相调用的类------------------------

#---------------------------------4.反射相关的类和方法-----------------------

#-------------------------------------------基本不用动区域--------------------------------------------
#---------------------------------基本指令区----------------------------------
-optimizationpasses 5
-dontskipnonpubliclibraryclassmembers
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
#----------------------------------------------------------------------------

#---------------------------------默认保留区---------------------------------
-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.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}

-keep public class * extends android.view.View{
  *** get*();
  void set*(***);
  public <init>(android.content.Context);
  public <init>(android.content.Context, android.util.AttributeSet);
  public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
  public <init>(android.content.Context, android.util.AttributeSet);
  public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * implements java.io.Serializable {
  static final long serialVersionUID;
  private static final java.io.ObjectStreamField[] serialPersistentFields;
  private void writeObject(java.io.ObjectOutputStream);
  private void readObject(java.io.ObjectInputStream);
  java.lang.Object writeReplace();
  java.lang.Object readResolve();
}
-keep class **.R$* {
 *;
}
-keepclassmembers class * {
  void *(**On*Event);
}

#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
  public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
  public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
  public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {
  public void *(android.webkit.WebView, jav.lang.String);
}
#------------------------------------------------------------------------------------

实体类:

-keep class 你的实体类所在的包.* { ; }

实体类由于涉及到与服务端的交互,各种gson的交互如此等等,是要保留的。将你项目中实体类都挑出来,用以上语法进行保留。

如果实体类都在同一一个包下,就和上面一样,很简单;如果实体类分布在各个包下,不好意思,挨个添加。

第三方包

需到项目的build.gradle文件中找到所有添的依赖,然后去官网或者github找到对应的混淆代码,添加到我们自己的混淆文件中。

如果是添的jar包的话,就像如下来写

#log4j
-libraryjars log4j-1.2.17.jar
-dontwarn org.apache.log4j.**
-keep class org.apache.log4j.** { *;}

大致意思就是不混淆,不报warn。如果gradle报错的话,可以考虑注释掉-libraryjars log4j-1.2.17.jar这句。

与JS交互相关

如果没有可跳过

-keep class 你的类所在的包.** { *; }

如果是内部类的话这样写:

-keepclasseswithmembers class 你的类所在的包.父类$子类 { <methods>; }

反射相关

没有可跳过

-keep class 你的类所在的包.** { *; }

ok,这样就可以了,其实混淆很简单!

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android Studio多渠道批量打包及代码混淆

    一.批量打包 1.集成了友盟统计,并在AndroidManifest.xml中添加了如下代码 <meta-data android:name="UMENG_CHANNEL" android:value="${CHANNEL_VALUE}"/> 2.在app的build.gradle的android标签下添加如下代码: productFlavors { myapp {} _360 {} appchina {} hiapk {} } productFlavo

  • android app进行代码混淆实例详解

    接到一个新的任务,对现有项目进行代码混淆.之前对混淆有过一些了解,但是不够详细和完整,知道有些东西混淆起来还是比较棘手的.不过幸好目前的项目不是太复杂(针对混淆这块来说),提前完成--现总结之. 第一部分 介绍下操作流程(eclipse): 1.打开混淆器:找到项目根目录下的project.properties文件,将"#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt"

  • Android应用开发之代码混淆

    混淆器(ProGuard) 混淆器通过删除从未用过的代码和使用晦涩名字重命名类.字段和方法,对代码进行压缩,优化和混淆.结果是一个比較小的.apk文件,该文件比較难进行逆向project.因此,当你的应用程序对安全敏感(要求高),比如当你授权应用程序的时候,混淆器是一种重要的保护手段. 混淆器被集成在android 构建系统中,所以你不必手动调用它.同一时候混淆器仅在公布模式下进行构建应用程序的时候才会执行起来,所以在调试模式下构建程序时,你不必处理混淆代码.让混淆器执行起来是可选择的,可是推荐

  • Android实用图文教程之代码混淆、第三方平台加固加密、渠道分发

    第一步:代码混淆(注意引入的第三方jar) 在新版本的ADT创建项目时,混码的文件不再是proguard.cfg,而是project.properties和proguard-project.txt. 新建一个项目的时候,会自动生成project.properties和proguard-project.txt文件,无需自己新建,如果你的项目无法自动生成,那么你就要检查一下你的ADT版本了 如果需要对项目进行全局混码,只需要进行一步操作: 将project.properties的中 "#progua

  • Android 实现代码混淆的实例

    Android 实现代码混淆的实例 1.简介 代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为. 混淆的目的是为了加大反编译的成本,但是并不能彻底防止反编译. 2.如何开启混淆 通常我们需要找到项目路径下app目录下的build.gradle文件,找到minifyEnabled这个配置,然后设置为true即可,如下: release { minifyEnabled true proguardFiles getDefa

  • Android使用插件实现代码混淆

    我们在打包的过程中,需要对代码进行混淆处理,可项目中需要混淆的地方很多,特别是添加依赖的,如果要我们一个一个添加,无疑这大大的添加了我们的工作量,下面介绍用插件的方式来对代码进行混淆. 使用流程: 下载AndroidProGuard插件并安装重启. 在菜单栏的Edit下拉菜单中选择AndroidProGuard选项. 如果弹出成功对话框,就可以按Ctrl+V粘贴到项目的proguard-rules.pro文件. 根据proguard-rules.pro报错的提示进行修改成. 将项目app下gra

  • Android 手势 正则匹配图片实例代码

    为没有手势的控件(ViewFlipper) 添加手势 xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools

  • Android自定义手机界面状态栏实例代码

    前言 我们知道IOS上的应用,状态栏的颜色总能与应用标题栏颜色保持一致,用户体验很不错,那安卓是否可以呢?若是在安卓4.4之前,答案是否定的,但在4.4之后,谷歌允许开发者自定义状态栏背景颜色啦,这是个不错的体验!若你手机上安装有最新版的qq,并且你的安卓SDK版本是4.4及以上,你可以看下它的效果: 实现这个效果有两个方法: 1.在xml中设置主题或自定义style: Theme.Holo.Light.NoActionBar.TranslucentDecor Theme.Holo.NoActi

  • Android 底部导航控件实例代码

    一.先给大家展示下最终效果 通过以上可以看到,图一是简单的使用,图二.图三中为结合ViewPager共同使用,而且都可以随ViewPager的滑动渐变色,不同点是图二为选中非选中两张图片,图三的选中非选中是一张图片只是做了颜色变化. 二. 需求 我们希望做可以做成这样的,可以在xml布局中引入控件并绑定数据,在代码中设置监听回调,并且配置使用要非常简单! 三.需求分析 根据我们多年做不明确需求项目的经验,以上需求还算明确.那么我们可以采用在LinearLayout添加子View控件,这个子Vie

  • Android Dialog详解及实例代码

     Android Dialog详解及实例代码 概述: Android开发中最常用的就是Dialog类,除了自定义dialog布局,最多的就是用在弹出对话框.进度条.输入框.单选.复选框. 1.选择对话框: AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setTitle("选择对话框"); dialog.setMessage("请选择确认或取消"); dialog.setCance

  • Android sd卡读取数据库实例代码

    Android sd卡读取数据库实例代码 前言: 本文主要给大家讲解如何利用Android SD卡读取数据库,提供一些代码如下.先在 Manifest 里添加权限: <span style="font-size:16px;"><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name=

  • Android okhttputils现在进度显示实例代码

    OkHttpUtils是一款封装了okhttp的网络框架,支持大文件上传下载,上传进度回调,下载进度回调,表单上传(多文件和多参数一起上传),链式调用,整合Gson,自动解析返回对象,支持Https和自签名证书,支持cookie自动管理,扩展了统一的上传管理和下载管理功能. //download the new app private void downLoadNewApp(NewVersion.XianzaishiRfBean version) { if (StringUtils.isEmpt

随机推荐