Android反编译的基本操作

来源:互联网 发布:试用网源码 编辑:程序博客网 时间:2024/06/07 11:02

反编译,顾名思义就是通过对安装包(APK)的一系列操作来获取到这个应用的源代码以及资源等。获取到了源代码,就能获取到很多信息,如加密解密算法,一些功能是如何实现的等等,我记得以前看过一个新闻就是有人通过反编译蜻蜓FM后发现这个应用中存在恶意代码,然后引起风波(具体是不是事实我也不太清楚)。还有上次的”微信15。。。ANR”事件,第一时间就有大神通过反编译来寻找原因(详情:http://androidwing.net/index.php/243)。当然本篇文章的出发点是简单的掌握反编译技术,在需要的时候可以用来解决自己碰到的问题,但是去用来反编译人家的应用,或者破解人家的应用都是不道德的。

准备工作

1.工具

反编译一个APK一般需要下面3款工具:

  • dex2jar 将apk中的dex文件转换成jar文件
    下载地址: https://sourceforge.net/projects/dex2jar/files/
  • jd-gui 用于查看jar文件中的java代码
    下载地址:http://jd.benow.ca/
  • apktool 用于最大程度地还原出APK文件中的各种资源文件。
    下载地址:http://ibotpeaches.github.io/Apktool/install/

解压dex2jar文件后如图:
这里写图片描述
这里面其实我们只用到d2j-dex2jar.bat文件,如果是linux和mac系统的话就是用d2j-dex2jar.sh这个文件。

jd-gui是jar文件,可直接运行的,当然得需要java环境。

apktool我们只需要两个文件,在给的下载地址上都可以下到,如图:
这里写图片描述

2.准备APK

为了尊重开发者以及让演示效果好点,这里我们就不用市面上的APK了,就自己写一个。

这里写图片描述

代码如下:
MainActivity.java

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                startActivity(new Intent(MainActivity.this, Main2Activity.class));            }        });    }}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.fu.demo.MainActivity">    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="跳转"/></LinearLayout>

Main2Activity.kt

class Main2Activity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main2)        val button = findViewById<Button>(R.id.button)        button.setOnClickListener({ Toast.makeText(this, "测试", Toast.LENGTH_SHORT).show() })    }}

activity_main2.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal"    tools:context="com.fu.demo.Main2Activity">    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="toast"/></LinearLayout>

注意、这里第二个Activity是用kotlin写的,我也是准备看看kotlin编写的Android程序反编译出来的是java代码还是kotlin代码。
然后编译打包,得到APK。

反编译获取源代码

首先我们要把APK解压出来,只需把”.apk”这个后缀改为”.zip”或者”.rar”就可以解压了。
解压后如图:

这里写图片描述

这里的classes.dex就是存放java代码的地方,也是我们需要反编译的文件。
我们把它复制到前面解压的dex2jar目录下,然后在这个目录下按住Shift,鼠标右键点击空白处,点击“在此处打开命令窗口”

这里写图片描述
然后执行:

d2j-dex2jar classes.dex

执行后:
正常情况下:

这里写图片描述

但我这里由于加了kotlin,反编译报错了,不知道是什么原因,但不影响后续操作,不用管它。

这里写图片描述

执行上面的命令后,我们会发现dex2jar目录多了一个jar文件,如图:

这里写图片描述

这个文件就是我们反编译出来存放java代码的文件,我们需要借助前面下载的工具jd-gui来查看java代码。
使用jd-gui打开”classes-dex2jar.jar”这个文件,如图:

这里写图片描述
这里写图片描述

可以看到MainActivity是用java写的,基本上还原了,只是像setContentView的参数这些也只能还原成资源ID。然后看看Main2Activity,这个是用kotlin写的,发现也还原成了java代码,onCreate基本上和java写的是一样,而不是还原成kotlin代码,而且还多了很多东西,可能是kotlin在内部自己生成的。
接下来,我们来看看如何反编译资源文件。

反编译获取资源文件

其实、在我们解压完APK的时候可以发现资源文件夹”res”,然后进去看看。
这里写图片描述

发现,资源文件不都是在这吗,是不是资源文件不用反编译。这里所说的资源文件是包含图片(.png),布局文件(.xml),而图片我们其实是可以直接查看不用反编译的,我们进到mipmap下,如图:

这里写图片描述

可以直接查看,甚至复制,然后自己使用。但是还有些素材、布局文件是用xml编写的,我们可以直接看吗?其实是不行。我们打开activity_main.xml看看,如图:

这里写图片描述

发现全是乱码,根本没法看。如果想看,就需要借助第三个工具反编译一下,就可以看了。
这里我们不用解压APK了,直接把APK放在第三个工具的目录中,如图:

这里写图片描述

然后按住Shift,鼠标右键点击空白处,点击“在此处打开命令窗口”,执行:

apktool d demo.apk

参数d就是接decode(解码)的意思,也就是说我们要对demo.apk这个文件进行解码。还有其他参数:

  • -f 如果目标文件夹已存在,则强制删除现有文件夹(默认如果目标文件夹已存在,则解码失败)。
  • -o 指定解码目标文件夹的名称(默认使用APK文件的名字来命名目标文件夹)。
  • -s 不反编译dex文件,也就是说classes.dex文件会被保留(默认会将dex文件解码成smali文件)。
  • -r 不反编译资源文件,也就是说resources.arsc文件会被保留(默认会将resources.arsc解码成具体的资源文件)。

执行之后:
这里写图片描述

说明反编译资源成功。
然后在当前目录下会多出一个demo目录,里面也有res目录,然后我们再看看刚才打开的activity_main.xml文件:

这里写图片描述
可以看到,虽然”android”变成了”n1”,但是也不影响我们的阅读,算是正常还原了。
反编译的基本操作就讲到这里了。