【车机版】酷狗音乐 v5.0.3.1 的逆向分析

查看 144|回复 15
作者:六哥。   

本文章仅作技术交流使用,切勿用于商业用途,测试后自行销毁。如有违规或侵权,联系作者删除。

[color=]测试环境:
[color=]         华为meta 60 pro
[color=]         mt管理器
有人要源文件,论坛有大佬发过:
https://www.52pojie.cn/forum.php?mod=viewthread&tid=1859000&highlight=%BF%E1%B9%B7
源文件下载地址:
https://www.123pan.com/s/iz19-tLkD3.html
提取码:52pj

车机酷狗最近更新了最新版本的V5.0.3.1版本,页面综合比之前的老版本页面好看很多,但是!多出来了好多VIP功能,车载VIP,超级VIP等。听歌就听个前奏,高潮都没了!?又不想连接蓝牙,网上也没个破解版,遂下载下来自己进行分析一波。
1.去除签名验证
看下软件是否加固。

没有加固那直接习惯性去下签名验证。MT一步到位。

2.修改SVIP/VIP
直接安装下APP,看下有什么关键字

APP目前这里看到了超级VIP,车载VIP。那就直接搜索VIP关键字


搜索出来有好多VIP,超级VIP,车载VIP,豪华VIP。感觉豪华VIP就是超级VIP+车载VIP。那直接先看豪华VIP,跳转到该函数
.method private j1(Lcom/kugou/ultimatetv/data/entity/User;)V
    .registers 24
    .param p1  # Lcom/kugou/ultimatetv/data/entity/User;
        .annotation build Lq/m0;
        .end annotation
    .end param
    .annotation system Ldalvik/annotation/MethodParameters;
        accessFlags = {
            0x0
        }
        names = {
            "user"
        }
    .end annotation
    move-object/from16 v0, p0
    move-object/from16 v1, p1
    .line 1
    iget-object v2, v1, Lcom/kugou/ultimatetv/data/entity/User;->carVipEndTime:Ljava/lang/String;
    invoke-virtual/range {p1 .. p1}, Lcom/kugou/ultimatetv/data/entity/User;->isVip()Z
    move-result v3
    invoke-static {v2, v3}, Lcom/kugou/android/common/utils/i;->k(Ljava/lang/String;Z)Z
    move-result v2
    .line 2
    iget-object v3, v1, Lcom/kugou/ultimatetv/data/entity/User;->suVipEndTime:Ljava/lang/String;
    invoke-virtual/range {p1 .. p1}, Lcom/kugou/ultimatetv/data/entity/User;->isSuVip()Z
    move-result v4
    invoke-static {v3, v4}, Lcom/kugou/android/common/utils/i;->k(Ljava/lang/String;Z)Z
    move-result v3
    .line 3
    iget-object v4, v1, Lcom/kugou/ultimatetv/data/entity/User;->svipEndTime:Ljava/lang/String;
    invoke-virtual/range {p1 .. p1}, Lcom/kugou/ultimatetv/data/entity/User;->isVip()Z
    move-result v5
    invoke-static {v4, v5}, Lcom/kugou/android/common/utils/i;->k(Ljava/lang/String;Z)Z
    move-result v4
    .line 4
    iget-object v5, v1, Lcom/kugou/ultimatetv/data/entity/User;->vipEndTimeForKSing:Ljava/lang/String;
    iget-boolean v6, v1, Lcom/kugou/ultimatetv/data/entity/User;->isVipForKSing:Z
    invoke-static {v5, v6}, Lcom/kugou/android/common/utils/i;->k(Ljava/lang/String;Z)Z
    move-result v5
    .line 5
    iget-object v6, v1, Lcom/kugou/ultimatetv/data/entity/User;->carVipEndTime:Ljava/lang/String;
    invoke-virtual/range {p1 .. p1}, Lcom/kugou/ultimatetv/data/entity/User;->isVip()Z
    move-result v7
    invoke-static {v6, v7}, Lcom/kugou/android/common/utils/i;->b(Ljava/lang/String;Z)J
    move-result-wide v6
    .line 6
    iget-object v8, v1, Lcom/kugou/ultimatetv/data/entity/User;->suVipEndTime:Ljava/lang/String;
    invoke-virtual/range {p1 .. p1}, Lcom/kugou/ultimatetv/data/entity/User;->isVip()Z
    move-result v9
    invoke-static {v8, v9}, Lcom/kugou/android/common/utils/i;->b(Ljava/lang/String;Z)J
    move-result-wide v8
    .line 7
    iget-object v10, v1, Lcom/kugou/ultimatetv/data/entity/User;->svipEndTime:Ljava/lang/String;
    invoke-virtual/range {p1 .. p1}, Lcom/kugou/ultimatetv/data/entity/User;->isVip()Z
    move-result v11
    invoke-static {v10, v11}, Lcom/kugou/android/common/utils/i;->b(Ljava/lang/String;Z)J
    move-result-wide v10
    .line 8
    iget-object v12, v1, Lcom/kugou/ultimatetv/data/entity/User;->vipEndTimeForKSing:Ljava/lang/String;
    invoke-virtual/range {p1 .. p1}, Lcom/kugou/ultimatetv/data/entity/User;->isVipForKSing()Z
    move-result v1
    invoke-static {v12, v1}, Lcom/kugou/android/common/utils/i;->b(Ljava/lang/String;Z)J
    move-result-wide v12
    .line 9
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->C1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    if-eqz v3, :cond_5a
    const v14, 0x7f080312
    goto :goto_5d
    :cond_5a
    const v14, 0x7f0802bc
    :goto_5d
    invoke-virtual {v1, v14}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->b(I)V
    .line 10
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->C1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    const-string v14, "超级VIP"
    invoke-virtual {v1, v14}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->e(Ljava/lang/String;)V
    .line 11
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->C1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    const-string v14, "至%s"
    const-string v15, "暂未开通"
    if-eqz v3, :cond_74
    invoke-static {v14}, Lcom/kugou/android/common/utils/i;->f(Ljava/lang/String;)Ljava/lang/String;
    move-result-object v3
    goto :goto_75
    :cond_74
    move-object v3, v15
    :goto_75
    invoke-virtual {v1, v3}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->d(Ljava/lang/String;)V
    .line 12
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->C1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    const/4 v3, 0x1
    const-wide/16 v16, 0x0
    const/16 v18, 0x0
    const-wide/16 v19, 0xf
    cmp-long v21, v8, v19
    if-gtz v21, :cond_8b
    cmp-long v21, v8, v16
    if-lez v21, :cond_8b
    const/4 v8, 0x1
    goto :goto_8c
    :cond_8b
    const/4 v8, 0x0
    :goto_8c
    invoke-virtual {v1, v8}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->c(Z)V
    .line 13
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->D1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    if-eqz v4, :cond_97
    const v8, 0x7f080310
    goto :goto_9a
    :cond_97
    const v8, 0x7f0802bb
    :goto_9a
    invoke-virtual {v1, v8}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->b(I)V
    .line 14
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->D1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    const-string v8, "豪华VIP" //跳转到了这里,往上看
    invoke-virtual {v1, v8}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->e(Ljava/lang/String;)V
    .line 15
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->D1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    if-eqz v4, :cond_ad
    invoke-static {v14}, Lcom/kugou/android/common/utils/i;->e(Ljava/lang/String;)Ljava/lang/String;
    move-result-object v4
    goto :goto_ae
    :cond_ad
    move-object v4, v15
    :goto_ae
    invoke-virtual {v1, v4}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->d(Ljava/lang/String;)V
    .line 16
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->D1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    cmp-long v4, v10, v19
    if-gtz v4, :cond_bd
    cmp-long v4, v10, v16
    if-lez v4, :cond_bd
    const/4 v4, 0x1
    goto :goto_be
    :cond_bd
    const/4 v4, 0x0
    :goto_be
    invoke-virtual {v1, v4}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->c(Z)V
    .line 17
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->E1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    if-eqz v2, :cond_c9
    const v4, 0x7f08030c
    goto :goto_cc
    :cond_c9
    const v4, 0x7f0802b9
    :goto_cc
    invoke-virtual {v1, v4}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->b(I)V
    .line 18
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->E1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    const-string v4, "车载VIP"
    invoke-virtual {v1, v4}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->e(Ljava/lang/String;)V
    .line 19
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->E1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    if-eqz v2, :cond_df
    invoke-static {v14}, Lcom/kugou/android/common/utils/i;->a(Ljava/lang/String;)Ljava/lang/String;
    move-result-object v2
    goto :goto_e0
    :cond_df
    move-object v2, v15
    :goto_e0
    invoke-virtual {v1, v2}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->d(Ljava/lang/String;)V
    .line 20
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->E1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    cmp-long v2, v6, v19
    if-gtz v2, :cond_ef
    cmp-long v2, v6, v16
    if-lez v2, :cond_ef
    const/4 v2, 0x1
    goto :goto_f0
    :cond_ef
    const/4 v2, 0x0
    :goto_f0
    invoke-virtual {v1, v2}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->c(Z)V
    .line 21
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->F1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    if-eqz v5, :cond_fb
    const v2, 0x7f08030f
    goto :goto_fe
    :cond_fb
    const v2, 0x7f0802ba
    :goto_fe
    invoke-virtual {v1, v2}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->b(I)V
    .line 22
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->F1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    const-string v2, "K歌VIP"
    invoke-virtual {v1, v2}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->e(Ljava/lang/String;)V
    .line 23
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->F1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    if-eqz v5, :cond_110
    invoke-static {v14}, Lcom/kugou/android/common/utils/i;->d(Ljava/lang/String;)Ljava/lang/String;
    move-result-object v15
    :cond_110
    invoke-virtual {v1, v15}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->d(Ljava/lang/String;)V
    .line 24
    iget-object v1, v0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->F1:Lcom/kugou/android/auto/ui/dialog/uservip/u0;
    cmp-long v2, v12, v19
    if-gtz v2, :cond_11e
    cmp-long v2, v12, v16
    if-lez v2, :cond_11e
    goto :goto_11f
    :cond_11e
    const/4 v3, 0x0
    :goto_11f
    invoke-virtual {v1, v3}, Lcom/kugou/android/auto/ui/dialog/uservip/u0;->c(Z)V
    return-void
