JSVMP · JavaScript 虛擬機混淆
JavaScript 加密與混淆
JSVeil 將 JavaScript 轉換為自訂位元組碼,由產生的虛擬機執行。保留原有功能,讓瀏覽器中的程式碼更難閱讀、複製與竄改。
立即體驗const project = {
name: "JSVeil",
greeting: "Hello",
excited: true
};
function createFormatter(settings) {
const prefix = settings.greeting + ", ";
let calls = 0;
return function (name) {
const label = String(name).trim() || "friend";
calls += 1;
let suffix = "";
if (settings.excited) {
for (let i = 0; i < calls && i < 3; i++) {
suffix += "!";
}
} else {
suffix = ".";
}
return prefix + label + suffix;
};
}
const greet = createFormatter(project);
console.log(greet(project.name));
(function/* JSVeil */ He(Y,d){const Q=d.Object,ee=d.Array,T=d.Function,fe=d.Reflect,S=d.Error,G=d.TypeError,ae=d.ReferenceError,Bt=d.RegExp,dt=d.BigInt,Ft=d.atob,bt=d.String.fromCharCode,Z=fe.apply,Ut=fe.construct,B=Q.defineProperty,Je=Q.getOwnPropertyDescriptor,F=Q.freeze,E=Math.imul,we=T.prototype.toString,ge=T.call.bind(T.call),Ne=T.call.bind(d.String.prototype.charCodeAt),kt=T.call.bind(ee.prototype.slice),Re=T.call.bind(ee.prototype.push),he=T.call.bind(ee.prototype.pop),qt=T.call.bind(ee.prototype.lastIndexOf),X=T.call.bind(WeakMap.prototype.get),me=T.call.bind(WeakMap.prototype.set);function ye(e){let t=2166136261;for(let n=0;n<e.length;n++)t=E(t^Ne(e,n),16777619);return t>>>0}const ve={},Qe=new WeakMap;let Xe=0;B(ve,"v",{get(){return Xe++,7}}),me(Qe,ve,9);const Ye=ve.v^7|Xe^1|X(Qe,ve)^9|E(2147483647,3)^2147483645,z=ye(Z(we,He,[]))^Ye,Ae=d.atob(Y[0]);let $=Y[1]^z;const Ce=new Uint8Array(Ae.length);for(let e=0;e<Ae.length;e++)$^=$<<13,$^=$>>>17,$^=$<<5,Ce[e]=Ne(Ae,e)^$&255;function Ze(e,t){if(!t)return e;if(t<0||t>134217728)throw new S;const n=new Uint8Array(t);let o=0,r=0;function i(f){if(f===15){let u;do{if(o>=e.length)throw new S;u=e[o++],f+=u}while(u===255)}return f}for(;o<e.length;){const f=e[o++],u=i(f>>>4);if(o+u>e.length||r+u>t)throw new S;if(n.set(e.subarray(o,o+u),r),o+=u,r+=u,o===e.length)break;if(o+2>e.length)throw new S;const c=e[o++]|e[o++]<<8;if(!c||c>r)throw new S;const a=i(f&15)+4;if(r+a>t)throw new S;if(a<=c)n.set(n.subarray(r-c,r-c+a),r),r+=a;else for混淆失敗
輸入程式碼
example.js輸出程式碼
// 處理後的程式碼將顯示在這裡。
處理完成後,即可複製或下載。關於 JSVeil
JSVeil 是一款採用 JavaScript 虛擬機混淆(JSVMP)的工具,讓程式碼更難分析與逆向還原。你可以依專案需求,選擇不同的混淆與防護功能。
免費版
30 KB 內免費使用。
自訂混淆選項
設定程式碼的混淆方式與執行限制,各項功能可個別啟用。
自訂種子
種子用來控制混淆時的隨機變化。原始碼、選項與編譯器版本相同時,使用同一個種子即可重現混淆結果。
關閉時,每次混淆都會自動產生密碼學安全的隨機種子。
全域名稱重新命名
替換符合條件的全域變數與函式名稱,讓原始程式結構更難辨識。
若 HTML、其他指令碼或外部介面會用到這些名稱,請先確認相關引用。
虛假分支
插入用來干擾分析的分支,讓真正的執行路徑更難辨識。
可能讓檔案變大、執行變慢,預設關閉。
環境偵測
啟用後,限制自動化工具、jsdom、Node.js 等環境執行。
僅允許在瀏覽器中執行。
網域限制
可填寫一個或多個網域,也支援子網域萬用字元。中文等國際化網域名稱會自動轉換成對應的 ASCII 網域。
*.example.com 只涵蓋子網域。若也要允許 example.com,請另外加入。
開發者工具偵測
定期檢查開發者工具是否開啟,預設每 1,500 毫秒偵測一次。
偵測到後會啟動相應的防護措施。
VM 逾時偵測
啟用後,會檢查受保護的程式碼執行時是否長時間暫停,例如偵錯時停在中斷點。預設每次偵測到至少 15 秒的暫停計為一次,累計 2 次後,目前的 VM 將停止執行受保護的程式碼。
這裡計算的是長時間暫停的次數,不是程式碼的總執行時間。暫停多久算一次、發生幾次後停止,都可以自行設定。
停用主控台輸出
混淆後的指令碼執行時,不再向主控台輸出訊息。
適合上線後不需要記錄訊息的情況,但也會增加排查問題的難度。
反偵錯
定期觸發 debugger 陳述式,干擾偵錯過程。預設每 1,000 毫秒觸發一次。
常見問題
JSVeil 是什麼?
JSVeil 是一款採用 JavaScript 虛擬機混淆(JSVMP)的工具,讓程式碼更難分析與逆向還原。你可以依專案需求,選擇不同的混淆與防護功能。
什麼是 JavaScript 虛擬機混淆(JSVMP)?
JSVMP 會將需要保護的程式碼轉換成自訂位元組碼(bytecode),再由檔案中附帶的 JavaScript 虛擬機執行。分析者必須先理解位元組碼與虛擬機的運作方式,才能還原程式邏輯,因此分析難度更高。
會儲存我的原始碼嗎?
不會。原始碼僅用於完成這次混淆,處理後不會留存。
JSVeil 免費嗎?
可以,30 KB 以內的 JavaScript 檔案都能免費混淆。歡迎用自己的程式碼試試看。
需要更強的混淆保護,或處理更大的檔案?
歡迎來信 ,說明您的需求,一起討論適合專案的客製化方案。