`
hunankeda110
  • 浏览: 746442 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

ProGuard总结和混淆Android代码中遇到的问题的解决方法以及寻找getSomething游戏

阅读更多

先说点题外的,前一秒我心想干点什么呢,想到写篇博文吧,最近写的频率有点低了。另外标题有点长了。

进正文。

前些日子几次遇到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

Keep
From being removed or renamed From being renamed
Classes and class members -keep -keepnames
Class members only -keepclassmembers -keepclassmembernames
Classes and class members, if class members present -keepclasseswithmembers -keepclasseswithmembernames

我就不解释了。

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吧!

分享到:
评论
3 楼 messigoogle 2013-07-05  
如果只是用-keep public class yourpackagename.JavascriptInterface这个的话,依然提示为object没有getSomething方法。
2 楼 messigoogle 2013-07-05  
如果只是用-keep public class yourpackagename.JavascriptInterface这个的话,依然提示

1 楼 messigoogle 2013-07-05  
楼主,跟你一样的使用方法,但是, 不能使用呀,使用proguard打包的时候就开始报错,-keep public class yourpackagename.JavascriptInterface {
  void getSomething(java.lang.String)
}, 一直提示JavascriptInterface这里的错误,望指教

相关推荐

    Android 4.0及以上版本 ProGuard 代码混淆

    ### Android 4.0 及以上版本 ...通过上述步骤,可以有效地解决在 Android 4.0 及以上版本中遇到的 ProGuard 代码混淆问题,无论是对于简单的项目还是那些使用了复杂第三方库的应用程序,都能提供有效的指导和支持。

    通过proguard5.2.1代码混淆工具和简单说明

    本实例使用的是把web项目中的源码(src)所有文件打包成jar文件,使用proguard混淆后再把jar文件以及jar解压后的混淆class类文件替换原war项目的相应位置即可。 混淆过程中需要使用keep参数来保持原有一些属性、注解...

    ProGuard工具包,Java代码混淆

    ProGuard是Android和Java平台上的一个强大的开源工具,它能实现代码混淆、优化、压缩以及预校验等功能。本文将深入探讨ProGuard的工作原理、配置与应用。 ### 1. ProGuard概述 ProGuard是一款免费的Java字节码混淆...

    SpringBoot + proguard+maven多模块实现代码混淆

    使用 proguard 混淆代码只能增加阅读和理解的难度, 并不能百分百保证代码安全。常用的应用场景是项目需要部署到客户机器上,一定程度上防止代码泄露。 springboot多maven工程结构:proguard-root 是顶级父工程,...

    如何混淆Android项目代码(ProGuard)防止反编译.rar

    为了对抗这种威胁,开发者通常会采用代码混淆技术,其中ProGuard是Android官方推荐的混淆工具。本教程将深入探讨如何使用ProGuard来混淆Android项目代码,以防止反编译。 一、ProGuard介绍 ProGuard是一款免费的...

    springboot工程(单个maven工程)利用proguard实现代码混淆

    基于springboot搭建一个简单案例,利用proguard插件实现代码混淆,增加源代码的阅读和理解的难度, 并不能百分百保证代码安全。常用的应用场景是项目需要部署到客户机器上,一定程度上防止代码泄露。 ProGuard 是一个...

    java代码混淆器proGuard

    Java代码混淆器ProGuard是Java开发中用于保护和优化应用程序的重要工具。它的主要功能是对Java字节码进行混淆,使得代码难以被逆向工程解析,从而提高代码的安全性。混淆过程中,函数变量、类和方法名会被重命名为...

    proguard,代码混淆

    **ProGuard:安全与效率的守护...总之,ProGuard作为Java和Android开发中的重要工具,其强大的混淆、优化和压缩功能为我们的代码提供了多层防护。正确理解和使用ProGuard,可以帮助我们打造出既安全又高效的软件产品。

    Proguard混淆Android/Java源代码

    7. 错误处理:如果在混淆过程中遇到问题,ProGuard会给出错误提示。通常问题由缺少关联类导致,此时需要在图形界面的“Libraryjars”选项中添加缺少的支持库。 8. 反编译检查:混淆完成后,可以使用反编译工具如...

    java 代码混淆 proguard

    ProGuard的配置文件(通常是`proguard.cfg`或`proguard-project.txt`)允许开发者指定保留哪些类、方法和字段不被混淆,这对于保持应用程序的可维护性和避免混淆引发的问题至关重要。例如,保留关键的库接口、公共...

    实现maven管理的Javaweb项目的proguard代码混淆功能

    本文将深入探讨如何在Maven管理的Java Web项目中集成ProGuard工具来实现代码混淆功能,以及在过程中可能遇到的问题及解决方案。 首先,让我们了解什么是ProGuard。ProGuard是一个开源的Java字节码混淆器、优化器和...

    android proguard5.3.3混淆包

    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文件,帮助开发者理解其工作...

    proguard4.6 代码混淆器

    在Android开发中,代码安全和优化是至关重要的环节,而ProGuard 4.6正是这样一个工具,专为Java代码提供混淆、优化、压缩和预检查等功能。它能有效地保护你的应用程序源代码,避免恶意用户反编译,同时减小程序包...

    springboot工程(单个maven工程)利用proguard实现代码混淆 java demo案例

    ProGuard的配置文件通常命名为`proguard.cfg`,在该文件中,我们可以定义混淆规则,比如保留特定包或类不被混淆,以及设置混淆策略等。 1. **ProGuard配置** 在`proguard.cfg`文件中,我们需要指定哪些类和包需要...

    proguard界面混淆版

    在Java中,混淆主要通过改变类名、方法名和变量名,以及重排代码结构来实现。ProGuard的界面混淆版提供了友好的图形用户界面,使得这个过程对非技术背景的开发者也变得更为易行。 **功能特性** 1. **混淆**:...

    proguard4.4混淆器

    ProGuard 是一款强大的开源代码混淆、优化和预校验工具,适用于Java和Android开发。在标题中提到的"proguard4.4混淆器"指的是ProGuard的一个特定版本,即4.4版。这个版本主要针对J2ME(Java 2 Micro Edition)和...

    ProGuard-java混淆加密

    ProGuard能够对Java类中的代码进行压缩(Shrink),优化(Optimize),混淆(Obfuscate),预检(Preveirfy)。  1. 压缩(Shrink):在压缩处理这一步中,用于检测和删除没有使用的类,字段,方法和属性。  2. 优化...

    proguard程序混淆器

    虽然ProGuard能够显著提升应用的安全性和性能,但混淆过程中可能会遇到一些问题,比如依赖关系丢失、混淆规则设置不当导致运行错误等。因此,在实际使用中,开发者需要充分测试混淆后的代码,确保其正常工作。 9. ...

Global site tag (gtag.js) - Google Analytics