2023最新版Android逆向教程——第2天:dex反编译工具的安装和使用

每个 Android App 都有对应的安装包,是以 apk 为名字后缀的文件,App 的实现逻辑都包含在这个文件中。apk 文件往往包含资源文件(如图标、字体等),由 Java 代码编译而成的 dex 文件(可通过反编译 dex 文件得到 Java 代码),和一些相关的配置文件(如 AndroidManifest.xml 文件)。关于其中的细节,这里就不再一一展开介绍了,后续会介绍 Android 开发相关的基本知识。逆向中关键的一步就是反编译 apk 文件,将其还原成可读性高的 Java 代码,以前多数情况下,我们通过观察并分析这个 Java 代码就能找到想要的核心逻辑。工欲善其事必先利其器,用来反编译 apk 文件的工具有很多,例如:jadx,JEB,GDA,Apktool 等。不同工具的用法和定位也有所不同。

一、jadx的安装和使用

1.1 jadx 的简介

jadx 是一款使用广泛的反编译工具,可以一键把 apk 文件还原成 Java 代码,使用起来很简单,功能强大,还具有一些附加功能可以辅助代码追查。其 GitHub 地址为:https://github.com/skylot/jadx。主要具有如下几个功能:

  1. 除了反编译 apk 文件,还可以反编译 jar、class、dex、aar 等文件和 zip 文件中的 Dalvik 字节码
  2. 解码 AndroidManifest.xml 文件和一些来自 resources.arsc 中的资源文件
  3. 一些 apk 文件在打包过程中增加了 Java 代码的混淆机制,对比 jadx 提供反混淆的支持。

jadx 本身是一个命令行工具,仅仅通过 jadx 这个命令就可以反编译一个 apk 文件。除此之外,它也有配套的图形化界面工具-----jadx-gui,这个使用起来更加方便,能直接以图形界面的方式打开一个 apk 文件。同时,jadx-gui 对反编译后得到的 java 代码和其他资源文件增加了高亮支持(就像在 IDE 中打开这些内容一样),还具有快速定位、引用搜索、全文搜索等功能。所以,我们往往直接使用 jadx-gui 完成一些反编译操作。

1.2 jadx 的安装

直接点击 https://github.com/skylot/jadx/releases/tag/v1.4.7 链接下载对应的 Release 包即可,如下图所示:
在这里插入图片描述
单击,下载中,如下图所示:
在这里插入图片描述
如果 Github 链接打不开的,可以直接从我的百度网盘中进行下载,下载链接如下:

链接:https://pan.baidu.com/s/13WbJNVjZ9-9C9P3Z5NzAhA 
提取码:yqgs 
--来自百度网盘超级会员V9的分享

下载之后直接解压到自己常用的目录即可,解压之后会得到一个 bin 目录,进入 bin 目录直接运行 jadx 和 jadx-gui 即可,Windows 可以直接双击 jadx.batjadx-gui.bat 即可运行。如下图所示:

1.3 jadx 的命令

使用 jadx 的命令执行文件的反编译操作,主要是指定一些输入参数和输出参数,这些参数的设置细节直接参考参数说明即可。运行 jadx -h 命令 (以管理员身份运行cmd窗口,并且进入到jadx解压的目录----可以根据自己情况添加环境变量),查看 jadx 命令的用法,如下图所示:
在这里插入图片描述
可以看到,参数 <input files> 就是输入文件的路径,其他参数如 -d 可以指定反编译后输出文件的路径, -r 可以指定不解析资源文件(能够提升整体反编译的速度)。使用下面的命令对已经下载好的 scrape-app5.apk 文件进行反编译:

jadx scrape-app5.apk -d scrape-app5

运行完毕后,本地会生成一个 scrape-app5 文件夹,从中可以看到,AndroidManifest.xml 文件、资源文件和原始的 java 文件等都成功还原出来了。例如,com.goldze.mvvmhabit.ui.MainActivity.java 文件的内容还原结果如下:

package com.goldze.mvvmhabit.ui;

import android.os.Bundle;
import com.goldze.mvvmhabit.R;
import com.goldze.mvvmhabit.databinding.ActivityMainBinding;
import com.goldze.mvvmhabit.ui.index.IndexFragment;
import me.goldze.mvvmhabit.base.BaseActivity;

