如何在Eclipse中使用Proguard对Android库(.jar文件)进行模糊处理

时间:2011-11-11 02:23:26

标签: android eclipse jar obfuscation proguard

我见过很多关于如何在Eclipse中使用ProGuard来混淆Android应用程序(.apk文件)的帖子。另请参阅http://developer.android.com/guide/developing/tools/proguard.html

“当您在发布模式下构建应用程序时,无论是通过运行ant发布还是使用Eclipse中的导出向导,构建系统都会自动检查是否设置了proguard.config属性。如果是,ProGuard会自动处理应用程序的字节码,然后将所有内容打包成 .apk文件。“

但是如果使用Eclipse Export Wizard在.jar文件中导出Android项目,请按照上述步骤(创建文件proguard.cfg,在文件default.properties中将proguard.config属性配置为proguard.cfg),使用导出向导等)似乎不起作用 - 我在生成的jar文件中看不到类名等的混淆。我的proguard.cfg文件中也有以下设置,但是我在项目目录或proguard目录中看不到任何输出文件(甚至没有创建该目录)。

-dump class_files.txt 
-printseeds seeds.txt 
-printusage unused.txt 
-printmapping mapping.txt

我甚至在项目目录中使用以下行创建了一个文件project.properties,但这似乎并没有引起ProGuard的采取行动:

proguard.config=proguard.cfg

此项目中未定义任何活动。我在Windows上使用Android 2.3.1和Eclipse Galileo 3.5.2。与Android 3.0相同的结果。似乎混淆步骤必须以某种方式在Eclipse导出向导中明确插入。我将不胜感激任何帮助或见解。谢谢。

5 个答案:

答案 0 :(得分:18)

正如上述答案之一的评论中所建议的那样(但我最初没有注意到,因为它被埋在其中一个“附加评论”中)......

我们只是在我们的proguard.cfg文件中使用下面第二个块中的参数在命令行上运行progruard(查看下面的第一个块)肯定使用-dontpreverify,或者由于您的project.jar中的StackMapTable问题,使用您的项目作为android库的项目将无法正确混淆。

命令行:

$ java -jar $ANDROID_SDK/tools/proguard/lib/proguard.jar \
  -libraryjars $ANDROID_SDK/platforms/android-18/android.jar @proguard.cfg
  -outjars /tmp/project.jar -verbose

proguard.cfg:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontwarn our.company.project.R*
-injars bin/project.jar
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep class org.apache.3rdparty.stuff.**
-keep public class our.company.project.ProjectAPI
-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

-keepclassmembers public class our.company.project.ProjectAPI {
    public static <fields>;
}

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
    public void *(android.view.View);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}

可能不是所有参数和-keep项都是严格必要的(除了不使用前面提到的-dontpreverify),但是大多数这些对我来说都是有意义的,如果你有需要的那些项目您要导出的库中的Activity类扩展。

答案 1 :(得分:11)

我使用间接方式生成导出的android混淆jar,我的方法是:

  1. 导出已签名的apk使用eclipse

  2. 解压缩apk,找到classes.dex

  3. 使用dex2jar.bat,将classes.dex更改为jar

  4. 解压缩jar并删除你不需要的类,然后压缩它 将文件名更改为XXX.jar

  5. 然后你在其他项目中使用这个jar,或者把它交给客户吧 是混淆的!

  6. 我相信这会对你有所帮助!享受吧!

答案 2 :(得分:7)

java -jar proguard.jar @yourconfig.pro

yourconfig.pro(从http://proguard.sourceforge.net/index.html#manual/examples.html扩展而来):

-injars yourjar.jar
-outjars yourjar_out.jar

-libraryjars 'C:\android\sdk\platforms\android-10\android.jar'

-printmapping mapping.txt
-verbose
-dontoptimize
-dontpreverify
-dontshrink
-dontskipnonpubliclibraryclassmembers
-dontusemixedcaseclassnames
-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-keep public class * {
    public protected *;
}

-keepclassmembernames class * {
    java.lang.Class class$(java.lang.String);
    java.lang.Class class$(java.lang.String, boolean);
}

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-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();
}

可以使用jd-gui

验证结果

答案 3 :(得分:2)

调用ProGuard的方法非常简单:

  1. 将行proguard.config=proguard.cfg添加到project.properties
  2. 导出应用程序包
  3. 默认的proguard.cfg文件应该由新项目向导自动创建。

答案 4 :(得分:2)

不要混淆纯Java Jar。在生成Jar时完全跳过该阶段(无论是在Eclipse中手动还是从命令行通过Ant构建)。

相反,在客户端项目中设置并执行正确的模糊处理,使用Jar,将库添加为外部Jar。 Proguard也能够在Jar中混淆代码。

我偶然发现了这个问题,并按照我在此描述的那样成功结束了。