ANT构建Android Proguard混淆

时间:2011-01-07 19:27:14

标签: android ant obfuscation proguard

任何人都可以与Android的示例/简单混淆ANT任务共享吗?如果我有完整的APK,我需要通过* class hru Proguard然后准备* .dex来构建APK

4 个答案:

答案 0 :(得分:12)

我找到了解决方案:

  1. 获取Proguard - 将proguard.jar复制到已知目录(比如MyProject / proguard)
  2. 准备proguard.cfg-描述优化/混淆的内容和方式。这个过程在Proguard的manual
  3. 中有详尽的描述
  4. 准备以下ANT的build.xml(或者类似于这个) - 非常好于this guy
  5. 更新完成build.xml

    <?xml version="1.0" encoding="UTF-8"?> 
    <project name="MyProject" default="zipalign" basedir=".">
        <property name="target" value="android-8"/>
        <!--property file="default.properties" /-->
        <property name="encoding" value="UTF-8"/>
    
        <!-- dirs -->
        <property name="sdk.dir" location="Location of Android SDK"/>
        <property name="proguard.dir" value="proguard" />
        <property name="src.dir" value="src"/>
        <property name="gen.dir" value="gen"/>
        <property name="res.dir" value="res"/>
        <property name="assets.dir" value="assets"/>
        <property name="libs.dir" value="libs"/>
        <property name="out.classes.unoptimized.dir" value="out"/>
        <property name="out.classes.optimized.dir" value="out/optimized"/>
    
        <!-- files -->
        <property name="manifest.file" value="AndroidManifest.xml"/>
        <property name="signed.apk" value="${ant.project.name}-signed.apk"/>
        <property name="unsigned.apk" value="${ant.project.name}-unsigned.apk"/>
        <property name="final.apk" value="${ant.project.name}.apk"/>
        <property name="android.jar" value="${sdk.dir}/tools/platforms/${target}/android.jar"/>
        <property name="unoptimized" value="unoptimized.jar" />
        <property name="optimized" value="optimized.jar" />
        <property name="proguard.config" value="${proguard.dir}/proguard.cfg"/>
    
        <!-- tools -->
        <property name="dx.jar" value="${sdk.dir}/platform-tools/lib/dx.jar"/>
        <property name="aapt" value="${sdk.dir}/platforms/${target}/tools/aapt.exe"/>
        <property name="zipalign" value="${sdk.dir}/tools/zipalign.exe"/>
        <property name="jarsign" value="jarsigner.exe location is here"/>
        <property name="keystore" value="Your key store is here"/>
        <property name="keyalias" value="Your key alias is here"/>
    
    
        <path id="android.antlibs">
            <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
            <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
            <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
            <pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
            <pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
        </path>
    
        <taskdef name="setup"
            classname="com.android.ant.SetupTask"
            classpathref="android.antlibs" />
        <setup import="false"/>
    
        <!--taskdef name="aaptexec"
                classname="com.android.ant.AaptExecLoopTask"
                classpathref="android.antlibs" /-->
    
        <target name="clean" description="Removes output files created by other targets.">
            <echo>Cleaning...</echo>
            <delete dir="${out.classes.unoptimized.dir}" verbose="true" />
            <delete dir="${out.classes.optimized.dir}" verbose="true" />
        </target>
    
        <target name="dirs">
            <echo>Creating output directories if needed...</echo>
            <mkdir dir="${out.classes.unoptimized.dir}" />
            <mkdir dir="${out.classes.optimized.dir}" />
        </target>
    
        <!-- Compiles this project's .java files into .class files. -->
        <target name="compile" depends="dirs"
                description="Compiles project's .java files into .class files">
            <echo>Compiling sources...</echo>
            <javac encoding="${encoding}" target="1.6" debug="true" extdirs=""
                    destdir="${out.classes.unoptimized.dir}"
                    bootclasspathref="android.target.classpath"
                    includeantruntime="true">
                <src path="${src.dir}" />
                <src path="${gen.dir}" />
                <classpath>
                    <fileset dir="${libs.dir}" includes="*.jar" />
                </classpath>
            </javac>
        </target>
    
        <target name="preobfuscate" depends="compile">
            <echo>Preparing to obfuscation...</echo>
        <jar destfile="${unoptimized}"
           basedir="${out.classes.unoptimized.dir}"
           includes="**/**"
           excludes="optimized/**"
           />
        </target>
    
        <!--  Obfuscation with ProGuard   -->
        <target name="optimize" unless="nooptimize" depends="preobfuscate">
            <echo>Proguard obfuscation...</echo>
            <java jar="${proguard.dir}/proguard.jar" fork="true" failonerror="true">
                <jvmarg value="-Dmaximum.inlined.code.length=16" />
                <arg value="@${proguard.dir}/proguard.cfg" />
                <arg value="-injars ${unoptimized}" />
                <arg value="-outjars ${optimized}" />
                <arg value="-libraryjars ${android.jar}" />
            </java>
            <unzip src="${optimized}" dest="${out.classes.optimized.dir}" />
            <!-- Delete optimized jar (now unzipped into bin directory)  -->
            <delete file="${optimized}"/>
            <delete file="${unoptimized}"/>
        </target>
    
        <target name="dex" description="Converting JVM bytecodes into Dalvik bytecodes" depends="optimize">
            <echo>Converting bytecodes to Dalvik VM bytecodes...</echo>
            <java jar="${dx.jar}" fork="true">
                <arg line="--dex --verbose --output=${out.classes.optimized.dir}/classes.dex ${out.classes.optimized.dir}"/>
            </java>
        </target>
    
        <target name="aapt" depends="dex" description="compile resources">
            <echo>Packing resources...</echo>
            <exec executable="${aapt}" logerror="true" osfamily="windows">
                <arg line="p
                -f
                -M ${manifest.file}
                -I ${android.jar}
                -S ${res.dir}
                -A ${assets.dir}
                -F ${out.classes.optimized.dir}/${unsigned.apk}
                -m -J ${gen.dir}"/>
            </exec>
        </target>
    
        <target name="sign" depends="aapt" description="sign apk">
            <input message="Please enter keystore password (store:${keystore}):"
                           addproperty="keystore.password" />
            <echo>Signing apk...</echo>
            <exec executable="${jarsign}" logerror="true" osfamily="windows">
                <arg line="-verbose
                -keystore ${keystore}
                -storepass ${keystore.password}
                -signedjar ${out.classes.optimized.dir}/${signed.apk}
                ${out.classes.optimized.dir}/${unsigned.apk} ${keyalias}"/>
            </exec>
        </target>
    
        <target name="zipalign" depends="sign" description="zip align">
            <echo>Aligning apk...</echo>
            <exec executable="${zipalign}" logerror="true" osfamily="windows">
                <arg line="-f
                -v
                4
                ${out.classes.optimized.dir}/${signed.apk}
                ${final.apk}"/>
            </exec>
        </target>
    
    </project>
    
    1. 必须在Java构建器之后和Android包构建器之前将此ANT任务添加到Eclipse的构建器(属性/构建器)任务中。

    2. 按“全部构建”(最好关闭Eclipse菜单中的自动构建检查)

