使用說明

JavaScript Deobfuscator 線上工具:還原成易讀的程式碼

JavaScript Deobfuscator 會把讓程式碼難以閱讀的手法還原。這個工具能展開單純的字串陣列、計算常數運算式、解碼十六進位與 Unicode 跳脫字元,並重新命名 _0x 形式的名稱,最後以 2 個空格縮排輸出結果。這一切都是靠讀取程式碼完成,不會執行:你的 JavaScript 不會被執行,也不會被上傳,後面列出的部分混淆則會維持原樣。


JavaScript Deobfuscator 線上使用步驟

  1. 把程式碼貼到「混淆過的 JavaScript」欄位。貼上之前,欄位會顯示「在此貼上混淆過的 JavaScript…」。上限是 5,000,000 個字元。
  2. 選擇「反混淆選項」會展開四個核取方塊,預設全部開啟:「展開字串陣列」、「計算常數」、「解碼十六進位與 Unicode 跳脫字元」和「重新命名十六進位變數」。不想要的步驟請取消勾選。
  3. 按下「反混淆」。「反混淆後的程式碼」畫面會把結果以上色的唯讀程式碼顯示出來。
  4. 查看程式碼上方的標籤。標籤會告訴你改了什麼,例如「已取代 3 個陣列查找」、「已簡化 5 個運算式」、「已解碼 2 個字面值」或「已重新命名 4 個變數」。如果沒有任何項目適用,標籤會顯示「這裡沒有需要展開或簡化的內容,因此只重新整理了程式碼格式。」
  5. 按下「複製」(按下後會變成「已複製」)或「下載 .js」,就能把程式碼存成 反混淆後.js。
  6. 選擇「編輯程式碼」可以回到輸入畫面,用其他選項再執行一次。

如果輸入的不是有效的 JavaScript,會顯示「這不是有效的 JavaScript:第 N 行第 M 欄有語法錯誤。」,並標出實際的行與欄,內容不會有任何變動。

每個選項的作用

這些步驟依上面的順序執行,所以陣列查找可以先展開,再由計算常數與前後的字串接在一起。屬性名稱、標籤,以及 import 和 export 的名稱都不會被改名,腳本開頭的 shebang 行也會保留。

實際範例

這段輸入包含一個字串陣列、一個十六進位風格的名稱、一個加引號的屬性和一個加法:

var _0x1a2b = ['hello', 'world', '\x68\x69']; function _0x3c(_0x4d) { console['log'](_0x1a2b[0] + ' ' + _0x1a2b[1], _0x4d, _0x1a2b[2]); } _0x3c(1 + 2 * 3);

結果如下:

function func1(arg1) { console.log("hello world", arg1, "hi"); } func1(7);

標籤會顯示「已取代 3 個陣列查找」、「已簡化 5 個運算式」、「已解碼 1 個字面值」和「已重新命名 2 個變數」。實際輸出會以 2 個空格縮排分成多行。

JavaScript 混淆解密:能還原與不能還原的部分

這個工具不會執行你的程式碼,所以只能還原文字中看得到的內容。凡是必須先執行程式才能知道的部分,都會維持原樣,而不是用猜的。

這是閱讀輔助工具,不是資安掃描器。它不會檢查程式碼是否有害,也無法讓來路不明的程式碼變得安全。如果腳本來自你不信任的地方,就算輸出看起來很整齊,也不要執行它。

旋轉過的字串陣列為什麼會維持原樣

許多混淆工具會在第一次讀取之前,用一小段迴圈把字串陣列的項目轉位,所以原始碼裡看到的第一個項目不一定是 list[0]。如果直接填入看得到的項目,你的程式碼裡就會出現錯誤的文字。

因此,只有當陣列的每一次使用都是範圍內數字的 list[3] 或 list.length 時,工具才會展開它。如果陣列被傳給函式、用 push 加入項目、被重新指派,或用算不出來的索引讀取,這個陣列就會完全維持寫下的樣子。

壓縮過的程式碼與大型檔案

沒有被混淆、只是壓縮過的程式碼,會以 2 個空格縮排重新排版後送回,標籤會說明只有版面改變。像 a 和 b 這樣的短名稱不會被改名,因為它們不是十六進位風格,原本的名稱也已經不在了。如果你想整理本來就易讀的程式碼,或是美化 JSON、HTML 和 CSS,請使用程式碼美化工具。要再次縮小樣式表可以用 CSS 壓縮工具,要解碼在腳本裡找到的 Base64 字串,則可以用 Base64 轉換器。

