先说点题外的,前一秒我心想干点什么呢,想到写篇博文吧,最近写的频率有点低了。另外标题有点长了。
进正文。
前些日子几次遇到ProGuard的问题,想偷个懒,没好好RTFM,后来通读了一下ProGuard的Manual,有点收获,总结一下。
主要是读了Usage部分,http://proguard.sourceforge.net/#manual/usage.html
命令:java -jar proguard.jar options ... 或 java -jar proguard.jar @myconfig.pro(myconfig.pro是配置文件)。Android提供的ant脚本把这个包含了进去,ADT也相应做了处理,所以基本不会直接用到这个。proguard包含在android sdk的tools目录下。
options或者配置文件设定了proguard的参数,分为Input/Output Options,Input/Output Options,Shrinking Options,Optimization Options,Obfuscation Options,Preverification Options,General Options 这些可选的参数。
从配置选项中其实可以看出,proguard有几部分的功能,Shrinking,Optimization,Obfuscation,Preverification。
1. Shrinking
就是缩减代码,他的工作是把代码中没被引用或者依赖的类、类成员删掉。可以通过Keep参数来设定保存。我之前就遇到这么一个问题,这里简称为“寻找getSomething游戏”(这个问题几乎会贯穿全文),我写了这么一段代码,大意如下:
public class JavascriptInterface {
void getSomething(String something) {}
}
webview.addJavascriptObject(new JavascriptInterface(), "jsi");
webview.loadUrl("javascript:window.jsi.getSomething("hello")");
就是通过js给java传个值。然后打包运行正常,再然后使用proguard处理打包,结果不正常,提示大意为object没有getSomething方法。
出了什么问题呢,因为android的proguard默认配置是开启Shrinking的,所以结果是getSomething(String)方法被删掉了,我通过反编译打出来的apk包也证实了这一点。
解决方法是,在配置文件中加入keep
-keep public class yourpackagename.JavascriptInterface
对于keep有几个类似的选项,下面的表格抄自:http://proguard.sourceforge.net/#manual/usage.html
我就不解释了。
2. Optimization
代码优化,说是bytecode层级的优化,具体怎么优化的我就不知道,而且Android默认配置也没开起这个。
3. Obfuscation
这个就是传说中的混淆了,可以通过-dontobfuscate关闭(关闭为什么还用proguard呢?)什么是混淆呢,就是把类和类成员 (包括变量和函数)的名字替换成相应的随机字符,大大增加别人解包破解你代码的难度。混淆过程生成mapping文件,记录每个类和成员被替换称什么随机字符了,也可以自己提供一些生成随机字符的规则,这里提供了很多选项,很有意思。
前面说道“寻找getSomething游戏”的例子,其实象刚才那样做并没有搞定这个问题,这里一个重要的概念是,单写一行keep并不能让proguard不做成员变量的混淆处理,而只是不被删掉。所以getSomething作为一个类成员方法依然会被混淆,变成了一个随机字符,比如a,那么这句代码:webview.loadUrl("javascript:window.jsi.getSomething("hello")"); 显然不再能正常使用了,因为它已经找不到getSomething了。
过程中我反复解包,由于认为keep就可以防止混淆,觉得无解,因我解包发现每次getSomething都变成了a,所以进行了一种很狗屎的方法的尝试,将webview.loadUrl("javascript:window.jsi.getSomething("hello")");换成webview.loadUrl("javascript:window.jsi.a("hello")");,把getSomething直接写成了a。。。但是由于我的实际JavascriptInterface类里面还有一些别的东西,有些东西也会被混淆成a,所以居然连狗屎运都没有。
后来我发现-useuniqueclassmembernames这个参数,顾名思义,可以让类成员使用唯一的名字,于是我给getSomething改成了后来混淆后的唯一的名字,终于在寻找getSomething的游戏中,找到了它,虽然它已经不叫getSomething了。。。
还是觉得这个方法太屎了,胜之不武。
关于keep有个复杂的语法,下面依然抄自ProGuard文档。
[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
[extends|implements [@annotationtype] classname]
[{
[@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> |
(fieldtype fieldname);
[@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> |
<init>(argumenttype,...) |
classname(argumenttype,...) |
(returntype methodname(argumenttype,...));
[@annotationtype] [[!]public|private|protected|static ... ] *;
...
}]
。。。
我之前看了这段就跳过了。后来耐心看下还是很容易看懂的,而且这个部分后面有个说明。
这些符号其实很常见了,“|” 表示或关系,“!”表示非,“[]”表示可选,“...”代表等等,黑色的部分是关键字。
之前-keep public class yourpackagename.JavascriptInterface 这样写,注意语法有个花括号,里面是用来说明成员变量是否keep的,可以写一个范围,比如写<fields>就是所有字段不被混淆,<methods>就是所有方法不被混淆,*就是所有都不被混淆。还可以单独指出哪个函数不被混淆,比如对于“寻找getSomething游戏”,可以这样写:
-keep public class yourpackagename.JavascriptInterface {
void getSomething(java.lang.String)
}
这样,getSomething函数就不会被混淆了。这里一个值得注意的问题是,所有类都要写全称,就是包名.类名,String要写成java.lang.String,我最开始就只写了String,结果是还别混淆了,郁闷了很久。
好了,“寻找getSomething游戏”完胜了。。。它再也不会找不到getSomething了。
4. Preverification
预验证,在载入类之前的验证,《Android前向兼容的几个问题》里面说的大概是这个,Android的ProGuard配置也没有开启这个,我也不是很清楚,就不说了。
还有很多选项,不在赘述,还是RTFM吧!
分享到:
相关推荐
### Android 4.0 及以上版本 ...通过上述步骤,可以有效地解决在 Android 4.0 及以上版本中遇到的 ProGuard 代码混淆问题,无论是对于简单的项目还是那些使用了复杂第三方库的应用程序,都能提供有效的指导和支持。
本实例使用的是把web项目中的源码(src)所有文件打包成jar文件,使用proguard混淆后再把jar文件以及jar解压后的混淆class类文件替换原war项目的相应位置即可。 混淆过程中需要使用keep参数来保持原有一些属性、注解...
ProGuard是Android和Java平台上的一个强大的开源工具,它能实现代码混淆、优化、压缩以及预校验等功能。本文将深入探讨ProGuard的工作原理、配置与应用。 ### 1. ProGuard概述 ProGuard是一款免费的Java字节码混淆...
使用 proguard 混淆代码只能增加阅读和理解的难度, 并不能百分百保证代码安全。常用的应用场景是项目需要部署到客户机器上,一定程度上防止代码泄露。 springboot多maven工程结构:proguard-root 是顶级父工程,...
为了对抗这种威胁,开发者通常会采用代码混淆技术,其中ProGuard是Android官方推荐的混淆工具。本教程将深入探讨如何使用ProGuard来混淆Android项目代码,以防止反编译。 一、ProGuard介绍 ProGuard是一款免费的...
基于springboot搭建一个简单案例,利用proguard插件实现代码混淆,增加源代码的阅读和理解的难度, 并不能百分百保证代码安全。常用的应用场景是项目需要部署到客户机器上,一定程度上防止代码泄露。 ProGuard 是一个...
Java代码混淆器ProGuard是Java开发中用于保护和优化应用程序的重要工具。它的主要功能是对Java字节码进行混淆,使得代码难以被逆向工程解析,从而提高代码的安全性。混淆过程中,函数变量、类和方法名会被重命名为...
**ProGuard:安全与效率的守护...总之,ProGuard作为Java和Android开发中的重要工具,其强大的混淆、优化和压缩功能为我们的代码提供了多层防护。正确理解和使用ProGuard,可以帮助我们打造出既安全又高效的软件产品。
7. 错误处理:如果在混淆过程中遇到问题,ProGuard会给出错误提示。通常问题由缺少关联类导致,此时需要在图形界面的“Libraryjars”选项中添加缺少的支持库。 8. 反编译检查:混淆完成后,可以使用反编译工具如...
ProGuard的配置文件(通常是`proguard.cfg`或`proguard-project.txt`)允许开发者指定保留哪些类、方法和字段不被混淆,这对于保持应用程序的可维护性和避免混淆引发的问题至关重要。例如,保留关键的库接口、公共...
本文将深入探讨如何在Maven管理的Java Web项目中集成ProGuard工具来实现代码混淆功能,以及在过程中可能遇到的问题及解决方案。 首先,让我们了解什么是ProGuard。ProGuard是一个开源的Java字节码混淆器、优化器和...
android proguard5.3.3混淆包 替换Jar包以后使 混淆的类名方法名变成空白 使用方法 直接 替换 5.3.3版本的 混淆jar包 Mac 路径为 Contents/gradle/m2repository/net/sf/proguard/proguard-base Win gradle/m2...
在Android应用开发中,安全性和性能优化是至关重要的环节,其中混淆(Proguard)就是一种常用的工具,用于保护代码安全并减小程序体积。本篇将详细介绍Android混淆以及各个版本的Proguard文件,帮助开发者理解其工作...
在Android开发中,代码安全和优化是至关重要的环节,而ProGuard 4.6正是这样一个工具,专为Java代码提供混淆、优化、压缩和预检查等功能。它能有效地保护你的应用程序源代码,避免恶意用户反编译,同时减小程序包...
ProGuard的配置文件通常命名为`proguard.cfg`,在该文件中,我们可以定义混淆规则,比如保留特定包或类不被混淆,以及设置混淆策略等。 1. **ProGuard配置** 在`proguard.cfg`文件中,我们需要指定哪些类和包需要...
在Java中,混淆主要通过改变类名、方法名和变量名,以及重排代码结构来实现。ProGuard的界面混淆版提供了友好的图形用户界面,使得这个过程对非技术背景的开发者也变得更为易行。 **功能特性** 1. **混淆**:...
ProGuard 是一款强大的开源代码混淆、优化和预校验工具,适用于Java和Android开发。在标题中提到的"proguard4.4混淆器"指的是ProGuard的一个特定版本,即4.4版。这个版本主要针对J2ME(Java 2 Micro Edition)和...
ProGuard能够对Java类中的代码进行压缩(Shrink),优化(Optimize),混淆(Obfuscate),预检(Preveirfy)。 1. 压缩(Shrink):在压缩处理这一步中,用于检测和删除没有使用的类,字段,方法和属性。 2. 优化...
虽然ProGuard能够显著提升应用的安全性和性能,但混淆过程中可能会遇到一些问题,比如依赖关系丢失、混淆规则设置不当导致运行错误等。因此,在实际使用中,开发者需要充分测试混淆后的代码,确保其正常工作。 9. ...