新聞中心
前言
前幾天在Python星耀和最強(qiáng)王者交流群里邊,好幾個(gè)人都在問JS逆向的視頻和相關(guān)代碼,看來都在學(xué)習(xí)進(jìn)階的知識(shí),真是卷不動(dòng)了。正好這幾天我也在看JS的部分學(xué)習(xí)資料,看到一個(gè)還不錯(cuò)的案例,這里拿出來給大家分享一下,也當(dāng)記錄一下。

創(chuàng)新互聯(lián)成立十余年來,這條路我們正越走越好,積累了技術(shù)與客戶資源,形成了良好的口碑。為客戶提供成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)站策劃、網(wǎng)頁設(shè)計(jì)、申請(qǐng)域名、網(wǎng)絡(luò)營(yíng)銷、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。網(wǎng)站是否美觀、功能強(qiáng)大、用戶體驗(yàn)好、性價(jià)比高、打開快等等,這些對(duì)于網(wǎng)站建設(shè)都非常重要,創(chuàng)新互聯(lián)通過對(duì)建站技術(shù)性的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究為客戶提供一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進(jìn)步。
JS代碼
關(guān)于JS代碼的尋找,寫文章說明倒是挺難的,錄制視頻講解會(huì)更好一些,這里直接把現(xiàn)成的JS的代碼安排上了。這個(gè)JS加密代碼找起來一開始是挺難的,需要不斷的打斷點(diǎn),找到加密規(guī)律,一層一層的剝洋蔥,才能一探究竟。本文使用的這個(gè)JS加密代碼來自某個(gè)小視頻網(wǎng)站,網(wǎng)頁上呈現(xiàn)的加密函數(shù)如下圖所示:
加密方式不算太難,其中decodeMp4.decode()加密函數(shù)核心代碼如下所示。
define("tool", function(a, b, c) {
var d = a("jquery")
, e = a("support")
, f = a("constants")
, g = a("base64")
, h = "substring"
, i = "split"
, j = "replace"
, k = "substr";
b.decodeMp4 = {
getHex: function(a) {
return {
str: a[h](4),
hex: a[h](0, 4)[i]("").reverse().join("")
}
},
getDec: function(a) {
var b = parseInt(a, 16).toString(); # 對(duì)應(yīng)Python中的str(int(a, 16))
return {
pre: b[h](0, 2)[i](""),
tail: b[h](2)[i]("")
}
},
substr: function(a, b) {
var c = a[h](0, b[0])
, d = a[k](b[0], b[1]);
return c + a[h](b[0])[j](d, "")
},
getPos: function(a, b) {
return b[0] = a.length - b[0] - b[1],
b
},
decode: function(a) {
var b = this.getHex(a)
, c = this.getDec(b.hex)
, d = this[k](b.str, c.pre);
return g.atob(this[k](d, this.getPos(d, c.tail)))
}
};可以看到調(diào)用了decodeMp4中的decode()函數(shù),而decode()函數(shù)中依次又調(diào)用了getHex(a)、getDec(b.hex)、g.atob()、getPos(d, c.tail)等函數(shù),而我們要做的,就是將這些函數(shù),轉(zhuǎn)換為Python的寫法,然后構(gòu)造對(duì)應(yīng)的加密方式,得到加密后的結(jié)果,就可以完成逆向效果了。
轉(zhuǎn)換過程
這里的變量a通過打斷點(diǎn)的方式,得到的是一個(gè)長(zhǎng)字符串,這里以下面的變量作為示例。
a = "c0b1Ly9tdnPflQ3cQpPZpZGVvMTAubWVpdHVkYXRhLmNvbS82MWM0NDNlOGI1MmFmMTYzMi5tcDkBOyQ"
這里先提前把后面需要用到的函數(shù)做個(gè)簡(jiǎn)單的整理,這樣也方便大家后面查看。
依次以每個(gè)函數(shù)來作為拆解,具體如下:
1、getHex(a)函數(shù)
var h = "substring",i = "split";
getHex: function(a) {
return {
str: a[h](4),
hex: a[h](0, 4)[i]("").reverse().join("")
}
},
上面這個(gè)是對(duì)應(yīng)的getHex()函數(shù)JS代碼,可以看到直接返回了一個(gè)字典,字典的key分別是str和hex,其中str對(duì)應(yīng)的值是a[h](4),h的定義是substring,這個(gè)函數(shù)的意思是字符串從指定下標(biāo)開始取值直到到字符串結(jié)尾,這里翻譯過來就是a.substring(4),也就是字符串a(chǎn)從下標(biāo)4開始取到結(jié)束;a[h](0, 4)[i]("").reverse().join("")這個(gè)理解起來復(fù)雜一些,首先是取字符串的值,位置是從0到4,之后調(diào)用了函數(shù)i,即split函數(shù),以空格("")作為分割,調(diào)用reverse()函數(shù)倒序排序,之后調(diào)用join("")進(jìn)行字符串連接,拆解之后就簡(jiǎn)單很多了。接下來就是構(gòu)造Python代碼了,對(duì)照寫完之后如下所示:
def getHex(a):
return {
"str": a[4:], # JS中的substring(4)指的是從4開始取值到字符串末尾
"hex": "".join(list(a[0:4])[::-1]) # [::-1]代表的是反向取值
}
看著是不是似曾相識(shí)呢?同上面的JS代碼如出一轍。
2、getDec(a)函數(shù)
其JS代碼如下:
getDec: function(a) {
var b = parseInt(a, 16).toString();
return {
pre: b[h](0, 2)[i](""),
tail: b[h](2)[i]("")
}
},根據(jù)對(duì)應(yīng)關(guān)系,可以寫出對(duì)應(yīng)的Python代碼如下所示:
def getDec(a):
b = str(int(a, 16))
print(b)
return {
"pre": list(b[:2]),
"tail": list(b[2:])
}
3、substr(a, b)函數(shù)
其JS代碼如下:
substr: function(a, b) {
var c = a[h](0, b[0])
, d = a[k](b[0], b[1]);
return c + a[h](b[0])[j](d, "")
},根據(jù)對(duì)應(yīng)關(guān)系,可以寫出對(duì)應(yīng)的Python代碼如下所示:
def substr(a, b):
c = a[0: int(b[0])]
print(c)
d = a[int(b[0]):int(b[0])+int(b[1])]
print(d)
return c + a[int(b[0]):].replace(d, '')
4、getPos(a, b)函數(shù)
其JS代碼如下:
getPos: function(a, b) {
return b[0] = a.length - b[0] - b[1],
b
},根據(jù)對(duì)應(yīng)關(guān)系,可以寫出對(duì)應(yīng)的Python代碼如下所示:
def getPos(a, b):
b[0] = len(a) - int(b[0]) - int(b[1])
print(b[0])
return b
5、decode(a, b)函數(shù)
其JS代碼如下:
decode: function(a) {
var b = this.getHex(a)
, c = this.getDec(b.hex)
, d = this[k](b.str, c.pre);
return g.atob(this[k](d, this.getPos(d, c.tail)))
}根據(jù)對(duì)應(yīng)關(guān)系,可以寫出對(duì)應(yīng)的Python代碼如下所示:
b = getHex(a)
# print(b)
c = getDec(b['hex'])
print(c)
# d = k(str(b), c.pre)
d = substr(b['str'], c['pre'])
# print(d)
return base64.b64decode(substr(d, getPos(d, c['tail'])))
效果展示
直接通過網(wǎng)絡(luò)爬蟲進(jìn)行請(qǐng)求,你拿不到最終的這個(gè)加密后的地址的,不論你怎么請(qǐng)求,都是拿不到的,你只能拿到data-src,即上面說的字符串變量a,只有通過逆向之后,通過上面的解析,運(yùn)行代碼,即可得到和網(wǎng)頁上一樣的請(qǐng)求地址,如下圖所示,逆向成功!
把這個(gè)地址放到瀏覽器,是可以播放的,然后一個(gè)請(qǐng)求下載,即可把視頻拿下。
總結(jié)
大家好,我是Python進(jìn)階者。這篇文章主要基于Python網(wǎng)絡(luò)爬蟲中的JS逆向問題,做了一個(gè)案例講解。網(wǎng)頁有JS加載的情況,如果直接通過網(wǎng)絡(luò)爬蟲進(jìn)行請(qǐng)求,你拿不到最終的這個(gè)加密后的地址的,針對(duì)該逆向問題,做了一個(gè)簡(jiǎn)單的逆向示例實(shí)現(xiàn)過程。
分享名稱:盤點(diǎn)一份JS逆向代碼轉(zhuǎn)換為Python代碼的教程
URL分享:http://www.5511xx.com/article/djcpedj.html


咨詢
建站咨詢
