原创加借鉴:http://blog.csdn.net/qeqeqe236/article/details/7346069
一个xxx.apk提交给测试、
ok,去倒杯水,看看网页~~~~~
呃,忽然觉得 是不是应该 给我的代码 提高点安全性,
记得看过 apk直接可以 解压,然后很容易的就可以 反编译出 .java
找了找,果然,这一切 只不过是 一分钟的事儿,
1、得到 classes.dex文件;直接用你机器上的 解压软件 打开 .apk 文件
解压出 classes.dex 文件,(这个就是 .jar 的前生--- 其实应该说 后世)
2、还原.jar文件;这一步需要用到一个工具 dex2jar (谷歌的代码库里有http://code.google.com/p/dex2jar/)
看名字也不难知道他是干嘛的了吧?(没错,就是 把 dex 还原 成 jar包 )
下载完了,解压,然后把第一步的 产物(即那个classes.dex文件)放到 dex2jar的解压目录里
(解压目录里 有 dex2jar.bat 文件,检查一下,没有的话 说明目录不对、再 找找)
cmd 命令行 ,目录切换到 dex2jar的目录下(linux 系统的话 执行那个 .sh文件)
“ dex2jar.bat classes.dex”
看到命令行 的 “Done” 之后, dex2jar 文件夹里 就会有“classes.dex.dex2jar.jar” 文件了,
这个就是 传说中的 jar包了
2.3SDK的两个新特点:
1.刚安装上2.3时,查看sdk目录,发现在<SDK_PATH>\tools下新增了一文件夹“proguard”,如下图,我就在想是不是Google终于官方对proguard考虑进去了。理论上,对java的混淆都是可以的,但关键在于如何编写proguard的混淆脚本。
<wbr><img title="混淆Android代码" alt="proguard" src="http://hi.csdn.net/attachment/201012/13/7303_1292213341UA78.jpg" width="234" height="184" style="border-width:0px; margin:0px; padding:0px; list-style-type:none"></wbr>
2.使用SDK2.3后,新建的工程下和之前相比,都会多了一个文件“proguard.cfg”。一打开,相当惊喜,这就是混淆所需的proguard脚本啊。
如下图:
<wbr><img title="混淆Android代码" alt="proguard1" src="http://hi.csdn.net/attachment/201012/13/7303_129221334105We.jpg" width="221" height="291" style="border-width:0px; margin:0px; padding:0px; list-style-type:none"></wbr>
其代码如下:
view plaincopy to clipboardprint?
-optimizationpasses 5 <wbr><br> -dontusemixedcaseclassnam<wbr>es <wbr><wbr><br> -dontskipnonpubliclibrary<wbr>classes <wbr><wbr><br> -dontpreverify <wbr><wbr><br> -verbose <wbr><wbr><br> -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* <wbr><wbr><br> -keep public class * extends android.app.Activity <wbr><wbr><br> -keep public class * extends android.app.Application <wbr><wbr><br> -keep public class * extends android.app.Service <wbr><wbr><br> -keep public class * extends android.content.BroadcastReceiver <wbr><wbr><br> -keep public class * extends android.content.ContentProvider <wbr><wbr><br> -keep public class com.android.vending.licensing.ILicensingService <wbr><wbr><br> -keepclasseswithmembernam<wbr>es class * { <wbr><wbr><br><wbr><wbr><wbr>native <methods>; <wbr><wbr><br> } <wbr><wbr><br> -keepclasseswithmembernam<wbr>es class * { <wbr><wbr><br><wbr><wbr><wbr>public <init>(android.content.Context, android.util.AttributeSet);<wbr><wbr><br> } <wbr><wbr><br> -keepclasseswithmembernam<wbr>es class * { <wbr><wbr><br><wbr><wbr><wbr>public <init>(android.content.Context, android.util.AttributeSet, int);<wbr><wbr><br> } <wbr><wbr><br> -keepclassmembers enum * { <wbr><wbr><br><wbr><wbr><wbr>public static **[] values(); <wbr><wbr><br><wbr><wbr><wbr>public static ** valueOf(java.lang.String); <wbr><wbr><br> } <wbr><wbr><br> -keep class * implements android.os.Parcelable { <wbr><wbr><br><wbr>public static final android.os.Parcelable$Creator *; <wbr><wbr><br> } <wbr><br> -optimizationpasses 5<br> -dontusemixedcaseclassnam<wbr>es<br> -dontskipnonpubliclibrary<wbr>classes<br> -dontpreverify<br> -verbose<br> -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*<br> -keep public class * extends android.app.Activity<br> -keep public class * extends android.app.Application<br> -keep public class * extends android.app.Service<br> -keep public class * extends android.content.BroadcastReceiver<br> -keep public class * extends android.content.ContentProvider<br> -keep public class com.android.vending.licensing.ILicensingService<br> -keepclasseswithmembernam<wbr>es class * {<br><wbr><wbr><wbr>native <methods>;<br> }<br> -keepclasseswithmembernam<wbr>es class * {<br><wbr><wbr><wbr>public <init>(android.content.Context, android.util.AttributeSet);<br> }<br> -keepclasseswithmembernam<wbr>es class * {<br><wbr><wbr><wbr>public <init>(android.content.Context, android.util.AttributeSet, int);<br> }<br> -keepclassmembers enum * {<br><wbr><wbr><wbr>public static **[] values();<br><wbr><wbr><wbr>public static ** valueOf(java.lang.String);<br> }<br> -keep class * implements android.os.Parcelable {<br><wbr>public static final android.os.Parcelable$Creator *;<br> }</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
从脚本中可以看到,混淆中保留了继承自Activity、Service、Application、BroadcastReceiver、ContentProvider等基本组件。
并保留了所有的Native变量名及类名,所有类中部分以设定了固定参数格式的构造函数,枚举等等。(详细信息请参考<proguard_path>\examples中的例子及注释。)
好了,进行得差不多了,下面就来看看如何真正的生成混淆APK吧。这儿又得提醒一下,SDK新的特性在文档里都是有的,所以文档很重要。
查看SDK2.3的文档,在路径“<androidSDK_path>/docs/guide/developing/tools/proguard.html”的“Enabling ProGuard ”中是这样描述的:
To enable ProGuard so that it runs as part of an Ant or Eclipse build, set the proguard.config property in the <project_root>/default.properties file. The path can be an absolute path or a path relative to the project's root.
好的,那就这样做吧。
在工程的"default.properties"中添加这样一句话“proguard.config=proguard.cfg”,如下图:
<wbr><img title="混淆Android代码" name="image_operate_88551300950443140" alt="proguard3" src="http://hi.csdn.net/attachment/201012/13/7303_1292213344TVtX.jpg" width="479" height="301" style="border-width:0px; margin:0px; padding:0px; list-style-type:none"></wbr>
这样就已经设置好ADT的混淆操作了。接下来就是正常的打包和签名了。。
好了,再次生成 新的 .apk文件,
然后用上面的方法 反编译你的 项目,你会看到 aa bb cc 的包、aa bb cc 的类 和 aa bb cc 的变量名,方法名.
这个我相信你自己也搞的头昏了吧?
下图是我混淆SDK Demo中自带的Notepad效果图:
<wbr><img title="混淆Android代码" name="image_operate_39331300950451265" alt="proguard4" src="http://hi.csdn.net/attachment/201012/13/7303_1292214553xOrn.jpg" width="303" height="165" style="border-width:0px; margin:0px; padding:0px; list-style-type:none"></wbr>
注意要点: <wbr><br></wbr>1.混淆以后的包会比混淆前的包小一点,一定要注意这点.
如果混淆不成功,请在第2步,将proguard.config=proguard.cfg修改为proguard.config=E:\Mobile_Develop\Google_Android\publicGoldenBeach_new\proguard.cfg这种类似的用绝对路径,请注意绝对路径中的文件夹名不能含有空格,如果有空格请替换为"_".<wbr><br></wbr>
<wbr></wbr>
2.android在用proguard混淆时,一般情况下使用系统自带的配置文件就可以保持大部分外部需要引用的类,比如Activity,view扩展等等,但是有些情况下一些引入的外部lib,如果被混淆也会出现各种各样的问题,如果不想混淆这些包,就要加上 -keep class packagename.** {*;} 这样就能完整保持原有class了 3.想自定义 混淆细节的话,就琢磨琢磨这个配置文件吧
|