jadx 的使用

本节只是对 jadx 的使用做简单介绍

我们知道,每个 Android 都有对应的安装包,是以 apk 为名字后缀的文件,App 的实现逻辑都包含在这个文件中。 apk 文件往往包含资源文件(如图标,字体等),由 java 代码编译而成的 dex 文件(可通过反编译 dex 文件得到 java 代码), 和一些相关的配置文件( 如 AndroidManifest.html 文件)。 关于其中细节可以去了解 Android 开发的相关知识

逆向中关键的一部就是反编译 apk 文件, 将其还原成可读性高的 java 代码, 在多数情况下,我们通过观察并分析这个 Java 代码就能找到想要的核心逻辑。 工欲善其事,必先利其器。用来反编译 apk 文件的工具有很多,例如 jadx , JEB , Apktool 等, 不同工具的用法和定位也有所不同

jadx 的简介

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

安装

下载:  Release 1.5.0 · skylot/jadx (github.com)

 进入到 bin 目录

主要功能如下:

除了反编译 apk 文件, 还可以反编译 jar , class,dex, aar 等文件和 zip 文件中的 Dalvik 字节码

解码 AndroidManifest.xml文件和一些来自 resources.arsc 中的资源文件

一些 pak 文件在打包过程中增加了 java 代码的混淆机制,对此 jadx 提供反混淆的支持

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

准备工作

