搜尋
首頁web前端js教程以下是如何在 JavaScript 中混淆而無需耗費大量時間:AST、Babel、插件。

介紹

嘿,你有沒有想過你的演算法有多酷、多獨特? ?許多程式設計師和公司都這樣做,這就是為什麼他們可能不願意與所有人分享他們的工作。如果將部分程式碼移至伺服器(對於客戶端-伺服器應用程式),這個問題會稍微好一點,但這種方法並不總是可行。有時,我們必須將敏感的程式碼部分直接公開。

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

這是怎麼回事?

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

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

  2. 幸運的是,鮑伯在高中時參加了一些電腦科學課程。他果斷按下F12打開開發者控制台,研究了一下腳本,發現主辦單位正在檢查螢幕解析度。然後他決定透過手機參與並成功通過測試。

一個美好結局的虛構故事 - 但如果主角看到的是這個而不是之前的代碼,它就不會這麼好:

l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+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!並且它執行相同的操作。您可以嘗試在此處的控制台中執行程式碼。

我想在這種情況下,我們的英雄就會認命,不參加有獎活動,主辦單位也會保留他們的計畫。

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

總之,混淆是將程式碼或資料轉換為人類難以理解但仍適用於機器或程式的形式的過程。

隱藏秘密。快速方式

理論已經夠多了,讓我們繼續看更多實際例子? ‍? 。現在,讓我們嘗試使用您更可能在網路上找到的混淆來轉換程式碼。讓我們來看一個更有趣的程式碼,其中包含我們的「專有技術」操作。而且非常不希望每個不懶得達到 F12 的人都可以了解它們:

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

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

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

現在讓我們使用流行的 JS 混淆器 - obfuscator.io 來修改上面的程式碼。結果,我們會得到這樣的程式碼:

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. 換行符和多餘空格消失了。
  2. 變數名稱已被替換為無資訊的名稱,例如 _0x587f42。
  3. 字串和物件屬性已轉換為函數調用,透過索引從數組返回其值。例如,document.createElement(“canvas”) 變成了 document[_0x12260c(0x197)](_0x12260c(0x191))。這是透過使用計算屬性來實現的。

在這種情況下,最後一種技術可能是最令人討厭的,因為它增加了靜態程式碼分析的負擔。

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

等等...如果有程式碼混淆服務,也許有些可以把這些東西拉回來?絕對嗎?而且不只一個!讓我們嘗試使用其中之一 - webcrack。看看我們是否可以獲得原始的、可讀的程式碼。以下是使用此反混淆器的結果:

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

哎呀? 。 當然,它沒有回傳變數的名稱,但謝謝你。

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

我們應該絕望並不戰而屈人之兵嗎?當然不是!讓我們看看還能做些什麼...

Here

你如何成為一個混淆者

混淆器 - 聽起來像是來自奇幻宇宙的某種法師,不是嗎? ??‍♂️
當然,有人可以在編寫程式碼時混淆程式碼,並且是天生的魔術師。你甚至可能無意中自己已經能夠施展這樣的咒語一段時間了。但是,如果這些技能由於「高級程式設計師」的批評而消失,並且您有一個可能使您的程式難以調查的想法,那麼您現在該怎麼辦?在這種情況下,轉向與程式碼結構本身互動並允許您修改它的工具是有意義的。讓我們來看看它們。

AS工具

也可以嘗試透過像與文字互動一樣簡單地與程式碼互動來修改程式碼,用正規表示式取代某些結構等等。但我想說,按照這種方式,你有更多的機會毀掉你的程式碼和時間,而不是混淆它。

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

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

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

0. 使用 AST

現在讓我們透過一個簡單的範例來看看如何在不離開瀏覽器的情況下輕鬆使用這些工具。假設我們需要將同名函數中的測試變數的名稱改為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),它應該在那裡顯示為AST。您可以單擊測試變數以在右側視窗中查看此程式碼部分的語法:
Here

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

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

控制台輸出包含在這個插件中是有原因的。這允許我們透過檢查瀏覽器控制台中的輸出來調試我們的插件。在這種情況下,我們輸出有關 Identifier 類型的所有節點的資訊。這些資訊包含有關節點本身(node)、父節點(parent)和環境(範圍-包含在當前上下文中創建的變數以及對它們的引用)的資料:
Here

因此,在右下視窗中,我們可以注意到原始程式碼中的變數已成功更改,而沒有影響其他標識符:

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

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

  1. 我們透過 astexplorer 使用 babel 將程式碼轉換為 AST。
  2. 透過檢查 AST,我們看到測試變數被標記為 Identifier 類型,其名稱可以使用 name 屬性定義。
  3. 接下來,使用我們的 babel 插件,我們繞過了所有標識符,並更改了函數中名稱為 test 的標識符。

1.隱藏函數和變數名

現在很清楚如何進行程式碼修改了。讓我們嘗試一些更有用的東西,我們可以將其稱為混淆:)我們將採用我們在上一節中嘗試混淆的更複雜的程式碼。現在我們將其中所有變數和函數的名稱更改為隨機名稱。因此,潛在的逆向工程師對某些程式碼元素的用途了解較少。

此外,請隨意使用任何 JS 程式碼來偵錯問題。 正如他們所說,沒有比痛苦更好的老師? .

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

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類型的AST節點;
  2. 這次,我們使用generateRndName函數無條件隨機產生識別碼的名稱;
  3. 產生唯一的名稱可以保證我們不會隨機得到可能破壞程式邏輯的重複名稱。

