国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁(yè) web前端 js教程 以下是如何在 JavaScript 中混淆而無(wú)需耗費(fèi)大量時(shí)間:AST、Babel、插件。

以下是如何在 JavaScript 中混淆而無(wú)需耗費(fèi)大量時(shí)間:AST、Babel、插件。

Jan 10, 2025 pm 12:34 PM

介紹

嘿,你有沒(méi)有想過(guò)你的演算法有多酷、多獨(dú)特? ?許多程式設(shè)計(jì)師和公司都這樣做,這就是為什麼他們可能不願(yuàn)意與所有人分享他們的工作。如果將部分程式碼移至伺服器(對(duì)於客戶端-伺服器應(yīng)用程式),這個(gè)問(wèn)題會(huì)稍微好一點(diǎn),但這種方法並不總是可行。有時(shí),我們必須將敏感的程式碼部分直接公開(kāi)。

在本文中,我們將研究 JavaScript 中的混淆,創(chuàng)建隱藏演算法並使學(xué)習(xí)程式碼變得更加困難的方法。我們還將探索 AST 是什麼,並提供可用於與其互動(dòng)以實(shí)現(xiàn)混淆的工具。

這是怎麼回事?

這是一個(gè)愚蠢的例子。讓我們想像一下這種情況:

  1. 鮑伯去了一個(gè)贈(zèng)送電腦顯示器的網(wǎng)站(這裡是 -> ?)。鮑伯的顯示器更好,但免費(fèi)的東西總是好的!
  2. 當(dāng) Bob 造訪網(wǎng)站時(shí),JavaScript 在瀏覽器中執(zhí)行,收集有關(guān)使用者裝置的資料並將其傳送到伺服器。比方說(shuō),就是這樣:
let w = screen.width, h = screen.height;
// Let's say there's a logic with some check. 
console.info(w, h);
  1. 不幸的是,鮑伯無(wú)法造訪贈(zèng)品頁(yè)面,他對(duì)此感到非常沮喪。他不明白為什麼。然後他在贈(zèng)品規(guī)則中了解到,不允許使用者擁有大而好的顯示器。

  2. 幸運(yùn)的是,鮑伯在高中時(shí)參加了一些電腦科學(xué)課程。他果斷按下F12打開(kāi)開(kāi)發(fā)者控制臺(tái),研究了一下腳本,發(fā)現(xiàn)主辦單位正在檢查螢?zāi)唤馕龆取H会崴麤Q定透過(guò)手機(jī)參與並成功通過(guò)測(cè)試。

一個(gè)美好結(jié)局的虛構(gòu)故事 - 但如果主角看到的是這個(gè)而不是之前的代碼,它就不會(huì)這麼好:

l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();

Here
我向你保證,這不是亂碼,而是 JavaScript!並且它執(zhí)行相同的操作。您可以嘗試在此處的控制臺(tái)中執(zhí)行程式碼。

我想在這種情況下,我們的英雄就會(huì)認(rèn)命,不參加有獎(jiǎng)活動(dòng),主辦單位也會(huì)保留他們的計(jì)畫(huà)。

那這裡有什麼意義呢?恭喜 - 您已經(jīng)了解了 jjencode 工具以及混淆是什麼以及它可以發(fā)揮什麼作用。

總之,混淆是將程式碼或資料轉(zhuǎn)換為人類難以理解但仍適用於機(jī)器或程式的形式的過(guò)程。

隱藏秘密??焖俜绞?

理論已經(jīng)夠多了,讓我們繼續(xù)看更多實(shí)際例子? ?? ?,F(xiàn)在,讓我們嘗試使用您更可能在網(wǎng)路上找到的混淆來(lái)轉(zhuǎn)換程式碼。讓我們來(lái)看一個(gè)更有趣的程式碼,其中包含我們的「專有技術(shù)」操作。而且非常不希望每個(gè)不懶得達(dá)到 F12 的人都可以了解它們:

let w = screen.width, h = screen.height;
// Let's say there's a logic with some check. 
console.info(w, h);

例如,此程式碼收集裝置和瀏覽器資料並將結(jié)果輸出到控制臺(tái)(我們將使用輸出作為程式碼效能的指標(biāo)):

