公司最近开发了一个SDK供第三方调用,如果只是单纯的把代码导出来弄成一个jar包没有混淆的话代码就赤裸的暴露了出来,毕竟是公司项目,要本着为公司保密,为公司着想的态度。。。嗯,就是这样(其实是别人指出来的。。)我去网上看了很多资料,然后自己再做了一些整理,以便下次自己要混淆的时候不用傻逼呵呵的再去到处乱找。。
1、把工程的.class文件导出到指定的目录下:(以ecplise为例)
1)右击工程,选择Export然后选择java下的jar file
然后next选择自己要导出的工程的.class文件,记住,就只有.class文件,其他的文件统统的不要
这样,一个原始的jar包就已经出来了,然后接下来就要进行非常关键的混淆jar包了
2、混淆jar包的话当然需要一个混淆的工具了,我用的是proguard,这个东西是编译器自带的,放在ecplise安装目录下的sdk,里面的tools文件下的proguard,proguard文件下有一个bin目录,目录里面有一个proguardgui.bat文件,找到没有?没有找到再来一遍,找到的就可以愉快的点击了。要是实在找不到的我这里有链接,你可以点击下载。。。,双击后的界面如下:
3、选择Input/Output按钮,然后在那个界面的上半部分选择add input按钮导入自己要混淆的jar包,然后点击add output按钮选择混淆后新生成的jar包位置,接下来在选择第三方jar包的时候非常关键!你要是少导了一个jar包,都会让你的工程出现一些奇怪的问题,就是一些警告啊,警告啊还是警告啊,然后不成功。所以这一步很关键,一定要把工程中遇到的什么jar包都要导进去比如我的工程中用到四个jar包,所以要都导入到那个红色方框里面。然后自带的有一个rt.jar文件要记得删掉
我的工程用到的jar包:
导入成功的后:
4、接下来就是一些混淆工作了然后按照下面设置即可全部混淆代码:
shrinking配置:
obfuscation配置:
optimization配置:
infomation配置(target是可以选择的,我选择的是1.6)
然后就是progress的输出了,如果你下一次觉得再配置麻烦的话记得点击save configuration按钮进行保存,然后保存的格式是.pro,
然后就可以点击progress按钮进行混淆了~如果没有什么警告或者提示错误的话就说明你的配置是没有错误的,如果有什么错误的话可以在网上谷歌一下错误,然后自行进行修改,混洗成功的话界面如下:
因为我是完全混淆的,就是全部的东西都给混淆了,混淆后用解压文件打开看的话都是一些a b c字母啥的。
但是一般jar包的话都是要给外部提供一些接口,或者类什么的,所以还需要keep一些类或者方法,不要全部都给混淆了,上一些步骤中有保存配置文件的话,现在就可以打开Test.pro文件进行编辑,然后手动进行修改部分配置,,也可以在Shrinking配置中点击add进行填写需要保存的类名或者方法:
我自己添加的部分如下:
-keep public class com.xygamesdk.GameSDK.IXYGameSDK
-keep public class com.xygamesdk.GameSDK.XYGameSDK
-keep public class com.xygamesdk.entity.**
就是保留一个对外的接口跟一些实体类。然后保存,继续progress后得到的结果如下:
然后就ok啦。。。,因为我的jar包涉及到webview跟js交互的问题,如果直接这样的话会出错,会提示window.XX.xxx is not function。。。就是无法识别,然后我百度了一下,说是会被混淆了,所以要keep住类跟javascriptinterface这个字段,反正就是加一keep配置进去,我加的配置如下
-keepclassmembers class com.xygamesdk.ui.PersonalWebJsActivity$PayOrder {
public *;
}
-keepattributes *Annotation*
-keepattributes *JavascriptInterface*
因为我那个类是内部类,如果不是内部类就不需要加$PayOrder这个了。
其他的说明配置
参数:
-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}
-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} 设置源文件中给定的字符串常量