安卓入门逆向实战第一期,破解两个日历软件vip

本文最后更新于:2024年10月4日 下午

前言

今天我们来讲安卓逆向,本期博客讲两种最基础的破解方法,两个日历软件的高级会员获取

准备如下

  • 一台电脑
  • frida框架
  • 一台已root的手机
  • jadx
  • 抓包软件

注:本博文仅研究逆向学习之类的方法,如果侵犯你的权益,请第一时间找我删除文章


365日历

我们首先打开app,登录之后要开通vip,我们打开抓包软件去查看

可以看到这里抓包出来有两个获取vip数据包的,这里我用黄鸟修改了返回数据,但是开屏广告还是存在

而且用抓包的方法破解,这样使用起来不方便,每次打开app都要开抓包,所以接下来我们使用frida


frida_hook

在进行hook,进行hook之前,我们首先要找到离方法最近的地方,这样hook起来容易,而且资源开销也不大,我们把app拆包

先去查一下有没有加固,我这里用的是app_msg点我,可以看到没有加固的

好,接下来我们使用jadx,对app,进行反编译操作,我们的目标是定位vip的判断逻辑

点进去,第二个

从逻辑上推断,他应该是访问了一个api,然后开始解析数据,通过刚才的黄鸟抓包,我们知道改数据包是走不通的,那有没有更好的方法呢?

我们可以直接打开app,在未开会员情况下,去使用会员功能

有个弹窗,那我们就从弹窗下手吧,去搜索对应的字符串

从这个onclick上看是点击后触发的代码,那么点击的时候肯定会判断是不是vip,所以我们点进去,看下内部结构

这里做了一个基础的判断,如果o返回false就是提示开通会员,那我们把o返回成true就行,按住ctrl进入o

这里的o函数返回了一个bool类型的数据,而且不需要传参,那我们开始写hook代码

1
2
3
4
5
6
7
8
9
10
11
12
13
function hook_vip(){
Java.perform(function() {
let v0 = Java.use("com.when.coco.o0.v0"); // 首先指定好包名,从package xxxx 就能看到 进入class
if(v0){
console.log("hook start......")
v0.o.implementation = function () { // 拦截o函数
console.log("hook vip success!")
return true; // 修改返回值
};
}
});
}
setImmediate(hook_vip())

这样就大功告成了


一叶日历

首先先查壳

也是没加固的,那我们直接用jadx反编译

遇到混淆了,我们不用慌,直接打开反混淆

打开app,点开高级会员,有给钱,也有使用激活码的,我们就从激活码这里下手,内购太难用了,先随便输入一个激活码,返回找不到激活码

并没有搜到,看来他对字符串也做了处理,那我们就搜一下其他的字符

字符都是从这个一个getString类获取的,我们断进去

发现这个是传递了一个id,然后返回字符的,那我们直接hook看一下

1
2
3
4
5
6
7
8
9
10
11
function hook_main(){
Java.perform(function(){
let Fragment = Java.use("androidx.fragment.app.Fragment");
Fragment.getString.overload('int').implementation = function (i10) {
console.log(`Fragment.getString is called: i10=${i10}`);
let result = this["getString"](i10);
console.log(`Fragment.getString result=${result}`);
return result;
};
})
}

激活码的字符串id也出来了,是一个2131886116,那我们直接搜索这个2131886116,找到对应的字段再去搜索

一个是c类,一个是j类,而且cj的代码差不多,经过hook程序调用的是j类的代码

但是这里混淆的太厉害了,经过一顿断点都毫无线索,那我们往弹窗上搞呢

废话不多说,我们直接在没有会员情况下,使用会员的功能

发现这里有个试用的按钮,那我们直接从试用上下手吧

点击试用,发现竟然没有返回东西,可以反编译包里的arsc,得知试用的英文是trial,去搜索trial

点这个istrial(意思为是否试用状态)

w

这里应该是判断是否是vip的代码,我们看这个needShowProDialog代表是否弹窗,那么得到以下结果

  • C6256a0.f14286a.m25077d() 这个是获取是否为永久会员
  • isTrial(scene) 这个是获取是否试用会员
  • C6262d0.f14311a.m25111f().getRewardTime() >= System.currentTimeMillis() 这个是获取会员是否到期,看来这软件之前还不是买永久会员的

我们进入C6256a0.f14286a.m25077d(),一探究竟

1
2
3
public final boolean m25077d() {
return C6262d0.f14311a.m25111f().getIsPro();
}

这是返回了一个bool类型的参数,我们让他true就代表有会员了,接下来可以写hook代码了

1
2
3
4
5
6
7
8
function hook_main(){
Java.perform(function(){
let a = Java.use(""w5.a0");
a.d.implementation = function () {
return true;
};
})
}

完事,用frida运行一下就有vip


我们现在得知了,vip具体函数的位置,但frida适合临时调试,如果我们要日常使用,这边可以把frida的脚本,转写成lsposed模块

关于lsp模块的编写,这里篇幅有限

我这里已经写好了,代码仓库->点我


安卓入门逆向实战第一期,破解两个日历软件vip
http://blog.bingyue.top/2024/10/04/an_zhuo_ni_xiang_shi_zhan_1/
作者
bingyue
发布于
2024年10月4日
许可协议