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

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

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

Jan 10, 2025 pm 12:34 PM

介紹

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

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

這是怎么回事?

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

  1. 鮑勃去了一個(gè)贈(zèng)送電腦顯示器的網(wǎng)站(這里是 -> ?)。鮑勃的顯示器更好,但免費(fèi)的東西總是好的!
  2. 當(dāng) Bob 訪問(wèn)該網(wǎng)站時(shí),JavaScript 在瀏覽器中運(yùn)行,收集有關(guān)用戶(hù)設(shè)備的數(shù)據(jù)并將其發(fā)送到服務(wù)器。比方說(shuō),就是這樣:
let w = screen.width, h = screen.height;
// Let's say there's a logic with some check. 
console.info(w, h);
  1. 不幸的是,鮑勃無(wú)法訪問(wèn)贈(zèng)品頁(yè)面,他對(duì)此感到非常沮喪。他不明白為什么。然后他在贈(zèng)品規(guī)則中了解到,不允許用戶(hù)擁有大而好的顯示器。

  2. 幸運(yùn)的是,鮑勃在高中時(shí)參加了一些計(jì)算機(jī)科學(xué)課程。他果斷按下F12打開(kāi)開(kāi)發(fā)者控制臺(tái),研究了一下腳本,發(fā)現(xiàn)主辦方正在檢查屏幕分辨率。然后他決定通過(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)中運(yùn)行代碼。

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

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

總之,混淆是將程序代碼或數(shù)據(jù)轉(zhuǎn)換為人類(lèi)難以理解但仍然適用于機(jī)器或程序的形式的過(guò)程。

隱藏秘密。快捷方式

理論已經(jīng)夠多了,讓我們繼續(xù)看更多實(shí)際例子????,F(xiàn)在,讓我們嘗試借助您更可能在互聯(lián)網(wǎng)上找到的混淆來(lái)轉(zhuǎn)換代碼。讓我們看一個(gè)更有趣的代碼,其中包含我們的“專(zhuān)有技術(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);

例如,此代碼收集設(shè)備和瀏覽器數(shù)據(jù)并將結(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. 變量名稱(chēng)已被替換為無(wú)信息的名稱(chēng),例如 _0x587f42。
  3. 字符串和對(duì)象屬性已轉(zhuǎn)換為函數(shù)調(diào)用,通過(guò)索引從數(shù)組返回其值。例如,document.createElement(“canvas”) 變成了 document[_0x12260c(0x197)](_0x12260c(0x191))。這是通過(guò)使用計(jì)算屬性實(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)有返回變量的名稱(chēng),但謝謝你。

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

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

Here

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

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

AS工具

也可以嘗試通過(guò)像與文本交互一樣簡(jiǎn)單地與代碼交互來(lái)修改代碼,用正則表達(dá)式替換某些結(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 交互。非常簡(jiǎn)約且方便的學(xué)習(xí)方法并修改代碼。但它使用特定版本的 AST,與 babel 不同,您可以在 shift-query 交互式演示中測(cè)試此工具的 CSS 查詢(xún))。

0. 使用 AST

現(xiàn)在讓我們通過(guò)一個(gè)簡(jiǎn)單的示例來(lái)看看如何在不離開(kāi)瀏覽器的情況下輕松使用這些工具。假設(shè)我們需要將同名函數(shù)中的測(cè)試變量的名稱(chēng)更改為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è)試變量以在右側(cè)窗口中查看此代碼部分的語(yǔ)法:
Here

為了解決我們的問(wèn)題,我們可以編寫(xiě)以下 babel 插件,它將解析我們的代碼并查找其中的所有名稱(chēng)標(biāo)識(shí)符,并在滿(mǎn)足某些條件時(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 類(lèi)型的所有節(jié)點(diǎn)的信息。這些信息包含有關(guān)節(jié)點(diǎn)本身(node)、父節(jié)點(diǎn)(parent)和環(huán)境(范圍-包含在當(dāng)前上下文中創(chuàng)建的變量以及對(duì)它們的引用)的數(shù)據(jù):
Here

因此,在右下窗口中,我們可以注意到源代碼中的變量已成功更改,而沒(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è)試變量被標(biāo)記為 Identifier 類(lèi)型,其名稱(chēng)可以使用 name 屬性定義。
  3. 接下來(lái),使用我們的 babel 插件,我們繞過(guò)了所有標(biāo)識(shí)符,并更改了函數(shù)中名稱(chēng)為 test 的標(biāo)識(shí)符。

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

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

此外,請(qǐng)隨意使用任何 JS 代碼來(lái)調(diào)試問(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))

