xx音乐app逆向分析

目标

看一下评论的请求

抓包

这里使用httpcanary

请求包如下

python 复制代码
POST /index.php?r=commentsv2/getCommentWithLike&code=ca53b96fe5a1d9c22d71c8f522ef7c4f&childrenid=collection_3_1069003079_330_0&kugouid=1959585341&ver=10&clienttoken=7123ecc548ec46d37574673793de1c825d9c213736a85283bf4517c71bfdcd90&appid=1005&clientver=10659&mid=255834326356876873930945227799988288305&clienttime=1693566637&key=7b098bdd24e31575d6977ddbd52c619e&uuid=e09ba4f899c6777225b76388a44e41bb&dfid=1tT6n21DUstm011Xnf3a0Llw&gitversion=45ced73&p=1&pagesize=20&show_admin_tags=1 h2
Host: gateway.kugou.com
user-agent: Android810-AndroidPhone-10659-14-0-COMMENT-wifi
kg-thash: 4fc50f7
accept-encoding: gzip, deflate
kg-rc: 1
kg-fake: 1959585341
kg-rf: 009831c9
x-router: m.comment.service.kugou.com
content-length: 0

参数分析

首先看看变化的参数

python 复制代码
v1 = "commentsv2/getCommentWithLike&code=ca53b96fe5a1d9c22d71c8f522ef7c4f&childrenid=collection_3_1985146619_68_0&kugouid=1959585341&ver=10&clienttoken=7123ecc548ec46d37574673793de1c82ef5ff5dbe19e27c1f1dd496ef8068914&appid=1005&clientver=10659&mid=334457935609434160207438033358774315577&clienttime=1693573528&key=b697376d876fc22548b636ae3e5ffac6&uuid=289a2994c5d812303781a7f2af74531e&dfid=348EFn2ifiKQ3hFGWR2tVCd9&gitversion=45ced73&p=1&pagesize=20&show_admin_tags=1".split("&")

v2 = "commentsv2/getCommentWithLike&code=ca53b96fe5a1d9c22d71c8f522ef7c4f&childrenid=collection_3_1985146619_68_0&kugouid=1959585341&ver=10&clienttoken=7123ecc548ec46d37574673793de1c82ef5ff5dbe19e27c1f1dd496ef8068914&appid=1005&clientver=10659&mid=334457935609434160207438033358774315577&clienttime=1693573554&key=0ee5e09a8270eb43a057de167465b166&uuid=289a2994c5d812303781a7f2af74531e&dfid=348EFn2ifiKQ3hFGWR2tVCd9&gitversion=45ced73&p=1&pagesize=20&show_admin_tags=1".split("&")
for a,b in zip(v1, v2):
    if a == b:
        continue
    else:
        print(a, b)

结果如下

python 复制代码
clienttime=1693573528 clienttime=1693573554
key=b697376d876fc22548b636ae3e5ffac6 key=0ee5e09a8270eb43a057de167465b166

clienttime是时间戳,那么只要知道key是怎么来的就行了

反编译apk

直接用jadx反编译,使用最新版本的可以不用内存大小。

接着就要看看是不是在java层。首先搜索show_admin_tags试试。

非常好就一处。

