ProGuard之——代码混淆

ProGuard之——代码混淆

2015年11月03日 21:39:40 阅读数:2756 标签: JavaProGuard 更多
个人分类: JAVA
所属专栏: Java
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l1028386804/article/details/49622317

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/49622317

1. 混淆器的选择

ProGuard


下载地址:http://proguard.sourceforge.net/index.html#downloads.html

2. 优化策略

因为公司项目都是 SSH 或者 SSJ 框架,涉及到非常多的配置文件,所以

a.  必须保留实现Action类中的公有的,友好的,私有的属性和公有的方法

b.  因为配置文件中的类名是一个完整的类名,如果经过处理后就有可能找不到这个类。

c.  类中的属性是jsp页面所需要的,如果经过处理jsp页面就无法得到action中的数据。

所以混淆器的配置需要根据 工程使用的技术、标准的编码规范以及pro配置编写人员对工程的深入理解,否则极易导致工程无法正常运行。

ProGuard混淆时运行proguard.jar,并读取配置文件 ***.pro

ProGuardUI 图形化界面不能完全满足需要,需要单独配置 pro文件,但通过图形界面配置可以很方便的查看配置内容。如图:


3. 命令

java -jar ProGuard4.8libproguard.jar @pathTrueCMS.pro

4. 为混淆器增加内存

使用 proguard进行混淆时,若项目比较大,经常会报 OutOfMemory错误,则需要增加混淆器的内存

java -Xms256m -Xmx512m -jar proguardgui.jarconfiguration.pro
注意:要在ProGuard目录的bin下运行这些命令

5.参数简介

参数

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

6.详细说明

A.     综述

这是一个不应该在开源社区出现的东西,但它的的确确是一个开源的项目,正像它的名字一样,Proguard,即Program Guard(程序卫士),它代表了开源的相对面--代码保护。

经过几天的摸索,终于对Proguard应用于实际项目有一些不成熟的见解。

上面提过,对于Web工程,公司都是用了SSH/SSJ框架,这类框架中所有action/service/dao/domain以及包结构都固定写死在对应的配置文件中,这使得Proguard发挥的空间仅限于 service/dao内的方法、各部分的通用工具方法及util工具类,Proguard灵活配置的优势便显现出来了。

B.    使用说明
1.在Eclipse中选中需要混淆的工程,右键Exprot->选择jar文件导出备用
2. 打开 proguard4.8lib 目录下的proguardgui.jar,在input/output 选项中增加输入文件,找到刚才导出的jar文件并确定,然后增加输出文件。

3.在  中增加工程lib文件夹下所有的jar包,以及java jre


4.Shrinking(压缩)中不设置任何配置 如图


  
5.Obfuscation如下图配置


其中 jss.txt 是我们提供给proguard 进行混淆的字符串,若为空,ProGuard会按小写英文字母a,b,c,d….顺序混淆。

6.Optimization如图配置


7.Information 如图配置


Target中选择当前jdk版本

8.在Process选项中选择, 将配置保存成 **.pro文件

9.打开pro文件


在配置后加入

  1. -keep class WebRoot.WEB-INFO.lib.* ---不混淆lib文件夹中所有jar
  2. -keep class * extends cn.com.trueway.platform.** {
  3. public <methods>;
  4. } #不混淆继承于platform的所有类
其他配置请根据实际情况进行添加
10.配置完成后在ProGuradUI中——>——>加载配置文件,——>

即开始混淆,混淆完的文件会根据配置文件输出到指定位置。
也可以使用命令行完成上述动作,且执行效率会有质的飞跃。
命令为: 

(java -Xms256m -Xmx512m –jar D:proguard4.8libproguard.jar@D: rm.pro)

7. 注意要点

A.在产品的开发过程中,应养成良好的代码习惯,将可重复利用的代码都封装成私有方法或工具类,便于代码维护及代码混淆的效果。
B.    工程比较大时,请使用命令行方式混淆,效率会提高10倍以上。
C.通配符:' ?“为任意单个字符,‘*’的任意数量的字符(不包扩分隔符),“**”为任意数量的字符,‘%’对于任何原始类型,“***”为任何类型,和“…“为任意数量的参数。
D.    虽然ProGuard声称支持war包,但遗憾的是混淆完的war包会丢失所有class,所以一定需要war包的情况下需要先对jar包混淆,再将jar包内的class替换到war包内,可正常运行,未出现异常。
E.配置文件中如下配置一定不能颠倒顺序,否则会无法生成outjar。
-injars 'D:akpgin m.jar'
-outjars 'D:akpgin mout.jar'
F.需要注意web.xml中配置的filter, listener等需要被skip掉。
G.ProGuardUI 可以看做是一个配置文件生成器,而不适合做混淆动作。
H.一个完整的配置例子:

