接到新任务。现有项目的代码混淆。在此之前混淆了一些理解,但还不够具体和全面,我知道有些东西混起来相当棘手。

但幸运的是,现在这个项目是不是太复杂(对于这有些混乱)。提前完成~~这是总结。

第一部分

介绍下操作流程(eclipse):

1、打开混淆器:找到项目根文件夹下的project.properties文件,将“#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt”这行前的“#”删除就可以;

2、改动混淆配置文件:找到项目根文件夹下的proguard-project.txt文件。改动当中代码,这部分是最关键;

3、保存相关文件供以后出错时使用:主要有导出的apk文件、项目根文件夹下的proguard文件夹下的文件(基本的是mapping.txt)和项目源代码;

4、项目执行过程出错处理:依据错误信息和第3步中保存的mapping定位错误位置。

知道这些之后。我们对其进行展开。打开eclipse然后新建一个项目,默认会创建proguard-project.txt和project.properties。编写我们的代码。然后将proguard-project.txt的“#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt”这行前的“#”删除,最后导出就可以实现对代码的混淆,即使我们没有去编写proguard-project.txt中的内容。

以下是我的測试代码:

public class MainActivity extends Activity {

	private String mName;

	@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mName = "ttdevs"; getString(mName);
setName(mName);
showDialog();
// testError();
} public String getString(String name) {
return "hello " + name;
} public void setName(String name) {
System.out.println("I'm " + name);
} private void showDialog() {
new Handler().postDelayed(new Runnable() { @Override
public void run() {
ScoreAlertDialog.showDialog(MainActivity.this);
}
}, 2000);
} public static class ScoreAlertDialog { public static void showDialog(final Activity activity) {
if (activity.isFinishing()) {
return;
}
try {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("alert_title");
builder.setNegativeButton("cancel", null);
builder.setPositiveButton("submit", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
Toast.makeText(activity, "Welcome", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
builder.show();
} catch (Exception e) {
e.printStackTrace();
}
}
} private void testError() {
try {
int error = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
}
}
}

打包,反编译,最后我们得到例如以下的代码:

分析上面的代码我们会发现,自己定义的方法名都被替换成无特殊意义的短字母,而activity的onCreate()方法却没变;最后一个testError()方法因为我们没有调用也被剔除掉了。这些就是默认的混淆处理策略。看到这里,感觉混淆还是小case的哈~~

继续往下,我们将注销的testError()打开,打包执行这个时候会报错。错误信息例如以下:

 java.lang.ArithmeticException: divide by zero
at com.ttdevs.proguard.MainActivity.b(Unknown Source)
at com.ttdevs.proguard.MainActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:4531)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2150)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2229)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4945)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

因为这个样例比較简单,非常easy看出来是何地方出了问题。只是还是能够用来说明我们想表达的问题:怎样还原混淆后的代码的错误信息。为了达到这个目的。我们须要三个文件:android-sdk-windows\tools\proguard\bin\retrace.bat、mapping.txt和上面的错误信息(log.txt)。然后运行以下的命令(window系统):

retrace.bat mapping.txt log.txt

从上图中能够非常清楚的看到错误日志中的b()方法为我们实际代码中的setName()方法。

这里须要注意的是每次导出apk都会在项目中文件夹下的proguard文件夹下生成一个相应的mapping文件,所以对于每一个apk我们都须要保存与之相应的mapping文件。至此整个混淆的流程介绍完成。

參考:

官方文档:http://developer.android.com/tools/help/proguard.html

官方文档的翻译:http://www.cnblogs.com/over140/archive/2011/04/22/2024528.html(本想自己去翻一个。结果发现非常久曾经农民伯伯已经翻译,在此直接引用并感谢之)


第二部分

第一部分讲了怎样操作,參照官方文档,基本都会掌握。

剩下的也是最难的就是proguard-project.txt文件的编写。对于这部分,两种处理策略:自己编写和使用别人写好的。

先说怎样使用别人写好的,我们引用的第三方库不管开源还是闭源如有特殊情况我们都能够在他的User Guide中找到混淆代码的配置,如我们引用了大名鼎鼎的guillep PullToRefresh,我们能够在他的文档中找到例如以下的代码:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService -keepclasseswithmembernames class * {
native <methods>;
} -keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
} -keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
} -keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
} -keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

有了这部分代码我们就能够直接copy插入我们的项目中就可以。这样的方式还是copy式的。那以下我们举个小样例看看怎样自己写代码控制是否混淆。还是用第一部分的样例。我们在这个项目的proguard-project.txt文件里(之前为空)增加例如以下几行(proguard-project.txt中“#”代表凝视):

# -keep public class com.ttdevs.proguard.** { *; }
# -keepclasseswithmembers public class com.ttdevs.proguard.** { *; } -keep public class com.ttdevs.proguard.MainActivity {
java.lang.String getString(java.lang.String);
}

然后我们在导出apk然后反编译。得到例如以下代码:





和之前的对照。我们发现当中的getString方法没有被混淆。

没错。上面proguard-project.txt的意思就是保持MainActivity的getString()方法不要被混淆。

大家也能够试试上述混淆代码中被凝视的两行各自是什么效果。

说到这里已经開始涉及ProGuard的核心部分了,剩下的就是研读ProGuard的文档。掌握的他的语法并使用之。

本想找一个完整的ProGuard的翻译文档,可是找了N久没有发现一个。并且连零零散散的翻译也非常的少,近期时间非常紧。加之能力有限,想翻译一下经常使用的几个命令也是非常困,所以细读的想法仅仅能临时往后推了。这里先简介下keep命令:

-keep [,modifier,...] class_specification

