Android
- 一、工具链总览
- 二、通用解题流程图
- 三、信息收集与预处理
-
- [1 使用 aapt 或 AndroidKiller 查看基本信息](#1 使用 aapt 或 AndroidKiller 查看基本信息)
- [2 判断是否加固](#2 判断是否加固)
- [3 提取关键文件](#3 提取关键文件)
- [四、静态分析(Java/Kotlin 层)](#四、静态分析(Java/Kotlin 层))
-
- [1 JADX-GUI 基本操作](#1 JADX-GUI 基本操作)
- [2 定位入口逻辑](#2 定位入口逻辑)
- [3 处理混淆](#3 处理混淆)
- [4 AndroidKiller 的妙用](#4 AndroidKiller 的妙用)
- [五、Native 层逆向(.so 文件)](#五、Native 层逆向(.so 文件))
-
- [1 从 APK 中提取 .so](#1 从 APK 中提取 .so)
- [2 IDA Pro 分析流程](#2 IDA Pro 分析流程)
- [六、动态调试与脱壳(模拟器 + Frida)](#六、动态调试与脱壳(模拟器 + Frida))
-
- [1 搭建环境](#1 搭建环境)
- [2 Frida 基础操作](#2 Frida 基础操作)
- [3 脱壳(Dump 加固后的 DEX)](#3 脱壳(Dump 加固后的 DEX))
- [4 动态 Hook Native 函数](#4 动态 Hook Native 函数)
- [5 抓包辅助](#5 抓包辅助)
一、工具链总览
| 工具 | 用途 | 适用场景 |
|---|---|---|
| JADX-GUI | 将 DEX 反编译为 Java 源码 | 快速阅读逻辑,搜索字符串 |
| AndroidKiller | Smali 级修改/重打包 | 破解校验、日志注入 |
| IDA Pro | 分析 ARM 架构的 .so 文件 | Native 层算法还原 |
| 夜神模拟器 | 运行 Android 应用(Root 环境) | 动态调试、脱壳、抓包 |
| Frida | 动态插桩,Hook Java/Native 函数 | 监控参数、脱壳、绕过反调试 |
二、通用解题流程图
- 初步信息收集
↓- 静态分析(Java/Kotlin 层)
↓- Native 层分析(so 文件)
↓- 动态调试/脱壳(如有加固)
↓- 关键点定位与逻辑还原
↓- 编写解密脚本/获取 Flag
三、信息收集与预处理
1 使用 aapt 或 AndroidKiller 查看基本信息
bash
aapt dump badging target.apk
关注:包名、入口 Activity、权限列表、支持的架构(arm64/x86)。
2 判断是否加固
- 检查
AndroidManifest.xml中application的name:- 正常:
android.app.Application或自定义普通类。 - 加固壳:
com.stub.StubApp、com.tencent.StubShell、com.qihoo.util.StubApplication等。
- 正常:
- 查看
lib/目录下是否有异常so(如libexec.so、libtup.so、libjiagu.so)。 - 使用
ApkScan-PKID或在线查壳工具。
3 提取关键文件
- 解压 APK → 得到
classes.dex、lib/、res/、assets/。 - 对于多 dex 应用(
classes2.dex等),全部保留。
四、静态分析(Java/Kotlin 层)
1 JADX-GUI 基本操作
打开 APK,等待反编译完成。
bash
快捷键:
Ctrl + Shift + F:全局搜索字符串(支持正则)。
Ctrl + N:快速跳转到类。
右键 → Find Usage:查找引用。
搜索关键词: flag、encrypt、decrypt、 Base64、AES、RSA、 check、verify、onClick
2 定位入口逻辑
- 从
AndroidManifest.xml中找到android.intent.action.MAIN对应的 Activity。 - 查看
onCreate、onClick等方法,往往包含核心验证或加解密逻辑。
3 处理混淆
- JADX 提供 反混淆 功能(菜单 Tools → Deobfuscation),但效果有限。
- 手动识别:
a.a.a可能是一个工具类;b.b可能是常量类。 - 利用字符串解密函数:很多混淆应用会在 Application 或静态块中动态解密字符串,可以在 Frida 中 hook 解密函数。
4 AndroidKiller 的妙用
当需要修改smali代码并重新打包时使用(比如强制绕过登录)。
修改后点击"编译",然后签名安装。
编译和签名最好把模拟器中的\bin\nox_adb.exe替换为AndroidKiller中\bin\adb\adb.exe文件,
其中我使用的是夜神模拟器所以是nox_adb.exe,替换的时候不要忘了备份和重命名一下。
| if-* 双寄存器比较(比较 vA 与 vB,满足条件则跳转到标签): | 条件跳转指令 |
|---|---|
| if-eq vA, vB | label 相等 |
| if-ne vA, vB | label 不等 |
| if-lt vA, vB | label 小于 |
| if-ge vA, vB | label 大于等于 |
| if-gt vA, vB | label 大于 |
| if-le vA, vB | label 小于等于 |
| if-*_z 单寄存器与 0(或 null)比较(if-*_z 形态,语法写作 if-eqz 等): | 条件跳转指令 |
|---|---|
| if-eqz vA | label vA == 0 (整数 0 或 null 引用) |
| if-nez vA | label vA != 0 |
| if-ltz vA | label vA < 0 |
| if-gez vA | label vA >= 0 |
| if-gtz vA | abel vA > 0 |
| if-lez vA | label vA <= 0 |
示例:在 smali 中将
if-eqz v0, :cond_0改为if-nez v0, :cond_0反转判断。
五、Native 层逆向(.so 文件)
1 从 APK 中提取 .so
解压后位于lib/armeabi-v7a/或lib/arm64-v8a/。
如果有多个架构,优先分析armeabi-v7a(IDA 支持良好)。
2 IDA Pro 分析流程
- 将
.so文件拖入IDA,选择ARM Little-Endian。 - 等待自动分析完成(可先按
Esc取消,手动分析关键位置)。 - 查看Exports窗口:寻找
JNI_OnLoad、Java_*开头的函数(native 方法)。 - 使用Strings窗口(
Shift + F12):查找可疑字符串(可能是明文、密钥或密文)。 - 按
F5反编译为伪代码
六、动态调试与脱壳(模拟器 + Frida)
1 搭建环境
- 夜神模拟器(开启 Root,设置中打开 USB调试)。
- 连接 ADB:
adb connect 127.0.0.1:62001(端口因模拟器而异)。 - 安装目标 APK:
adb install target.apk。
2 Frida 基础操作
安装frida、frida-tools并下载frida-server,将下载好的frida-server文件粘贴到模拟器并运行,版本要和frida版本一致,
bash
pip install frida frida-tools
验证安装成功:frida --version
端口转发:adb forward tcp:27042 tcp:27042。
列出进程:frida-ps -U。
3 脱壳(Dump 加固后的 DEX)
使用frida-dexdump自动 dump:
bash
frida-dexdump -U -f com.package.name
或使用脚本 Frida-DexDump(手动触发):
javascript
function dumpDex() {
Java.perform(function() {
var DexFile = Java.use("dalvik.system.DexFile");
// 遍历加载的 dex 并 dump
});
}
dump出的dex文件用JADX打开,可见原始代码。
4 动态 Hook Native 函数
javascript
Interceptor.attach(Module.findExportByName("libnative.so", "Java_com_example_NativeClass_encrypt"), {
onEnter: function(args) {
console.log("Input: " + hexdump(args[2])); // 参数
},
onLeave: function(retval) {
console.log("Output: " + retval);
}
});
5 抓包辅助
设置模拟器代理到BurpSuite或Charles。
对于HTTPS,可使用JustTrustMe或Frida脚本绕过SSL Pinning。
关于关键点定位与逻辑还原 与编写解密脚本/获取 Flag皆需要在实战中进一步熟悉工具的使用和代码的理解能力,因此在这里不作总结。