前九篇学了所有单项技能,本篇把它们串起来,完整还原一次真实逆向过程。目标:某出行类 App(授权测试环境),任务:还原其航班查询接口的签名算法。
⚠️ 郑重声明: 本文所有操作均在授权测试环境中完成,使用自有测试账号,不涉及任何真实用户数据。本系列内容仅供安全研究与学习,请遵守相关法律法规。
第一阶段:侦察收集
1.1 获取 APK
# 方式一:从已安装的手机提取
adb shell pm path com.example.travel
# output: package:/data/app/~~xxx/com.example.travel-xxx/base.apk
adb pull /data/app/~~xxx/com.example.travel-xxx/base.apk ./target.apk
# 方式二:apkpure.com 下载
1.2 识别加固类型
apkid target.apk[RESULT] target.apk!classes.dex
compiler : dex compiler (Android Studio)
packer : Bangbang Enterprise - Shanghai (梆梆加固)
结论: 梆梆加固,整体加密型,可用 frida-dexdump 脱壳。
1.3 抓包初探
配置好 Burp 代理,打开 App 搜索航班,抓到以下请求:
POST /api/v3/flights/search HTTP/1.1
Host: api.example-travel.com
Content-Type: application/json
X-App-Token: eyJhbGc...(JWT 格式)
X-Timestamp: 1713661234
X-Sign: 8f4a2b9c...(64位hex,疑似 HMAC-SHA256)
{"from":"SHA","to":"PEK","date":"2024-04-21","adults":1}
关注点:
X-Sign:64位hex → HMAC-SHA256 可能性大X-Timestamp:Unix 时间戳,防重放X-App-Token:JWT,需要分析生成逻辑
第二阶段:砸壳 + 静态分析
2.1 脱壳
# 启动 frida-server
adb shell "/data/local/tmp/frida-server &"
# 打开 App,然后执行脱壳
frida-dexdump -U-f com.example.travel
# 输出(示例)
[*] Scanning for classes...
[+] Dump ./com.example.travel_0x12345678.dex (2.8 MB)
[+] Dump ./com.example.travel_0x23456789.dex (1.2 MB)
[+] Dump ./com.example.travel_0x34567890.dex (0.9 MB)
2.2 jadx 静态分析
jadx-gui com.example.travel_0x12345678.dex搜索策略:
① 全局搜索 "X-Sign"
→ 找到: headers.put("X-Sign", RequestSigner.sign(body, timestamp))
② 进入 RequestSigner.sign()
→ 找到核心逻辑
还原的代码:
publicclassRequestSigner {
privatestaticfinalStringAPP_SECRET="tr4vel_s3cret_2024";
publicstaticStringsign(Stringbody, longtimestamp) {
// 拼接原始字符串
Stringraw=body+"|"+timestamp+"|"+APP_SECRET;
// HMAC-SHA256
try {
Macmac=Mac.getInstance("HmacSHA256");
SecretKeySpeckeySpec=newSecretKeySpec(
APP_SECRET.getBytes("UTF-8"), "HmacSHA256"
);
mac.init(keySpec);
byte[] result=mac.doFinal(raw.getBytes("UTF-8"));
returnbytesToHex(result);
} catch (Exceptione) {
return"";
}
}
}
关键发现:
签名格式:
body + "|" + timestamp + "|" + APP_SECRET算法:HMAC-SHA256
密钥:
tr4vel_s3cret_2024(硬编码在代码中!)
第三阶段:动态验证
3.1 Frida Hook 确认
// verify_sign.js
Java.perform(function() {
varRequestSigner=Java.use("com.example.travel.http.RequestSigner");
RequestSigner.sign.implementation=function(body, timestamp) {
console.log("=== RequestSigner.sign() ===");
console.log("body: "+body);
console.log("timestamp: "+timestamp);
varresult=this.sign(body, timestamp);
console.log("sign: "+result);
console.log("===========================");
returnresult;
};
});
frida -U-f com.example.travel -l verify_sign.js输出(触发搜索后):
=== RequestSigner.sign() ===
body: {"from":"SHA","to":"PEK","date":"2024-04-21","adults":1}
timestamp: 1713661234
sign: 8f4a2b9c3e1d7a5f...(与抓包一致 ✅)
===========================
3.2 绕过 SSL Pinning
# App 有证书固定,先用 objection 绕过
objection -g com.example.travel explore
# 进入 shell 后:
android sslpinning disable
第四阶段:Python 复现
4.1 完整签名代码
importhmac
importhashlib
importtime
importjson
importrequests
APP_SECRET = "tr4vel_s3cret_2024"
BASE_URL = "https://api.example-travel.com"
defsign(body: str, timestamp: int) ->str:
"""生成请求签名"""
raw = f"{body}|{timestamp}|{APP_SECRET}"
h = hmac.new(
APP_SECRET.encode("utf-8"),
raw.encode("utf-8"),
hashlib.sha256
)
returnh.hexdigest()
defsearch_flights(from_city: str, to_city: str, date: str):
"""查询航班"""
timestamp = int(time.time())
body = json.dumps({
"from": from_city,
"to": to_city,
"date": date,
"adults": 1
}, separators=(',', ':'))
headers = {
"Content-Type": "application/json",
"X-Timestamp": str(timestamp),
"X-Sign": sign(body, timestamp),
}
resp = requests.post(
f"{BASE_URL}/api/v3/flights/search",
data=body,
headers=headers,
timeout=10
)
returnresp.json()
# 调用测试
result = search_flights("SHA", "PEK", "2024-04-21")
print(json.dumps(result, ensure_ascii=False, indent=2))
五、踩过的坑与经验总结
| 坑 | 现象 | 解决方案 |
|---|---|---|
| frida-dexdump 脚本执行到一半 App 崩溃 | 加固有心跳检测 | 加快 dump 速度,减少停留时间 |
| jadx 反编译结果缺少关键方法 | 函数被内联或混淆 | 配合 Frida 动态追踪调用链 |
| 时间戳校验失败 | 服务端有 ±5 分钟窗口 | 同步手机时间或调整 ts |
| 请求成功但数据为空 | 需要登录态 Token | 先 Hook 登录接口拿 Token |
六、安卓逆向学习路线图
入门阶段(1-2 周)
├── 理解 APK 结构
├── jadx 基本使用
└── ADB 常用命令
进阶阶段(2-4 周)
├── Frida Java Hook 实战
├── SSL Pinning 绕过
└── 基础抓包分析
高级阶段(1-3 月)
├── Native 层 Hook
├── 砸壳与加固对抗
├── 算法逆向
└── 反检测对抗
专家阶段(持续积累)
├── IDA Pro / Ghidra 静态分析
├── ARM 汇编调试
├── VMP/定制虚拟机分析
└── 漏洞挖掘与利用
七、工具链汇总
| 分类 | 工具 | 用途 |
|---|---|---|
| 静态分析 | jadx、apktool | 反编译、资源提取 |
| 动态分析 | Frida、objection | Hook、运行时分析 |
| 脱壳 | frida-dexdump、BlackDex | APK 脱壳 |
| 抓包 | Burp Suite、r0capture | 流量分析 |
| 加固识别 | APKiD | 快速识别加固类型 |
| 反编译辅助 | IDA Pro、Ghidra | Native 层分析 |
八、推荐学习资源
Frida 官方文档
jadx GitHub
Android 逆向工程 Wiki
看雪论坛(国内最活跃的逆向社区)
CTF Wiki Android 章节
移动安全框架 MobSF
感谢阅读完整个系列! 从工具链到实战,从 Java Hook 到 Native 分析,希望这 10 篇文章能成为你安卓逆向路上的可靠参考。
系列完结 · 仅供安全研究与授权测试使用
夜雨聆风