/* loaded from: classes.dex */
public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> {
    
    
    @Override // me.goldze.mvvmhabit.base.BaseActivity
    public int initContentView(Bundle bundle) {
    
    
        return R.layout.activity_main;
    }

    @Override // me.goldze.mvvmhabit.base.BaseActivity
    public int initVariableId() {
    
    
        return 2;
    }

    @Override // me.goldze.mvvmhabit.base.BaseActivity, me.goldze.mvvmhabit.base.IBaseView
    public void initParam() {
    
    
        super.initParam();
        setRequestedOrientation(-1);
    }

    /* JADX INFO: Access modifiers changed from: protected */
    @Override // me.goldze.mvvmhabit.base.BaseActivity, com.trello.rxlifecycle2.components.support.RxAppCompatActivity, android.support.v7.app.AppCompatActivity, android.support.v4.app.FragmentActivity, android.support.v4.app.SupportActivity, android.app.Activity
    public void onCreate(Bundle bundle) {
    
    
        super.onCreate(bundle);
        startContainerActivity(IndexFragment.class.getCanonicalName());
    }
}

还原效果还是比较理想的,就这样,我们只需要一条简单的命令就完成了对 apk 文件的反编译,其中 Java 代码的逻辑一览无遗。

1.4 jadx-gui 的使用方法

jadx-gui 是一个图形界面工具,它就像一个 IDE,支持很多方便快捷的交互式操作(例如把一个 apk 文件拖到 jadx-gui 后,它会直接打开这个文件,之后高亮显示反编译后的代码),以及代码搜索、定位等。相比 jadx 命令,个人更推荐直接使用 jadx-gui 反编译 apk 文件。

① 启动和反编译

在 Windows 下直接双击 jadx-gui.bat ,jadx-gui 便启动了,这是我们可以看到下图所示的界面:

可以通过 开始-->打开文件 打开 apk,也可以直接将 apk 文件拖到 jadx-gui 的窗口中,还可以从菜单栏中的 文件-->打开文件 调出资源管理器来打开 apk 文件。文件打开之后,稍等片刻,反编译就完成了,这时看到的界面如下图所示:
在这里插入图片描述
从界面的左侧可以发现,反编译后的 Java 源代码以一个个包的形式组织在一起,另外还有资源文件,其中包括图片文件、布局文件和 AndroidManifest.xml 文件(内含 apk 文件的基本信息)等。在左侧展开想要查看的包,右侧就会出现对应的 Java 源代码,如下图所示:
在这里插入图片描述
可以看出,Java 源代码的还原度还是很高的。

② 保存为 Gradle 项目

我们也可以把反编译后的文件另存为 Gradle 项目,Gradle 项目就是开发版本的 Andriod 项目,如下图所示:
在这里插入图片描述
导出后的项目目录结构和我们在 jadx-gui 界面里看到的结构基本一致,这个项目是可以被 Android Studio 工具打开的,打开的界面如下图所示:
在这里插入图片描述
打开之后的代码一般没办法直接运行,因为毕竟整个项目是反编译出来的,不太可能完全还原出开发版本的 Andriod 项目。如果你对 Andriod 开发比较了解,可以尝试修改一下源码和 Gradle 配置,是可以使项目正常运行的,即使不能运行也没有太大关系,我们的目的并不是运行这个代码,而是分析其中的逻辑,所以要把目光聚焦在查找和定位目标方法与逻辑定义上,Android Studio 能够帮我们更方便地完成这些操作,当然 jadx-gui 也提供了查找和定位的相关功能,现在我们回到 jadx-gui,了解一下它的其他常见用法。

③ 文本搜索

在源代码中搜索 /api/movie 字符串,可以使用 jadx-gui 提供的搜索功能,打开菜单栏里的 导航-->搜索文本,如下图所示:
在这里插入图片描述
这时 jadx-gui 会显示一个搜索框,如下图所示,在 搜索文本: 下方填入 /api/movie,同时可以从类名、方法名、变量名和代码中选择搜索位置,自行勾选即可,下方会显示搜索结果。
在这里插入图片描述
可以看到,搜索到了一处包含 /api/movie 字符串的位置,可以看一下该处的内容,先选中搜索结果,然后点击 转到 按钮,即可跳转到对应的代码处,如下图所示:
在这里插入图片描述
在这里插入图片描述
④ 查找方法的声明