答案 1 :(得分:9)

Android构建过程首先将Java源文件(.java)编译为Java类文件(.class),然后将这些类文件转换为Dalvik代码(classes.dex),最后将此Dalvik代码打包到APK文件中。

ProGuard读取和写入Java类文件,因此必须在编译步骤和转换步骤之间插入此管道。它不会读取或写入Dalvik代码本身,因此它无法在APK文件上运行。

Android SDK documentation on ProGuard讨论了如何在Android-9的Ant构建中启用模糊处理步骤。简而言之,您必须在文件default.properties中添加一行“proguard.config = proguard.cfg”,然后运行“ant release”。

答案 2 :(得分:4)

注意:barmaley的回复来自2011年,似乎适用于Android SDK工具版本8或10。

我尝试使用Android SDK工具版本18.1.1修改此解决方案,但仍然未能解决错误:
taskdef class com.android.ant.SetupTask cannot be found

最终,我做的是:

rm build.xml
android update project -p .
  • 如果您的PATH中没有SDK工具,则需要使用Android工具的完整路径,例如在Windows上: C:\ Android \ sdk \ tools

这创建了一个新的build.xml,它符合当前的SDK Tools,并且似乎自动化了barmaley的回复中描述的许多手动工作。

之后我能够运行ant release,它负责构建和混淆结果.apk文件开箱即用。

为了通过ant自动进行模糊处理,您需要:

  1. Enable Proguard obfuscator(显然)
  2. 创建一个ant.properties文件并使用相应的key.store params填充(有关详细信息,请参阅this SO reply)。

答案 3 :(得分:2)

proGuard混淆过程需要.class文件,因此您无法在IDE构建(.java)之前或之后(.dex压缩)启动Ant。

看看这篇文章,其中解释了如何在全局Ant构建中添加proGuard步骤:

http://www.androidengineer.com/2010/07/optimizing-obfuscating-and-shrinking.html

如果您真的想使用IDEA版本,可以尝试以下操作。

  • 在IDEA构建之后用apktool解压缩apk。
  • 使用dex2jar
  • 将.dex文件转换为.class
  • 按照上一篇文章的说明运行proGuard

很抱歉,我没有附上apktool和dexjar的链接,但由于我是新手,我不能发布多个超链接。