本节会以一个 App 为例介绍 jadx 的命令和 jadx-gui 的使用方法,在开始前需要安装好 jadx 和  app5 (https://app5.scrape.center)

jadx 命令

使用 jadx 的命令执行文件的反编译操作,主要是指定一些输入参数和输出参数,这些参数的设置细节直接参考说明即可, 运行 jadx  -h  命令 查看 jadx 命令的用法

jadx  -h 

jadx - dex to java decompiler, version: 1.5.0

usage: jadx [command] [options] <input files> (.apk, .dex, .jar, .class, .smali, .zip, .aar, .arsc, .aab, .xapk, .jadx.kts)
commands (use '<command> --help' for command options):
  plugins         - manage jadx plugins

options:
  -d, --output-dir                    - output directory
  -ds, --output-dir-src               - output directory for sources
  -dr, --output-dir-res               - output directory for resources
  -r, --no-res                        - do not decode resources
  -s, --no-src                        - do not decompile source code
  --single-class                      - decompile a single class, full name, raw or alias
  --single-class-output               - file or dir for write if decompile a single class
  --output-format                     - can be 'java' or 'json', default: java
  -e, --export-gradle                 - save as android gradle project
  -j, --threads-count                 - processing threads count, default: 2
  -m, --decompilation-mode            - code output mode:

可以看到, 参数 <input files >  就是输入文件的路径,其他参数如 -d 可以指定反编译后输出文件的路径, -r 可以指定不解析资源文件(能够提升整体反比编译的速度)。于是我们可以使用下面的命令对已经下载好的 scrape-app5-apk 文件进行编译

jadx scrape-app5.apk -d scrape-app5

运行完毕后会生成一个 scrape-app5 文件夹

从中可以看到, AndroidManifest.xml 文件,资源文件和原始的 java 文件等都成功还原出来了。例如 com.glodz.mvvmhabit.ui.MainActivity.java 文件的内容还原结果如下

package com.goldze.mvvmhabit.ui;

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

/* loaded from: classes.dex */
public class MainActivity extends BaseActivity<l, 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
    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 代码逻辑一览无余

jadx-gui 的使用方法

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

启动和反编译

直接使用命令启动

jadx-gui

可以通过文件路径打开示例 apk 文件,也可以直接将 apk 文件拖入到 jadx-gui 的窗口中,还可以从菜单栏中的 “文件” -- “打开文件” 调出资源管理器来打开 apk 文件。 文件打开后,稍等片刻,反编译就完成了。

从界面中的左侧可以发现,反编译后的 Java 代码以一个个包的形式组织在一起,另外还有资源文件,其中包括图片文件,布局文件和 AndroidManifest.xml 文件(内含 apk 文件的基础信息)等。 在左侧展开想要查看的包,右侧就会出现对应的 java 代码,可以看出,Java 源码的还原度还是很高的

保存为 Gradle 项目

我们可以把反编译的文件另存为 Gradle 项目, Gradle 项目就是开发版本的 Android 项目

文件----另存为 Gradle 项目

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

文本搜索

首先我们可以通过 mitmdump 之类的工具知道请求的 URL 是

 https://app5.scrape.center/api/movie/?offset=0&limit=10&token=YmM2Mzg2MTg2ZjlmZDE4MGMyY2Q5NGFjZ

具体操作查看

写文章-CSDN创作中心

我们发现请求中是带有token 的,而在学习本章之前,我们只能通过抓包的方式获取 token ,现在我们可以反编译 apk 文件, 得到了 java 源代码, 就有办法找出这个 token 的生成逻辑。可以先寻找一些突破口,例如搜索固定字符串,想这里的 URL 中的 api/movie 和 token 这个字符串都是可以的,因为在构造 URL 的时候, 它们经常就是写死的常量, 如果能找到对一个的字符串,就可以顺藤摸瓜找到 token 的生成逻辑

那我们在源代码中搜索一下 URL 中的 api/movie 字符串,可以使用 jadx-gui 提供的搜索功能,打开菜单栏里面的 导航-----搜索文本  , 这时 jadx-gui 会显示一个搜索框,在搜索文本下方填入 /api/movei 同时可以从类名, 方法名, 变量名和代码中选择搜索为,自行勾选即可,下方会显示搜索结果

可以看到,搜索到了两处包含 /api/movie 字符串的位置,可以依次看一下这两处的内容,先选中第一个搜索结果然后点击  “转到”  按钮, 即可跳转到对应的代码出

可以看到,代码中有一个名为 i 的类, 里面有一个 index 方法, 该方法接收两个参数,分别是 i 和 i2 ,目前还不知道它的作用

不防先看看 index 方法的逻辑。 方法内首先构造了一个 ArrayList 对象并赋值给了 arrayList 变量,这相当于 python 中初始化空列表, 然后调用 add 方法往 arrayList 中添加了一个字符串 /api/movie , 接着调用了一个 encrypt 方法,并传入参数 arrayList , 通过名字大致可以猜到 encrypt 方法实现的是加密过程, 加密后的结果被赋值为 encrypt 变量, 最后调用 index 方法本身,并传入参数 i 和 i2 的组合计算结果以及刚刚得到的 encrypt 变量,并返回最终的结果

现在我们大致了解了整个流程,但对其中的一些参数和调用过程还是一头雾水,难道这里就包含 token 逻辑,似乎不好确认

逆向过程其实就包含一些不确定性,在查到一些蛛丝马迹之后,如果不确定查到的内容实时不是我们想要的,就继续深入研究,这就是一个推敲和追查的过程

查找方法的声明

我们可以试着寻找一下 encrypt 方法的声明,右击 encrypt 方法名,会打开一个菜单,选择跳到声明,这样我们就能找到 encrypt 的方法位置

可以看到,这里显示了 encrypt 方法的源代码,初步观察期逻辑是传入一个包含字符串的 List 对象,然后经过一些加密处理返回一个高度意思 Base64 编码的字符串,而我们之前看到的 token 字符串的格式也符合 Base64 的编码格式,至于这里究竟是不是 token 的生成过程,我们会在后面继续验证,这里主要是了解 jadx-gui 的一些用法

刚才我们通过 “ 跳到声明” 选项到了声明 encrypt 方法的位置, 那能不能通过该声明,找到调用 encrypt 方法的位置呢?

查找用例

右击声明处的 encrypt 方法名, 在打开的菜单中可以看到一个 “查找用例” 的选项,点击之后,查找结果

在搜到的结果上直接双击,或者先选中结果,再点击 “转到” 按钮,都可以跳转到对应的代码处。

反混淆

jadx-gui 还有一个强大的功能,就是反混淆。(这里的图是上面跳转过来的)

我们看到 encrypt 方法所在的类是 i ,它实现了一个接口 h ,仅从这些字母并不好推测究竟是什么意思,这时 APP 在编译和打包阶段做了一些混淆操作导致的结果,和 JS 中的变量混淆很相似

针对这个问题, jadx-gui 具有反混淆功能, 我们可以打开反混淆开关,点击菜单中的 “工具”---“反混淆”  可以看到原来的类名和接口都还原出来了

代码的可读性就打打增加了

设置选项

jadx-gui 还提供了很多设置功能,可以点击工具栏中的 “更多设置” 按钮

然后回打开一个设置页面

这其实是一个总的设置页面,我们可以在这里配置 jadx-gui 的各个选项,如是否启用反混淆,反编译过程允许的并行线程数,系统是否区分大小写,是否反编译资源文件等,这些和 jadx 的一些命令动能是一致的

日志查看

在 jadx-gui 运行的过程中,还可以查看运行日志,点击工具栏中的 “日志” 按钮即可打开日志查看器

可以通过上方的选择框选择日志等级,例如这里选择了 ERROR 级别,即显示错误日志,如果在反编译过程中出现了错误,可以在这里查看错误细节

常见问题

如果有些 apk 文件比较大, jadx-gui  反编译所需的事件和消耗的资源就会更多,所以有时候会出现类似  OutOfMemoryError 类型的错误,表示内存溢出,对于一些比较大的 apk 文件,是会出现这种错误,我们可以尝试下面两种解决方案

增加 JVM 的最大内存, 设置 JVM_OPTS , 把 JVM 的最大内存调大,

减少线程数,线程多了,反编译过程消耗内存自然也会增多,可以在运行 jadx 命令的时候通过 -j 命令适当将线程数设置为更小的值

jadx-gui是一个Android应用反编译工具,它可以将APK文件转换为可读取的java代码。下面是jadx-gui的简要使用教程: 1. 下载和安装:您可以从jadx官方网站(https://github.com/skylot/jadx)下载jadx-gui的安装文件。根据您的操作系统选择正确的版本并进行安装。 2. 打开jadx-gui:安装完成后,双击桌面上的jadx-gui图标以打开工具。 3. 导入APK文件:在jadx-gui界面上,点击菜单栏中的“File”选项,然后选择“Open”来导入您要反编译的APK文件。也可以直接将APK文件拖放到jadx-gui窗口中。 4. 查看反编译结果:一旦APK文件成功导入,jadx-gui将开始反编译过程,并将显示项目结构和java代码树。您可以通过单击文件夹和文件来查看反编译后的java代码。 5. 搜索和浏览代码:使用jadx-gui提供的搜索功能可以轻松找到特定的类、方法或变量。还可以通过双击代码行号来在源代码窗口和反编译结果之间快速切换。 6. 保存反编译结果:如果您想保存反编译后的代码,可以选择菜单栏中的“File”选项,然后选择“Save All”来保存所有代码文件。您也可以选择“Save As”来单独保存某个文件。 要注意的是,由于jadx-gui是一个开源项目,虽然有GUI界面提供便捷的操作,但也可以通过命令行界面使用jadx命令来完成相同的任务。希望这个教程可以帮助您快速入门jadx-gui工具的使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值