l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();

現(xiàn)在讓我們使用流行的 JS 混淆器 - obfuscator.io 來(lái)修改上面的程式碼。結(jié)果,我們會(huì)得到這樣的程式碼:

function getGpuData(){
  let cnv = document.createElement("canvas");
  let ctx = cnv.getContext("webgl");
  const rendererInfo = ctx.getParameter(ctx.RENDERER);
  const vendorInfo = ctx.getParameter(ctx.VENDOR);

  return [rendererInfo, vendorInfo]
}

function getLanguages(){
  return window.navigator.languages;
}

let data = {};
data.gpu = getGpuData();
data.langs = getLanguages();
console.log(JSON.stringify(data))

瞧!現(xiàn)在,只有機(jī)器會(huì)樂(lè)意解析這段程式碼(你和我可能不在其中?)。儘管如此,它仍然有效並產(chǎn)生相同的結(jié)果。注意變化:

  1. 換行符和多餘空格消失了。
  2. 變數(shù)名稱已被替換為無(wú)資訊的名稱,例如 _0x587f42。
  3. 字串和物件屬性已轉(zhuǎn)換為函數(shù)調(diào)用,透過(guò)索引從數(shù)組返回其值。例如,document.createElement(“canvas”) 變成了 document[_0x12260c(0x197)](_0x12260c(0x191))。這是透過(guò)使用計(jì)算屬性來(lái)實(shí)現(xiàn)的。

在這種情況下,最後一種技術(shù)可能是最令人討厭的,因?yàn)樗黾恿遂o態(tài)程式碼分析的負(fù)擔(dān)。

好吧,看來(lái)所有的秘密都被隱藏了。我們可以將程式碼部署到生產(chǎn)中嗎?

等等...如果有程式碼混淆服務(wù),也許有些可以把這些東西拉回來(lái)?絕對(duì)嗎?而且不只一個(gè)!讓我們嘗試使用其中之一 - webcrack??纯次覀兪欠窨梢垣@得原始的、可讀的程式碼。以下是使用此反混淆器的結(jié)果:

{"gpu":["ANGLE (NVIDIA, NVIDIA GeForce GTX 980 Direct3D11 vs_5_0 ps_5_0), or similar","Mozilla"],"langs":["en-US","en"]}

哎呀? 。 當(dāng)然,它沒(méi)有回傳變數(shù)的名稱,但謝謝你。

所以事實(shí)證明,在這種情況下冷靜研究我們的程式碼的唯一障礙是研究人員使用反混淆器的意志力。毫無(wú)疑問(wèn),也可以使用其他解決方案和定制,但對(duì)於任何流行的混淆,我們很可能應(yīng)該期待流行的反混淆。

我們應(yīng)該絕望並不戰(zhàn)而屈人之兵嗎?當(dāng)然不是!讓我們看看還能做些什麼...

Here

你如何成為一個(gè)混淆者

混淆器 - 聽(tīng)起來(lái)像是來(lái)自奇幻宇宙的某種法師,不是嗎? ???♂?
當(dāng)然,有人可以在編寫程式碼時(shí)混淆程式碼,並且是天生的魔術(shù)師。你甚至可能無(wú)意中自己已經(jīng)能夠施展這樣的咒語(yǔ)一段時(shí)間了。但是,如果這些技能由於「高級(jí)程式設(shè)計(jì)師」的批評(píng)而消失,並且您有一個(gè)可能使您的程式難以調(diào)查的想法,那麼您現(xiàn)在該怎麼辦?在這種情況下,轉(zhuǎn)向與程式碼結(jié)構(gòu)本身互動(dòng)並允許您修改它的工具是有意義的。讓我們來(lái)看看它們。

AS工具

也可以嘗試透過(guò)像與文字互動(dòng)一樣簡(jiǎn)單地與程式碼互動(dòng)來(lái)修改程式碼,用正規(guī)表示式取代某些結(jié)構(gòu)等等。但我想說(shuō),按照這種方式,你有更多的機(jī)會(huì)毀掉你的程式碼和時(shí)間,而不是混淆它。