所有處理都在 Web Worker 中進行,所以處理大型檔案時頁面仍能保持順暢。非常長或巢狀很深的運算式可能超出頁面負荷,這時會顯示這段程式碼太大或巢狀層數太深,無法在這裡處理。


常見問題

要怎麼把混淆過的 JavaScript 還原?

把程式碼貼到「混淆過的 JavaScript」,再按「反混淆」。程式碼會先轉成語法樹,接著展開字串陣列、計算常數、解碼跳脫字元、重新命名 _0x 名稱,最後把語法樹以縮排後的程式碼印出。你可以直接複製,也可以按「下載 .js」存成 反混淆後.js。

有可以線上使用的 JavaScript Deobfuscator 嗎?

有,這個頁面就是。它在你的瀏覽器分頁裡執行:程式碼在 Web Worker 中分析,不會上傳,也不會執行。它能處理單純的字串陣列、常數運算式、十六進位與 Unicode 跳脫字元,以及 _0x 形式的名稱。它無法還原所有種類的混淆,維持原樣的項目清單就在這個頁面上。

可以處理 obfuscator.io 產生的程式碼嗎?

只能處理不需要執行程式碼的部分。十六進位與 Unicode 跳脫字元會被解碼,常數會被計算,_0x 名稱會被改成 var1、func1 和 arg1。obfuscator.io 在啟動時用 push(shift()) 旋轉的字串陣列,以及透過解碼函式取得的字串,都會維持原樣,因為要還原它們就得執行程式碼。

混淆過的 JavaScript 裡的十六進位字串要怎麼解碼?

在「反混淆選項」裡,讓「解碼十六進位與 Unicode 跳脫字元」維持勾選。像 \x68\u0069 這樣的字串會變成 hi,像 0x1f 這樣的十六進位數字會變成 31。只有寫在程式碼裡的跳脫字元會被解碼,程式執行時才組出來的十六進位字串則不會。

它也能把壓縮過的程式碼展開嗎?

可以,輸出一律以 2 個空格縮排重新印出,所以即使沒有東西需要展開,壓縮過的程式碼也會變得易讀。這時結果會顯示「這裡沒有需要展開或簡化的內容,因此只重新整理了程式碼格式。」輸入中的註解會被移除。像 a 和 b 這樣被縮短的變數名稱無法還原。

這個工具會執行我的 JavaScript 嗎?

不會。程式碼只會被讀取,並以文字的形式改寫。頁面和 Web Worker 裡都沒有 eval、沒有 Function 呼叫,也沒有任何執行,所以旋轉過的陣列和解碼函式才會維持原樣。這也不是安全檢查:輸出會比較好讀,但掃描或判斷是否為惡意程式是另一回事。

為什麼輸出裡還留著字串陣列?

只有當陣列的每一次使用都是像 list[3] 或 list.length 這樣的固定索引時,才會展開。如果程式碼還會旋轉它、把它傳給函式、用 push 加入項目,或用算出來的索引讀取,整個陣列就會原封不動,因為在那種情況下替換讀取可能會得到錯誤的字串。

「重新命名十六進位變數」會做什麼?

它會替 _0x1a2b 這類名稱取一個易讀的名字:變數用 var1,函式用 func1,參數用 arg1。同一個名稱的每一處用法會一起改名,程式裡已經存在的名稱不會被重複使用,屬性名稱和標籤也完全不會動。它無法還原原本的名稱,因為那些名稱不在檔案裡。

程式碼可以多大?如果有錯誤會怎樣?

最多 5,000,000 個字元。如果程式碼不是有效的 JavaScript,會顯示「這不是有效的 JavaScript:第 N 行第 M 欄有語法錯誤。」,並附上實際的數字,內容不會有任何變動;你輸入的文字會留在欄位裡,方便你修正那個地方。

我的程式碼會被上傳到哪裡嗎?

不會。解析、改寫和輸出全都在你的瀏覽器裡、由 Web Worker 完成,沒有任何內容會傳到伺服器。程式碼也不會被執行。