在上一篇文章当中,我们学习了Android程序反编译方面的知识,包括反编译代码、反编译资源、以及重新打包等内容。通过这些内容我们也能看出来,其实我们的程序并没有那么的安全。可能资源被反编译影响还不是很大,重新打包又由于有签名的保护导致很难被盗版,但代码被反编译就有可能会泄漏核心技术了,因此一款安全性高的程序最起码要做到的一件事就是:对代码进行混淆。
混淆代码并不是让代码无法被反编译,而是将代码中的类、方法、变量等信息进行重命名,把它们改成一些毫无意义的名字。因为对于我们而言可能Cellphone类的call()方法意味着很多信息,而A类的b()方法则没有任何意义,但是对于计算机而言,它们都是平等的,计算机不会试图去理解Cellphone是什么意思,它只会按照设定好的逻辑来去执行这些代码。所以说混淆代码可以在不影响程序正常运行的前提下让破解者很头疼,从而大大提升了程序的安全性。
今天是我们Android安全攻防战系列的下篇,本篇文章的内容建立在上篇的基础之上,还没有阅读过的朋友可以先去参考 Android安全攻防战,反编译与混淆技术完全解析(上) 。
混淆
本篇文章中介绍的混淆技术都是基于Android Studio的,Eclipse的用法也基本类似,但是就不再为Eclipse专门做讲解了。
我们要建立一个Android Studio项目,并在项目中添加一些能够帮助我们理解混淆知识的代码。这里我准备好了一些,我们将它们添加到Android Studio当中。
首先新建一个MyFragment类,代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class MyFragment extends Fragment { private String toastTip = "toast in MyFragment"; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_layout, container, false); methodWithGlobalVariable(); methodWithLocalVariable(); return view; } public void methodWithGlobalVariable() { Toast.makeText(getActivity(), toastTip, Toast.LENGTH_SHORT).show(); } public void methodWithLocalVariable() { String logMessage = "log in MyFragment"; logMessage = logMessage.toLowerCase(); System.out.println(logMessage); } } |
可以看到,MyFragment是继承自Fragment的,并且MyFragment中有一个全局变量。onCreateView()方法是Fragment的生命周期函数,这个不用多说,在onCreateView()方法中又调用了methodWithGlobalVariable()和methodWithLocalVariable()方法,这两个方法的内部分别引用了一个全局变量和一个局部变量。
接下来新建一个Utils类,代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Utils { public void methodNormal() { String logMessage = "this is normal method"; logMessage = logMessage.toLowerCase(); System.out.println(logMessage); } public void methodUnused() { String logMessage = "this is unused method"; logMessage = logMessage.toLowerCase(); System.out.println(logMessage); } } |
这是一个非常普通的工具类,没有任何继承关系。Utils中有两个方法methodNormal()和methodUnused(),它们的内部逻辑都是一样的,唯一的据别是稍后methodNormal()方法会被调用,而methodUnused()方法不会被调用。
下面再新建一个NativeUtils类,代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 |
public class NativeUtils { public static native void methodNative(); public static void methodNotNative() { String logMessage = "this is not native method"; logMessage = logMessage.toLowerCase(); System.out.println(logMessage); } } |
这个类中同样有两个方法,一个是native方法,一个是非native方法。
最后,修改MainActivity中的代码,如下所示:
1 2 3 4 5 6 iped-num" data-line="crayon-5812bfed14955750256469-2">2 3 4 5 6 被反编译就有可能会泄漏核心技术了,因此一款安全性高的程序最起码要做到的一件事就是:对代码进行混淆。 混淆代码并不是让代码无法被反编译,而是将代码中的类、方法、变量等信息进行重命名,把它们改成一些毫无意义的名字。因为对于我们而言可能Cellphone类的call()方法意味着很多信息,而A类的b()方法则没有任何意义,但是对于计算机而言,它们都是平等的,计算机不会试图去理解Cellphone是什么意思,它只会按照设定好的逻辑来去执行这些代码。所以说混淆代码可以在不影响程序正常运行的前提下让破解者很头疼,从而大大提升了程序的安全性。 今天是我们Android安全攻防战系列的下篇,本篇文章的内容建立在上篇的基础之上,还没有阅读过的朋友可以先去参考 Android安全攻防战,反编译与混淆技术完全解析(上) 。 混淆本篇文章中介绍的混淆技术都是基于Android Studio的,Eclipse的用法也基本类似,但是就不再为Eclipse专门做讲解了。
可以看到,MyFragment是继承自Fragment的,并且MyFragment中有一个全局变量。onCreateView()方法是Fragment的生命周期函数,这个不用多说,在onCreateView()方法中又调用了methodWithGlobalVariable()和methodWithLocalVariable()方法,这两个方法的内部分别引用了一个全局变量和一个局部变量。
这是一个非常普通的工具类,没有任何继承关系。Utils中有两个方法methodNormal()和methodUnused(),它们的内部逻辑都是一样的,唯一的据别是稍后methodNormal()方法会被调用,而methodUnused()方法不会被调用。
这个类中同样有两个方法,一个是native方法,一个是非native方法。
|