android app进行代码混淆实例详解

时间:2021-05-20

接到一个新的任务,对现有项目进行代码混淆。之前对混淆有过一些了解,但是不够详细和完整,知道有些东西混淆起来还是比较棘手的。不过幸好目前的项目不是太复杂(针对混淆这块来说),提前完成~~现总结之。

第一部分

介绍下操作流程(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)

由于这个例子比较简单,很容易看出来是何地方出了问题,不过还是可以用来说明我们想表达的问题:如何还原混淆后的代码的错误信息。为了达到这个目的,我们需要三个文件:android-sdk-windows oolsproguardin etrace.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://.ttdevs.proguard下的所有类和子包下的类的所有方法和成员变量都不混淆。
// TODO 细节还有很多,比如-libraryjars、-dontwarn、-keepattributes等等,这些待续吧

通过此文希望能帮助到读者进行代码的混淆,谢谢大家对本站的支持!

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章