某音乐平台歌曲信息逆向之参数寻找

news/2024/7/19 13:53:04 标签: js逆向, js, python, 逆向

如何逆向加密参数:某音乐平台歌曲信息逆向之webpack扣取-CSDN博客

参数构建

js">{
	"comm": {
		"cv": 4747474,
		"ct": 24,
		"format": "json",
		"inCharset": "utf-8",
		"outCharset": "utf-8",
		"notice": 0,
		"platform": "yqq.json",
		"needNewCode": 1,
		"uin": 0,
		"g_tk_new_20200303": 5381,
		"g_tk": 5381
	},
	"req_1": {
		"module": "vkey.GetVkeyServer",
		"method": "CgiGetVkey",
		"param": {
			"guid": "7146813132",
			"songmid": ["002dw4gv1ZmiGt"],
			"songtype": [0],
			"uin": "0",
			"loginflag": 1,
			"platform": "20"
		}
	},
	"req_2": {
		"module": "music.musicasset.SongFavRead",
		"method": "IsSongFanByMid",
		"param": {
			"v_songMid": ["002dw4gv1ZmiGt"]
		}
	},
	"req_3": {
		"module": "music.musichallSong.PlayLyricInfo",
		"method": "GetPlayLyricInfo",
		"param": {
			"songMID": "002dw4gv1ZmiGt",
			"songID": 372639235
		}
	},
	"req_4": {
		"method": "GetCommentCount",
		"module": "music.globalComment.GlobalCommentRead",
		"param": {
			"request_list": [{
				"biz_type": 1,
				"biz_id": "372639235",
				"biz_sub_type": 0
			}]
		}
	},
	"req_5": {
		"module": "music.musichallAlbum.AlbumInfoServer",
		"method": "GetAlbumDetail",
		"param": {
			"albumMid": "003QIVDT3UB8zG"
		}
	},
	"req_6": {
		"module": "vkey.GetVkeyServer",
		"method": "CgiGetVkey",
		"param": {
			"guid": "9868485411",
			"songmid": ["002dw4gv1ZmiGt"],
			"songtype": [0],
			"uin": "0",
			"loginflag": 1,
			"platform": "20"
		}
	}
}

分析参数

  • req_1 中参数  【guid】,【songmid】,
  • req_2中参数【v_songMid】,
  • req_3中参数【songMID】,【songID】
  • req_4中参数【biz_id】
  • req_5 中参数【albumMid】
  • req_6中参数【guid】,【songmid】

由请求参数中可看出:

songmid == v_songMid ==  songMID == biz_id

那么这几个可以根据歌曲详情页链接后缀得到

问题参数

guid   

songID   歌曲编号

albumMid  专辑短链

guid 参数逆向

调试跟栈可定位到giud生成位置

function getGuid() {
    a = (new Date).getUTCMilliseconds()

    return String(Math.round(2147483647 * Math.random()) * a % 1e10);
}

那么其余参数如何获取呢 ??? 带着这个问题开始寻找之路

寻找接口

来到歌曲详情页面开始各种搜索发现前文章中提到得接口被反复请求,仔细观察之下发现有需要得结果。

请求参数

js">{
	"comm": {
		"cv": 4747474,
		"ct": 24,
		"format": "json",
		"inCharset": "utf-8",
		"outCharset": "utf-8",
		"notice": 0,
		"platform": "yqq.json",
		"needNewCode": 1,
		"uin": 0,
		"g_tk_new_20200303": 5381,
		"g_tk": 5381
	},
	"req_1": {
		"module": "music.musicsearch.HotkeyService",
		"method": "GetHotkeyForQQMusicMobile",
		"param": {
			"searchid": "26594278617551874",
			"remoteplace": "txt.yqq.top",
			"from": "yqqweb"
		}
	},
	"req_2": {
		"method": "get_song_detail_yqq",
		"module": "music.pf_song_detail_svr",
		"param": {
			"song_mid": "002dw4gv1ZmiGt"
		}
	},
	"req_3": {
		"module": "music.paycenterapi.LoginStateVerificationApi",
		"method": "GetChargeAccount",
		"param": {
			"appid": "mlive"
		}
	}
}

