如果我們添加一個字符串,JavaScript會假定我們希望為文本形式表示,所以將它轉(zhuǎn)換為一個字符串。如果我們添加一個正負(fù)前綴符號,JavaScript會假定我們希望為數(shù)值形式表示,如果可能的話,對我們來說并將字符串轉(zhuǎn)換為一個數(shù)字。如果我們添加一個否定符號,JavaScript會將將字符串轉(zhuǎn)換為一個布爾值。
我們可以使用Javascript中[,],(,),! and +這六個符號寫一些神奇的代碼。如果你現(xiàn)在不是在手機(jī),你可以打開瀏覽器的控制臺,你可以將任何代碼示例粘貼到控制臺,并且代碼值為true。
讓我們從最基本的開始,要記住一些黃金規(guī)則:
!后面跟的字符會被轉(zhuǎn)換成布爾值
+后面跟的字符會被轉(zhuǎn)換成數(shù)值
[]后面跟的字符會被轉(zhuǎn)換成字符串
來看下面的例子:
![] === false +[] === 0 []+[] === ""
另一件事你應(yīng)該知道的是,它可以從字符串使用方括號檢索特定的字母,像這樣:
"hello"[0] === "h"
還記得可以使多個數(shù)字號碼通過添加字符串表示在一起,然后把整個表達(dá)式轉(zhuǎn)換成一個數(shù)字:
+("1" + "1") === 11
我們們繼續(xù)把一些東西結(jié)合在一起得到字母a
![] === false ![]+[] === "false" +!![] === 1 ------------------------ (![]+[])[+!![]] === "a" // same as "false"[1]
舉一反三!
我們可以通過true 和 false得到相似的字母a,e,f,l,r,s,t,u,那么我們可以從其他地方得到的字母嗎?
我們可以通過一些特別的式子如[][[]]得到undefined,利用我們上面講到的黃金法則得到另外的字母d,i 和 n。
`[][[]] + [] === "undefined"`
到目前為止,利用我們已經(jīng)獲得的所有字母,我們可以拼fill, filter 和 find。當(dāng)然也有一些其他的單詞,我們也可以拼寫,但這些單詞最重要的是,他們都是數(shù)組的方法。這意味著他們是數(shù)組對象的一部分,可以直接調(diào)用數(shù)組實例,如:[2,1].sort()。
現(xiàn)在,了解JavaScript的另一件重要的特性是一個對象的屬性可以通過點(diǎn)符號.或方括號[]訪問。上述數(shù)組方法是數(shù)組對象本身的屬性,我們可以使用方括號代替點(diǎn)符號調(diào)用這些方法。
所以[2,1]["sort"]() 等效于 [2,1].sort().
我們繼續(xù)看看,當(dāng)我們試圖使用一個數(shù)組的方法會發(fā)生什么,我們可以使用到目前為止我們拼寫的但沒有調(diào)用的字母。
[]["fill"]
這會得到function fill() { [native code] },我們可以把這個方法頭作為一個字符串再次使用我們的黃金法則:
[]["fill"]+[] === "function fill() { [native code] }"
所以現(xiàn)在我們又得到其他的字符:c,o,v,(,),{,[,],}。
隨著我們新得到的c和o,我們現(xiàn)在可以形成constructor這個單詞。構(gòu)造函數(shù)是一個方法,所有JS對象僅返回自己的構(gòu)造函數(shù)。
到目前為止我們已經(jīng)處理的對象,我們可以得到它用字符串表示的構(gòu)造器函數(shù):
true["constructor"] + [] === "function Boolean() { [native code] }" 0["constructor"] + [] === "function Number() { [native code] }" ""["constructor"] + [] === "function String() { [native code] }" []["constructor"] + [] === "function Array() { [native code] }" ({})["constructor"] + [] === "function Object() { [native code] }"
通過這些式子,我們可以將下面的字符加入到我們的庫中:
現(xiàn)在我們可以構(gòu)造一個我們可以使用方括號的函數(shù)"toString"`,我們可以這樣調(diào)用:
(10)["toString"]() === "10"
使用我們的黃金法則,我們已經(jīng)可以將任何我們想要轉(zhuǎn)換成一個字符串,但是上面這個式子怎么用呢?
好吧,我告訴你,Number類型的toString方法有一個稱為radix(“基數(shù)”)的秘密的論點(diǎn)。它可以將數(shù)值在轉(zhuǎn)換為一個字符串之前先經(jīng)過基數(shù)換算,像這樣:
(12)["toString"](10) === "12" // 十進(jìn)制 (12)["toString"](2) === "1100" // 二進(jìn)制 (12)["toString"](8) === "14" // 八進(jìn)制 (12)["toString"](16) === "c" // 十六進(jìn)制
但是為什么基數(shù)只寫到16?最大值是36,包括所有的字符0-9 和 a-z,所以現(xiàn)在我們可以得到任何我們想要的字母數(shù)字:
(10)["toString"](36) === "a" (35)["toString"](36) === "z"
太棒了!但是其它符號如標(biāo)點(diǎn)符號和大寫字母呢?我們接著深入探索。
這取決于你的JS執(zhí)行時,它可能會或可能不會訪問特定的預(yù)定義的對象或數(shù)據(jù)。如果你在瀏覽器中運(yùn)行它,那么你可以訪問一些存在的HTML包裝器方法。
例如,bold是一個包裝在<>標(biāo)簽中的字符串方法。
"test"["bold"]() === "test"
通過這個我們得到<>和/兩個字符。
你可能聽說過escape方法,它主要將字符串轉(zhuǎn)換為一個URI友好的格式,可以讓簡單的瀏覽器解釋。如果我們傳遞一個空格字符,我們得到的"%20"。
這里有一個工具可以自動將每個字符自動轉(zhuǎn)換。 工具地址:http://www.jsfuck.com/ 源代碼地址:https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js
為什么這幾個字符有用?
它不是易趣網(wǎng)做的一些不好的事情,不久前允許賣家將執(zhí)行JS在頁面中使用只能使用這些字符,但它是一個相當(dāng)罕見的攻擊向量。有些人說混淆,但事實上,有更好的方法混淆。
最后,希望你會喜歡本次探秘之旅。
資源:
https://en.wikipedia.org/wiki/JSFuck
https://esolangs.org/wiki/JSFuck
http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html
https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com