一、为什么选这个项目?
说实话,市面上讲逆向的教程不少,但大多都是零散的知识点。今天讲个脱壳,明天讲个Hook,后天又跳到协议分析。学完你会发现——嗯,单个技术好像都会了,但真拿到一个App,还是不知道从哪下手。
我个人习惯是,学技术一定要有个完整的项目跟着走。就像学游泳,你不能只在岸上比划动作,得跳进水里扑腾几回才行。
所以这一章,我挑了一个典型的社交类应用作为靶标。为什么选社交?因为这类App功能多、协议复杂、安全防护也相对完善,非常适合练手。你想想看,一个简单的聊天功能,背后可能涉及TCP长连接、加密协议、签名校验、反调试、代码混淆……几乎涵盖了移动安全的所有核心知识点。
二、整体流程概览
先给你看张图,这是我做逆向分析的标准流程。说白了,就是一套「从外到内、从静到动」的拆解思路。
你看,这个流程不是线性的。很多时候你静态分析到一半,发现代码被混淆了,就得跳到动态调试;动态调试时发现App有反调试,又得先脱壳。嗯,这就是实战的常态——来回折腾。
三、环境搭建——工欲善其事
我记得刚开始做逆向时,光搭环境就花了两天。不是这个版本不兼容,就是那个工具缺依赖。所以这一节,我把最常用的环境清单列给你,照着配就行。
3.1 硬件准备
- 一台Root过的Android手机(推荐Pixel系列或一加,解锁方便)
- 一台Mac或Linux电脑(Windows也能用,但有些工具体验差一点)
- 数据线(别小看这个,劣质线会导致adb频繁断开)
3.2 软件工具清单
| 工具 | 用途 | 备注 |
|---|---|---|
| adb | 设备通信 | Android SDK自带 |
| Jadx | 反编译APK | 图形化界面,好用 |
| Frida | 动态Hook | 目前最主流的框架 |
| Burp Suite | 抓包/改包 | 配合手机代理使用 |
| Ghidra | Native层分析 | NSA出品,免费 |
| Objection | 自动化逆向 | 基于Frida的封装 |
adb shell getprop ro.product.cpu.abi
四、静态分析——先摸清底细
拿到APK后,我习惯先做三件事:查壳、看权限、找入口。这三步走完,心里就有个大概的谱了。
4.1 查壳
用 libradar 或者 ApkScan 扫一下,看看有没有加固。常见的壳有360、腾讯加固、娜迦、顶象等。如果发现是加固的,别急着脱壳——先看看能不能直接分析。
为什么?因为有些App虽然加固了,但核心逻辑在Native层,Java层只是个空壳。这种情况下,你直接分析so文件反而更高效。
4.2 权限分析
用 aapt dump permissions 或者直接看AndroidManifest.xml。重点关注:
- 有没有申请
READ_PHONE_STATE(IMEI获取) - 有没有
ACCESS_FINE_LOCATION(精确定位) - 有没有
RECORD_AUDIO(录音权限)
这些权限如果和App功能不匹配,可能就是敏感行为。
4.3 入口点分析
用Jadx打开APK,找到Application类和MainActivity。我一般会先看onCreate方法,这里通常会初始化各种SDK和检测逻辑。
// 伪代码示例
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
// 初始化加固
Shell.init(this);
// 初始化埋点
TrackSDK.init(this);
// 检测root
if (RootDetect.isRooted()) {
// 退出或限制功能
}
}
}
五、动态调试——让代码跑起来
静态分析只能看到代码的「骨架」,真正的逻辑还得靠动态调试。我个人最常用的组合是:Frida + Chrome DevTools。
5.1 启动Frida
# 推送frida-server到手机
adb push frida-server-16.0.1-android-arm64 /data/local/tmp/
adb shell chmod 755 /data/local/tmp/frida-server-16.0.1-android-arm64
adb shell /data/local/tmp/frida-server-16.0.1-android-arm64 &
# 启动App并附加
frida -U -f com.example.app -l script.js
5.2 常用Hook脚本
这里分享一个我常用的模板,用来快速定位关键函数:
// hook.js
Java.perform(function() {
// Hook某个类的方法
var TargetClass = Java.use('com.example.TargetClass');
TargetClass.sensitiveMethod.implementation = function(arg) {
console.log('sensitiveMethod called, arg: ' + arg);
// 可以修改返回值
return this.sensitiveMethod(arg);
};
});
Java.enumerateLoadedClasses()先枚举所有已加载的类,然后根据包名筛选。我经常用这招来找混淆后的类名。
六、脱壳——撕掉保护层
脱壳是逆向里最头疼的一环。市面上壳的种类太多,没有万能方案。但别慌,大部分壳都有规律可循。
6.1 常见脱壳思路
- 内存Dump: 等App运行起来后,从内存中把dex文件dump出来。工具推荐Frida的
frida-dexdump。 - 主动调用: 有些壳会在运行时动态解密dex,你可以Hook解密函数,在解密完成后把内存数据抓出来。
- 定制ROM: 对于强壳,可能需要修改系统源码,在ART虚拟机层面拦截。
# 使用frida-dexdump
frida-dexdump -U -f com.example.app -o dump/
七、协议逆向——看懂网络通信
App和服务器怎么通信的?数据加密了吗?签名怎么算的?这些都得靠协议逆向来回答。
7.1 抓包配置
用Burp Suite抓HTTPS流量,需要安装CA证书。步骤:
- 手机设置代理到Burp的IP和端口
- 浏览器访问
http://burp,下载CA证书 - 安装到系统信任区(需要Root)
7.2 绕过证书校验
很多App会做SSL Pinning,直接抓包会看到乱码。这时候需要Hook证书校验函数:
// 绕过SSL Pinning
Java.perform(function() {
var TrustManager = Java.use('javax.net.ssl.TrustManager');
// 自定义信任所有证书
// ... 具体代码略长,这里只展示思路
});
八、漏洞挖掘——找茬时间
前面的所有工作,最终都是为了这一步。常见的漏洞类型包括:
- 硬编码密钥: 在代码里直接写死了AES密钥或API Token
- 逻辑漏洞: 比如支付金额可以篡改、签到次数可以伪造
- 数据泄露: 日志里打印了敏感信息,或者本地数据库未加密
- 越权访问: 修改用户ID就能看到别人的数据
举个例子,我曾经分析一个社交App,发现它的聊天记录加密密钥是固定的字符串"chat_secret_key_2023"。你想想看,这跟没加密有什么区别?
九、报告输出——把成果固化
最后一步,把分析结果整理成报告。一份好的安全报告应该包含:
- 概述: App基本信息、分析范围、使用工具
- 发现的问题: 按严重程度排序,每个问题附上截图和复现步骤
- 修复建议: 针对每个问题给出具体的修复方案
- 附录: 关键代码片段、流量数据、Hook脚本等
漏洞名称: 聊天记录加密密钥硬编码
严重程度: 高危
复现步骤:
1. 使用Jadx反编译APK
2. 搜索字符串"chat_secret_key_2023"
3. 发现该密钥在ChatManager.java中被直接使用
修复建议: 使用动态生成的密钥,或基于用户密码派生
十、写在最后
这一章我们走完了整个逆向分析的流程框架。说实话,每个环节单独拿出来都能讲一整章。但我觉得,先让你看到「全貌」更重要。就像拼图,你得先知道最终要拼成什么样子,再一块一块去拼。
接下来的章节,我会带着你一步步深入每个环节。从环境搭建的细节,到脱壳的实战技巧,再到协议逆向的完整案例。嗯,路还长,但每一步都会很扎实。
记住,逆向分析不是魔法,是经验和耐心的积累。多动手,多踩坑,慢慢就熟了。
公众号:蓝海资料掘金营,微信deep3321