為了更可靠和受控的修改,將其引入抽象結(jié)構(gòu)、樹(shù)(AST - 抽象語(yǔ)法樹(shù))是有意義的,透過(guò)它我們可以更改我們感興趣的元素和結(jié)構(gòu).

處理 JS 程式碼有不同的解決方案,最終的 AST 也有所不同。在本文中,我們將使用 babel 來(lái)實(shí)現(xiàn)此目的。你不需要安裝任何東西,你可以在astexplorer這樣的資源上嘗試一切。

(如果你不想搞亂babel,請(qǐng)查看shift-refactor。它允許你使用**CSS 選擇器與AST 互動(dòng)。非常簡(jiǎn)約且方便的學(xué)習(xí)方法並修改程式碼。但它使用特定版本的AST,與babel 不同,您可以在shift-query 互動(dòng)式簡(jiǎn)報(bào)中測(cè)試此工具的CSS 查詢)。

0. 使用 AST

現(xiàn)在讓我們透過(guò)一個(gè)簡(jiǎn)單的範(fàn)例來(lái)看看如何在不離開(kāi)瀏覽器的情況下輕鬆使用這些工具。假設(shè)我們需要將同名函數(shù)中的測(cè)試變數(shù)的名稱改為changed:

let w = screen.width, h = screen.height;
// Let's say there's a logic with some check. 
console.info(w, h);

將此程式碼貼到astexplorer中(從上方選擇JavaScript@babel/parser),它應(yīng)該在那裡顯示為AST。您可以單擊測(cè)試變數(shù)以在右側(cè)視窗中查看此程式碼部分的語(yǔ)法:
Here

為了解決我們的問(wèn)題,我們可以編寫以下 babel 插件,它將解析我們的程式碼並查找其中的所有名稱標(biāo)識(shí)符,並在滿足某些條件時(shí)重命名它們。讓我們將其貼到 astexplorer 的左下視窗中(打開(kāi) transform 滑桿並選擇 babelv7 使其出現(xiàn)):

let w = screen.width, h = screen.height;
// Let's say there's a logic with some check. 
console.info(w, h);

控制臺(tái)輸出包含在這個(gè)插件中是有原因的。這允許我們透過(guò)檢查瀏覽器控制臺(tái)中的輸出來(lái)調(diào)試我們的插件。在這種情況下,我們輸出有關(guān) Identifier 類型的所有節(jié)點(diǎn)的資訊。這些資訊包含有關(guān)節(jié)點(diǎn)本身(node)、父節(jié)點(diǎn)(parent)和環(huán)境(範(fàn)圍-包含在當(dāng)前上下文中創(chuàng)建的變數(shù)以及對(duì)它們的引用)的資料:
Here

因此,在右下視窗中,我們可以注意到原始程式碼中的變數(shù)已成功更改,而沒(méi)有影響其他標(biāo)識(shí)符:

l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();

我希望,基於這個(gè)例子,我們可以更清楚地了解如何解析和修改程式碼。無(wú)論如何,讓我總結(jié)一下所做的工作:

  1. 我們透過(guò) astexplorer 使用 babel 將程式碼轉(zhuǎn)換為 AST。
  2. 透過(guò)檢查 AST,我們看到測(cè)試變數(shù)被標(biāo)記為 Identifier 類型,其名稱可以使用 name 屬性定義。
  3. 接下來(lái),使用我們的 babel 插件,我們繞過(guò)了所有標(biāo)識(shí)符,並更改了函數(shù)中名稱為 test 的標(biāo)識(shí)符。

1.隱藏函數(shù)和變數(shù)名

現(xiàn)在很清楚如何進(jìn)行程式碼修改了。讓我們嘗試一些更有用的東西,我們可以將其稱為混淆:)我們將採(cǎi)用我們?cè)谏弦还?jié)中嘗試混淆的更複雜的程式碼。現(xiàn)在我們將其中所有變數(shù)和函數(shù)的名稱更改為隨機(jī)名稱。因此,潛在的逆向工程師對(duì)某些程式碼元素的用途了解較少。

此外,請(qǐng)隨意使用任何 JS 程式碼來(lái)偵錯(cuò)問(wèn)題。 正如他們所說(shuō),沒(méi)有比痛苦更好的老師? .

