Android安全攻防战,反编译与混淆技术完全解析(上)

Posted 火龙裸先生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android安全攻防战,反编译与混淆技术完全解析(上)相关的知识,希望对你有一定的参考价值。

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/49738023 
之前一直有犹豫过要不要写这篇文章,毕竟去反编译人家的程序并不是什么值得骄傲的事情。不过单纯从技术角度上来讲,掌握反编译功能确实是一项非常有用的技能,可能平常不太会用得到,但是一旦真的需要用到的了,而你却不会的话,那就非常头疼了。另外既然别人可以反编译程序,我们当然有理由应该对程序进行一定程度的保护,因此代码混淆也是我们必须要掌握的一项技术。那么最近的两篇文章我们就围绕反编译和混淆这两个主题来进行一次完全解析。


反编译

我们都知道,Android程序打完包之后得到的是一个APK文件,这个文件是可以直接安装到任何android手机上的,我们反编译其实也就是对这个APK文件进行反编译。Android的反编译主要又分为两个部分,一个是对代码的反编译,一个是对资源的反编译,我们马上来逐个学习一下。 
在开始学习之前,首先我们需要准备一个APK文件,为了尊重所有开发者,我就不拿任何一个市面上的软件来演示了,而是自己写一个Demo用来测试 
这里我希望代码越简单越好,因此我们建立一个新项目,在Activity里加入一个按钮,当点击按钮时弹出一个Toast,就这么简单,代码如下所示:

 1 public class MainActivity extends AppCompatActivity {
 2 
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.activity_main);
 7         Button button = (Button) findViewById(R.id.button);
 8         button.setOnClickListener(new View.OnClickListener() {
 9             @Override
10             public void onClick(View v) {
11                 Toast.makeText(MainActivity.this, "you clicked button", Toast.LENGTH_SHORT).show();
12             }
13         });
14     }
15 
16 }

activity_main.xml中的资源如下所示:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout
 3     xmlns:android="http://schemas.android.com/apk/res/android"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:paddingBottom="@dimen/activity_vertical_margin"
 7     android:paddingLeft="@dimen/activity_horizontal_margin"
 8     android:paddingRight="@dimen/activity_horizontal_margin"
 9     android:paddingTop="@dimen/activity_vertical_margin">
10 
11     <Button
12         android:id="@+id/button"
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:text="Button"/>
16 
17 </RelativeLayout>

然后我们将代码打成一个APK包,并命名成Demo.apk,再把它安装到手机上,结果如下所示: 

好的,到这里准备工作就已经基本完成了,接下来就让我们开始对这个Demo程序进行反编译吧。

 

反编译代码

要想将APK文件中的代码反编译出来,我们需要用到以下两款工具:

将这两个工具都下载好并解压,然后我们就开始对Demo程序进行反编译。解压dex2jar压缩包后,你会发现有很多个文件,如下图所示: 


其中我们要用到的是d2j-dex2jar.bat这个文件,当然如果你是linux或mac系统的话就要用d2j-dex2jar.sh这个文件。 
然后我们将Demo.apk文件也进行解压,如果不知道怎么直接解压的可以先将文件重命名成Demo.zip,然后用解压软件打开。解压之后你会发现里面有一个classes.dex文件,如下图所示: 


这个classes.dex文件就是存放所有java代码的地方了,我们将它拷贝到dex2jar解压后的目录下,并在cmd中也进入到同样的目录,然后执行:

 

1 d2j-dex2jar classes.dex

 

执行结果如下图所示: 


没有报任何错误,这就说明我们已经转换成功了。现在观察dex2jar目录,你会发现多了一个文件,如下图所示: 


可以看到,classes-dex2jar.jar这个文件就是我们借助工具之后成功转换出来的jar文件了。但是对于我们而言,jar文件也不是可读的,因此这里还需要再借助一下jd-gui这个工具来将jar文件转换成java代码。 
下面就很简单了,使用jd-gui工具打开classes-dex2jar.jar这个文件,结果如下图所示: 


OK,由此可见,我们的代码反编译工作已经成功了,MainActivity中的代码非常清晰,基本已经做到了90%以上的还原工作。但是如果想要做到100%的代码还原还是非常有难度的,因为像setContentView()方法传入的参数,其实就是一个资源的id值而已,那么这里反编译也就只能将相应的id值进行还原,而无法变成像R.layout.activity_main这样直观的代码展示。 
另外,除了MainActivity之外,还有很多其它的代码也被反编译出来了,因为当前项目有引用support-v4和support-v7的包,这些引用的library也会作为代码的一部分被打包到classes.dex文件当中,因此反编译的时候这些代码也会一起被还原。 
好的,学完了反编译代码,接下来我们看一下如何反编译资源。

 

反编译资源

其实细心的朋友可能已经观察到了,刚才Demo.apk的解压目录当中不是已经有资源文件了吗,有AndroidManifest.xml文件,也有res目录。进入res目录当中,内容如下图所示: 


这不是所有资源文件都在这里了么?其实这些资源文件都是在打包的时候被编译过了,我们直接打开的话是看不到明文的,不信的话我们打开AndroidManifest.xml文件来瞧一瞧,内容如下图所示: 


可以看到,这代码是完全没法阅读的。当然如果你去打开activity_main.xml看看,结果也不会好到哪儿去: 


由此可见,直接对APK包进行解压是无法得到它的原始资源文件的,因此我们还需要对资源进行反编译才行。 
要想将APK文件中的资源反编译出来,又要用到另外一个工具了:

 

关于这个工具的下载我还要再补充几句,我们需要的就是apktool.bat和apktool.jar这两个文件。目前apktool.jar的最新版本是2.0.3,这里我就下载最新的了,然后将apktool_2.0.3.jar重命名成apktool.jar,并将它们放到同一个文件夹下就可以了,如下图所示: 

安卓apk反编译

AndroidLinker与SO加壳技术之上篇

AndroidLinker与SO加壳技术之上篇

Android Proguard安全加固教你如何让自己的应用程序或SDK更难被反编译--library打包成jar并且混淆

Android 应用安全风险与防范

Android Proguard安全加固教你如何让自己的应用程序或SDK更难被反编译--library打包成jar并且混淆