在你的代码中指定作为切入点而被保留的类或者类的成员(属性和方法)。比如,为了保持一个应用,你能够指定主类和他的main方法。为了处理一个库,你须要具体说明他的public訪问的元素。

另外还有keep的简单概述 和
语法中规范

Class Specification中会告诉你怎样表示构造方法。属性和方法,"*" 与“**”的差别等等。比方"*"表示匹配不论什么的类名可是不包含包的分隔符。而"**"则是匹配不论什么的类名而且包含随意数量的包分隔符。因此上面我们凝视掉的代码意思例如以下:第一行:保持com.ttdevs.proguard下的全部类和子包下的类的全部方法都不混淆。第二行保持com.ttdevs.proguard下的全部类和子包下的类的全部方法和成员变量都不混淆。

// TODO 细节还有非常多。比方-libraryjars、-dontwarn、-keepattributes等等。这些待续吧

參考:

ProGuard 5.0:http://proguard.sourceforge.net 
 (ProGuard 4.7

版权声明:本文博主原创文章。博客,未经同意不得转载。

android对app代码混淆的更多相关文章

  1. 转:Android 2.3 代码混淆proguard技术介绍

    ProGuard简介 ProGuard是一个SourceForge上非常知名的开源项目.官网网址是:http://proguard.sourceforge.net/. Java的字节码一般是非常容易反 ...

  2. android studio 实现代码混淆

    =======本文章属于转载==========原文章地址:http://my.oschina.net/aibenben/blog/370985 这篇文章等是跟大家分享一在Android studio ...

  3. (通用)Android App代码混淆终极解决方案【转】

    App虽然没有那么的高大上,但是代码的混淆是代表了程序员对App的责任心, 也是对App安全的一点点保证.今天我会将自己做Android混淆的过程和体会分享给大家,也避免大家少走弯路,少跳坑. 本篇博 ...

  4. 【Android】Android Studio 进行代码混淆,打包release APK

    整了一天,感觉坑挺多. 1. 选择如图中的选项Android Studio进行签名打包: 2. 填写APP对应的信息:(最好用个文本记下来放在项目中同步给Team) - Key store path: ...

  5. Android 简单的代码混淆

    Android的代码混淆是开发者需要了解的相关知识,它能够防止android应用程序的反编译.因为android程序多数是java语言开发的,而java代码很容易被反编译,所以为了使android应用 ...

  6. Android 项目的代码混淆,Android proguard 使用说明

    简单介绍 Java代码是非常easy反编译的. 为了非常好的保护Java源码,我们往往会对编译好的class文件进行混淆处理. ProGuard是一个混淆代码的开源项目.它的主要作用就是混淆,当然它还 ...

  7. Android程序增加代码混淆器

    增加代码混淆器.主要是增加proguard-project.txt文件的规则进行混淆,之前新建Android程序是proguard.cfg文件 能够看一下我採用的通用规则(proguard-proje ...

  8. Android Studio实现代码混淆

     1,在build.grandle添加,其中规则写在proguard-rules.pro中,也可以自定义一个文件,将其代替,比如eclipse常用的 proguard-project.txt: bui ...

  9. Android ProGuard:代码混淆压缩

    写这篇文章的目的 一直以来,在项目中需要进行代码混淆时每次都要去翻文档,很麻烦.也没有像写代码那样记得那么多.既然要查来查去,就不如自己捋一捋这个知识点了,被人写的终究还是别人的.所以自己去翻看了很多 ...

随机推荐

  1. EJBCA 在windows上的安装

    为了做EJBCA的封装測试,在我自己电脑上装了个,可是在国内的开发上面的介绍实在是太少.有的也仅仅是些傻瓜式的安装介绍,这是介绍在Windows上安装的过程,(后面介绍下 linux 红帽上的),有些 ...

  2. uva live-2322 - Wooden Sticks

    首先排个序,然后找一次0花费,然后再找一次0花费,然后再找一次0花费,然后再找一次0花费......... 最后看找了几次,+1就是答案 #include<iostream> #inclu ...

  3. No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7 armv7s)

    问题: No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7 armv ...

  4. GitHub上最火的40个iOS开源项目

    1. AFNetworking 在众多iOS开源项目中,AFNetworking可以称得上是最受开发者欢迎的库项目.AFNetworking是一个轻量级的iOS. Mac OS X网络通信类库,现在是 ...

  5. 浅谈spring——注解配置(九)

    spring定义一个切面是件麻烦的事情,需要实现专门的接口,还要进行一些较为复杂的配置,有没有较为简单的方法??? @AspectJ注解可以很容易定义一个切面,且不需要实现任何的接口.缺点是对JDK的 ...

  6. 物联网操作系统HelloX开发人员入门指南

    HelloX开发人员入门指南 HelloX是聚焦于物联网领域的操作系统开发项目,能够通过百度搜索"HelloX".获取具体信息. 当前开发团队正在进一步招募中,欢迎您的了解和添加. ...

  7. Android拖动和缩放图片

    Android拖动和缩放图片 2014年5月9日 我们在使用应用其中常常须要浏览图片.比方在微信其中.点击图片之后能够对图片进行缩放. 本博客介绍怎样对图片进行拖拽和缩放.这首先要了解Android中 ...

  8. 【OpenCV新手教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨) ...

  9. UVA 10140 - Prime Distance(数论)

    10140 - Prime Distance 题目链接 题意:求[l,r]区间内近期和最远的素数对. 思路:素数打表,打到sqrt(Max)就可以,然后利用大的表去筛素数.因为[l, r]最多100W ...

  10. python实用小代码

    栈的实现 #!/usr/bin/env python #coding=utf-8 #python version 2.7.4 class stack: def __init__(self,list=N ...