概述
Android 逆向工程的第一步是熟悉工具链。本文梳理逆向开发中最常用的命令行工具及其使用场景,覆盖 APK 拆解、DEX 分析、SO 调试、网络抓包等核心环节。
一、APK 拆解与重打包
apktool 是 Android 逆向的瑞士军刀,用于反编译 APK 中的资源文件和 smali 代码。
apktool d target.apk -o output_dir
apktool b output_dir -o repacked.apk
apktool d -s target.apk -o output_dir
apktool d -f target.apk -o output_dir
|
| 参数 |
含义 |
d / decode |
解码/反编译 |
b / build |
重新打包 |
-s |
跳过 dex 解码(保留 classes.dex 原始状态) |
-r |
跳过资源解码 |
-f |
强制删除目标目录覆盖 |
面试要点:apktool 反编译后生成的是 smali 代码而非 Java 源码,smali 是 Dalvik/ART 虚拟机的汇编语言,每一个寄存器操作都清晰可见。
1.2 jarsigner / apksigner
jarsigner -verbose -keystore debug.keystore -storepass android app.apk androiddebugkey
apksigner sign --ks debug.keystore --ks-pass pass:android app.apk
apksigner verify -v app.apk
|
Android 7.0 (API 24) 开始引入 APK Signature Scheme v2,对整个文件进行签名校验,比 V1 逐条目签名性能大幅提升。Android 9.0 (API 28) 进一步引入 V3 支持密钥轮换。
二、DEX / 字节码分析
2.1 d8 / dx(DEX 编译器)
dx --dex --output=classes.dex input.jar
d8 --release --output out_dir input.jar
|
2.2 dexdump
dexdump -d classes.dex | head -50
dexdump classes.dex | grep -A 20 "Class descriptor"
|
2.3 baksmali / smali
baksmali d classes.dex -o smali_output/
smali a smali_output/ -o new_classes.dex
|
smali/baksmali 是理解字节码注入、插桩、反混淆的核心工具。当你需要修改应用逻辑(如跳过付费验证),就是在 smali 层面操作。
三、SO / Native 层分析
3.1 objdump(binutils)
objdump -T libtarget.so
objdump -d libtarget.so | less
objdump -p libtarget.so | grep NEEDED
|
3.2 readelf
readelf -h libtarget.so
readelf -S libtarget.so
readelf -l libtarget.so
|
3.3 nm
nm -D libtarget.so
nm --dynamic libtarget.so
|
四、动态调试工具
4.1 adb 逆向专用命令
adb shell cat /proc/<pid>/maps
adb shell pm list packages -f
adb shell dumpsys package <package_name> | grep -A 5 "signatures"
adb shell pm path <package_name>
|
4.2 strace
adb shell strace -p <pid>
adb shell strace -e open,read,write -p <pid>
|
4.3 frida(动态插桩)
adb push frida-server /data/local/tmp/ adb shell chmod 755 /data/local/tmp/frida-server adb shell /data/local/tmp/frida-server &
frida-ps -U
|
五、网络抓包
5.1 tcpdump
adb shell tcpdump -i wlan0 -w /sdcard/capture.pcap
adb shell tcpdump -i wlan0 port 443 -w /sdcard/capture.pcap
|
5.2 Charles / mitmproxy
adb shell settings put global http_proxy <proxy_ip>:8888
adb shell settings put global http_proxy :0
|
Android 7.0+ HTTPS 抓包关键:系统默认不信任用户安装的 CA 证书。需要将 Charles/mitmproxy 证书安装为系统证书(root 后推送到 /system/etc/security/cacerts/),或使用 Xposed 模块(如 JustTrustMe)Hook 证书校验。
六、命令速查表
| 场景 |
命令 |
| 反编译 APK |
apktool d app.apk |
| 查看 DEX 结构 |
dexdump -d classes.dex |
| DEX → smali |
baksmali d classes.dex |
| 反汇编 SO |
objdump -d lib.so |
| 查看 SO 符号 |
nm -D lib.so |
| 查看进程内存 |
adb shell cat /proc/<pid>/maps |
| 抓取网络包 |
adb shell tcpdump -i wlan0 -w /sdcard/cap.pcap |
| 签名验证 |
apksigner verify app.apk |
| 动态插桩 |
frida -U -p <pid> -l script.js |
面试常考问题
Q1: apktool 反编译出的 smali 与 Java 源码的关系?
smali 是 DEX 字节码的文本表示,每个 .smali 文件对应一个 Java 类,每一行对应 Dalvik 虚拟机的寄存器操作指令。理解 smali 是做字节码修改和插桩的基本功。
Q2: Android 7.0+ 抓 HTTPS 包为什么需要额外处理?
Android 7.0 引入 Network Security Config,默认只信任系统预装的 CA 证书。用户安装的证书(如 Charles 根证书)对 targetSdkVersion >= 24 的应用无效。解决方法:root 后安装为系统证书、Hook 证书校验、或修改应用 network_security_config.xml。
Q3: apksigner V2 签名比 V1 好在哪?
V1 逐个对 JAR 条目签名,验证慢且 APK 解压后签名信息丢失;V2 对整个 APK 文件签名,安装时一次性验证,效率更高,且能检测整个文件是否被篡改。