這段代碼有什么作用?與前面的示例幾乎相同:

  1. 我們遍歷所有Identifier類(lèi)型的AST節(jié)點(diǎn);
  2. 這次,我們使用generateRndName函數(shù)無(wú)條件隨機(jī)生成標(biāo)識(shí)符的名稱(chēng);
  3. 生成唯一的名稱(chēng)可以保證我們不會(huì)隨機(jī)得到可能破壞程序邏輯的重復(fù)名稱(chēng)。

作為插件執(zhí)行的結(jié)果,我們得到以下帶有隨機(jī)變量名稱(chēng)和函數(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ò)替換名稱(chēng),經(jīng)驗(yàn)豐富的程序員也很容易理解這段代碼的目的。如果任何 JS 壓縮器都可以處理這個(gè)任務(wù),那還有什么意義呢?現(xiàn)在是否可以為逆向者做一些更實(shí)際、更麻煩的事情呢?還有一個(gè)咒語(yǔ)...

Here

2.隱藏?一切!

當(dāng)我寫(xiě)“一切”時(shí),我可能有點(diǎn)自信,但我們現(xiàn)在要做的將最大程度地隱藏我們代碼的操作。在本節(jié)中,我們將隱藏字符串和各種對(duì)象屬性,以使靜態(tài)分析復(fù)雜化,并可能阻止“客戶(hù)端”深入我們的代碼!

讓我們使用上一階段獲得的隱藏名稱(chēng)的代碼,并對(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. 我們創(chuàng)建一個(gè)數(shù)組 data,其中將存儲(chǔ)代碼中要替換的所有屬性和字符串。該數(shù)組將在返回?cái)?shù)據(jù)的 getData 函數(shù)中使用;
  2. 接下來(lái),我們遍歷 AST 并找到根節(jié)點(diǎn) Program,使用該程序?qū)?getData 函數(shù)(返回給定索引處的屬性和字符串)插入到代碼的開(kāi)頭;
  3. 然后我們繞過(guò)MemberExpression類(lèi)型的節(jié)點(diǎn)。我們用對(duì) getData 函數(shù)的調(diào)用來(lái)替換屬性。在這種情況下,像 document.createElement 這樣的構(gòu)造將被轉(zhuǎn)換為 document[getData(0)],這要?dú)w功于計(jì)算屬性。一路上,我們將屬性的名稱(chēng)放入數(shù)據(jù)數(shù)組中;
  4. 最后,我們繞過(guò) StringLiteral 類(lèi)型的節(jié)點(diǎn),其中我們還通過(guò)調(diào)用具有所需索引的 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ù)調(diào)用替換。我們對(duì)字符串做了同樣的事情,并開(kāi)始通過(guò)函數(shù)調(diào)用來(lái)獲取它們。屬性名稱(chēng)和字符串本身使用 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ù)并應(yīng)用加密而不是眾所周知的編碼。
  • getData 函數(shù)是唯一的,編寫(xiě)一個(gè)腳本并不難,通過(guò)拉取并執(zhí)行該函數(shù)本身,將其所有調(diào)用替換為原始值。

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

我們必須記住最初的問(wèn)題——這些混淆對(duì)于公共反混淆器來(lái)說(shuō)是小菜一碟?,F(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ǔ)我們的屬性和字符串的調(diào)用函數(shù);
  • 對(duì)該函數(shù)的調(diào)用不會(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. 我們從混淆代碼中復(fù)制了 getData 函數(shù),通過(guò)使用所需的參數(shù)(索引)執(zhí)行它,我們可以獲得所需的字符串;
  2. 我們檢查了所有 getData 函數(shù)調(diào)用,并用其執(zhí)行結(jié)果替換它們;
  3. 最后,我們?cè)?AST 中找到了 getData 函數(shù),并將其從代碼中刪除,因?yàn)槟抢锊辉傩枰?/li>

結(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 編寫(xiě)一個(gè)簡(jiǎn)單的插件來(lái)擺脫隱藏屬性和字符串的混淆。

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

結(jié)論

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

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

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

有一些高級(jí)方法,例如,混淆中的一種是代碼虛擬化,或者簡(jiǎn)單地說(shuō),在JS中創(chuàng)建一個(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ì)?

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

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系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脫衣機(jī)

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)

熱門(mén)話題

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)用戶(hù)操作的時(shí)機(jī)和方式。

JavaScript:探索用于高效編碼的數(shù)據(jù)類(lèi)型 JavaScript:探索用于高效編碼的數(shù)據(jù)類(lèi)型 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.替換重型依賴(lài),選用輕量級(jí)庫(kù)如day.js、fetch

See all articles