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)
相关推荐
_小马快跑_11 分钟前
ConstraintLayout之layout_constraintDimensionRatio属性详解
android
百锦再1 小时前
Android Studio开发 SharedPreferences 详解
android·ide·android studio
青春给了狗2 小时前
Android 14 修改侧滑手势动画效果
android
CYRUS STUDIO2 小时前
Android APP 热修复原理
android·app·frida·hotfix·热修复
火柴就是我3 小时前
首次使用Android Studio时,http proxy,gradle问题解决
android
limingade3 小时前
手机打电话时电脑坐席同时收听对方说话并插入IVR预录声音片段
android·智能手机·电脑·蓝牙电话·电脑打电话
浩浩测试一下3 小时前
计算机网络中的DHCP是什么呀? 详情解答
android·网络·计算机网络·安全·web安全·网络安全·安全架构
青春给了狗5 小时前
Android 14 系统统一修改app启动时图标大小和圆角
android
pengyu5 小时前
【Flutter 状态管理 - 柒】 | InheritedWidget:藏在组件树里的"魔法"✨
android·flutter·dart
居然是阿宋7 小时前
Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
android·开发语言·kotlin