.end method
.method private k1()V
    .registers 5
    .line 1
    iget-object v0, p0, Lcom/kugou/android/auto/ui/dialog/uservip/e1;->g:Landroid/widget/TextView;
    const/4 v1, 0x1
    new-array v1, v1, [Ljava/lang/Object;
    invoke-static {}, Lcom/kugou/a;->x()Ljava/lang/String;
    move-result-object v2
    const/4 v3, 0x0
    aput-object v2, v1, v3
    const-string v2, "酷狗ID %s"
    invoke-static {v2, v1}, Ljava/lang/String;->format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
    move-result-object v1
    invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
    return-void
.end method
出来更多VIP了,什么K歌VIP,车载VIP,豪华VIP,超级VIP,这尼玛各种VIP得多少monery。不过根据代码,看到大部分调用了isvip()和vipEndTime()相关的相关的代码,前者判断是否位会员,后者是会员到期。那直接从函数头往下看,一个一个修改,直接全方位VIP套餐。
    invoke-virtual/range {p1 .. p1}, Lcom/kugou/ultimatetv/data/entity/User;->isVip()Z
进入isVip()函数中

在当前类中出现多个与VIP有关的函数(如是否VIP,是否超级VIP,是否XXVIP,各种VIP到期时间等),那就一个一个修改。
先修改第一个isVIP(),返回boolean类型数据。结果保存在v0中,那就在return v0前添加 const v0,1(或者const v0,true)

在isVip()函数下有个isVipForSing(),此处应该是判断是否为VIP歌曲。返回的也是boolean类型。此处也可以修改,将返回值直接重新赋值为false,赋值false是把VIP歌曲让判断成非VIP歌曲达到免费听歌效果,但是我这里不搞它。先一步一步来,把所有是否为VIP的都先重新赋值。往上拉,有个isSuVip(),判断是否为豪华VIP,还有一个函数是isSuperVIP()这个才是超级VIP,不一样的。重 类型。

isLogin()判断是否登录,我这里也不修改它,我要的是微信扫码登录,然后都有VIP效果,这样把妹的时候,B格满满。
往上继续看,有个getVoiceBoxVipEndTime()获取语音信箱VIP的到期时间?这个好像与歌曲VIP联系不大,也不修改了。
getVipEndTimeForKSing()这个应该是获取K歌VIP的到期时间,这个酷狗支持在线K歌,车载上面K歌,五音不全这不让妹纸拉低对我的好感对,不改不改,继续往上看。
getVipEndTime()获取VIP的到期时间,改必须改,必须逼格拉满了改。返回值类型为String,我这里修改为:const-string v0,"2099-12-31",大家根据自己B格自己修改。最好修改成日期格式,我记得好像有split函数,应该是用于分割,不过MT中显示splite分割的是空白,所以这里你们修改成 const-string v0,"永久VIP"应该也没问题。

getUserId()获取用户的编号,这个不用改,登录后每个用户都有自己的编号的。让他自己获取就行。
getTvVipEndTime()获取TV的会员到期时间,这个对我没意义,你们可自行修改。
getToken()获取用户登录的token密钥,不用管。
getSvipEndTime()获取超级会员结束时间,改它,和上面一样。const-string v0,"2099-12-31"

getSuVipEndTime()这个应该是豪华VIP的到期时间,改它

上面好几个函数,是注册时间,这个都不用管,在上面还有一个getCarVipEndTime()获取车载VIP的到期时间,修改它!

修改完之后,往上拉有个add函数

这个函数中含有大量的VIP判断。第34行,就有一个isVIP判断,跳转过去

来到这个函数后,发现还有有很多判断是否是会员的,和会员到期时间,这里我就不一个一个函数讲解了,我直接贴出我修改后的代码吧。微信发送消息字数有上限,就粘贴部分修改过的代码吧。
.method public getCarVipEndTime()Ljava/lang/String;
    .registers 2
    .line 1
    iget-object v0, p0, Lcom/kugou/ultimatetv/data/entity/User;->carVipEndTime:Ljava/lang/String;
    const-string v0, "2099-12-31"
    return-object v0
.end method
method public getSuVipEndTime()Ljava/lang/String;
    .registers 2
    .line 1
    iget-object v0, p0, Lcom/kugou/ultimatetv/data/entity/User;->suVipEndTime:Ljava/lang/String;
    const-string v0, "2099-12-31"
    return-object v0
.end method
.method public getSvipEndTime()Ljava/lang/String;
    .registers 2
    .line 1
    iget-object v0, p0, Lcom/kugou/ultimatetv/data/entity/User;->svipEndTime:Ljava/lang/String;
    const-string v0, "2099-12-31"
    return-object v0
.end method
.method public getVipEndTime()Ljava/lang/String;
    .registers 2
    .line 1
    iget-object v0, p0, Lcom/kugou/ultimatetv/data/entity/User;->vipEndTime:Ljava/lang/String;
    const-string v0, "2099-12-31"
    return-object v0
.end method
.method public isSuVip()Z
    .registers 2
    .line 1
    iget-boolean v0, p0, Lcom/kugou/ultimatetv/data/entity/User;->isSuVip:Z
    const v0, 0x1
    return v0
.end method
.method public isVip()Z
    .registers 2
    .line 1
    iget-boolean v0, p0, Lcom/kugou/ultimatetv/data/entity/User;->isVip:Z
    const v0, 0x1
    return v0
.end method
修改完还不是VIP,我们要回到最初搜索到的豪华VIP函数进行再次分析读程序

在1075行,有个k函数,我们进去看下,这个函数传入了endtime和isvip又做了一次判断

第796行,if-nez v2,:conda_la,v2不等于0跳转到conda_la位置,看下conda_la处的代码为:const/4 p0 0x0。如果p0返回false,VIP一样是不显示的,所以我们直接把const/4,0修改为const/4 ,1。保存签名安装微信登录。

超级VIP,车载VIP,K歌VIP图标都点亮了。超级VIP到期时间是到了2099-12-31。这里车载VIP没有显示会员到期的时间,这里当给你们留个作业了,拒绝白嫖党。(提示:车载VIP到期时间显示,是在a函数里面判断的。)
到这里就完结了?NO!NO!NO!上面的VIP只是装逼的用的,没有任何VIP功能,不信你听个VIP的歌试试???肯定和下图一样,歌曲中间有个小白线,只能听多少秒,高潮部分完全不给你听?!

3.修改VIP歌曲
进入核心点,让VIP歌免费听起来!
第一步搜索试听

搜索出来以下内容

我们点击第一个进到函数

因为我比较懒,所以不想分析,直接把这个函数里面的所有判断都注释掉,直接nop大法好。

注意是上面的所有判断都要注释掉。我们返回打签名安装测试。

VIP歌曲可以直接听了,直接拉到了后面。
多测试几首歌




基本OK了,但是有部分的歌曲只能听中间60s的高潮部分。这里我没有做处理,有些歌听高潮部分还是可以的。不然前奏太长。
最后上一张我自己修改的完整版本的,以及传到车机上测试。




函数, 有个

sdieedu   

就等一个APP了嘿嘿
wo1jiu   

感谢分享,同求成品!
yufd1986   

已经研究过了,这个功能只能自慰,服务器会检测用户的token是不是会员,再返回试听的链接或者整首歌的链接,大家散了吧。
xiayusammr   

其实来这里就想看有无成品的人很多,奈何不让发。
六哥。
OP
  


yufd1986 发表于 2024-1-24 22:02
确实,楼主你是对的,vip的有些不能听。

isVipForSing(),此处应该是判断是否为VIP歌曲。返回的也是boolean类型。此处也可以修改,将返回值直接重新赋值为false,赋值false是把VIP歌曲让判断成非VIP歌曲达到免费听歌效果。
你可以试试修改修改这个,把返回值设置为false,也就是再retrun之前添加const v0,0 让VIP音乐编程普通音乐,看下试听部分可不可以变成全部可听
qinsmoon   

大神,发个成品试一下
sunnymed   

我是来仰慕大神的,求一个成品呢
yufd1986   


六哥。 发表于 2024-1-24 22:05
isVipForSing(),此处应该是判断是否为VIP歌曲。返回的也是boolean类型。此处也可以修改,将返回值直接重 ...

method public declared-synchronized isVipForSong()Z
    .registers 2
    monitor-enter p0
    const/4 v0, 0x1
    .line 1
    :try_start_2
    invoke-virtual {p0, v0}, Lcom/kugou/ultimatetv/UserManager;->isVipForSong(Z)Z
    move-result v0
    :try_end_6
    .catchall {:try_start_2 .. :try_end_6} :catchall_8
    monitor-exit p0
    return v0
    :catchall_8
    move-exception v0
    monitor-exit p0
    throw v0
.end method
是这个吗?
Marcel007   

看代码,慢慢改去咯
您需要登录后才可以回帖 登录 | 立即注册

返回顶部