我们可以试着寻找一下 encrypt 方法的声明,右击 encrypt 方法名,会打开一个菜单,选择 跳到声明,如下图所示:
在这里插入图片描述
这时候就会跳转到声明 encrypt 方法的位置,如下图所示:
在这里插入图片描述
初步观察其逻辑是传入一个包含字符串的 List 对象,然后经过一些加密处理返回一个高度疑似 Base64 编码的字符串。

更简单的方法,鼠标放到 encrypt 上,然后双击鼠标左键,即可跳转到方法声明处。

⑤ 查找用例:通过声明找到调用方法的位置

右击声明处的 encrypt 方法名,在打开的菜单中可以看到一个 查找用例 的选项,如下图所示:
在这里插入图片描述
点击之后,查找到的结果如下图所示:
在这里插入图片描述
搜索结果有一处,直接双击结果或者先选中结果再点击 转到按钮,都可以跳转到对应的代码处。查看结果,可以发现这就是之前调用 encrypt 方法的位置,如下图所示:
在这里插入图片描述
⑥ 反混淆

jadx-gui 还有一个强大的功能,就是反混淆。有时候从一些单个字母变量等并不好推测究竟是什么意思,这是 App 在编译和打包阶段做了一些混淆操作导致的结果,和 JavaScript 中的变量混淆非常相似。针对这个问题,jadx-gui 具有反混淆功能。我们可以打开反混淆开关,点击菜单栏中的 工具-->反混淆,如下图所示:
在这里插入图片描述
反混淆能够进一步提升代码的还原度,从而让我们更方便地推敲代码中的逻辑。

⑦ 设置选项

jadx-gui 还提供了很多功能设置,可以点击工具栏中的 首选项 按钮,如下图所示:
在这里插入图片描述
然后会打开一个设置页面,如下图所示:
在这里插入图片描述
这其实是一个总的设置页面,我们可以在这里配置 jadx-gui 的各个选项,如是否启用反混淆、反编译过程中允许的并行线程数、系统是否区分大小写、是否反编译资源文件等,这些和 jadx 的一些命令功能是一致的。

⑧ 日志查看

在 jadx-gui 运行的过程中,还可以查看运行日志,点击工具栏中的 日志 按钮即可打开日志查看器,如下图所示:
在这里插入图片描述
日志查看器如下图所示,可以通过上方的选择框选择日志等级,例如这里选择了 ERROR 级别,即显示错误日志。
在这里插入图片描述
如果反编译过程出现了错误,就可以来这里查看错误细节。当然,也可以从运行 jadx-gui 命令的控制台观察一些日志输出结果。

1.5 常见问题

如果有些 apk 文件比较大,jadx-gui 反编译所需的时间和消耗的资源会更多,所以有时候在反编译过程中会提示如下错误:

java.lang.OutOfMemoryError: GC overhead limit exceeded
....

这里报了一个 OutOfMemoryError 错误,代表内存溢出,对于一些比较大的 apk 文件,是会出现这种问题的,可以尝试用以下两种方式解决:

  1. 增加 JVM 的最大内存:设置 JVM_OPTS,把 JVM 的最大内存调大,之后内存溢出的问题自然可以得到有效解决。
  2. 减小线程数:线程多了,反编译过程消耗的内存自然也会增多,可以在运行 jadx 的命令时通过 -j 命令适当将线程数量设置为更小的值。

二、gda的安装和使用

文章:https://bbs.kanxue.com/thread-266700.htm
官网:http://www.gda.wiki:9090/introducation.php

三、JEB的安装和使用

在之前两小节中我们了解了 jadx 和 gda 的基本使用方法,体验了其强大的功能。当然,类似提供反编译功能的工具还有很多,JEB 就是一个。本小节我们会结合一个案例学习使用 JEB 反编译和分析 apk 文件的过程。本小节介绍的内容仅是 JEB 所有功能的冰山一角,更多关于 JEB 的使用教程可以参考其官方文档:https://www.pnfsoftware.com/jeb/manual/

3.1 JEB的简介

