承接昨日分析,今日我们将进一步深入,通过增设更多断点并丰富日志输出内容,将运算符号+、-、*、/、%、&、|、^等纳入一级关注范畴,继而继续展开细致的分析工作。
此外,我们还将为其他类型的运算添加相应的日志断点,以确保全面获取日志输出。接下来,我们将逐行深入分析这些日志,以揭示其背后的运算逻辑和细节。
在执行过程中,我们将采取逆向分析法,逐步追溯并尝试还原算法的细节。首先,我们需要定位并查阅与a_bogus第一个字符生成相关的日志信息,以此为切入点深入探究。
[ -1 ]apply::: ƒ charCodeAt() { [native code] } 参数d= £Rp`"6¼+½¢è&ý=ßËå4øbòKéçj¡Wjî/Î)<tüÈGåáµ¹Þ¬$¸?ÕEýÁÐò¯tO¾ËT$|Tâ¸GG6,û"øwÆh°å¶ç|ïX*J?
x4õäó#¬¿võHë0£kuã0cí<´U 参数e= [0] 结果m= 163
bdms_1.0.1.19_fix.js:2 [ 0 ]&运算 参数 163 参数 255 结果 163
bdms_1.0.1.19_fix.js:2 [ 0 ]<<运算 参数 163 参数 16 结果 10682368
bdms_1.0.1.19_fix.js:2 [ 1 ]入栈 £Rp`"6¼+½¢è&ý=ßËå4øbòKéçj¡Wjî/Î)<tüÈGåáµ¹Þ¬$¸?ÕEýÁÐò¯tO¾ËT$|Tâ¸GG6,û"øwÆh°å¶ç|ïX*J?
x4õäó#¬¿võHë0£kuã0cí<´U
bdms_1.0.1.19_fix.js:2 [ 3 ]入栈 (10) [Array(2), {…}, '£Rp\x07\x7F`"6\x12¼+½¢è&ý=ßËå\x9F\x8E\x9B4\x0EøbòKéç\x97j¡Wj\x99\x88î\x07/\x96Î)<tüÈG\x80…øwÆh°å¶\x84ç\x1A|\x93ïX*\x9CJ?\x85x4õ\x94äó#¬\x02¿võHë0£k\buã0\x16c\x96í<\x03´U\x7F', 's4', '=', {…}, 'Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe', '', empty, 1]0: (2) [{…}, {…}]1: {0: '£Rp\x07\x7F`"6\x12¼+½¢è&ý=ßËå\x9F\x8E\x9B4\x0EøbòKéç\x97j¡Wj\x99\x88î\x07/\x96Î)<tüÈG\x80…øwÆh°å¶\x84ç\x1A|\x93ïX*\x9CJ?\x85x4õ\x94äó#¬\x02¿võHë0£k\buã0\x16c\x96í<\x03´U\x7F', 1: 's4', length: 2}2: "£Rp\u0007`\"6\u0012¼+½¢è&ý=ßËå4\u000eøbòKéçj¡Wjî\u0007/Î)<tüÈGå\u0006áµ¹\u0003Þ¬$¸?ÕE\u001eýÁÐò¯tO¾ËT$\u001a|Tâ¸GG6,û\u001e\"\u001aøwÆh°å¶ç\u001a|ïX*J?
x4õäó#¬\u0002¿võHë0£k\buã0\u0016cí<\u0003´U"3: "s4"4: "="5: {s0: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', s1: 'Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=', s2: 'Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=', s3: 'ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe', s4: 'Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe'}6: "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe"7: "Y7sjkHtEmNRVFdKtYKEoe3HlnCIlNTuypFixSLFTGGUOYXUOoRNKknCIrxLSUMrmvbpwkK27KfMAPdVbMtXhZFHkLmpfSOty3G2Cn7fL2qJ6bPiZvrRuCJbxLiPbUS4Yu/I9i/W5lsMFIdOWVNChAp37w/3rmcjdFH-7V/ujY9umUA8jho/Ia3jpzhXe"8: 118183679: 141length: 10[[Prototype]]: Array(0)at: ƒ at()concat: ƒ concat()constructor: ƒ Array()copyWithin: ƒ copyWithin()entries: ƒ entries()every: ƒ every()fill: ƒ fill()filter: ƒ filter()find: ƒ find()findIndex: ƒ findIndex()findLast: ƒ findLast()findLastIndex: ƒ findLastIndex()flat: ƒ flat()flatMap: ƒ flatMap()forEach: ƒ forEach()includes: ƒ includes()indexOf: ƒ indexOf()join: ƒ join()keys: ƒ keys()lastIndexOf: ƒ lastIndexOf()length: 0map: ƒ map()pop: ƒ pop()push: ƒ push()reduce: ƒ reduce()reduceRight: ƒ reduceRight()reverse: ƒ reverse()shift: ƒ shift()slice: ƒ slice()some: ƒ some()sort: ƒ sort()splice: ƒ splice()toLocaleString: ƒ toLocaleString()toReversed: ƒ toReversed()toSorted: ƒ toSorted()toSpliced: ƒ toSpliced()toString: ƒ toString()unshift: ƒ unshift()values: ƒ values()with: ƒ with()Symbol(Symbol.iterator): ƒ values()Symbol(Symbol.unscopables): {at: true, copyWithin: true, entries: true, fill: true, find: true, …}[[Prototype]]: Object 9
bdms_1.0.1.19_fix.js:2 [ 0 ]apply::: ƒ charCodeAt() { [native code] } 参数d= £Rp`"6¼+½¢è&ý=ßËå4øbòKéçj¡Wjî/Î)<tüÈGåáµ¹Þ¬$¸?ÕEýÁÐò¯tO¾ËT$|Tâ¸GG6,û"øwÆh°å¶ç|ïX*J?
x4õäó#¬¿võHë0£kuã0cí<´U 参数e= [1] 结果m= 82
bdms_1.0.1.19_fix.js:2 [ 1 ]&运算 参数 82 参数 255 结果 82
bdms_1.0.1.19_fix.js:2 [ 1 ]<<运算 参数 82 参数 8 结果 20992
bdms_1.0.1.19_fix.js:2 [ 0 ]|运算 参数 10682368 参数 20992 结果 10703360
bdms_1.0.1.19_fix.js:2 [ 1 ]入栈 £Rp`"6¼+½¢è&ý=ßËå4øbòKéçj¡Wjî/Î)<tüÈGåáµ¹Þ¬$¸?ÕEýÁÐò¯tO¾ËT$|Tâ¸GG6,û"øwÆh°å¶ç|ïX*J?
x4õäó#¬¿võHë0£kuã0cí<´U
bdms_1.0.1.19_fix.js:2 [ 3 ]入栈 (10) [Array(2), {…}, '£Rp\x07\x7F`"6\x12¼+½¢è&ý=ßËå\x9F\x8E\x9B4\x0EøbòKéç\x97j¡Wj\x99\x88î\x07/\x96Î)<tüÈG\x80…øwÆh°å¶\x84ç\x1A|\x93ïX*\x9CJ?\x85x4õ\x94äó#¬\x02¿võHë0£k\buã0\x16c\x96í<\x03´U\x7F', 's4', '=', {…}, 'Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe', '', empty, 2]0: (2) [{…}, {…}]1: {0: '£Rp\x07\x7F`"6\x12¼+½¢è&ý=ßËå\x9F\x8E\x9B4\x0EøbòKéç\x97j¡Wj\x99\x88î\x07/\x96Î)<tüÈG\x80…øwÆh°å¶\x84ç\x1A|\x93ïX*\x9CJ?\x85x4õ\x94äó#¬\x02¿võHë0£k\buã0\x16c\x96í<\x03´U\x7F', 1: 's4', length: 2}0: "£Rp\u0007`\"6\u0012¼+½¢è&ý=ßËå4\u000eøbòKéçj¡Wjî\u0007/Î)<tüÈGå\u0006áµ¹\u0003Þ¬$¸?ÕE\u001eýÁÐò¯tO¾ËT$\u001a|Tâ¸GG6,û\u001e\"\u001aøwÆh°å¶ç\u001a|ïX*J?
x4õäó#¬\u0002¿võHë0£k\buã0\u0016cí<\u0003´U"1: "s4"length: 2[[Prototype]]: Object2: "£Rp\u0007`\"6\u0012¼+½¢è&ý=ßËå4\u000eøbòKéçj¡Wjî\u0007/Î)<tüÈGå\u0006áµ¹\u0003Þ¬$¸?ÕE\u001eýÁÐò¯tO¾ËT$\u001a|Tâ¸GG6,û\u001e\"\u001aøwÆh°å¶ç\u001a|ïX*J?
x4õäó#¬\u0002¿võHë0£k\buã0\u0016cí<\u0003´U"3: "s4"4: "="5: s0: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="s1: "Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe="s2: "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe="s3: "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe"s4: "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe"[[Prototype]]: Object6: "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe"7: "Y7sjkHtEmNRVFdKtYKEoe3HlnCIlNTuypFixSLFTGGUOYXUOoRNKknCIrxLSUMrmvbpwkK27KfMAPdVbMtXhZFHkLmpfSOty3G2Cn7fL2qJ6bPiZvrRuCJbxLiPbUS4Yu/I9i/W5lsMFIdOWVNChAp37w/3rmcjdFH-7V/ujY9umUA8jho/Ia3jpzhXe"8: 118183679: 141length: 10[[Prototype]]: Array(0) 9
bdms_1.0.1.19_fix.js:2 [ 0 ]apply::: ƒ charCodeAt() { [native code] } 参数d= £Rp`"6¼+½¢è&ý=ßËå4øbòKéçj¡Wjî/Î)<tüÈGåáµ¹Þ¬$¸?ÕEýÁÐò¯tO¾ËT$|Tâ¸GG6,û"øwÆh°å¶ç|ïX*J?
x4õäó#¬¿võHë0£kuã0cí<´U 参数e= [2] 结果m= 112
bdms_1.0.1.19_fix.js:2 [ 1 ]&运算 参数 112 参数 255 结果 112
bdms_1.0.1.19_fix.js:2 [ 0 ]|运算 参数 10703360 参数 112 结果 10703472
第一个字符串代码还原
import { assert } from "console"
const SALT_2: any = {
"s0": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
"s1": "Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=",
"s2": "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=",
"s3": "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe",
"s4": "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe"
}
const obj = {
"0": "Bâ®ö<0\u0012¤)ÍQüÜ\u00184©¦¤ß`\u0003WÛVu9°j¹ÒNÂa妵?§øºÌ\u0007©í\u000f^\"¾\u0003|¤\u0001ÞaÓmèc:ÔrâÃýñG¬EªÀ 9R¦»÷ $+\u0010ü b3\\\b5¦Ê^Å\u0000l ÷uz",
"1": "s3"
}
export function sign() {
// 栈指针位置
let token = ``
const a = 16515072
const params = obj["0"]
const sign = obj["1"]
const signValue = SALT_2[sign]
// step 1
const t0 = params.charCodeAt(0)
const t1 = t0 & 255;
const t2 = t1 << 16; // 4325376
// step2
const t3 = params.charCodeAt(1)
const t4 = t3 & 255;
const t5 = t4 << 8
const t6 = t2 | t5; // 4383232
// step3
const t7 = params.charCodeAt(2)
const t8 = t7 & 255; // 174
const t9 = t8 | t6; // 4383406
// 计算第1个字符串
const t10 = t9 & a; // 4194304
const t11 = t10 >> 18; // 16
const t12 = signValue.charAt(t11)
token += t12;
assert(token === `f`)
// 计算第2个字符串
const t13 = t9 & 258048;// 188416
const t14 = t13 >> 12;
const t15 = signValue.charAt(t14)
token += t15;
assert(token === `fm`)
// 计算第3个字符串
const t16 = t9 & 4032 ;// 640
const t17 = t16 >> 6;
const t18 = signValue.charAt(t17)
token += t18;
assert(token === `fmU`)
// 计算第4个字符串
const t19 = t9 & 63 ;// 640
const t20 = signValue.charAt(t19)
token += t20;
assert(token === `fmUm`)
// 计算第6个字符串
const t21 = params.charCodeAt(3)
const t22 = t21 & 255;
const t23 = t22 << 16; // 16121856
const t24 = params.charCodeAt(4)
const t25 = t24 & 255;
const t26 = t25 << 8;
const t27 = t23 | t26; // 16137216
const t28 = params.charCodeAt(5)
const t29 = t28 & 255;
// 关键值
const t30 = t27 | t29; // 16137264
const t31 = t30 & a; // 15990784
const t32 = t31 >> 18;
const tt33 = signValue.charAt(t32)
token += tt33;
assert(token === `fmUmt`)
const t34 = t30 & 258048;
const t35 = t34 >> 12;
const t36 = signValue.charAt(t35)
token += t36;
assert(token === `fmUmtN`)
console.log({ token })
return token;
}
至此,我们已经可以发现一些潜在的规律。首先,我们需要确定关键值,然后根据数组[258048, 4032, 63]中的元素分别计算索引,并从字典中取出相应的字符串进行拼接,最终形成a_bogus。
import { assert } from "console"
const SALT_2: any = {
"s0": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
"s1": "Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=",
"s2": "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=",
"s3": "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe",
"s4": "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe"
}
const obj = {
"0": "Bâ®ö<0\u0012¤)ÍQüÜ\u00184©¦¤ß`\u0003WÛVu9°j¹ÒNÂa妵?§øºÌ\u0007©í\u000f^\"¾\u0003|¤\u0001ÞaÓmèc:ÔrâÃýñG¬EªÀ 9R¦»÷ $+\u0010ü b3\\\b5¦Ê^Å\u0000l ÷uz",
"1": "s3"
}
export function sign() {
// 栈指针位置
let token = ``
const a = 16515072
const params = obj["0"]
const sign = obj["1"]
const signValue = SALT_2[sign]
const f1 = (v: number) => {
[16515072, 258048, 4032, 63].map((val, i) => {
const t1 = v & val;
const t2 = i % 4
if (t2 === 0) {
const t3 = t1 >> 18
const t4 = signValue.charAt(t3)
token += t4;
}
if (t2 === 1) {
const t3 = t1 >> 12
const t4 = signValue.charAt(t3)
token += t4;
}
if (t2 === 2) {
const t3 = t1 >> 6
const t4 = signValue.charAt(t3)
token += t4;
}
if (t2 === 3) {
const t4 = signValue.charAt(t1)
token += t4;
}
})
}
let toSignValue = 0;
for (let i = 0; i < params.length; i++) {
const t0 = params.charCodeAt(i)
const t1 = t0 & 255;
const t2 = i % 3
if (t2 === 0) {
const t3 = t1 << 16;
toSignValue = t3;
continue;
}
if (t2 === 1) {
const t3 = t1 << 8;
toSignValue = toSignValue | t3;
continue;
}
if (t2 === 2) {
toSignValue = toSignValue | t1;
f1(toSignValue)
continue;
}
}
console.log({ token })
return token;
}
至此,a_bogus算法的还原工作已经顺利完成。在下一节中,我们将不再全面探讨参数obj,而是聚焦于其他关键环节。
各位亲爱的家人们,我目前正在积极寻找与逆向爬虫相关的工作机会。如果您手头有合适的职位,或者知道相关的工作信息,非常希望能得到您的内推帮助!