*************************************************************************************************************************************************************************************

  1. -injars 'D:akpgin m.jar'
  2. -outjars 'D:akpgin mout.jar'
  3. -libraryjars 'D:eclipse_v34jdkjdk1.5.0_11jrelib t.jar'
  4. -libraryjars 'D:workspace mWebRootWEB-INFlibFastInfoset-1.2.7.jar'
  5. -libraryjars 'D:workspace mWebRootWEB-INFlibXmlSchema-1.4.5.jar'
  6. -libraryjars 'D:workspace mWebRootWEB-INFlibabdera-core-0.4.0-incubating.jar'
  7. -libraryjars 'D:workspace mWebRootWEB-INFlibabdera-extensions-json-0.4.0-incubating.jar'
  8. -libraryjars 'D:workspace mWebRootWEB-INFlibabdera-extensions-main-0.4.0-incubating.jar'
  9. -libraryjars 'D:workspace mWebRootWEB-INFlibabdera-i18n-0.4.0-incubating.jar'
  10. -libraryjars 'D:workspace mWebRootWEB-INFlibabdera-parser-0.4.0-incubating.jar'
  11. -libraryjars 'D:workspace mWebRootWEB-INFlibactivation.jar'
  12. -libraryjars 'D:workspace mWebRootWEB-INFlibant-1.6.5.jar'
  13. -libraryjars 'D:workspace mWebRootWEB-INFlibantlr-2.7.7.jar'
  14. -libraryjars 'D:workspace mWebRootWEB-INFlibaopalliance-1.0.jar'
  15. -libraryjars 'D:workspace mWebRootWEB-INFlibasm-2.2.3.jar'
  16. -libraryjars 'D:workspace mWebRootWEB-INFlibaspectjrt.jar'
  17. -libraryjars 'D:workspace mWebRootWEB-INFlibaspectjweaver.jar'
  18. -libraryjars 'D:workspace mWebRootWEB-INFlibaspriseTIFF.jar'
  19. -libraryjars 'D:workspace mWebRootWEB-INFlibaxiom-api-1.2.7.jar'
  20. -libraryjars 'D:workspace mWebRootWEB-INFlibaxiom-impl-1.2.7.jar'
  21. -libraryjars 'D:workspace mWebRootWEB-INFlibaseframework.jar'
  22. -libraryjars 'D:workspace mWebRootWEB-INFlibcprov-jdk15-1.43.jar'
  23. .
  24. .
  25. .
  26. -dontskipnonpubliclibraryclassmembers
  27. -target 1.5
  28. -dontshrink
  29. -dontoptimize
  30. -useuniqueclassmembernames
  31. -keeppackagenames
  32. -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
  33. -keepparameternames
  34. -dontpreverify
  35. -dontwarn
  36. -ignorewarnings
  37. -keep class WebRoot.WEB-INFO.lib.*
  38. -keep class * extends cn.com.trueway.platform.** {
  39. public <methods>;
  40. }
  41. -keep class * extends org.springframework.orm.hibernate3.support.HibernateDaoSupport {
  42. public <methods>;
  43. }
  44. -keep class **.model.** {
  45. public private protected <fields>;
  46. public <methods>;
  47. }
  48. -keep class cn.com.trueway.resourceAllocation.application.domain.* {
  49. public private protected <fields>;
  50. public <methods>;
  51. }
  52. -keep class **.service.impl.* {
  53. public <methods>;
  54. }
  55. -keep class cn.com.trueway.platform.** {
  56. public private protected <fields>;
  57. public <methods>;
  58. }
  59. -keep class cn.com.trueway.resourceInterface.service.** {
  60. public private protected <fields>;
  61. public <methods>;
  62. }
  63. -keep class **.po.* {
  64. public private protected <fields>;
  65. public <methods>;
  66. }
  67. -keep class cn.com.trueway.sso.* {
  68. public private protected <fields>;
  69. public <methods>;
  70. }
  71. -keep class cn.com.trueway.startup.AdminFilter {
  72. public private protected <fields>;
  73. public <methods>;
  74. }
  75. # Keep names - Native method names. Keep all native class/method names.
  76. -keepclasseswithmembers,allowshrinking class * {
  77. native <methods>;
  78. }
  79. # Keep names - _class method names. Keep all .class method names. This may be
  80. # useful for libraries that will be obfuscated again with different obfuscators.
  81. -keepclassmembers,allowshrinking class * {
  82. java.lang.Class class$(java.lang.String);
  83. java.lang.Class class$(java.lang.String,boolean);
  84. }
  85. # Remove - System method calls. Remove all invocations of System
  86. # methods without side effects whose return values are not used.
  87. -assumenosideeffects public class java.lang.System {
  88. public static long currentTimeMillis();
  89. static java.lang.Class getCallerClass();
  90. public static int identityHashCode(java.lang.Object);
  91. public static java.lang.SecurityManager getSecurityManager();
  92. public static java.util.Properties getProperties();
  93. public static java.lang.String getProperty(java.lang.String);
  94. public static java.lang.String getenv(java.lang.String);
  95. public static java.lang.String mapLibraryName(java.lang.String);
  96. public static java.lang.String getProperty(java.lang.String,java.lang.String);
  97. }
  98. # Remove - Math method calls. Remove all invocations of Math
  99. # methods without side effects whose return values are not used.
  100. -assumenosideeffects public class java.lang.Math {
  101. public static double sin(double);
  102. public static double cos(double);
  103. public static double tan(double);
  104. public static double asin(double);
  105. public static double acos(double);
  106. public static double atan(double);
  107. public static double toRadians(double);
  108. public static double toDegrees(double);
  109. public static double exp(double);
  110. public static double log(double);
  111. public static double log10(double);
  112. public static double sqrt(double);
  113. public static double cbrt(double);
  114. public static double IEEEremainder(double,double);
  115. public static double ceil(double);
  116. public static double floor(double);
  117. public static double rint(double);
  118. public static double atan2(double,double);
  119. public static double pow(double,double);
  120. public static int round(float);
  121. public static long round(double);
  122. public static double random();
  123. public static int abs(int);
  124. public static long abs(long);
  125. public static float abs(float);
  126. public static double abs(double);
  127. public static int max(int,int);
  128. public static long max(long,long);
  129. public static float max(float,float);
  130. public static double max(double,double);
  131. public static int min(int,int);
  132. public static long min(long,long);
  133. public static float min(float,float);
  134. public static double min(double,double);
  135. public static double ulp(double);
  136. public static float ulp(float);
  137. public static double signum(double);
  138. public static float signum(float);
  139. public static double sinh(double);
  140. public static double cosh(double);
  141. public static double tanh(double);
  142. public static double hypot(double,double);
  143. public static double expm1(double);
  144. public static double log1p(double);
  145. }
  146. # Remove - Number method calls. Remove all invocations of Number
  147. # methods without side effects whose return values are not used.
  148. -assumenosideeffects public class java.lang.* extends java.lang.Number {
  149. public static java.lang.String toString(byte);
  150. public static java.lang.Byte valueOf(byte);
  151. public static byte parseByte(java.lang.String);
  152. public static byte parseByte(java.lang.String,int);
  153. public static java.lang.Byte valueOf(java.lang.String,int);
  154. public static java.lang.Byte valueOf(java.lang.String);
  155. public static java.lang.Byte decode(java.lang.String);
  156. public int compareTo(java.lang.Byte);
  157. public static java.lang.String toString(short);
  158. public static short parseShort(java.lang.String);
  159. public static short parseShort(java.lang.String,int);
  160. public static java.lang.Short valueOf(java.lang.String,int);
  161. public static java.lang.Short valueOf(java.lang.String);
  162. public static java.lang.Short valueOf(short);
  163. public static java.lang.Short decode(java.lang.String);
  164. public static short reverseBytes(short);
  165. public int compareTo(java.lang.Short);
  166. public static java.lang.String toString(int,int);
  167. public static java.lang.String toHexString(int);
  168. public static java.lang.String toOctalString(int);
  169. public static java.lang.String toBinaryString(int);
  170. public static java.lang.String toString(int);
  171. public static int parseInt(java.lang.String,int);
  172. public static int parseInt(java.lang.String);
  173. public static java.lang.Integer valueOf(java.lang.String,int);
  174. public static java.lang.Integer valueOf(java.lang.String);
  175. public static java.lang.Integer valueOf(int);
  176. public static java.lang.Integer getInteger(java.lang.String);
  177. public static java.lang.Integer getInteger(java.lang.String,int);
  178. public static java.lang.Integer getInteger(java.lang.String,java.lang.Integer);
  179. public static java.lang.Integer decode(java.lang.String);
  180. public static int highestOneBit(int);
  181. public static int lowestOneBit(int);
  182. public static int numberOfLeadingZeros(int);
  183. public static int numberOfTrailingZeros(int);
  184. public static int bitCount(int);
  185. public static int rotateLeft(int,int);
  186. public static int rotateRight(int,int);
  187. public static int reverse(int);
  188. public static int signum(int);
  189. public static int reverseBytes(int);
  190. public int compareTo(java.lang.Integer);
  191. public static java.lang.String toString(long,int);
  192. public static java.lang.String toHexString(long);
  193. public static java.lang.String toOctalString(long);
  194. public static java.lang.String toBinaryString(long);
  195. public static java.lang.String toString(long);
  196. public static long parseLong(java.lang.String,int);
  197. public static long parseLong(java.lang.String);
  198. public static java.lang.Long valueOf(java.lang.String,int);
  199. public static java.lang.Long valueOf(java.lang.String);
  200. public static java.lang.Long valueOf(long);
  201. public static java.lang.Long decode(java.lang.String);
  202. public static java.lang.Long getLong(java.lang.String);
  203. public static java.lang.Long getLong(java.lang.String,long);
  204. public static java.lang.Long getLong(java.lang.String,java.lang.Long);
  205. public static long highestOneBit(long);
  206. public static long lowestOneBit(long);
  207. public static int numberOfLeadingZeros(long);
  208. public static int numberOfTrailingZeros(long);
  209. public static int bitCount(long);
  210. public static long rotateLeft(long,int);
  211. public static long rotateRight(long,int);
  212. public static long reverse(long);
  213. public static int signum(long);
  214. public static long reverseBytes(long);
  215. public int compareTo(java.lang.Long);
  216. public static java.lang.String toString(float);
  217. public static java.lang.String toHexString(float);
  218. public static java.lang.Float valueOf(java.lang.String);
  219. public static java.lang.Float valueOf(float);
  220. public static float parseFloat(java.lang.String);
  221. public static boolean isNaN(float);
  222. public static boolean isInfinite(float);
  223. public static int floatToIntBits(float);
  224. public static int floatToRawIntBits(float);
  225. public static float intBitsToFloat(int);
  226. public static int compare(float,float);
  227. public boolean isNaN();
  228. public boolean isInfinite();
  229. public int compareTo(java.lang.Float);
  230. public static java.lang.String toString(double);
  231. public static java.lang.String toHexString(double);
  232. public static java.lang.Double valueOf(java.lang.String);
  233. public static java.lang.Double valueOf(double);
  234. public static double parseDouble(java.lang.String);
  235. public static boolean isNaN(double);
  236. public static boolean isInfinite(double);
  237. public static long doubleToLongBits(double);
  238. public static long doubleToRawLongBits(double);
  239. public static double longBitsToDouble(long);
  240. public static int compare(double,double);
  241. public boolean isNaN();
  242. public boolean isInfinite();
  243. public int compareTo(java.lang.Double);
  244. public <init>(byte);
  245. public <init>(short);
  246. public <init>(int);
  247. public <init>(long);
  248. public <init>(float);
  249. public <init>(double);
  250. public <init>(java.lang.String);
  251. public byte byteValue();
  252. public short shortValue();
  253. public int intValue();
  254. public long longValue();
  255. public float floatValue();
  256. public double doubleValue();
  257. public int compareTo(java.lang.Object);
  258. public boolean equals(java.lang.Object);
  259. public int hashCode();
  260. public java.lang.String toString();
  261. }
  262. # Remove - String method calls. Remove all invocations of String
  263. # methods without side effects whose return values are not used.
  264. -assumenosideeffects public class java.lang.String {
  265. public <init>();
  266. public <init>(byte[]);
  267. public <init>(byte[],int);
  268. public <init>(byte[],int,int);
  269. public <init>(byte[],int,int,int);
  270. public <init>(byte[],int,int,java.lang.String);
  271. public <init>(byte[],java.lang.String);
  272. public <init>(char[]);
  273. public <init>(char[],int,int);
  274. public <init>(java.lang.String);
  275. public <init>(java.lang.StringBuffer);
  276. public static java.lang.String copyValueOf(char[]);
  277. public static java.lang.String copyValueOf(char[],int,int);
  278. public static java.lang.String valueOf(boolean);
  279. public static java.lang.String valueOf(char);
  280. public static java.lang.String valueOf(char[]);
  281. public static java.lang.String valueOf(char[],int,int);
  282. public static java.lang.String valueOf(double);
  283. public static java.lang.String valueOf(float);
  284. public static java.lang.String valueOf(int);
  285. public static java.lang.String valueOf(java.lang.Object);
  286. public static java.lang.String valueOf(long);
  287. public boolean contentEquals(java.lang.StringBuffer);
  288. public boolean endsWith(java.lang.String);
  289. public boolean equalsIgnoreCase(java.lang.String);
  290. public boolean equals(java.lang.Object);
  291. public boolean matches(java.lang.String);
  292. public boolean regionMatches(boolean,int,java.lang.String,int,int);
  293. public boolean regionMatches(int,java.lang.String,int,int);
  294. public boolean startsWith(java.lang.String);
  295. public boolean startsWith(java.lang.String,int);
  296. public byte[] getBytes();
  297. public byte[] getBytes(java.lang.String);
  298. public char charAt(int);
  299. public char[] toCharArray();
  300. public int compareToIgnoreCase(java.lang.String);
  301. public int compareTo(java.lang.Object);
  302. public int compareTo(java.lang.String);
  303. public int hashCode();
  304. public int indexOf(int);
  305. public int indexOf(int,int);
  306. public int indexOf(java.lang.String);
  307. public int indexOf(java.lang.String,int);
  308. public int lastIndexOf(int);
  309. public int lastIndexOf(int,int);
  310. public int lastIndexOf(java.lang.String);
  311. public int lastIndexOf(java.lang.String,int);
  312. public int length();
  313. public java.lang.CharSequence subSequence(int,int);
  314. public java.lang.String concat(java.lang.String);
  315. public java.lang.String replaceAll(java.lang.String,java.lang.String);
  316. public java.lang.String replace(char,char);
  317. public java.lang.String replaceFirst(java.lang.String,java.lang.String);
  318. public java.lang.String[] split(java.lang.String);
  319. public java.lang.String[] split(java.lang.String,int);
  320. public java.lang.String substring(int);
  321. public java.lang.String substring(int,int);
  322. public java.lang.String toLowerCase();
  323. public java.lang.String toLowerCase(java.util.Locale);
  324. public java.lang.String toString();
  325. public java.lang.String toUpperCase();
  326. public java.lang.String toUpperCase(java.util.Locale);
  327. public java.lang.String trim();
  328. }
  329. # Remove - StringBuffer method calls. Remove all invocations of StringBuffer
  330. # methods without side effects whose return values are not used.
  331. -assumenosideeffects public class java.lang.StringBuffer {
  332. public <init>();
  333. public <init>(int);
  334. public <init>(java.lang.String);
  335. public <init>(java.lang.CharSequence);
  336. public java.lang.String toString();
  337. public char charAt(int);
  338. public int capacity();
  339. public int codePointAt(int);
  340. public int codePointBefore(int);
  341. public int indexOf(java.lang.String,int);
  342. public int lastIndexOf(java.lang.String);
  343. public int lastIndexOf(java.lang.String,int);
  344. public int length();
  345. public java.lang.String substring(int);
  346. public java.lang.String substring(int,int);
  347. }
  348. # Remove - StringBuilder method calls. Remove all invocations of StringBuilder
  349. # methods without side effects whose return values are not used.
  350. -assumenosideeffects public class java.lang.StringBuilder {
  351. public <init>();
  352. public <init>(int);
  353. public <init>(java.lang.String);
  354. public <init>(java.lang.CharSequence);
  355. public java.lang.String toString();
  356. public char charAt(int);
  357. public int capacity();
  358. public int codePointAt(int);
  359. public int codePointBefore(int);
  360. public int indexOf(java.lang.String,int);
  361. public int lastIndexOf(java.lang.String);
  362. public int lastIndexOf(java.lang.String,int);
  363. public int length();
  364. public java.lang.String substring(int);
  365. public java.lang.String substring(int,int);
  366. }
原文地址:https://www.cnblogs.com/LiuYanYGZ/p/9661610.html