JEB 是由 PNF 软件(PNF Software) 机构开发的一款专业的反编译 Android App 的工具,适用于逆向和审计工程,功能非常强大。相比 jadx,JEB 除了支持 apk 文件的反编译和 Android App 的动态调试,还支持 ARM、MIPS、AVR、Inter-x86、WebAssembly、Ethereum(以太坊) 等程序的反编译、反汇编、动态调试等。另外,JEB 能解析和处理一些 PDF 文件,是一个极其强大的综合性逆向和审计工具。由于本小节主要讲 Android 逆向相关的内容,所以多关注它和 Android 相关的功能。对于 Android App,JEB 主要提供如下功能:

  1. 可以对 Android App 和 Dalvik(Android 虚拟机,类似 Java 中的 JVM) 字节码执行精确和快速的反编译操作
  2. 内置的分析模块可以对高度混淆的代码提供虚拟层次化重构,对分析混淆代码很有帮助
  3. 可以对接 JEB API 来执行一些逆向任务,支持用 Java 和 Python 编写自动化逆向脚本

JEB 支持 Windows、Linux、Mac 三大平台,目前主要分为三个版本:JEB CE(社区版)、JEB Android(Android版)、JEB Pro(专业版)。JEB CE 提供一些基础功能,如反编译 dex 文件,反编译和反汇编 Inter-x86,但不支持反编译 Dalvik 字节码。JEB Android 则更专注于 Android 系统,支持反编译 dex 文件,也支持反编译和反汇编 Dalvik 字节码。JEB Pro 则是 完全体,支持官网介绍的所有功能。三个版本的具体功能对比可以参考官网 https://www.pnfsoftware.com/jeb/ 的介绍。JEB CE 是免费的,JEB Android 和 JEB Pro 都是收费的,需要购买许可证才可以使用。

3.2 JEB的安装

如果从官方网站直接下载的话,一些 Android 功能是没法用的,这里建议下载社区大佬们提供的版本,请移步:https://bbs.kanxue.com/thread-268316.htm 另外这里我也准备了一个安装包,大家可以从百度网盘中下载:

链接:https://pan.baidu.com/s/1pGlrgXqr-YM-Sp5sgWv26A 
提取码:3oxs 
--来自百度网盘超级会员V9的分享

下载完成,解压后会得到如下的文件目录:

安装好 JEB 之后,需要下载示例 apk 文件,地址为:https://app5.scrape.center/ ,下载好后保存为 scrape-app5.apk 文件即可。然后准备好一部 Android 手机(建议大家都使用真机-----模拟器也能用,但不好用),在手机上安装好刚下载的 apk 文件并启动 App。另外还需要确保在电脑上能使用 adb 命令正常连接到手机。

3.3 JEB实战

进入 JEB 解压后的目录,Windows 下双击 jeb_wincon.bat,按照弹窗 generate a license,即可正常使用。设置中文:

重新打开 JEB,把示例 apk 文件直接拖到窗口里,经过一段时间的处理,JEB 就完成了反编译,如下图所示:
在这里插入图片描述
从左侧的 Bytecode/层级 部分可以看到,反编译后的代码以一个个包的形式组织在一起,右侧显示的则是 Smali 代码(Dalvik 的反汇编程序实现,类似 x86 平台下的汇编语言),通过这个代码,我们大体能够看出一些执行逻辑和数据操作的过程。虽然我们得到了 Smali 代码,由于我们要找的是 URL 中加密参数 token 的位置,因此最简单的方式当然是借助 API 的一些标志字符串查找了。

示例 App 在启动的时候会开始请求数据。请求 URL 里包含关键字 /api/movie,以及 offset、token 等参数,具体的抓包过程这里就不再赘述(后续会进行详细的讲解)。因为 API 的路径通常是用字符串定义的,而且一般写死在 App 代码里,所以我们可以尝试使用 /api/movie 来搜索,看看是否能搜索到相关的逻辑。点击菜单中的 编辑--> Quick Search,在文本框中输入需要查找的内容。
在这里插入图片描述
这里其实是声明了一个静态不可变的字符串,叫作 indexPath。但是这里是 Smali 代码,选中该字符串,然后右击,在菜单中选择 解析,如下图所示:
在这里插入图片描述
之后就成功定位到了 Java 代码的声明处,如下图所示:
在这里插入图片描述
这里就是 indexPath 的原始声明,同时还能看到 index 方法的声明,它包含 3 个参数:offset、limit 和 token。由此可以发现,这里的参数和声明恰好跟请求 URL 的格式是相同的。我们可以在 Java 代码处再次选择 解析,即可回到对应的 Smali 代码处,如下图所示:

