有时候为了保护代码不被非法查看或使用时,我们都会对应用或游戏的代码进行混淆打包,就是将类名和方法名换成abcde等没有意义和很难阅读的名字. 像如下图片中的效果,但是有些是不能混淆的.因为配置文件中使用了.
将应用中的所有类变成a,b,c,d,e等等的类,方法名也全部变成a,b,c,d,e的,让反编译出来的全部很难阅读.
上图中的目录与文件说明 :
proguard4.5.1 : 该目录是proguard4.5.1版本的所需文件,就是使用它来实现混淆效果的
build.properties : 该文件定义使用ant打包打包的配置,如生成的apk包的文件名,jdk目录,android-sdk目录等
build.xml : Ant的配置文件,一般不需要修改,直接执行 “_buildAPK(打包)” 任务来打包,apk包默认放在android-pub目录下
keystore/rbase.keystore : keystore签名文件,如果要上传到google market的话,该文件是必须.因为我们打出来的包都已经进行签名的.
p.properties : 配置keystore的密码(password=xxxx),keystore签名时要使用的
proguard.cfg : 混淆的配置文件,定义了哪些类或方法要进行混淆.因为有一些类是不能混淆的,AndroidManifest.xml需要定义的都不能进行混淆.
——————————————————–
以下是一些重要的文件内容,便于大家直接查看
build.properties文件内容
## 打包后的文件名,该文件将放在项目的根目录下的android-pub目录下 app.name=RB-HitShrew-0.9.9-beta ## 进行操作的包名 application.package=rbase.app.hitshrew sdk.folder=${eclipse.home}/android-sdk-windows/platforms/android-4/ eclipse.home=e/:/android/eclipse-3.6.0 android.tools=${sdk.folder}tools android_version=1.6 apk.sdk.home=${eclipse.home}/android-sdk-windows-4/ apk.tools=${apk.sdk.home}tools/ bin.dir=${jde.home}bin app.source.path=d/:/test/ jdk.home=${eclipse.home}/jdk1.6.0_20 output.dir=android-pub proguard-home=proguard4.5.1/lib ## 指定keystore的文件路径 keystore.file=keystore/rbase.keystore ## 指定制作keystore时的应用名字 keystore.name=myapp.keystore
以下是 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 * extends android.app.backup.BackupAgentHelper -keep public class * extends android.preference.Preference -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); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
以下是p.properties的文件内容
## keystore的密码,制作keystore文件时输入的密码 password=xxxxxx
以下是build.xml中的内容,是使用Ant打包中最重要的文件
<?xml version="1.0" encoding="UTF-8"?> <project name="hit-shrew" default="debug" basedir="." > <property file="build.properties" /> <property file="p.properties" /> <!-- The intermediates directory --> <!-- Eclipse uses "bin" for its own output, so we do the same. --> <property name="outdir" value="target" /> <!-- ************************************************************************************* --> <!-- No user servicable parts below. --> <property name="android-framework" value="${sdk.folder}/framework.aidl" /> <!-- Input directories --> <property name="resource-dir" value="res" /> <property name="asset-dir" value="assets" /> <property name="srcdir" value="src" /> <condition property="srcdir-ospath" value="${basedir}/${srcdir}" else="${basedir}/${srcdir}"> <os family="windows" /> </condition> <property name="external-libs" value="lib" /> <condition property="external-libs-ospath" value="${basedir}/${external-libs}" else="${basedir}/${external-libs}"> <os family="windows" /> </condition> <!-- Output directories --> <property name="outdir-classes" value="${outdir}/classes" /> <condition property="outdir-classes-ospath" value="${basedir}/${outdir-classes}" else="${basedir}/${outdir-classes}"> <os family="windows" /> </condition> <condition property="zipalign-package-ospath" value="${basedir}/${output.dir}/${app.name}.apk" else="${basedir}/${output.dir}"> <os family="windows" /> </condition> <condition property="zipalign-package-ospath-test" value="${basedir}/${output.dir}/${app.name}-test.apk" else="${basedir}/${output.dir}"> <os family="windows" /> </condition> <!-- Create R.java in the source directory --> <property name="outdir-r" value="gen" /> <!-- Intermediate files --> <property name="dex-file" value="classes.dex" /> <property name="intermediate-dex" value="${outdir}/${dex-file}" /> <condition property="intermediate-dex-ospath" value="${basedir}/${intermediate-dex}" else="${basedir}/${intermediate-dex}"> <os family="windows" /> </condition> <!-- The final package file to generate --> <property name="resources-package" value="${outdir}/${ant.project.name}.apk" /> <condition property="resources-package-ospath" value="${basedir}/${resources-package}" else="${basedir}/${resources-package}"> <os family="windows" /> </condition> <property name="out-debug-package" value="${outdir}/${ant.project.name}-debug.apk" /> <condition property="out-debug-package-ospath" value="${basedir}/${out-debug-package}" else="${basedir}/${out-debug-package}"> <os family="windows" /> </condition> <property name="out-unsigned-package" value="${outdir}/${ant.project.name}-unsigned.apk" /> <property name="out-signed-package" value="${outdir}/${ant.project.name}-signed.apk" /> <condition property="out-unsigned-package-ospath" value="${basedir}/${out-unsigned-package}" else="${basedir}/${out-unsigned-package}"> <os family="windows" /> </condition> <condition property="out-signed-package-ospath" value="${basedir}/${out-signed-package}" else="${basedir}/${out-signed-package}"> <os family="windows" /> </condition> <!-- Tools --> <condition property="aapt" value="${android.tools}/aapt.exe" else="${android.tools}/aapt"> <os family="windows" /> </condition> <condition property="zipalign" value="${apk.tools}/zipalign.exe" else="${apk.tools}/zipalign"> <os family="windows" /> </condition> <condition property="jarsigner" value="${jdk.home}/bin/jarsigner.exe" else="${jdk.home}/bin/jarsigner"> <os family="windows" /> </condition> <condition property="aidl" value="${android.tools}/aidl.exe" else="${android.tools}/aidl"> <os family="windows" /> </condition> <condition property="adb" value="${apk.tools}/adb.exe" else="${apk.tools}/adb"> <os family="windows" /> </condition> <condition property="dx" value="${android.tools}/dx.bat" else="${android.tools}/dx"> <os family="windows" /> </condition> <condition property="apk-builder" value="${apk.tools}/apkbuilder.bat" else="${apk.tools}/apkbuilder"> <os family="windows" /> </condition> <property name="android-jar" value="${sdk.folder}/android.jar" /> <target name="_buildAPK(打包)" description="标准的android打包方法" depends="compile,dex, package-res,release,jarsigner,zipalign"> </target> <target name="_buildAPK-no-asserts(打包)" description="不打包asserts目录" depends="compile,dex, package-res-no-assets,release,jarsigner,zipalign"> </target> <target name="_buildAPK-no-asserts-test(打包)" depends="compile,dex, package-res-no-assets,release,jarsigner,zipalign-test"> </target> <target name="_buildAPK(模糊打包)" depends="compile-optimize,dex, package-res,release,jarsigner,zipalign"> </target> <!-- Create the output directories if they don't exist yet. --> <target name="dirs" depends="init"> <echo>Creating output directories if needed...</echo> <delete dir="${outdir-classes}" /> <mkdir dir="${outdir}" /> <mkdir dir="${outdir-classes}" /> </target> <!-- Generate the R.java file for this project's resources. --> <target name="resource-src" depends="dirs"> <echo>Generating R.java / Manifest.java from the resources...</echo> <exec executable="${aapt}" failonerror="true"> <arg value="package" /> <arg value="-m" /> <arg value="-J" /> <arg value="${outdir-r}" /> <arg value="-M" /> <arg value="AndroidManifest.xml" /> <arg value="-S" /> <arg value="${resource-dir}" /> <arg value="-I" /> <arg value="${android-jar}" /> </exec> </target> <!-- Generate java classes from .aidl files. --> <target name="aidl" depends="dirs"> <echo>Compiling aidl files into Java classes...</echo> <apply executable="${aidl}" failonerror="true"> <arg value="-p${android-framework}" /> <arg value="-I${srcdir}" /> <fileset dir="${srcdir}"> <include name="**/*.aidl" /> </fileset> </apply> </target> <!-- Compile this project's .java files into .class files. --> <target name="compile" depends="dirs, resource-src, aidl"> <javac encoding="utf-8" target="1.6" debug="true" extdirs="" srcdir="gen" destdir="${outdir-classes}" bootclasspath="${android-jar}"> <classpath> <fileset dir="${external-libs}" includes="*.jar" /> </classpath> </javac> <javac encoding="utf-8" target="1.6" debug="true" extdirs="" srcdir="src" destdir="${outdir-classes}" bootclasspath="${android-jar}"> <classpath> <fileset dir="${external-libs}" includes="*.jar" /> </classpath> </javac> </target> <!-- Compile this project's .java files into .class files. --> <target name="compile-optimize" depends="compile"> <antcall target="optimize" /> </target> <!-- Convert this project's .class files into .dex files. --> <target name="dex"> <echo>Converting compiled files and external libraries into ${outdir}/${dex-file}...</echo> <apply executable="${dx}" failonerror="true" parallel="true"> <arg value="--dex" /> <arg value="--output=${intermediate-dex-ospath}" /> <arg path="${outdir-classes-ospath}" /> <fileset dir="${external-libs}" includes="*.jar" /> </apply> </target> <!-- Put the project's resources into the output package file. --> <target name="package-res-and-assets"> <echo>Packaging resources and assets...</echo> <exec executable="${aapt}" failonerror="true"> <arg value="package" /> <arg value="-f" /> <arg value="-M" /> <arg value="AndroidManifest.xml" /> <arg value="-S" /> <arg value="${resource-dir}" /> <arg value="-A" /> <arg value="${asset-dir}" /> <arg value="-I" /> <arg value="${android-jar}" /> <arg value="-F" /> <arg value="${resources-package}" /> </exec> </target> <!-- Same as package-res-and-assets, but without "-A ${asset-dir}" --> <target name="package-res-no-assets"> <echo>Packaging resources...</echo> <exec executable="${aapt}" failonerror="true"> <arg value="package" /> <arg value="-f" /> <arg value="-M" /> <arg value="AndroidManifest.xml" /> <arg value="-S" /> <arg value="${resource-dir}" /> <!-- No assets directory --> <arg value="-I" /> <arg value="${android-jar}" /> <arg value="-F" /> <arg value="${resources-package}" /> </exec> </target> <!-- Invoke the proper target depending on whether or not an assets directory is present. --> <!-- TODO: find a nicer way to include the "-A ${asset-dir}" argument only when the assets dir exists. --> <target name="package-res"> <available file="${asset-dir}" type="dir" property="res-target" value="and-assets" /> <property name="res-target" value="no-assets" /> <antcall target="package-res-${res-target}" /> </target> <!-- Package the application and sign it with a debug key. This is the default target when building. It is used for debug. --> <target name="debug" depends="dex, package-res"> <echo>Packaging ${out-debug-package}, and signing it with a debug key...</echo> <exec executable="${apk-builder}" failonerror="true"> <arg value="${out-debug-package-ospath}" /> <arg value="-z" /> <arg value="${resources-package-ospath}" /> <arg value="-f" /> <arg value="${intermediate-dex-ospath}" /> <arg value="-rf" /> <arg value="${srcdir-ospath}" /> <arg value="-rj" /> <arg value="${external-libs-ospath}" /> </exec> </target> <!-- Package the application without signing it. This allows for the application to be signed later with an official publishing key. --> <target name="release"> <echo>Packaging ${out-unsigned-package} for release...</echo> <exec executable="${apk-builder}" failonerror="true"> <arg value="${out-unsigned-package-ospath}" /> <arg value="-u" /> <arg value="-z" /> <arg value="${resources-package-ospath}" /> <arg value="-f" /> <arg value="${intermediate-dex-ospath}" /> <arg value="-rf" /> <arg value="${srcdir-ospath}" /> <arg value="-rj" /> <arg value="${external-libs-ospath}" /> </exec> <echo>It will need to be signed with jarsigner before being published.</echo> </target> <!-- Install the package on the default emulator --> <target name="install" depends="debug"> <echo>Installing ${out-debug-package} onto default emulator...</echo> <exec executable="${adb}" failonerror="true"> <arg value="install" /> <arg value="${out-debug-package}" /> </exec> </target> <target name="reinstall" depends="debug"> <echo>Installing ${out-debug-package} onto default emulator...</echo> <exec executable="${adb}" failonerror="true"> <arg value="install" /> <arg value="-r" /> <arg value="${out-debug-package}" /> </exec> </target> <!-- Uinstall the package from the default emulator --> <target name="uninstall"> <echo>Uninstalling ${application.package} from the default emulator...</echo> <exec executable="${adb}" failonerror="true"> <arg value="uninstall" /> <arg value="${application.package}" /> </exec> </target> <!--初始化目录--> <target name="init" depends="Copy_Ressource"> <echo message="Init output directory....."> </echo> <mkdir dir="${output.dir}" /> </target> <!--拷贝资源--> <target name="Copy_Ressource"> <echo message="Copy app resource. "> </echo> <copy todir="${asset-dir}" overwrite="true" failonerror="false"> <fileset dir="${app.source.path}"> <include name="*.*" /> </fileset> </copy> </target> <!--进行签名--> <target name="jarsigner"> <exec executable="${jarsigner}" failonerror="true"> <arg value="-verbose" /> <arg value="-storepass" /> <arg value="${password}" /> <arg value="-keystore" /> <arg value="${keystore.file}" /> <arg value="-signedjar" /> <arg value="${out-signed-package-ospath}" /> <arg value="${out-unsigned-package-ospath}" /> <arg value="${keystore.name}" /> </exec> </target> <!--进行优化--> <target name="zipalign"> <exec executable="${zipalign}" failonerror="true"> <arg value="-v" /> <arg value="-f" /> <arg value="4" /> <arg value="${out-signed-package-ospath}" /> <arg value="${zipalign-package-ospath}" /> </exec> </target> <!--进行优化--> <target name="zipalign-test"> <exec executable="${zipalign}" failonerror="true"> <arg value="-v" /> <arg value="-f" /> <arg value="4" /> <arg value="${out-signed-package-ospath}" /> <arg value="${zipalign-package-ospath-test}" /> </exec> </target> <!--直接上传到手机中去--> <target name="adb" depends="zipalign"> <exec executable="${adb}" failonerror="true"> <arg value="install" /> <arg value="-r" /> <arg value="${zipalign-package-ospath}" /> </exec> </target> <!--Execute proguard class flies--> <target name="optimize"> <jar basedir="${outdir-classes}" destfile="temp.jar"/> <java jar="${proguard-home}/proguard.jar" fork="true" failonerror="true"> <jvmarg value="-Dmaximum.inlined.code.length=32"/> <arg value="-injars temp.jar"/> <arg value="-outjars optimized.jar"/> <arg value="-libraryjars ${android-jar}"/> <arg value="-libraryjars ${external-libs}/"/> <arg value="-dontpreverify"/> <arg value="-dontoptimize"/> <arg value="-dontusemixedcaseclassnames"/> <arg value="-repackageclasses ''"/> <arg value="-allowaccessmodification"/> <!--<arg value="-keep public class ${exclude-activity}"/>--> <!--<arg value="-keep public class ${exclude-provider}"/>--> <arg value="@proguard.cfg"/> <arg value="-optimizationpasses 7"/> <arg value="-verbose"/> <arg value="-dontskipnonpubliclibraryclasses"/> <arg value="-dontskipnonpubliclibraryclassmembers"/> </java> <delete file="temp.jar"/> <delete dir="${outdir-classes}"/> <mkdir dir="${outdir-classes}"/> <unzip src="optimized.jar" dest="${outdir-classes}"/> <delete file="optimized.jar"/> </target> </project>
—————————— 相关资源 ———————————–
相关资源下载与使用方法说明 :
以上的所有目录与文件都可以在这里下载. 我已经将它打成压缩包了.
Android使用Ant打包(混淆).zip
1 : 不进行签名使用:
一般只需要修改build.properties就以使用.
2 : 进行签名使用方法 :
1, 修改build.properties就能使用.
2, 覆盖rbase.keystore,当然也可以修改,修改build.properties中的keystore.file与keystore.name的配置
3, 修改p.properties,改成生成keystore时定义的密码
(以上资源的rbase.keystore是我的测试keystore,如果大家不想制作keystore也直接使用)
其它相关博文:
如何生成keystore,可以查看我另一篇博文 制作keystore用于android打包