Skip to content

apk

第一部分:APK 的本质

我们在复盘时提到过,APK 本质上是一个 ZIP 压缩包。了解它的骨架是逆向的第一步。

文件/目录 全称 作用
AndroidManifest.xml 清单文件 定义应用名、包名、权限、四大组件(Activity 等)。
classes.dex Dalvik Executable Java/Kotlin 代码编译后的字节码文件。
lib/ Library 存放 .so 文件(Native 库),按 CPU 架构分类(arm64, x86 等)。
res/ Resources 存放图片、布局 XML、字符串等资源。
resources.arsc Resources Index 编译后的资源索引表。
META-INF/ Meta Information 封条。存放签名信息(CERT.RSA 等)。重打包时必须删除并重新签名,否则无法安装。
图标字母 含义 英文全称 例子
P (通常是包图标) 包 Package leadroyal.aaa.com.apk04
C 类 Class MainActivity
m 方法 Method onCreate, getKeyFromJNI
f (有时会出现) 字段 Field 变量,如 String str;

第二部分:安卓的运行机制

1. 虚拟机:Dalvik 与 ART

安卓不直接运行 Java 字节码(.class),而是运行 DEX 字节码。

  • Dalvik (老安卓): 边解释边执行(JIT)。

  • ART (Android 5.0+): 安装时预编译为机器码(AOT),运行更快。

  • 逆向意义: 逆向分析的主要是 .dex 文件。

2. Smali 语言

用 apktool 反编译 APK 时,看到 Smali 代码。

  • 地位: Smali 之于 Android,就像 汇编语言 之于 C/C++,是 Dalvik 字节码的人类可读形式。

  • 为什么重要: JADX 看到的 Java 代码是“猜”出来的,不一定准,而且无法直接修改。如果想修改 APP 的逻辑(比如把 if(false) 改成 if(true)),必须修改 Smali 代码。

Smali 示例:

# Java: int a = 10;
const/4 v0, 0xa  # 将 10 (0xa) 放入寄存器 v0

3. JNI (Java Native Interface)

Java 代码可以通过 JNI 调用 C/C++ 编写的 .so 库。

  • 特征: Java 代码中会有 native 关键字,例如 public native String getString();。

第三部分:逆向工具箱(拆解工具)

1. 静态分析(观察外观和图纸)

不运行程序,直接分析代码。

  • JADX-GUI:

    • 用途: 查看 Java 伪代码,分析 classes.dex。

    • 优点: 搜索方便,逻辑清晰,适合看整体逻辑。

    • 场景: 刚才的题目你主要用的就是这个。

  • IDA Pro / Ghidra:

    • 用途: 分析 .so 文件(C/C++/汇编)。

    • 优点: 也就是“反汇编神器”,能把机器码转成汇编或伪 C 代码。

    • 场景: 刚才题目中用来找 Key 的工具。

  • Apktool:

    • 用途: 反编译和重打包 APK。

    • 优点: 能获取 smali 代码和资源文件,修改后可以重新生成 APK。

2. 动态分析(运行并观察行为)

让程序跑起来,在运行时监控、修改数据。

  • Frida:

    • 用途: Hook(挂钩)框架。可以用 Python/JS 脚本在运行时插入代码。

    • 能力: 修改参数、打印返回值、绕过检测。

    • 地位: 目前最主流的动态调试工具。

  • Xposed:

    • 用途: 也是 Hook 框架,但需要安装模块,重启生效,较重。
  • ADB (Android Debug Bridge):

    • 用途: 官方调试桥。

    • 能力: 安装应用、查看日志 (adb logcat)、进入手机 Shell (adb shell)。


第四部分:逆向的标准流程(拆解步骤)

遇到一个 APK,通常的分析思路是这样的:

  1. 查壳(Detect): 检查 APK 是否被“加固”(也就是加密了)。如果有壳,第一步是“脱壳”(Unpacking)。

  2. 安装测试(Run): 在模拟器或真机上运行,抓包(Fiddler/Burp)看网络请求,看 Logcat 日志。

  3. 静态定位(Locate):

    • 用 JADX 打开。

    • 搜索关键字符串(如 "Invalid password"、"Token")。

    • 分析 AndroidManifest.xml 找入口 Activity。

  4. 分析逻辑(Analyze):

    • 如果是 Java 逻辑:看 JADX 伪代码。

    • 如果是 Native 逻辑:用 IDA 打开对应 .so。

  5. 动态调试(Debug/Hook):

    • 逻辑太复杂看不懂?

    • 用 Frida Hook 关键函数,打印输入输出(也就是你刚才没做但应该做的那一步)。

  6. 破解/利用(Exploit):

    • 编写注册机(还原算法)。

    • 或者修改 Smali 代码重打包(去除验证)。


第五部分:进阶

  1. ARM 汇编语言:

    • 安卓手机主要是 ARM 架构。看懂 .so 就必须看懂 LDR(加载)、STR(存储)、BL(跳转)、CMP(比较)等指令。
  2. 加密算法识别:

    • 一眼看出这是 Base64、MD5、AES 还是 RSA。

    • 识别常见的加密常量(S-Box, Magic Numbers)。

  3. 反调试与混淆:

    • 混淆: 类名变成了 a.b.c(如你刚才看到的 class a),需要耐心还原。

    • 反调试: APP 会检测是否有调试器连接(ptrace),如果有就崩溃。你需要学会如何绕过这些检测。