APK逆向分析入门-以某斗地主APP为例
字数 1261 2025-08-22 12:22:48
APK逆向分析入门 - 以某斗地主APP支付逻辑修改为例
1. 准备工作
1.1 所需工具
- MT管理器:用于查看APK结构、检测加固状态、编辑dex文件等
- Jadx:Java反编译工具,用于查看APK源码
- BlackDex:脱壳工具(如遇到加固情况使用)
- GitHub地址:https://github.com/CodingGay/BlackDex/releases
1.2 目标APP分析
- 目标:某斗地主APP的记牌器支付功能
- 加固状态检测:使用MT管理器显示为未加固
2. 初步分析
2.1 界面与Activity分析
- 启动游戏,使用MT管理器的Activity记录器查看当前Activity
- 初始Activity:
StartActivity
- 初始Activity:
- 点击记牌器功能,观察Activity切换
- 点击购买按钮,跳转到阿里支付Activity
2.2 关键字符串搜索
- 使用Jadx加载APK
- 搜索"记牌器"关键词,定位相关代码
- 发现关键方法:
com.june.game.doudizhu.activities.b.a- 此方法用于判断开通记牌器的天数
3. 支付逻辑分析
3.1 支付流程梳理
a方法有三个调用点,对应2天、7天、30天记牌器选项- 点击记牌器会弹出三个Dialog(对应三种时长)
- 选择其中一个会调用
a方法,传入2/7/30作为参数 a方法根据参数调用不同的支付流程
3.2 关键支付方法
最终调用链:
com.june.game.doudizhu.activities.b.a
→ com.june.game.a.a.a().a(this.e, str, str2, d + "", new w(this))
支付核心方法:
public void a(String str, String str2, String str3, String str4, c cVar) {
if (str3 str3
String a2 = a(str, str2, str3, str4);
String a3 = f.a(a2, "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAN565YmUT5fKPEho3DRpQFhmsRkZTAr+5mbsYgyya8hlOlte/U0/6iD/fzZqkdXUqg80zwUO5bw6iZj5zVb66iYScY6W6bMQkYkTOMSmsqVUkbdpaYojOkC4cBR87N/VGL8hTDWHlwoXCpMAEDIwV5Rmpj6AZNYGfE5ertMEAQJbAgMBAAECgYBOvLvjtwN8Ouyey82zFtTY9G8U7OkGszOjlWEWEUcoAvtmPvXykv4vc3z4Kzs1rDALdasWpTEVLrpn03CiqeaXraS++2+8utnFdA2jH+FQPGBPHu+uP5Ye5NeE2o3HD+0VFC9MBcZomPGA8tKT3b82FFnmtUhdw+UzhN5AUQkVAQJBAPtX6+Y6tQwPIsAw/8pHxKvZcMI+5E5X23I6BtzTc5YFGKxTRy5HRbhMQEeYuENhzXJPiCZs7EXjFCqPrm+KSpsCQQDimhTFI4txjX/6H6QKkiAETTgog+1AUVZt8OWJdz6TwOziGv1vpXqaiumTRq8C+owWDAWhbzFtCQUc/Wv6MMNBAkBKxhBXEPYVnVcgSDOA0TMQUQL7tswjBn4xkFPEVF/ZrLB3a9sMSIXUW1LwOd3vpeQB8uk1TUhJTlIMi2xAoKqrAkAvcEJY4xAWPaFFI8qby+uX+vJ+yN+qT1zgt0XWeXhIRmNREoVsEiCQqfQsOOf6n6kkFHA5U6XtRa4kW4l3Xy4BAkAzMB2x6cX18IIe3suZPZfTLLeiXXmMm+IiwlRExKKYevwZ3U5a+yK7+UEedwkCWf92HQW9e5xDSZEqeFzuUq7r");
try {
a3 = URLEncoder.encode(a3, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
new b(this, a2 + "&sign=\"" + a3 + "\"&sign_type=\"RSA\"", cVar);
}
3.3 支付结果验证
关键验证代码位于com.june.game.doudizhu.activities.b.w.a:
String a2 = new com.june.game.a.e(str).a();
if (a2.equals("9000")) {
// 支付成功逻辑
} else {
// 支付失败逻辑
}
9000是支付宝支付成功的resultCode- 通过搜索确认9000代表支付成功状态
4. 支付逻辑修改
4.1 修改目标
定位到com.june.game.doudizhu.activities.b.w类,修改支付验证逻辑
4.2 修改方法一:强制返回成功
- 在获取a2值后,直接赋值为"9000"
- 确保无论实际支付结果如何,都返回成功状态
4.3 修改方法二:修改判断条件
- 将
if-eqz(等于零跳转)改为if-nez(不等于零跳转) - 反转判断逻辑,使支付失败时执行成功逻辑
4.4 修改步骤(使用MT管理器)
- 定位到目标类:
com.june.game.doudizhu.activities.b.w - 使用dex编辑器进行修改
- 保存并重新打包APK
5. 验证结果
- 修改后,选择购买并跳转支付宝支付后返回
- 记牌器功能可正常使用,验证修改成功
6. 关键逻辑流程图
- 用户选择记牌器时长 → 调用对应a方法
- a方法 → 调用支付接口方法
- 支付完成 → 验证返回码是否为9000
- 根据验证结果决定是否开通功能
7. 总结
通过逆向分析,我们:
- 定位了支付验证的关键类和方法
- 分析了支付结果验证逻辑
- 通过两种方式成功绕过支付验证
- 强制返回成功状态码
- 修改判断条件逻辑
此案例展示了基本的APK逆向分析流程,特别是针对支付逻辑的分析和修改方法。