以下外掛程式將幫助我們完成工作:

function getGpuData(){
  let cnv = document.createElement("canvas");
  let ctx = cnv.getContext("webgl");
  const rendererInfo = ctx.getParameter(ctx.RENDERER);
  const vendorInfo = ctx.getParameter(ctx.VENDOR);

  return [rendererInfo, vendorInfo]
}

function getLanguages(){
  return window.navigator.languages;
}

let data = {};
data.gpu = getGpuData();
data.langs = getLanguages();
console.log(JSON.stringify(data))

這段程式碼有什麼作用?與前面的範(fàn)例幾乎相同:

  1. 我們遍歷所有Identifier類型的AST節(jié)點(diǎn);
  2. 這次,我們使用generateRndName函數(shù)無(wú)條件隨機(jī)產(chǎn)生識(shí)別碼的名稱;
  3. 產(chǎn)生唯一的名稱可以保證我們不會(huì)隨機(jī)得到可能破壞程式邏輯的重複名稱。

作為插件執(zhí)行的結(jié)果,我們得到以下帶有隨機(jī)變數(shù)名稱和函數(shù)的程式碼:

{"gpu":["ANGLE (NVIDIA, NVIDIA GeForce GTX 980 Direct3D11 vs_5_0 ps_5_0), or similar","Mozilla"],"langs":["en-US","en"]}

您可以透過(guò)在控制臺(tái)中執(zhí)行程式碼來(lái)檢查它 - 經(jīng)過(guò)我們的操作,它仍然有效!這就是一個(gè)好的混淆器的主要品質(zhì)?。

但是我們的混淆品質(zhì)怎麼樣?對(duì)我來(lái)說(shuō) - 邪惡還不太強(qiáng)大:即使透過(guò)替換名稱,經(jīng)驗(yàn)豐富的程式設(shè)計(jì)師也很容易理解這段程式碼的目的。如果任何 JS 壓縮器都可以處理這個(gè)任務(wù),那還有什麼意義呢?現(xiàn)在是否可以為逆向者做一些更實(shí)際、更麻煩的事情?還有一個(gè)咒語(yǔ)...

Here

2.隱藏?一切!

當(dāng)我寫「一切」時(shí),我可能有點(diǎn)自信,但我們現(xiàn)在要做的將最大程度地隱藏我們程式碼的操作。在本節(jié)中,我們將隱藏字串和各種物件屬性,以使靜態(tài)分析複雜化,並可能阻止「客戶端」深入我們的程式碼!

讓我們使用上一階段獲得的隱藏名稱的程式碼,並對(duì)其應(yīng)用以下插件:

let w = screen.width, h = screen.height;
// Let's say there's a logic with some check. 
console.info(w, h);

我已經(jīng)在程式碼註解中描述了這個(gè)外掛程式的一些工作,但讓我們一步一步簡(jiǎn)單描述一下它的作用:

  1. 我們建立一個(gè)陣列 data,其中將儲(chǔ)存程式碼中要替換的所有屬性和字串。此陣列將在傳回資料的 getData 函數(shù)中使用;
  2. 接下來(lái),我們遍歷 AST 並找到根節(jié)點(diǎn) Program,使用程式將 getData 函數(shù)(傳回給定索引處的屬性和字串)插入到程式碼的開(kāi)頭;
  3. 然後我們繞過(guò)MemberExpression類型的節(jié)點(diǎn)。我們用對(duì) getData 函數(shù)的呼叫來(lái)取代屬性。在這種情況下,像 document.createElement 這樣的構(gòu)造將被轉(zhuǎn)換為 document[getData(0)],這要?dú)w功於計(jì)算屬性。一路上,我們將屬性的名稱放入資料數(shù)組中;
  4. 最後,我們繞過(guò) StringLiteral 類型的節(jié)點(diǎn),其中我們還透過(guò)呼叫具有所需索引的 getData 來(lái)替換字串。

值得一提的是,解析操作不是順序執(zhí)行的,而是在 AST 處理過(guò)程中找到必要的節(jié)點(diǎn)。

執(zhí)行此外掛程式的結(jié)果,我們將得到以下程式碼:

