Android混淆、反编译基础教程

434 阅读5分钟

这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

Android混淆、反编译基础教程

Android APK混淆

Java代码是非常容易反编译的。为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理。

根据 SDK 的版本不同有 2 中不同的代码混淆方式,以上的 proguard.cfg 参数详解中所涉及到的信息是在较低版本 SDK 下的混淆脚本,事实上在高版本的 SDK 下混淆的原理和参数也与低版本的相差无几,只是在不同 SDK 版本的环境下引入混淆脚本的方式有所不同。具体方法如下:

低版本 SDK 下,项目中同时包含 proguard.cfg 和 project.properties 文件,则只需在 project.properties 文件末尾添加 proguard.config=proguard.cfg 再将项目 Export 即可。 高版本 SDK 下,项目中同时包含 proguard-project.txt 和 project.properties 文件,这时需要在 proguard-project.txt 文件中进行如下信息的配置,然后再将项目 Export 即可。

例如:

	# This file is automatically generated by Android Tools.
	# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
	#
	# This file must be checked in Version Control Systems.
	#
	# To customize properties used by the Ant build system edit
	# "ant.properties", and override values to adapt the script to your
	# project structure.
	#
	# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
	proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
	
	# Project target.
	target=android-23

这样就配置好了混淆的关联文件。下面就是开始配置混淆内容。

语法:

	-include {filename}    从给定的文件中读取配置参数 
	-basedirectory {directoryname}    指定基础目录为以后相对的档案名称 
	-injars {class_path}    指定要处理的应用程序jar,war,ear和目录 
	-outjars {class_path}    指定处理完后要输出的jar,war,ear和目录的名称 
	-libraryjars {classpath}    指定要处理的应用程序jar,war,ear和目录所需要的程序库文件 
	-dontskipnonpubliclibraryclasses    指定不去忽略非公共的库类。 
	-dontskipnonpubliclibraryclassmembers    指定不去忽略包可见的库类的成员。
保留选项 
	-keep {Modifier} {class_specification}    保护指定的类文件和类的成员 
	-keepclassmembers {modifier} {class_specification}    保护指定类的成员,如果此类受到保护他们会保护的更好
	-keepclasseswithmembers {class_specification}    保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。 
	-keepnames {class_specification}    保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除) 
	-keepclassmembernames {class_specification}    保护指定的类的成员的名称(如果他们不会压缩步骤中删除) 
	-keepclasseswithmembernames {class_specification}    保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后) 
	-printseeds {filename}    列出类和类的成员-keep选项的清单,标准输出到给定的文件 
压缩 
	-dontshrink    不压缩输入的类文件 
	-printusage {filename} 
	-dontwarn   如果有警告也不终止
	-whyareyoukeeping {class_specification}     
优化 
	-dontoptimize    不优化输入的类文件 
	-assumenosideeffects {class_specification}    优化时假设指定的方法,没有任何副作用 
	-allowaccessmodification    优化时允许访问并修改有修饰符的类和类的成员 
混淆 
	-dontobfuscate    不混淆输入的类文件 
	-printmapping {filename} 
	-applymapping {filename}    重用映射增加混淆 
	-obfuscationdictionary {filename}    使用给定文件中的关键字作为要混淆方法的名称 
	-overloadaggressively    混淆时应用侵入式重载 
	-useuniqueclassmembernames    确定统一的混淆类的成员名称来增加混淆 
	-flattenpackagehierarchy {package_name}    重新包装所有重命名的包并放在给定的单一包中 
	-repackageclass {package_name}    重新包装所有重命名的类文件中放在给定的单一包中 
	-dontusemixedcaseclassnames    混淆时不会产生形形色色的类名 
	-keepattributes {attribute_name,...}    保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and 
	 
	InnerClasses. 
	-renamesourcefileattribute {string}    设置源文件中给定的字符串常量

混淆能提高我们代码的安全性,但同时也会导致出错,所以在混淆的时候,我们一定要明确哪些不能混淆。
(1)、 申明你所有的jar包。如-libraryjars libs/gson-2.0.jar
(2)、 系统中的不混淆的申明出来,防止变异出错。API里边的类,最好都要避免混淆。

	-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 com.android.vending.licensing.ILicensingService

###Android APK反编译 了解反编译的都知道,反编译的过程中我们需要三个工具(下载地址),分别是:

  • apktool 作用:资源文件获取,可以提取出图片文件和布局文件进行使用查看
  • dex2jar 作用:将apk反编译成java源码(classes.dex转化成jar文件)
  • jd-gui 作用:查看APK中classes.dex转化成出的jar文件,即源码文件

使用方式:

  • apktool:把apktool 解压到任意位置 执行 在dos 改目录下 执行 apktool d -f xxx.apk test ,便会把编译后的资源存入test文件夹下。注意,由于低版本的apktool对很多apk都没有效果,所以我们最好下载高版本的apktool.jar,当使用的版本大于2.0时(2.0下载),语句修改为apktool d -f xxx.apk -o test
  • dex2jar:首先将apk文件后缀改为zip并解压,得到其中的classes.dex,它就是java文件编译再通过dx工具打包而成的,将classes.dex复制到dex2jar.bat所在目录dex2jar-0.0.9.15 文件夹。在命令行下定位到dex2jar.bat所在目录,运行dex2jar.bat classes.dex生成 classes_dex2jar.jar之后借助工具jdgui便可以查看源码。
  • jd-gui:将使用dex2jar 反编译出来的classes_dex2jar.jar文件用此软件打开便可以看到源码。

下面我们制作一个没有混淆的apk——TranslateDemo.apk。 1、首先使用apktool进行解压资源文件。我们下载好资源,解压工具中的apktool压缩文件,解压得到3个文件:aapt.exe,apktool.bat,apktool.jar 0
(1)、将TranslateDemo.apk拷贝到解压的apktool目录下,在cmd命令行中进入该目录(通过cd指令),然后执行apktool d -f TranslateDemo.apk test。即将资源文件解压。

apktool

(2)、将我们的apk文件后缀名改为.rar或者.zip,然后进行解压,获取classes.dex文件,拷贝至dex2jar的解压目录下,然后执行在cmd中进入dex2jar目录下,执行dex2jar.bat classes.dex指令。获取解压后的classes_dex2jar.jar文件。

dex2jar

(3)、通过jd-gui工具打开jar包即可查看源码。

jd-ui

是不是很nice,所以我们的应用一定要进行混淆,不然代码都被抄袭了。最后我们以某牛的apk做个测试。看下效果图。

result