可以看到 Smail 代码的定义和 Java 代码的定义一一对应。但这里似乎仅仅定义了 API,并没有真正的实现,因此我们可以接着搜索引用 /api/movie 的位置,同样在查找结果处右击,在打开的菜单中选择 解析,就跳转到了对应的 Java 代码处,如下图所示:
在这里插入图片描述
很明显,这里就是逻辑实现相关的代码了。稍微读一下这里的 Java 代码,大致是调用了一个 apiService 对象的 index 方法,并传入了几个参数,第一个参数是 v 和 v1 计算后的结果,第二个参数是 v1,第三个参数是 encrypt 方法返回的结果(这个方法的参数还是一个包含 /api/movie 字符串的 ArrayList 对象)。

这里看起来似乎是请求 API 的一个操作,但是我们也不确定是不是真的是这个位置。为了更好地确定这里是不是我们想要的数据加载入口,下面尝试使用 JEB 的动态调试功能验证一下,例如在刚才代码的位置添加一个断点,设置断点的方式如下:

然后滑动 App 加载数据,看在运行到断点的位置时是否停止了运行,如果停止了,就证明我们找的这个位置是正确的,否则继续寻找。动态调试的操作很简单,首先确保示例 App 已经安装在了手机上,并且能在电脑上通过 adb 命令与手机连接。然后运行 adb 命令:

C:\Users\Administrator>adb devices
List of devices attached
FA6BG0303294    device
C:\Users\Administrator>adb shell am start -D -n com.goldze.mvvmhabit/.ui.MainActivity
Starting: Intent { cmp=com.goldze.mvvmhabit/.ui.MainActivity }

这条命令的功能就是让 App 以调试模式启动,-D 指定了 App 以调试模式启动,-n 指定了启动入口,这里设置为示例 App 的包名和 MainActivity 。运行这条命令后,可以看到手机上显示如下图所示的字样:

这时回到 JEB 的界面,点击工具栏里的 Debug 按钮,如下图所示:
在这里插入图片描述
之后会检测出正在运行的 Android 设备,如下图所示:

点击下方的 附上 按钮,调试器就成功挂载了手机上的 App 进程,JEB 的界面变成下图所示的这样,弹出了几个调试窗口:
在这里插入图片描述
并且 JEB 显示代码执行到断点的位置时停了下来,于此同时,手机上的 Waiting for Debugger 提示消失了。说明数据加载的过程正是调用这个断点位置处代码的过程,即数据加载入口找对了。我们可以点击 Step Over 按钮尝试逐行执行此处的代码,如下图所示:
在这里插入图片描述
在执行的过程中,我们可以观察 VM/局部变量 窗口,这里显示了各个变量的类型和对应的值。另外,可以点击工具栏中的 Run 按钮继续执行到下一个断点,如下图所示:
在这里插入图片描述
如果没有下一个断点,会直接完成数据请求,App 中加载出下一页数据。后续的分析我就不再进行赘述,这里主要是为了演示 JEB 的使用方法。

ps:不推荐使用 JEB 进行 Java 层的动态调试,① JEB 是大神来的,调试的功能可能大神没有那啥,调试起来可能会有问题;② 调试的时候分析的还是 Smail 代码,有一定的难度,后续直接使用 Hook,Hook Java,Java 层的算法对于现在的逆向手段来讲几乎是没有什么太大的秘密,不需要向以前那样借助 Java 的动态调试。

在第2天,我们学习了 dex 反编译工具的安装和使用,利用此一类工具,我们可以非常方便地反编译 apk 文件,还原出原始的 Java 代码,从而找到我们想要的核心逻辑。今天学习的内容比较基础,需要好好掌握,之后会经常使用 jadx 来反编译 apk 文件。

至此今天的学习就到此结束了,笔者在这里声明,笔者写文章只是为了学习交流,以及让更多学习逆向的读者少走一些弯路,节省时间,并不用做其他用途,如有侵权,联系博主删除即可。感谢您阅读本篇博文,希望本文能成为您编程路上的领航者。祝您阅读愉快!


在这里插入图片描述

    好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。
    如果我的博客对你有帮助、如果你喜欢我的博客内容,请 点赞评论收藏 一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。
 编码不易,大家的支持就是我坚持下去的动力。点赞后不要忘了 关注 我哦!

猜你喜欢

转载自blog.csdn.net/xw1680/article/details/133472418