|
"use strict"; |
|
var __importDefault = (this && this.__importDefault) || function (mod) { |
|
return (mod && mod.__esModule) ? mod : { "default": mod }; |
|
}; |
|
Object.defineProperty(exports, "__esModule", { value: true }); |
|
exports.getApkInfo = exports.Platform = exports.Device = exports.generateFullDevice = exports.generateShortDevice = void 0; |
|
const crypto_1 = require("crypto"); |
|
const constants_1 = require("./constants"); |
|
const axios_1 = __importDefault(require("axios")); |
|
const algo_1 = require("./algo"); |
|
function generateImei() { |
|
let imei = `86${(0, constants_1.randomString)(12, '0123456789')}`; |
|
function calcSP(imei) { |
|
let sum = 0; |
|
for (let i = 0; i < imei.length; ++i) { |
|
if (i % 2) { |
|
let j = parseInt(imei[i]) * 2; |
|
sum += j % 10 + Math.floor(j / 10); |
|
} |
|
else { |
|
sum += parseInt(imei[i]); |
|
} |
|
} |
|
return (100 - sum) % 10; |
|
} |
|
return imei + calcSP(imei); |
|
} |
|
|
|
function generateShortDevice() { |
|
const randstr = (length, num = false) => { |
|
const map = num ? '0123456789' : '0123456789abcdef'; |
|
return (0, constants_1.randomString)(length, map); |
|
}; |
|
return { |
|
"--begin--": "该设备为随机生成,丢失后不能得到原先配置", |
|
product: `ILPP-${randstr(5).toUpperCase()}`, |
|
device: `${randstr(5).toUpperCase()}`, |
|
board: `${randstr(5).toUpperCase()}`, |
|
brand: `${randstr(4).toUpperCase()}`, |
|
model: `ILPP ${randstr(4).toUpperCase()}`, |
|
wifi_ssid: `HUAWEI-${randstr(7)}`, |
|
bootloader: `U-boot`, |
|
android_id: `IL.${randstr(7, true)}.${randstr(4, true)}`, |
|
boot_id: `${randstr(8)}-${randstr(4)}-${randstr(4)}-${randstr(4)}-${randstr(12)}`, |
|
proc_version: `Linux version 5.10.101-android12-${randstr(8)}`, |
|
mac_address: `2D:${randstr(2).toUpperCase()}:${randstr(2).toUpperCase()}:${randstr(2).toUpperCase()}:${randstr(2).toUpperCase()}:${randstr(2).toUpperCase()}`, |
|
ip_address: `192.168.${randstr(2, true)}.${randstr(2, true)}`, |
|
imei: `${generateImei()}`, |
|
incremental: `${randstr(10).toUpperCase()}`, |
|
"--end--": "修改后可能需要重新验证设备。" |
|
}; |
|
} |
|
exports.generateShortDevice = generateShortDevice; |
|
|
|
function generateFullDevice(apk, d) { |
|
if (!d) |
|
d = generateShortDevice(); |
|
return { |
|
display: d.android_id, |
|
product: d.product, |
|
device: d.device, |
|
board: d.board, |
|
brand: d.brand, |
|
model: d.model, |
|
bootloader: d.bootloader, |
|
fingerprint: `${d.brand}/${d.product}/${d.device}:10/${d.android_id}/${d.incremental}:user/release-keys`, |
|
boot_id: d.boot_id, |
|
proc_version: d.proc_version, |
|
baseband: "", |
|
sim: "T-Mobile", |
|
os_type: "android", |
|
mac_address: d.mac_address, |
|
ip_address: d.ip_address, |
|
wifi_bssid: d.mac_address, |
|
wifi_ssid: d.wifi_ssid, |
|
imei: d.imei, |
|
android_id: d.android_id, |
|
apn: "wifi", |
|
version: { |
|
incremental: d.incremental, |
|
release: "10", |
|
codename: "REL", |
|
sdk: 29, |
|
}, |
|
imsi: (0, crypto_1.randomBytes)(16), |
|
guid: (0, constants_1.md5)(Buffer.concat([Buffer.from(d.imei), Buffer.from(d.mac_address)])), |
|
}; |
|
} |
|
exports.generateFullDevice = generateFullDevice; |
|
class Device { |
|
constructor(apk, d) { |
|
this.apk = apk; |
|
this.secret = 'ZdJqM15EeO2zWc08'; |
|
this.publicKey = `-----BEGIN PUBLIC KEY----- |
|
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEIxgwoutfwoJxcGQeedgP7FG9 |
|
qaIuS0qzfR8gWkrkTZKM2iWHn2ajQpBRZjMSoSf6+KJGvar2ORhBfpDXyVtZCKpq |
|
LQ+FLkpncClKVIrBwv6PHyUvuCb0rIarmgDnzkfQAqVufEtR64iazGDKatvJ9y6B |
|
9NMbHddGSAUmRTCrHQIDAQAB |
|
-----END PUBLIC KEY-----`; |
|
if (!d) |
|
d = generateShortDevice(); |
|
Object.assign(this, generateFullDevice(apk, d)); |
|
} |
|
async getQIMEI() { |
|
if (this.apk.app_key === "") { |
|
return; |
|
} |
|
const k = (0, constants_1.randomString)(16); |
|
const key = (0, algo_1.encryptPKCS1)(this.publicKey, k); |
|
const time = Date.now(); |
|
const nonce = (0, constants_1.randomString)(16); |
|
const payload = this.genRandomPayloadByDevice(); |
|
const params = (0, algo_1.aesEncrypt)(JSON.stringify(payload), k).toString('base64'); |
|
try { |
|
const { data } = await axios_1.default.post("https://snowflake.qq.com/ola/android", { |
|
key, |
|
params, |
|
time, nonce, |
|
sign: (0, constants_1.md5)(key + params + time + nonce + this.secret).toString("hex"), |
|
extra: '' |
|
}, { |
|
headers: { |
|
'User-Agent': `Dalvik/2.1.0 (Linux; U; Android ${this.version.release}; PCRT00 Build/N2G48H)`, |
|
'Content-Type': "application/json" |
|
} |
|
}); |
|
if (data?.code !== 0) { |
|
return; |
|
} |
|
const { q16, q36 } = JSON.parse((0, algo_1.aesDecrypt)(data.data, k)); |
|
this.qImei16 = q16; |
|
this.qImei36 = q36; |
|
} |
|
catch { |
|
} |
|
} |
|
genRandomPayloadByDevice() { |
|
const fixedRand = (max = 1, min = 0) => { |
|
if (max < min) |
|
[max, min] = [min, max]; |
|
const diff = max - min; |
|
return Math.floor(Math.random() * diff) + min; |
|
}; |
|
const reserved = { |
|
"harmony": "0", |
|
"clone": Math.random() > 0.5 ? "1" : "0", |
|
"containe": "", |
|
"oz": "", |
|
"oo": "", |
|
"kelong": Math.random() > 0.5 ? "1" : "0", |
|
"uptimes": (0, constants_1.formatTime)(new Date()), |
|
"multiUser": Math.random() > 0.5 ? "1" : "0", |
|
"bod": this.board, |
|
"brd": this.brand, |
|
"dv": this.device, |
|
"firstLevel": "", |
|
"manufact": this.brand, |
|
"name": this.model, |
|
"host": "se.infra", |
|
"kernel": this.fingerprint |
|
}; |
|
const timestamp = Date.now(); |
|
this.mtime = this.mtime || Date.now(); |
|
const mtime1 = new Date(this.mtime || Date.now()); |
|
const dateFormat = (fmt, time = Date.now()) => (0, constants_1.formatTime)(time, fmt); |
|
const mtimeStr1 = dateFormat("YYYY-mm-ddHHMMSS", mtime1) + "." + this.imei.slice(2, 11); |
|
const mtime2 = new Date(this.mtime - parseInt(this.imei.slice(2, 4))); |
|
const mtimeStr2 = dateFormat("YYYY-mm-ddHHMMSS", mtime2) + "." + this.imei.slice(5, 14); |
|
let beaconIdArr = [ |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
mtimeStr1, |
|
'0000000000000000', |
|
(0, constants_1.md5)(this.android_id + this.imei).toString("hex").slice(0, 16), |
|
...new Array(4).fill(false).map((_) => fixedRand(10000000, 1000000)), |
|
this.boot_id, |
|
'1', |
|
fixedRand(5, 0), |
|
fixedRand(5, 0), |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
fixedRand(5, 0), |
|
fixedRand(100, 10), |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
fixedRand(50000, 10000), |
|
fixedRand(100, 10), |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
mtimeStr2, |
|
fixedRand(10000, 1000), |
|
fixedRand(5, 0), |
|
`${dateFormat("YYYY-mm-ddHHMMSS")}.${String(((10 + parseInt(this.imei.slice(5, 7))) % 100)).padStart(2, "0")}0000000`, |
|
`${dateFormat("YYYY-mm-ddHHMMSS")}.${String(((11 + parseInt(this.imei.slice(5, 7))) % 100)).padStart(2, "0")}0000000`, |
|
fixedRand(10000, 1000), |
|
fixedRand(100, 10), |
|
`${dateFormat("YYYY-mm-ddHHMMSS")}.${String(((11 + parseInt(this.imei.slice(5, 7))) % 100)).padStart(2, "0")}0000000`, |
|
`${dateFormat("YYYY-mm-ddHHMMSS")}.${String(((11 + parseInt(this.imei.slice(5, 7))) % 100)).padStart(2, "0")}0000000`, |
|
fixedRand(10000, 1000), |
|
fixedRand(5, 0), |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
fixedRand(5, 0), |
|
fixedRand(100, 10), |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
`${(0, constants_1.formatTime)(new Date(timestamp + fixedRand(60, 0)))}.${String(fixedRand(99, 0)).padStart(2, '0')}0000000`, |
|
fixedRand(5, 0), |
|
fixedRand(5, 0), |
|
].map((str, idx) => `k${idx + 1}:${str}`); |
|
return { |
|
"androidId": this.android_id, |
|
"platformId": 1, |
|
"appKey": this.apk.app_key, |
|
"appVersion": this.apk.version, |
|
"beaconIdSrc": beaconIdArr.join(';'), |
|
"brand": this.brand, |
|
"channelId": "2017", |
|
"cid": "", |
|
"imei": this.imei, |
|
"imsi": this.imsi.toString("hex"), |
|
"mac": this.mac_address, |
|
"model": this.model, |
|
"networkType": "unknown", |
|
"oaid": "", |
|
"osVersion": `Android ${this.version.release},level ${this.version.sdk}`, |
|
"qimei": "", |
|
"qimei36": "", |
|
"sdkVersion": "1.2.13.6", |
|
"targetSdkVersion": "26", |
|
"audit": "", |
|
"userId": "{}", |
|
"packageId": this.apk.id, |
|
"deviceType": this.display, |
|
"sdkName": "", |
|
"reserved": JSON.stringify(reserved), |
|
}; |
|
} |
|
} |
|
exports.Device = Device; |
|
|
|
var Platform; |
|
(function (Platform) { |
|
Platform[Platform["Android"] = 1] = "Android"; |
|
Platform[Platform["aPad"] = 2] = "aPad"; |
|
Platform[Platform["Watch"] = 3] = "Watch"; |
|
Platform[Platform["iMac"] = 4] = "iMac"; |
|
Platform[Platform["iPad"] = 5] = "iPad"; |
|
})(Platform = exports.Platform || (exports.Platform = {})); |
|
const mobile = { |
|
id: "com.tencent.mobileqq", |
|
app_key: '0S200MNJT807V3GE', |
|
name: "A8.9.50.f5a7d351", |
|
version: "8.9.50.10650", |
|
ver: "8.9.50", |
|
sign: Buffer.from([0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D]), |
|
buildtime: 1676531414, |
|
appid: 16, |
|
subid: 537118044, |
|
bitmap: 150470524, |
|
main_sig_map: 16724722, |
|
sub_sig_map: 0x10400, |
|
sdkver: "6.0.0.2535", |
|
display: "Android", |
|
ssover: 19, |
|
}; |
|
const watch = { |
|
id: "com.tencent.qqlite", |
|
app_key: '0S200MNJT807V3GE', |
|
name: "A2.0.8", |
|
version: "2.0.8", |
|
ver: "2.0.8", |
|
sign: Buffer.from([166, 183, 69, 191, 36, 162, 194, 119, 82, 119, 22, 246, 243, 110, 182, 141]), |
|
buildtime: 1559564731, |
|
appid: 16, |
|
subid: 537118044, |
|
bitmap: 16252796, |
|
main_sig_map: 16724722, |
|
sub_sig_map: 0x10400, |
|
sdkver: "6.0.0.2365", |
|
display: "Watch", |
|
ssover: 5 |
|
}; |
|
const hd = { |
|
id: "com.tencent.minihd.qq", |
|
app_key: '0S200MNJT807V3GE', |
|
name: "A5.9.3.3468", |
|
version: "5.9.3.3468", |
|
ver: "5.9.3", |
|
sign: Buffer.from([0xAA, 0x39, 0x78, 0xF4, 0x1F, 0xD9, 0x6F, 0xF9, 0x91, 0x4A, 0x66, 0x9E, 0x18, 0x64, 0x74, 0xC7]), |
|
buildtime: 1637427966, |
|
appid: 16, |
|
subid: 537118044, |
|
bitmap: 150470524, |
|
main_sig_map: 1970400, |
|
sub_sig_map: 66560, |
|
sdkver: "6.0.0.2433", |
|
display: "iMac", |
|
ssover: 12 |
|
}; |
|
const apklist = { |
|
[Platform.Android]: mobile, |
|
[Platform.aPad]: { |
|
...mobile, |
|
subid: 537118044, |
|
display: 'aPad' |
|
}, |
|
[Platform.Watch]: watch, |
|
[Platform.iMac]: { ...hd }, |
|
[Platform.iPad]: { |
|
...mobile, |
|
subid: 537118044, |
|
sign: hd.sign, |
|
name: 'A8.9.50.611', |
|
version: 'A8.9.50.611', |
|
sdkver: '6.0.0.2535', |
|
display: 'iPad' |
|
}, |
|
}; |
|
function getApkInfo(p) { |
|
return apklist[p] || apklist[Platform.Android]; |
|
} |
|
exports.getApkInfo = getApkInfo; |
|
|