参数刨析

  • req_1 中参数  【searchid】
  • req_2中参数【song_mid】,

由首次分析可知  song_mid  为歌曲得短链,可有歌曲详情页中链接提取到

调试取参

【searchid】26594278617551874

断点跟栈

如上方式跟栈大概到  k.request  处发现关键位置

this.request = function(t) {
    var n = t instanceof Array ? t : [t];
    e.wait || (e.wait = e.sendRequest());
    var r = {};
    return n.forEach((function(t) {
        e.index += 1,
        t.param || (t.param = {}),
            r["req_" + e.index] = t
        }
        )),
        e.reqData = Object.assign(Object.assign({}, e.reqData), r),
        e.wait.then((function(t) {
            var e = Object.keys(r);
            return 0 === e.length ? [] : e.map((function(e) {
                return t[e]
        }
        ))
    }
    ))
}

e.reqData = Object.assign(Object.assign({}, e.reqData), r),

 此处打上断点看变量 r 值结果

存在需要得变量   【searchid】

进一步跟栈可跟踪到我们需要得位置: searchid: Object(_.a)(1)

扣取代码
, function(e, t, n) {
    "use strict";
    n.d(t, "a", (function() {
        return i
    }
    ));
    var a = function(e, t) {
        for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = [], i = n.length, o = a.length, c = 0, s = i + o - 1; c <= s; c++)
            r[c] = 0;
        for (var l = 0; l < o; l++)
            for (var u = 0; u < i; u++)
                r[u + l] += parseInt(n[u], 10) * parseInt(a[l], 10),
                r[u + 1 + l] += Math.floor(r[u + l] / 10),
                r[u + l] = r[u + l] % 10;
        return r.reverse(),
        0 == r[0] && r.shift(),
        r.join("")
    }
      , r = function(e, t) {
        for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = n.length, i = a.length, o = 0, c = 0, s = 0, l = 0, u = 0, m = Math.max(r, i); u < m; u++)
            c = u < r ? parseInt(n[u], 10) : 0,
            s = u < i ? parseInt(a[u], 10) : 0,
            l = Math.round(c) + Math.round(s) + o,
            n[u] = "".concat(l % 10),
            o = l >= 10 ? 1 : 0;
        return 1 == o && n.push("1"),
        n.reverse().join("")
    }
      , i = function(e) {
        var t = a(e, "18014398509481984")
          , n = a(Math.round(Math.random() * parseInt("4194304", 10)), "4294967296")
          , i = new Date
          , o = 1e3 * (3600 * i.getHours() + 60 * i.getMinutes() + i.getSeconds()) + i.getMilliseconds();
        return r(r(t, n), o)
    }
}

通看下来 没有进行其余操作, 我们可以将该内容加入到前文webpack加载器中,也可自行更改函数,

方式二实现

function getSearchId( e ){
     var a = function(e, t) {
        for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = [], i = n.length, o = a.length, c = 0, s = i + o - 1; c <= s; c++)
            r[c] = 0;
        for (var l = 0; l < o; l++)
            for (var u = 0; u < i; u++)
                r[u + l] += parseInt(n[u], 10) * parseInt(a[l], 10),
                r[u + 1 + l] += Math.floor(r[u + l] / 10),
                r[u + l] = r[u + l] % 10;
        return r.reverse(),
        0 == r[0] && r.shift(),
        r.join("")
    }
      , r = function(e, t) {
        for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = n.length, i = a.length, o = 0, c = 0, s = 0, l = 0, u = 0, m = Math.max(r, i); u < m; u++)
            c = u < r ? parseInt(n[u], 10) : 0,
            s = u < i ? parseInt(a[u], 10) : 0,
            l = Math.round(c) + Math.round(s) + o,
            n[u] = "".concat(l % 10),
            o = l >= 10 ? 1 : 0;
        return 1 == o && n.push("1"),
        n.reverse().join("")
    };

    var t = a(e, "18014398509481984")
      , n = a(Math.round(Math.random() * parseInt("4194304", 10)), "4294967296")
      , i = new Date
      , o = 1e3 * (3600 * i.getHours() + 60 * i.getMinutes() + i.getSeconds()) + i.getMilliseconds();
    return r(r(t, n), o)

}
调用方式

 