java 复制代码
public String m() {
        StringBuffer a2 = o.a("", b(), a(), this.f9765a, "", "", true, f());
        if (!TextUtils.isEmpty(this.f9766b)) {
            a2.append("extdata=");
            a2.append(this.f9766b);
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        if (e() == 1) {
            a2.append("tid=");
            a2.append(this.f9769e);
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        a(a2);
        a2.append("p=");
        a2.append(this.f9767c);
        a2.append(ContainerUtils.FIELD_DELIMITER);
        if (this.f9768d > 0) {
            a2.append("pagesize=");
            a2.append(this.f9768d);
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        if (this.i > 0) {
            a2.append("mixsongid=");
            a2.append(this.i);
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        if (!TextUtils.isEmpty(this.n)) {
            a2.append("ex_cmtid");
            a2.append(ContainerUtils.KEY_VALUE_DELIMITER);
            a2.append(this.n);
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        if (!TextUtils.isEmpty(this.j)) {
            a2.append("cmtreturnserver");
            a2.append(ContainerUtils.KEY_VALUE_DELIMITER);
            a2.append(i());
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        if (!TextUtils.isEmpty(this.k)) {
            a2.append("cmtdreturnserver");
            a2.append(ContainerUtils.KEY_VALUE_DELIMITER);
            a2.append(j());
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        if ("ca53b96fe5a1d9c22d71c8f522ef7c4f".equals(a())) {
            a2.append("show_admin_tags");
            a2.append(ContainerUtils.KEY_VALUE_DELIMITER);
            a2.append("1");
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        Long g = g();
        if (g != null) {
            a2.append("user_id=");
            a2.append(g);
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        String l = l();
        if (!TextUtils.isEmpty(l)) {
            a2.append("godk=");
            a2.append(l);
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        if (!TextUtils.isEmpty(this.l)) {
            a2.append("session=");
            a2.append(by.b(this.l));
            a2.append(ContainerUtils.FIELD_DELIMITER);
        }
        if (this.q) {
            a2.append("show_weightlist=1&");
        }
        if (this.r) {
            a2.append("show_replys=1&");
        }
        if (!TextUtils.isEmpty(this.f9770f)) {
            a2.append(this.f9770f);
        }
        return o.a(a2);
    }

先来hook一下试试m方法。

javascript 复制代码
function my_g(){
        let g = Java.use("com.kugou.android.app.common.comment.b.g");
        g["m"].implementation = function () {
            console.log('m is called');
            let ret = this.m();
            console.log('m ret value is ' + ret);
            return ret;
        };
    }
javascript 复制代码
# m is called
# m ret value is r=commentsv2/getCommentWithLike&code=ca53b96fe5a1d9c22d71c8f522ef7c4f&childrenid=collection_3_1985146619_68_0&kugouid=1959585341&ver=10&clienttoken=7123ecc548ec46d37574673793de1c82ef5ff5dbe19e27c1f1dd496ef8068914&appid=1005&clientver=10659&mid=334457935609434160207438033358774315577&clienttime=1693573528&key=b697376d876fc22548b636ae3e5ffac6&uuid=289a2994c5d812303781a7f2af74531e&dfid=348EFn2ifiKQ3hFGWR2tVCd9&gitversion=45ced73&p=1&pagesize=20&show_admin_tags=1

确实如此,但m函数代码里并没有出现key, 所以看看StringBuffer a2 = o.a("", b(), a(), this.f9765a, "", "", true, f());

跟一下就知道了。

key的加密方式

是md5,如何确定参数呢

贴一下hook代码比对下参数就行了

python 复制代码
# -*- coding: utf-8 -*-
# @Time    : 27/8/2023 下午 1:32
# @Author  : 明月清风我
# @File    : main.py
# @Software: PyCharm
import frida, sys
import os
import re

os.system("adb forward tcp:27042 tcp:27042")
os.system("adb forward tcp:27043 tcp:27043")

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

rdev = frida.get_remote_device()
front_app = rdev.get_frontmost_application()
print(front_app)
pid = re.findall(r'pid=(\d+)', str(front_app))[0]
jscode_hook = """
    console.log("Enter the Script!");
    function my_g(){
        let g = Java.use("com.kugou.android.app.common.comment.b.g");
        g["m"].implementation = function () {
            console.log('m is called');
            let ret = this.m();
            console.log('m ret value is ' + ret);
            return ret;
        };
    }
    function my_a(){
        let o = Java.use("com.kugou.android.app.common.comment.b.o");
        let ba = Java.use("com.kugou.common.utils.ba");
        ba["a"].overload('java.lang.String').implementation = function (str) {
            console.log('a is called' + ', ' + 'str: ' + str);
            let ret = this.a(str);
            console.log('a ret value is ' + ret);
            return ret;
        };
    }
    function br_a(){
        let br = Java.use("com.kugou.common.utils.br");
        br["a"].overload('[Ljava.lang.Object;').implementation = function (objArr) {
            console.log('br_a is called' + ', ' + 'objArr: ' + objArr);
            let ret = this.a(objArr);
            console.log('br_a ret value is ' + ret);
            return ret;
        };
    }
    Java.perform(function () {
        my_a();
        br_a();
        my_g();
    });

"""
process = frida.get_usb_device().attach(int(pid))
script = process.create_script(jscode_hook)
script.on('message', on_message)
print('[*] Hook Start Running')
script.load()
sys.stdin.read()

对于同一首歌曲只会改变clienttime

python复现

python 复制代码
import hashlib
import time
import requests


def hash_md5(s):
    return hashlib.md5(s.encode()).hexdigest()
timeStamp = str(int(time.time()))

s = "1005OIlwieks28dk2k092lksi2UIkp10659{}334457935609434160207438033358774315577".format(timeStamp)
key = hash_md5(s)

url = "https://gateway.kugou.com/index.php?r=commentsv2/getCommentWithLike&code=ca53b96fe5a1d9c22d71c8f522ef7c4f&childrenid=collection_3_1069003079_330_0&kugouid=1959585341&ver=10&clienttoken=7123ecc548ec46d37574673793de1c825d9c213736a85283bf4517c71bfdcd90&appid=1005&clientver=10659&mid=255834326356876873930945227799988288305&clienttime=1693566637&key={}&uuid=e09ba4f899c6777225b76388a44e41bb&dfid=1tT6n21DUstm011Xnf3a0Llw&gitversion=45ced73&p=1&pagesize=20&show_admin_tags=1".format(key)
headers = {
    "Host": "gateway.kugou.com",
    "user-agent": "Android810-AndroidPhone-10659-14-0-COMMENT-wifi",
    "x-router": "m.comment.service.kugou.com"
}
response = requests.post(url, headers=headers).text
print(response)
相关推荐
叽哥1 分钟前
Kotlin学习第 1 课:Kotlin 入门准备:搭建学习环境与认知基础
android·java·kotlin
风往哪边走19 分钟前
创建自定义语音录制View
android·前端
用户20187928316719 分钟前
事件分发之“官僚主义”?或“绕圈”的艺术
android
用户20187928316720 分钟前
Android事件分发为何喜欢“兜圈子”?不做个“敞亮人”!
android
Kapaseker2 小时前
你一定会喜欢的 Compose 形变动画
android
QuZhengRong3 小时前
【数据库】Navicat 导入 Excel 数据乱码问题的解决方法
android·数据库·excel
zhangphil4 小时前
Android Coil3视频封面抽取封面帧存Disk缓存,Kotlin(2)
android·kotlin
程序员码歌10 小时前
【零代码AI编程实战】AI灯塔导航-总结篇
android·前端·后端
书弋江山12 小时前
flutter 跨平台编码库 protobuf 工具使用
android·flutter
来来走走14 小时前
Flutter开发 webview_flutter的基本使用
android·flutter