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)
相关推荐
键盘上的蚂蚁-2 分钟前
PHP爬虫类的并发与多线程处理技巧
android
喜欢猪猪1 小时前
Java技术专家视角解读:SQL优化与批处理在大数据处理中的应用及原理
android·python·adb
JasonYin~2 小时前
HarmonyOS NEXT 实战之元服务:静态案例效果---手机查看电量
android·华为·harmonyos
zhangphil3 小时前
Android adb查看某个进程的总线程数
android·adb
抛空3 小时前
Android14 - SystemServer进程的启动与工作流程分析
android
Gerry_Liang5 小时前
记一次 Android 高内存排查
android·性能优化·内存泄露·mat
天天打码6 小时前
ThinkPHP项目如何关闭runtime下Log日志文件记录
android·java·javascript
爱数学的程序猿9 小时前
Python入门:6.深入解析Python中的序列
android·服务器·python
brhhh_sehe9 小时前
重生之我在异世界学编程之C语言:深入文件操作篇(下)
android·c语言·网络
zhangphil9 小时前
Android基于Path的addRoundRect,Canvas剪切clipPath简洁的圆形图实现,Kotlin(2)
android·kotlin