怎樣看出一個網(wǎng)站是那個公司做的合肥百度推廣公司哪家好
a_bogus算法還原大賞
hello,大家好呀,我是你的好兄弟,[星云牛馬],花了幾天時間算法還原了這個參數(shù)的加密過程,一起看看吧,記得加入我們的學(xué)習(xí)群:529528142
- 天才第一步,
F12
你會不?
- 天才第二步,
js
斷點要斷住
從這里開始你的逐步斷點之旅……
有經(jīng)驗的伙伴肯定知道,這是jsvmp
扣代碼意義不大,所以這篇文章,介紹算法還原
每個循環(huán)的處理中,我們都加入這樣的日志,將關(guān)鍵的存放運算中間值的變量全部輸出到日志中。
另外,因為是算法還原,最重要的位運算相關(guān)的地方,全部加上輸出日志:
好的,你已經(jīng)成功了1/2,毫不夸張的說,好的日志是還原算法的最重要的前提之一哦。
好的刷新頁面,保存日志到本地,開始分析!
直接搜索a_bogus
:
定位到最開始出現(xiàn)的地方,接下來往上尋找依賴關(guān)系!
[xx]func function charCodeAt() { [native code] } called, args->, [30] ==> 10[algo]10&255 => 10[algo]10<<16 => 655360[algo] 31++ =>[xx]func function charCodeAt() { [native code] } called, args->, [31] ==> 217[algo]217&255 => 217[algo]217<<8 => 55552[algo]655360|55552 => 710912[algo] 32++ =>[xx]func function charCodeAt() { [native code] } called, args->, [32] ==> 153[algo]153&255 => 153[algo]710912|153 => 711065[algo]711065&16515072 => 524288[algo]524288>>18 => 2[xx]func function charAt() { [native code] } called, args->, [2] ==> d[algo]711065&258048 => 184320[algo]184320>>12 => 45[xx]func function charAt() { [native code] } called, args->, [45] ==> z[algo]711065&4032 => 2432[algo]2432>>6 => 38[xx]func function charAt() { [native code] } called, args->, [38] ==> o[algo]711065&63 => 25[xx]func function charAt() { [native code] } called, args->, [25] ==> 4
可以看到,是亂碼的三個一組,三個一組地生成的4個字符,由亂碼、和Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe
字符串參與運算,得出。
亂碼長度為33 那么最終產(chǎn)生的a_bogus長度就是33/3*4=44,和上面的截圖一致
解密代碼如下:
let lm1 = "�BàR?ü<�\u0017=\u0004\u001c�Pm?�H\bí\r??é\u0010x-?-t\nù�"
let s = {"s0": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=","s1": "Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=","s2": "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=","s3": "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe","s4": "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe"}let out = "";for (let i = 0; i < lm1.length; i = i + 3) {let num1 = lm1.charCodeAt(i) << 16 | lm1.charCodeAt(i + 1) << 8 | lm1.charCodeAt(i + 2) << 0out += s.s4.charAt((num1 & 16515072) >> 18)out += s.s4.charAt((num1 & 258048) >> 12)out += s.s4.charAt((num1 & 4032) >> 6)out += s.s4.charAt((num1 & 63) >> 0)}console.log(out)return out
}
接著就是看亂碼是怎么產(chǎn)生的,那個s4是觀察多幾個日志發(fā)現(xiàn)是固定的。
往上看日志發(fā)現(xiàn):
亂碼是由兩個亂碼產(chǎn)生:
let lm_part1 = "?BàR";
let lm_part2 = "?ü<–\u0017=\u0004\u001c”Pm??H\bí\r??é\u0010x-?-t\nù?"
往上搜索lm_part1
最開始出現(xiàn)的位置:
可以看出,日志打印出來的信息還是非常全面的,直接告訴你了是調(diào)用了String.fromCharCode()
這個函數(shù),參數(shù)是[131,66,224,82]
,我還是花費了些時間,思考如何添加日志點的,確實傷頭發(fā),哈哈。
那么這四個數(shù)來自于哪呢?當(dāng)然是就在它上面的這地方尋找線索咯。
[xx]func function now() { [native code] } called, args->, [] ==> 1693911085249
[algo]1693911085250&255 => 194
[algo]1693911085250>>8 => 6617072
[algo]6617072&255 => 240
[algo]194&170 => 130
[algo]3&85 => 1
[algo]130|1 => 131
[algo]194&85 => 64
[algo]3&170 => 2
[algo]64|2 => 66
[algo]240&170 => 160
[algo]160|64 => 224
[algo]240&85 => 80
[algo]66&170 => 2
[algo]80|2 => 82
[xx]func function fromCharCode() { [native code] } called, args->, [131,66,224,82] ==> ?BàR
為了讓大家理解這個過程,我們看一下這個完整過程,下面大家就照葫蘆畫瓢就可以。
131 = 130|1,而130 = 194&170, 1 = 3&85,故:
131 = (194&170) | (3&85),而194 = 1693911085250&255,170、85、3為定數(shù),故
131 = ((1693911085250&255)&170) | (3&85)
其余的數(shù)類似,解密代碼為:
let t3 = 1693911085250
let n1 = t3 & 255
let n2 = (t3 >> 8) & 255
lm_part1_arr.push(n1, n2)
lm_part1_arr.push((n1 & 170) | (3 & 85), (n1 & 85) | (3 & 170), (n2 & 170) | (66 & 85), (n2 & 85) | (66 & 170))
console.log(lm_part1_arr);
let lm_part1 = String.fromCharCode(...lm_part1_arr.slice(5))
接下來我們看一下lm_part2
的地方:
從圖上可以看出,這個亂碼的生成涉及兩個輸入:
- 亂碼:
Ad\u0000\u0004\u0000??’÷\u0000\u0001\u0000???à\u0000\u0000\u0000?\u0000\u0000\u000ed÷?\u000e\u0003à
- 數(shù)組
[62, 17, 140, 235, 54………………50, 219, 128, 218, 223]
這兩個多次調(diào)試數(shù)組為固定的值,也可以去看日志里面的產(chǎn)生邏輯:
這個是由亂碼?
產(chǎn)生的數(shù)組序列,迭代256產(chǎn)生,這里我們就不多分析了。
我們繼續(xù)分析,這個數(shù)組和亂碼是怎么生成lm_part2
的:
從這里可以看出,
? = String.fromCharCode(lm_in.charCodeAt(0) ^ arr_256[24])
ü = String.fromCharCode(lm_in.charCodeAt(1) ^ arr_256[47])
……
其余的類似,看日志就能得出結(jié)論,其中24、47等數(shù)字都是固定的,看日志就能得出。
這樣這個?ü<**–**\u0017=\u0004\u001c**”**Pm?**?**H\\b?\\r??n\u0010
亂碼就逆推完成了。
接下來是lm_in = Ad\u0000\u0004\u0000??’÷\u0000\u0001\u0000????\u0000\u0000\u0000\u001c\u0000\u0000\u000ed÷?\u000e\u0003A
這個的逆推:
顯而易見是由這個數(shù)列產(chǎn)生的亂碼。
那么這個數(shù)列怎么來的:
仔細(xì)分析上面的日志發(fā)現(xiàn)這個數(shù)組是由另一個數(shù)組交換位置得來的,具體我們放在下一篇中介紹!
放一張算法驗證成功截圖:
記得加入粉絲群哦,新鮮文章首先發(fā)布哦。