l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();

從結(jié)果程式碼中可以看到,所有屬性都已被具有給定索引的 getData 函數(shù)呼叫取代。我們對(duì)字串做了同樣的事情,並開(kāi)始透過(guò)函數(shù)呼叫來(lái)獲取它們。屬性名稱和字串本身使用 base64 進(jìn)行編碼,使它們更難以被注意到...

Here

我想您已經(jīng)注意到了 - 這個(gè)外掛程式以及一般的程式碼在這個(gè)階段有缺陷。例如,可以修正以下問(wèn)題:

  • 傳回我們的屬性和字串的函數(shù)尖叫著它們的目的 - getData。但好處是,這一點(diǎn)可以透過(guò)應(yīng)用我們的第一個(gè)插件來(lái)修正,該插件會(huì)重新命名標(biāo)識(shí)符。
  • getData 函數(shù)內(nèi)部的字串本身沒(méi)有受到可靠的保護(hù),很容易找到它們的初始值,因?yàn)樗皇?base64。解決這個(gè)問(wèn)題更具挑戰(zhàn)性,例如,您可以重新製作 getData 函數(shù)並套用加密而不是眾所周知的編碼。
  • getData 函數(shù)是唯一的,編寫一個(gè)腳本並不難,透過(guò)拉取並執(zhí)行該函數(shù)本身,將其所有呼叫替換為原始值。

儘管有這些簡(jiǎn)單性和缺點(diǎn),我認(rèn)為它已經(jīng)可以稱為混淆。但話又說(shuō)回來(lái),我們與開(kāi)源混淆器有何不同,因?yàn)樗鼈冏鲱愃频氖虑椋?

我們必須記住最初的問(wèn)題—這些混淆對(duì)於公共反混淆器來(lái)說(shuō)是小菜一碟。現(xiàn)在,讓我們使用得到的程式碼並在 webcrack 中對(duì)其進(jìn)行反混淆! (希望它仍然無(wú)法解決我們的咒語(yǔ)?)。我想你可能會(huì)說(shuō)實(shí)際重要性已經(jīng)實(shí)現(xiàn) - 我們的“受保護(hù)”代碼不再可以通過(guò)公共反混淆器一鍵拉回

獎(jiǎng)金。反混淆

現(xiàn)在讓我們學(xué)習(xí)一個(gè)全新的咒語(yǔ)。儘管公共反混淆器無(wú)法處理我們的插件,但是,在研究了混淆的實(shí)際概念後,我們可以注意到一些可用於恢復(fù)原始程式碼的模式。

讓我們開(kāi)始吧,並特別利用:

  • 有一個(gè)儲(chǔ)存我們的屬性和字串的呼叫函數(shù);
  • 對(duì)此函數(shù)的呼叫不會(huì)被屏蔽;

鑑於這些缺點(diǎn),我們可以實(shí)現(xiàn)以下插件:

let w = screen.width, h = screen.height;
// Let's say there's a logic with some check. 
console.info(w, h);

我們來(lái)描述一下這個(gè)反混淆插件的功能:

  1. 我們從混淆程式碼複製了 getData 函數(shù),透過(guò)使用所需的參數(shù)(索引)執(zhí)行它,我們可以獲得所需的字串;
  2. 我們檢查了所有 getData 函數(shù)調(diào)用,並用其執(zhí)行結(jié)果替換它們;
  3. 最後,我們?cè)?AST 中找到了 getData 函數(shù),並將其從程式碼中刪除,因?yàn)槟茄e不再需要它。

結(jié)果,我們得到以下程式碼:

l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();

Here

因此,我們能夠透過(guò)使用所示的缺點(diǎn)為 babel 編寫一個(gè)簡(jiǎn)單的插件來(lái)擺脫隱藏屬性和字串的混淆。

我希望這個(gè)小例子能夠解釋你如何在babel的幫助下對(duì)抗這些滋擾。使用這些方法,你還可以解決更複雜的混淆問(wèn)題 - 主要是找到程式碼中的模式並熟練地使用 AST 進(jìn)行操作。

結(jié)論