整合调试

详情接口

组建参数

【searchid】,【song_mid】

发起请求
_ 为时间戳, sign 值为前文逆向出来将请求参数传递进入可得到加密后得结果
歌曲id = result['req_2'][ 'data' ][ 'track_info' ][ 'id' ]
专辑短链 = result['req_2'][ 'data' ][ 'track_info' ][ 'album' ][ 'mid' ]

播放接口

将上述拿到得信息写入对应参数位置后,则可发起请求

songID   result['req_2'][ 'data' ][ 'track_info' ][ 'id' ]

albumMid  result['req_2'][ 'data' ][ 'track_info' ][ 'album' ][ 'mid' ]


http://www.niftyadmin.cn/n/5471423.html

相关文章

java -网络编程socket-聊天室-02

完整版代码 java -聊天室的代码: 用于存放聊天室的项目的代码和思路导图https://gitee.com/to-uphold-justice-for-others/java---code-for-chat-rooms.git 先引入线程的正统解释 线程&#xff08;Thread&#xff09;是程序执行流的最小单元。线程是操作系统分配CPU时间片的基…

【51单片机入门记录】A/D、D/A转换器PCF859应用

目录 一、IIC初始化代码 二、开发板电路图 三、PCF8591读/写字节操作流程及相关函数 &#xff08;1&#xff09;PCF8591&#xff08;AD&#xff09;读操作流程及代码 &#xff08;2&#xff09;PCF8591&#xff08;AD&#xff09;写操作流程及代码 四、应用示例-显示电压…

4.5日学习打卡----学习Apache HttpClient 5

4.5日学习打卡 目录&#xff1a; 4.5日学习打卡Apache Commons HttpClient简介 Apache HttpClient 5简介依赖HttpClient 5 GET 请求HttpClient 5 Fluent GETHttpClient5 GET 请求参数HttpClient 5 POST 请求HttpClient 5 Fluent POSTHttpClient5 POST JSON 参数HttpClient 5 设…

OJ练习第190题——坐标移动

坐标移动 HJ17 坐标移动 题目描述 开发一个坐标计算工具&#xff0c; A表示向左移动&#xff0c;D表示向右移动&#xff0c;W表示向上移动&#xff0c;S表示向下移动。从&#xff08;0,0&#xff09;点开始移动&#xff0c;从输入字符串里面读取一些坐标&#xff0c;并将最终…

【退役之重学Java】关于RabbitQM的消息异步确认发布

RbbitMQ 是一个异步通信机制的库 RabbitMQ 中的角色 producer 生产者&#xff0c;是消息的提供者&#xff0c;使用channel 发布消息channel&#xff0c;通道&#xff0c; 负责消息的接收和发送&#xff0c;由connection 进行创建queue&#xff0c;队列&#xff0c;生产者发布消…

c++ 动态分配内存

在 C 中&#xff0c;new 是一个运算符&#xff0c;用于在堆上动态分配内存&#xff0c;并返回指向新分配的内存的指针。使用 new 运算符分配的内存&#xff0c;需要手动释放以防止内存泄漏。 动态分配的内存需要手动释放&#xff0c;否则会导致内存泄漏。使用 new 分配的内存不…

C++入门 (2) >>引用>>内联函数>>auto关键字

1 引用 定义&#xff1a;给变量起别名。 方法&#xff1a;在类型后面加上&符号。 主要作用&#xff1a;代替函数传指针。 例&#xff1a; void test(int& a) //参数为int&类型 {a 10; }int main() {int m 3;int& z m; //给m起别名叫z&#xff0…

如何通过C++身份证实名认证接口实现实名认证功能

线上平台使用身份核验过程是验证个人身份真实性的过程&#xff0c;对于大多数线上平台来说&#xff0c;自己去开发集成身份证实名认证接口需要耗费大量的人力、物力成本&#xff0c;对此&#xff0c;为助力有需要的企业快速实现实名认证的功能&#xff0c;翔云平台提供了身份证…