From 69c8db619dd34914c256828585bf326f1c06f523 Mon Sep 17 00:00:00 2001 From: rnet Date: Sun, 21 Jan 2024 00:48:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=201.=20=E5=A2=9E=E5=8A=A0=E7=94=B5?= =?UTF-8?q?=E9=87=8F=E4=BF=A1=E6=81=AF=E4=B8=8E=E7=BD=91=E7=BB=9C=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E4=BF=A1=E6=81=AF=E7=9A=84=E5=A4=84=E7=90=86=EF=BC=9B?= =?UTF-8?q?2.=20=E5=A2=9E=E5=8A=A0meta=E6=A0=87=E7=AD=BE=E7=9A=84content?= =?UTF-8?q?=E5=80=BC=E7=9A=84=E8=A7=A3=E6=9E=90=E4=B8=8E=E6=89=93=E5=8D=B0?= =?UTF-8?q?=EF=BC=9B3.=20uua=E5=80=BC=E4=BB=8Enpm=E5=8C=85=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E9=9A=8F=E6=9C=BA=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ main.js | 4 ++- package.json | 1 + src/handler/Cookie.js | 39 +++++++++++++++++++++++++++--- src/handler/globalVarible.js | 3 +++ src/handler/parser/common/tools.js | 2 ++ src/handler/parser/index.js | 1 + src/handler/parser/meta.js | 18 ++++++++++++++ src/makeCookie.js | 4 +++ test/cp0_96.test.js | 3 ++- test/parser.test.js | 4 --- utils/parseRsurl.js | 34 ++++++++++++++++++++++++++ 12 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 src/handler/parser/meta.js create mode 100644 utils/parseRsurl.js diff --git a/README.md b/README.md index 6d8aa5e..848c4fa 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,8 @@ Examples: url方式提取的ts:/path/to/output/makecookie_url_ts_1704391389883.json url方式提取的静态文本:/path/to/output/makecookie_url_immutext_1704391389883.json + 存在meta-content值:n5fQ9G1lGvUzfS_yMHx30yYAbp2_NDZI 解析结果:/sgtmi + Cookie值: 0yk64LrpoFnc8Wi4Mmu_rijgRRoC2SHY1bQlR2_QZ805_CqRd1uOgGRnlEvHvXSoQuwkx_fwn4iQnPDFrQigm1b4GnD61Pf9vU5XKtJtAWIoWeG_22OLiccUwGjI0lQaJ_jaYIBFygNsPSPf_0GnJyT1umFrFgAkAoqh1s0G9IDE1uPEM3PV8M1J.wbKdSgMLg8T3bGD5w2sHHohKfnwsT7bMNbb8xbjSxsn8qb8AvY0 Cookie长: 236 diff --git a/main.js b/main.js index c2c7750..154229f 100755 --- a/main.js +++ b/main.js @@ -14,6 +14,7 @@ const cheerio = require('cheerio'); const log4js = require('log4js'); const urlresolve = require('url').resolve; const adapt = require('@src/adapt'); +const _get = require('lodash/get'); function debugLog(level) { if (level) { @@ -32,10 +33,11 @@ const getCode = async (url) => { if (!isValidUrl(url)) throw new Error('输入链接不正确'); const res = await request(url) const $ = cheerio.load(res); - const scripts = [...$('script')] + const scripts = [...$('script[r=m]')] const tsscript = scripts.map(ele => $(ele).text()).filter(text => text.includes('$_ts.nsd') && text.includes('$_ts.cd')); if (!tsscript.length) throw new Error('链接返回结果未找到cd或nsd'); const $_ts = Function('window', tsscript[0] + 'return $_ts')({}); + $_ts.metaContent = _get($('meta[r=m]'), '0.attribs.content'); const checkSrc = (src) => src?.split('.').pop() === 'js' ? src : undefined; const remotes = scripts.map(it => checkSrc(it.attribs.src)).filter(Boolean); if (!remotes.length) throw new Error('未找到js外链,无法提取配置文本请检查!'); diff --git a/package.json b/package.json index 02c52a2..eb448c9 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "lodash": "^4.17.21", "log4js": "^6.9.1", "module-alias": "^2.2.3", + "random-useragent": "^0.5.0", "request": "^2.88.2", "request-promise": "^4.2.6", "yargs": "^17.7.2" diff --git a/src/handler/Cookie.js b/src/handler/Cookie.js index 2cbdd8d..9870443 100644 --- a/src/handler/Cookie.js +++ b/src/handler/Cookie.js @@ -2,6 +2,7 @@ const _random = require('lodash/random'); const dataOper = require('./dataOper'); const parser = require('./parser/'); const gv = require('./globalVarible'); +const randomUseragent = require('random-useragent'); const { factorial, @@ -32,9 +33,21 @@ module.exports = class { this.config = { 'window.navigator.maxTouchPoints': 0, 'window.eval.toString().length': 33, - 'window.navigator.userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', + 'window.navigator.userAgent': randomUseragent.getRandom(), 'window.navigator.platform': 'MacIntel', 'window.name': '$_YWTU=LjFNq_oZCsth6KJ9xHOin6RRhL4fQt7Vsn8YCz9dRjl&$_YVTX=Wa&vdFm=_$hh', + 'window.navigator.battery': { + charging: true, // 正在充电 + chargingTime: 0, // 距离充满时间 + dischargingTime: Infinity, // 预估可使用时间 + level: 1, // 电量100% + }, + 'window.navigator.connection': { + downlink: 6.66, // 下行速度 + effectiveType: "4g", // 网络类型 + rtt: 0, // 往返延时 + saveData: false, // 节流模式 + }, } this.runTime = Math.floor(new Date().getTime() / 1000); // 运行时间 this.startTime = this.runTime - 1; // 模拟浏览器启动时间 @@ -57,7 +70,7 @@ module.exports = class { gv.cp2[56], this.getSubFive(), gv.cp2[6], - [gv.cp2[52], 0], // 网络类型检测通过 + this.getSubSix(), gv.cp2[39], [gtn('0>one>55>one>3-189', 6)], ) @@ -137,8 +150,8 @@ module.exports = class { }, {}); return [ 1, 0, 0, 0, 0, 0, - ...encryptMode2(decrypt(name.$_YWTU), keyarr), - ...numToNumarr2(+decode(decrypt(name.$_YVTX))), + ...encryptMode2(decrypt(name.$_YWTU || ''), keyarr), + ...numToNumarr2(+decode(decrypt(name.$_YVTX || ''))), ]; } @@ -151,6 +164,24 @@ module.exports = class { ] } + getSubSix() { + // 网络与电量信息 + const { connType } = this.config['window.navigator.connection']; + const { charging, chargingTime, level } = this.config['window.navigator.battery'] + const connTypeIdx = ['bluetooth', 'cellular', 'ethernet', 'wifi', 'wimax'].indexOf(connType) + 1; + let oper = 0; + if (level) oper |= gv.cp2[56]; + if (charging) oper |= 1; + if (connTypeIdx !== undefined) oper |= gv.cp2[52] + return [ + oper, + level * 100, + chargingTime >> gv.cp2[52], + chargingTime & gv.cp2[34], + connTypeIdx, + ] + } + getTaskNumber(name, idx) { return gv.r2mka(name).taskarr[idx]; } diff --git a/src/handler/globalVarible.js b/src/handler/globalVarible.js index 1ddf652..c0320b7 100644 --- a/src/handler/globalVarible.js +++ b/src/handler/globalVarible.js @@ -5,6 +5,9 @@ const _get = require('lodash/get'); const cache = {}; class GlobalVarible { + get metaContent() { + return cache.metaContent; + } get bignum() { return cache.bignum; } diff --git a/src/handler/parser/common/tools.js b/src/handler/parser/common/tools.js index 03208ff..14ed476 100644 --- a/src/handler/parser/common/tools.js +++ b/src/handler/parser/common/tools.js @@ -22,3 +22,5 @@ exports.xor = function (numarr1, numarr2, num) { } return numarr1; } + +exports.stringReverse = (str) => str.split('').reverse().join(''); diff --git a/src/handler/parser/index.js b/src/handler/parser/index.js index e78846c..a9e9c97 100644 --- a/src/handler/parser/index.js +++ b/src/handler/parser/index.js @@ -10,6 +10,7 @@ function init(ts, r2mkaText) { require('./tscp').init(); require('./tscd').init(); require('./bignum').init(); + require('./meta').init(); logger.debug(`globalVarible完成初始化!用时:${new Date().getTime() - startTime}ms`); } diff --git a/src/handler/parser/meta.js b/src/handler/parser/meta.js new file mode 100644 index 0000000..56734bc --- /dev/null +++ b/src/handler/parser/meta.js @@ -0,0 +1,18 @@ +// meta标签的content值解析 +const gv = require('../globalVarible'); +const logger = require('@utils/logger'); +const { extrace, bitwiseTwoNumarr, decrypt, decode } = require('./common/index'); + +exports.init = function() { + const content = gv._getAttr('_ts').metaContent; + if (!content) return; + const arr = extrace(bitwiseTwoNumarr(decrypt(content), gv.keys[17])).filter(it => it.length); + if (!arr.length) { + logger.debug(`meta标签content值:${content} 解析失败!`) + return; + } + gv._setAttr('metaContent', { + content, + value: decode(arr.pop()), + }); +} diff --git a/src/makeCookie.js b/src/makeCookie.js index f1cb634..38efe90 100644 --- a/src/makeCookie.js +++ b/src/makeCookie.js @@ -40,6 +40,10 @@ module.exports = function (ts, immucfg) { const { code, $_ts } = coder.run(); const r2mkaText = parseR2mka(coder.r2mkaText); const cookie = new Cookie($_ts, r2mkaText).run(); + if (gv.metaContent) { + logger.info(`存在meta-content值:${gv.metaContent.content} 解析结果:${gv.metaContent.value}`); + } logger.info([`生成动态cookie成功!用时:${new Date().getTime() - startTime}ms\n`, `Cookie值: ${cookie}`, `Cookie长: ${cookie.length}\n`].join('\n ')) + return cookie; } diff --git a/test/cp0_96.test.js b/test/cp0_96.test.js index cb0af4a..8365e0f 100644 --- a/test/cp0_96.test.js +++ b/test/cp0_96.test.js @@ -1,5 +1,5 @@ const gv = require('../utils/initGv')(); -const { main, swap4, swap2, hexnum, init } = gv.utils; +const { main, swap4, swap2, hexnum, stringReverse, init } = gv.utils; /* setData('G_$cc', cp0[0]); setData('G_$ia', cp0[1]); @@ -25,6 +25,7 @@ const valueMap = { 'captureStackTrace': main(gv.cp0_96(7, 63))[0], '16777216': hexnum(gv.cp0_96(6, 76)), 'navigator': swap2(gv.cp0_96(10, 63)), + 'getBattery': gv.cp0_96(4, 6) + gv.cp0_96(4, 55) + stringReverse(gv.cp0_96(6, 55)), } test('test cp0_96', () => { diff --git a/test/parser.test.js b/test/parser.test.js index 7af43b4..cb6a206 100644 --- a/test/parser.test.js +++ b/test/parser.test.js @@ -57,10 +57,6 @@ describe('test parser common', () => { expect(numarr).toEqual([136, 133, 100, 46]); expect(numToNumarr4.reverse(numarr)).toBe(ua); }); - test('test execRandomByNumber', () => { - const randoms = [0.37630721305483794,0.2049460014355331,0.03410129090487546,0.2559079515317211,0.8377333429169194,0.619292978894294,0.4764635791178553,0.11004709981352878,0.8170060761966771,0.8912536097378767,0.3429872257409361,0.5367431913317162,0.1448222378776065,0.13721258163260086,0.4481790608416749,0.04311100885930985,0.6479884219882253,0.9273382739877349,0.3772136159635484,0.7717630008212142,0.42930838879719513,0.9985907486817889,0.5120853266504071,0.6329456412698085,0.38321486257144755,0.5695697450388872,0.3465729558019228,0.8778743938498155,0.024480669878132133,0.9070571729910759,0.8364410662648827,0.9669481262609505,0.07964482428249209,0.5297012796809408,0.21707900074248832,0.9188445039067206,0.8891992862516525,0.5850359934249489,0.527957313371116,0.37782459814806235,0.9753371617969784,0.9583194759953719,0.20562520266687168,0.6543535471216768,0.9183569514304248,0.6891275630046727,0.15242546632122167,0.4310357539068497,0.3027770541955994,0.13451123317248914,0.6203119685550011,0.6827551212241167,0.3073104017788997,0.9338556600045314,0.3722074026925808,0.43574057511654285,0.5384535459384472,0.3337761997946602,0.19885586866091054,0.3508775524265033,0.5119992383579299,0.36780327787218337,0.42221833899684724,0.11657126994371492,0.9298990516926506,0.0321849565507113,0.32944413386321036,0.14344209098548966,0.46021855121620003,0.8499248665702428,0.3368607733729687,0.2841884826356751,0.2750956232497943,0.06926311510145133,0.6381030029388948,0.05110415814304714,0.08773716922264008,0.021305098235796294,0.4359464033542948,0.6969103629361093,0.7713124866246208,0.5982446587781842,0.19015508004688697,0.5934645228072788,0.99154595778769,0.6112663700541248,0.4665216313510534,0.6221792047459951,0.8294207139375269,0.9589407138679342,0.11675372570297649,0.007631410573399888,0.40959542468137955,0.41510808627149975,0.5123086579716352,0.7497877285646639,0.10999323473542444,0.9814640696203702]; - expect(execRandomByNumber(undefined, randoms)).toEqual([49, 9]); - }) test('test numToNumarr8', () => { expect(numToNumarr8(3127628117497590)).toEqual([0, 11, 28, 143, 170, 238, 214, 246]); }); diff --git a/utils/parseRsurl.js b/utils/parseRsurl.js new file mode 100644 index 0000000..a016a33 --- /dev/null +++ b/utils/parseRsurl.js @@ -0,0 +1,34 @@ +const adapt = require('@src/adapt'); +const isValidUrl = require('@utils/isValidUrl'); +const request = require('request-promise'); +const cheerio = require('cheerio'); +const tough = require('tough-cookie'); +const urlresolve = require('url').resolve; + +module.exports = async (url, name, options = {}) => { + if (!isValidUrl(url)) throw new Error('输入链接不正确'); + const cookieJar = new tough.CookieJar(); + options.jar = cookieJar; + const res = await request(url, options); + const $ = cheerio.load(res); + const scripts = [...$('script')] + const tsscript = scripts.map(ele => $(ele).text()).filter(text => text.includes('$_ts.nsd') && text.includes('$_ts.cd')); + if (!tsscript.length) throw new Error('链接返回结果未找到cd或nsd'); + const $_ts = Function('window', tsscript[0] + 'return $_ts')({}); + const checkSrc = (src) => src?.split('.').pop() === 'js' ? src : undefined; + const remotes = scripts.map(it => checkSrc(it.attribs.src)).filter(Boolean); + if (!remotes.length) throw new Error('未找到js外链,无法提取配置文本请检查!'); + for(let src of remotes) { + const jscode = await request(urlresolve(url, src), options); + if (jscode.includes('r2mKa')) { + return { + $_ts, + immucfg: adapt(jscode, name), + options, + request, + }; + } + } + throw new Error('js外链中没有瑞数的代码文件'); +} +