作為插件執行的結果,我們得到以下帶有隨機變數名稱和函數的程式碼:

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

您可以透過在控制台中執行程式碼來檢查它 - 經過我們的操作,它仍然有效!這就是一個好的混淆器的主要品質✨。

但是我們的混淆品質怎麼樣?對我來說 - 邪惡還不太強大:即使透過替換名稱,經驗豐富的程式設計師也很容易理解這段程式碼的目的。如果任何 JS 壓縮器都可以處理這個任務,那還有什麼意義呢?現在是否可以為逆向者做一些更實際、更麻煩的事情?還有一個咒語...

Here

2.隱藏?一切!

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

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

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

我已經在程式碼註解中描述了這個外掛程式的一些工作,但讓我們一步一步簡單描述一下它的作用:

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

值得一提的是,解析操作不是順序執行的,而是在 AST 處理過程中找到必要的節點。

執行此外掛程式的結果,我們將得到以下程式碼:

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

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

Here

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

  • 傳回我們的屬性和字串的函數尖叫著它們的目的 - getData。但好處是,這一點可以透過應用我們的第一個插件來修正,該插件會重新命名標識符。
  • getData 函數內部的字串本身沒有受到可靠的保護,很容易找到它們的初始值,因為它只是 base64。解決這個問題更具挑戰性,例如,您可以重新製作 getData 函數並套用加密而不是眾所周知的編碼。
  • getData 函數是唯一的,編寫一個腳本並不難,透過拉取並執行該函數本身,將其所有呼叫替換為原始值。

儘管有這些簡單性和缺點,我認為它已經可以稱為混淆。但話又說回來,我們與開源混淆器有何不同,因為它們做類似的事情?

我們必須記住最初的問題—這些混淆對於公共反混淆器來說是小菜一碟。現在,讓我們使用得到的程式碼並在 webcrack 中對其進行反混淆! (希望它仍然無法解決我們的咒語?)。我想你可能會說實際重要性已經實現 - 我們的“受保護”代碼不再可以通過公共反混淆器一鍵拉回

獎金。反混淆

現在讓我們學習一個全新的咒語。儘管公共反混淆器無法處理我們的插件,但是,在研究了混淆的實際概念後,我們可以注意到一些可用於恢復原始程式碼的模式。

讓我們開始吧,並特別利用:

  • 有一個儲存我們的屬性和字串的呼叫函數;
  • 對此函數的呼叫不會被屏蔽;

鑑於這些缺點,我們可以實現以下插件:

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

我們來描述一下這個反混淆插件的功能:

  1. 我們從混淆程式碼複製了 getData 函數,透過使用所需的參數(索引)執行它,我們可以獲得所需的字串;
  2. 我們檢查了所有 getData 函數調用,並用其執行結果替換它們;
  3. 最後,我們在 AST 中找到了 getData 函數,並將其從程式碼中刪除,因為那裡不再需要它。

結果,我們得到以下程式碼:

l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+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

因此,我們能夠透過使用所示的缺點為 babel 編寫一個簡單的插件來擺脫隱藏屬性和字串的混淆。

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

結論

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

因此,您需要編寫自己的解決方案來保護公共反混淆器無法刪除的程式碼。在 JS 中實現混淆的一種可靠方法是編寫自訂 babel 插件,與所需程式碼的 AST 交互,將其轉換為可讀性較差的形式。

當然,這個領域已經有已知的混淆技術和方法,但仍然對創造力和新「技巧」持開放態度,這可能會使學習程式碼變得更加困難。儘管此類技術數量眾多,但它們根本無法保證演算法的保密性,因為程式碼始終「掌握在客戶端手中」。此外,還有調試的可能性,這可以使研究程式碼變得更容易。混淆可以讓您拒絕動機不良的研究人員,從而增加逆向工程的成本。

有一些高階方法,例如,混淆中的一種是程式碼虛擬化,或者簡單地說,在JS中建立一個虛擬機器來執行自訂字節碼。這種方法幾乎完全消除了靜態分析的機會,並使調試變得盡可能困難。然而,這是一個單獨的主題來討論? ....

我希望這對您獲取有關此主題的資訊有用,並且您不會再因為最初混淆的程式碼而責怪自己或您的程式設計師。欣賞這些奇才??‍♀️!我很高興在這裡與您討論魔法的最新趨勢?

以上是以下是如何在 JavaScript 中混淆而無需耗費大量時間:AST、Babel、插件。的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:開發環境和工具Python vs. JavaScript:開發環境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

JavaScript是用C編寫的嗎?檢查證據JavaScript是用C編寫的嗎?檢查證據Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript的角色:使網絡交互和動態JavaScript的角色:使網絡交互和動態Apr 24, 2025 am 12:12 AM

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C和JavaScript:連接解釋C和JavaScript:連接解釋Apr 23, 2025 am 12:07 AM

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

從網站到應用程序:JavaScript的不同應用從網站到應用程序:JavaScript的不同應用Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python vs. JavaScript:比較用例和應用程序Python vs. JavaScript:比較用例和應用程序Apr 21, 2025 am 12:01 AM

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C/C在JavaScript口譯員和編譯器中的作用C/C在JavaScript口譯員和編譯器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具