我們了解了混淆,一種使程式碼逆向工程複雜化的技術(shù),以及實(shí)現(xiàn)它的工具。儘管有一些公共解決方案可以混淆 JavaScript 程式碼,但也有同樣多的公共解決方案可以立即消除這種保護(hù)。

因此,您需要編寫自己的解決方案來(lái)保護(hù)公共反混淆器無(wú)法刪除的程式碼。在 JS 中實(shí)現(xiàn)混淆的一種可靠方法是編寫自訂 babel 插件,與所需程式碼的 AST 交互,將其轉(zhuǎn)換為可讀性較差的形式。

當(dāng)然,這個(gè)領(lǐng)域已經(jīng)有已知的混淆技術(shù)和方法,但仍然對(duì)創(chuàng)造力和新「技巧」持開(kāi)放態(tài)度,這可能會(huì)使學(xué)習(xí)程式碼變得更加困難。儘管此類技術(shù)數(shù)量眾多,但它們根本無(wú)法保證演算法的保密性,因?yàn)槌淌酱a始終「掌握在客戶端手中」。此外,還有調(diào)試的可能性,這可以使研究程式碼變得更容易?;煜梢宰屇芙^動(dòng)機(jī)不良的研究人員,從而增加逆向工程的成本。

有一些高階方法,例如,混淆中的一種是程式碼虛擬化,或者簡(jiǎn)單地說(shuō),在JS中建立一個(gè)虛擬機(jī)器來(lái)執(zhí)行自訂字節(jié)碼。這種方法幾乎完全消除了靜態(tài)分析的機(jī)會(huì),並使調(diào)試變得盡可能困難。然而,這是一個(gè)單獨(dú)的主題來(lái)討論? ....

我希望這對(duì)您獲取有關(guān)此主題的資訊有用,並且您不會(huì)再因?yàn)樽畛趸煜某淌酱a而責(zé)怪自己或您的程式設(shè)計(jì)師。欣賞這些奇才???♀?!我很高興在這裡與您討論魔法的最新趨勢(shì)?

以上是以下是如何在 JavaScript 中混淆而無(wú)需耗費(fèi)大量時(shí)間:AST、Babel、插件。的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語(yǔ)言,各自適用於不同的應(yīng)用場(chǎng)景。 Java用於大型企業(yè)和移動(dòng)應(yīng)用開(kāi)發(fā),而JavaScript主要用於網(wǎng)頁(yè)開(kāi)發(fā)。

JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時(shí)間合作? 如何在JS中與日期和時(shí)間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時(shí)間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對(duì)像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時(shí)間信息可用get和set方法,注意月份從0開(kāi)始;3.手動(dòng)格式化日期需拼接字符串,也可使用第三方庫(kù);4.處理時(shí)區(qū)問(wèn)題建議使用支持時(shí)區(qū)的庫(kù),如Luxon。掌握這些要點(diǎn)能有效避免常見(jiàn)錯(cuò)誤。

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開(kāi)發(fā)人員的全面比較 JavaScript與Java:開(kāi)發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個(gè)階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過(guò)addEventListener的useCapture參數(shù)設(shè)為true實(shí)現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動(dòng)態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯(cuò)誤處理。了解這兩個(gè)階段有助於精確控制JavaScript響應(yīng)用戶操作的時(shí)機(jī)和方式。

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

如何減少JavaScript應(yīng)用程序的有效載荷大??? 如何減少JavaScript應(yīng)用程序的有效載荷大??? Jun 26, 2025 am 12:54 AM

如果JavaScript應(yīng)用加載慢、性能差,問(wèn)題往往出在payload太大,解決方法包括:1.使用代碼拆分(CodeSplitting),通過(guò)React.lazy()或構(gòu)建工具將大bundle拆分為多個(gè)小文件,按需加載以減少首次下載量;2.移除未使用的代碼(TreeShaking),利用ES6模塊機(jī)制清除“死代碼”,確保引入的庫(kù)支持該特性;3.壓縮和合併資源文件,啟用Gzip/Brotli和Terser壓縮JS,合理合併文件並優(yōu)化靜態(tài)資源;4.替換重型依賴,選用輕量級(jí)庫(kù)如day.js、fetch

See all articles