Referensi Opsi
Daftar Isi
compact
config
controlFlowFlattening
controlFlowFlatteningThreshold
deadCodeInjection
deadCodeInjectionThreshold
debugProtection
debugProtectionInterval
disableConsoleOutput
domainLock
Beberapa domain dan subdomain
domainLockRedirectUrl
exclude
forceTransformStrings
identifierNamesCache
Node.js API
CLI
identifierNamesGenerator
identifiersDictionary
identifiersPrefix
randomIdentifiersPrefix
ignoreImports
inputFileName
log
numbersToExpressions
optionsPreset
parseHtml
renameGlobals
renameProperties
renamePropertiesMode
reservedNames
reservedStrings
seed
selfDefending
simplify
sourceMap
sourceMapBaseUrl
sourceMapFileName
sourceMapMode
sourceMapSourcesMode
splitStrings
splitStringsChunkLength
stringArray
stringArrayCallsTransform
stringArrayCallsTransformThreshold
stringArrayEncoding
stringArrayIndexesType
stringArrayIndexShift
stringArrayRotate
stringArrayShuffle
stringArrayWrappersCount
stringArrayWrappersChainedCalls
stringArrayWrappersParametersMaxCount
stringArrayWrappersType
stringArrayThreshold
strictMode
target
transformObjectKeys
warnings
vmObfuscation
vmTargetFunctions
vmExcludeFunctions
vmTargetFunctionsMode
vmForceCompileDynamicCode
vmWrapTopLevelInitializers
vmDynamicOpcodes
vmBytecodeEncoding
vmBytecodeArrayEncoding
vmBytecodeArrayEncodingKey
vmBytecodeArrayEncodingKeyGetter
vmAsyncExecutor
vmJumpsEncoding
vmMacroOps
vmDebugProtection
vmSelfDefending
vmDefenseHook
vmDefenseReaction
vmStatefulOpcodes
vmCallContextOpcodes
vmStackEncoding
vmCompactDispatcher
vmStringArrayBytecodeOnly
vmDomainLock
Beberapa domain dan subdomain
vmDomainLockRedirectUrl
Preset Options
Obfuskasi tinggi, performa rendah
Obfuskasi sedang, performa optimal
Obfuskasi rendah, performa tinggi
Preset bawaan, performa tinggi
Obfuskasi VM Ultra High (Keamanan Maksimal)
VM Anti-LLM (Proteksi Agen AI)
Obfuskasi VM High (Keamanan Tertinggi)
Obfuskasi VM Medium (Keamanan Seimbang)
Obfuskasi VM Low (Keamanan Dasar, Performa Lebih Baik)
VM Default (Proteksi VM + String Array)
compact
Type: boolean Default: true
Keluaran kode yang ringkas dalam satu baris.
config
Type: string Default: ``
Nama berkas konfigurasi JS/JSON yang berisi opsi obfuscator. Opsi ini akan ditimpa oleh opsi yang diteruskan langsung ke CLI
controlFlowFlattening
Type: boolean Default: false
⚠️ Opsi ini sangat memengaruhi performa hingga kecepatan runtime 1,5x lebih lambat. Gunakan controlFlowFlatteningThreshold untuk mengatur persentase node yang akan terpengaruh oleh control flow flattening.
Mengaktifkan control flow flattening pada kode. Control flow flattening adalah transformasi struktur kode sumber yang mempersulit pemahaman program.
Contoh:
// input
(function(){
function foo () {
return function () {
var sum = 1 + 2;
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
console.log(6);
}
}
foo()();
})();
// output
(function () {
function _0x3bfc5c() {
return function () {
var _0x3260a5 = {
'WtABe': '4|0|6|5|3|2|1',
'GokKo': function _0xf87260(_0x427a8e, _0x43354c) {
return _0x427a8e + _0x43354c;
}
};
var _0x1ad4d6 = _0x3260a5['WtABe']['split']('|'), _0x1a7b12 = 0x0;
while (!![]) {
switch (_0x1ad4d6[_0x1a7b12++]) {
case '0':
console['log'](0x1);
continue;
case '1':
console['log'](0x6);
continue;
case '2':
console['log'](0x5);
continue;
case '3':
console['log'](0x4);
continue;
case '4':
var _0x1f2f2f = _0x3260a5['GokKo'](0x1, 0x2);
continue;
case '5':
console['log'](0x3);
continue;
case '6':
console['log'](0x2);
continue;
}
break;
}
};
}
_0x3bfc5c()();
}());
controlFlowFlatteningThreshold
Type: number Default: 0.75 Min: 0 Max: 1
Probabilitas bahwa transformasi controlFlowFlattening akan diterapkan pada suatu node.
Pengaturan ini sangat berguna untuk ukuran kode yang besar karena banyaknya transformasi control flow dapat memperlambat kode Anda dan menambah ukuran kode.
controlFlowFlatteningThreshold: 0 setara dengan controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Secara drastis meningkatkan ukuran kode hasil obfuskasi (hingga 200%), gunakan hanya jika ukuran kode hasil obfuskasi tidak menjadi masalah. Gunakan deadCodeInjectionThreshold untuk mengatur persentase node yang akan terpengaruh oleh dead code injection.
⚠️ Opsi ini secara paksa mengaktifkan opsi stringArray.
⚠️ Opsi ini dinonaktifkan secara diam-diam ketika vmObfuscation diaktifkan.
Dengan opsi ini, blok-blok kode mati (dead code) acak akan ditambahkan ke kode hasil obfuskasi.
Contoh:
// input
(function(){
if (true) {
var foo = function () {
console.log('abc');
};
var bar = function () {
console.log('def');
};
var baz = function () {
console.log('ghi');
};
var bark = function () {
console.log('jkl');
};
var hawk = function () {
console.log('mno');
};
foo();
bar();
baz();
bark();
hawk();
}
})();
// output
var _0x37b8 = [
'YBCtz',
'GlrkA',
'urPbb',
'abc',
'NMIhC',
'yZgAj',
'zrAId',
'EtyJA',
'log',
'mno',
'jkl',
'def',
'Quzya',
'IWbBa',
'ghi'
];
function _0x43a7(_0x12cf56, _0x587376) {
_0x43a7 = function (_0x2f87a8, _0x47eac2) {
_0x2f87a8 = _0x2f87a8 - (0x16a7 * 0x1 + 0x5 * 0x151 + -0x1c92);
var _0x341e03 = _0x37b8[_0x2f87a8];
return _0x341e03;
};
return _0x43a7(_0x12cf56, _0x587376);
}
(function () {
if (!![]) {
var _0xbbe28f = function () {
var _0x2fc85f = _0x43a7;
if (_0x2fc85f(0xaf) === _0x2fc85f(0xae)) {
_0x1dd94f[_0x2fc85f(0xb2)](_0x2fc85f(0xb5));
} else {
console[_0x2fc85f(0xb2)](_0x2fc85f(0xad));
}
};
var _0x5e46bc = function () {
var _0x15b472 = _0x43a7;
if (_0x15b472(0xb6) !== _0x15b472(0xaa)) {
console[_0x15b472(0xb2)](_0x15b472(0xb5));
} else {
_0x47eac2[_0x15b472(0xb2)](_0x15b472(0xad));
}
};
var _0x3669e8 = function () {
var _0x47a442 = _0x43a7;
if (_0x47a442(0xb7) !== _0x47a442(0xb0)) {
console[_0x47a442(0xb2)](_0x47a442(0xb8));
} else {
_0x24e0bf[_0x47a442(0xb2)](_0x47a442(0xb3));
}
};
var _0x28b05a = function () {
var _0x497902 = _0x43a7;
if (_0x497902(0xb1) === _0x497902(0xb1)) {
console[_0x497902(0xb2)](_0x497902(0xb4));
} else {
_0x59c9c6[_0x497902(0xb2)](_0x497902(0xb4));
}
};
var _0x402a54 = function () {
var _0x1906b7 = _0x43a7;
if (_0x1906b7(0xab) === _0x1906b7(0xac)) {
_0xb89cd0[_0x1906b7(0xb2)](_0x1906b7(0xb8));
} else {
console[_0x1906b7(0xb2)](_0x1906b7(0xb3));
}
};
_0xbbe28f();
_0x5e46bc();
_0x3669e8();
_0x28b05a();
_0x402a54();
}
}());
deadCodeInjectionThreshold
Type: number Default: 0.4 Min: 0 Max: 1
Memungkinkan Anda mengatur persentase node yang akan terpengaruh oleh deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Dapat membekukan peramban Anda jika Anda membuka Developer Tools.
⚠️ Opsi ini dinonaktifkan secara diam-diam ketika vmObfuscation diaktifkan. Gunakan vmDebugProtection sebagai gantinya.
Opsi ini membuat fungsi debugger pada Developer Tools hampir mustahil digunakan (baik pada peramban berbasis WebKit maupun Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Dapat membekukan peramban Anda! Gunakan dengan risiko Anda sendiri.
⚠️ Opsi ini dinonaktifkan secara diam-diam ketika vmObfuscation diaktifkan. Gunakan vmDebugProtection sebagai gantinya.
Jika diatur, sebuah interval dalam milidetik digunakan untuk memaksa mode debug pada tab Console, sehingga mempersulit penggunaan fitur-fitur lain dari Developer Tools. Berfungsi jika debugProtection diaktifkan. Nilai yang direkomendasikan adalah antara 2000 dan 4000 milidetik.
disableConsoleOutput
Type: boolean Default: false
⚠️ Opsi ini menonaktifkan pemanggilan console secara global untuk semua skrip
Menonaktifkan penggunaan console.log, console.info, console.error, console.warn, console.debug, console.exception, dan console.trace dengan menggantinya menjadi fungsi kosong. Hal ini mempersulit penggunaan debugger.
domainLock
Type: string[] Default: []
⚠️ Opsi ini tidak berfungsi dengan target: 'node', target: 'service-worker', atau target: 'bytenode'
Memungkinkan kode sumber hasil obfuskasi hanya berjalan pada domain dan/atau subdomain tertentu. Hal ini membuat orang lain sangat sulit untuk sekadar menyalin dan menempelkan kode sumber Anda lalu menjalankannya di tempat lain.
Jika kode sumber tidak dijalankan pada domain yang ditentukan oleh opsi ini, peramban akan dialihkan ke URL yang diteruskan pada opsi domainLockRedirectUrl.
Beberapa domain dan subdomain
Anda dapat mengunci kode Anda pada lebih dari satu domain atau subdomain. Misalnya, untuk menguncinya agar kode hanya berjalan pada www.example.com tambahkan www.example.com. Agar berfungsi pada domain root termasuk subdomain apa pun (example.com, sub.example.com), gunakan .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Opsi ini tidak berfungsi dengan target: 'node', target: 'service-worker', atau target: 'bytenode'
Memungkinkan peramban dialihkan ke URL yang diberikan jika kode sumber tidak dijalankan pada domain yang ditentukan oleh domainLock
exclude
Type: string[] Default: []
Nama berkas atau glob yang menunjukkan berkas mana yang dikecualikan dari obfuskasi.
forceTransformStrings
Type: string[] Default: []
Mengaktifkan transformasi paksa terhadap literal string yang cocok dengan pola RegExp yang diberikan.
⚠️ Opsi ini hanya memengaruhi string yang seharusnya tidak ditransformasi oleh stringArrayThreshold (atau kemungkinan threshold lain di masa mendatang)
Opsi ini memiliki prioritas di atas opsi reservedStrings tetapi tidak memiliki prioritas di atas conditional comments.
Contoh:
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
Tujuan utama opsi ini adalah kemampuan untuk menggunakan nama pengenal yang sama selama obfuskasi beberapa sumber/berkas.
Saat ini terdapat dua jenis pengenal yang didukung:
- Pengenal global:
- Semua pengenal global akan ditulis ke cache;
- Semua pengenal global yang tidak dideklarasikan yang cocok akan diganti dengan nilai dari cache.
- Pengenal properti, hanya jika opsi
renamePropertiesdiaktifkan:- Semua pengenal properti akan ditulis ke cache;
- Semua pengenal properti yang cocok akan diganti dengan nilai dari cache.
Node.js API
Jika nilai null diberikan, cache dinonaktifkan sepenuhnya.
Jika objek kosong ({}) diberikan, mengaktifkan penulisan nama pengenal ke objek-cache (tipe TIdentifierNamesCache). Objek-cache ini akan diakses melalui pemanggilan metode getIdentifierNamesCache dari objek ObfuscationResult.
Objek-cache yang dihasilkan selanjutnya dapat digunakan sebagai nilai opsi identifierNamesGenerator untuk menggunakan nama-nama ini selama obfuskasi semua nama pengenal yang cocok dari sumber berikutnya.
Contoh:
const source1ObfuscationResult = JavaScriptObfuscator.obfuscate(
`
function foo(arg) {
console.log(arg)
}
function bar() {
var bark = 2;
}
`,
{
compact: false,
identifierNamesCache: {},
renameGlobals: true
}
)
console.log(source1ObfuscationResult.getIdentifierNamesCache());
/*
{
globalIdentifiers: {
foo: '_0x5de86d',
bar: '_0x2a943b'
}
}
*/
const source2ObfuscationResult = JavaScriptObfuscator.obfuscate(
`
// Expecting that these global functions are defined in another obfuscated file
foo(1);
bar();
// Expecting that this global function is defined in third-party package
baz();
`,
{
compact: false,
identifierNamesCache: source1ObfuscationResult.getIdentifierNamesCache(),
renameGlobals: true
}
)
console.log(source2ObfuscationResult.getObfuscatedCode());
/*
_0x5de86d(0x1);
_0x2a943b();
baz();
*/
CLI
CLI memiliki opsi berbeda --identifier-names-cache-path yang memungkinkan penentuan path ke berkas .json yang sudah ada yang akan digunakan untuk membaca dan menulis cache nama pengenal.
Jika path ke berkas kosong diberikan - cache nama pengenal akan ditulis ke berkas tersebut.
Berkas dengan cache yang sudah ada ini dapat digunakan kembali sebagai nilai opsi --identifier-names-cache-path untuk menggunakan nama-nama ini selama obfuskasi semua nama pengenal yang cocok dari berkas berikutnya.
identifierNamesGenerator
Type: string Default: hexadecimal
Mengatur generator nama pengenal.
Nilai yang tersedia:
dictionary: nama pengenal dari daftaridentifiersDictionaryhexadecimal: nama pengenal seperti_0xabc123mangled: nama pengenal pendek sepertia,b,cmangled-shuffled: sama sepertimangledtetapi dengan alfabet yang diacak
identifiersDictionary
Type: string[] Default: []
Mengatur kamus pengenal untuk opsi identifierNamesGenerator: dictionary. Setiap pengenal dari kamus akan digunakan dalam beberapa varian dengan penggunaan huruf besar/kecil yang berbeda pada setiap karakter. Oleh karena itu, jumlah pengenal dalam kamus sebaiknya bergantung pada jumlah pengenal pada kode sumber asli.
identifiersPrefix
Type: string Default: ''
Mengatur awalan untuk semua pengenal global.
Gunakan opsi ini saat Anda ingin mengobfuskasi beberapa berkas. Opsi ini membantu menghindari konflik antar-pengenal global dari berkas-berkas tersebut. Awalan harus berbeda untuk setiap berkas.
randomIdentifiersPrefix
Type: boolean Default: false
Menambahkan awalan acak berbasis seed (6 karakter alfanumerik) ke semua pengenal global. Gunakan opsi ini untuk menghindari tabrakan antara bundel yang diobfuskasi secara terpisah yang dimuat ke dalam scope global yang sama — opsi ini menghilangkan kebutuhan memilih identifiersPrefix unik untuk setiap bundel secara manual.
- Nilai acak diturunkan dari opsi
seeddan hash kode sumber, sehingga build yang dapat direproduksi dengan seed yang sama menghasilkan awalan yang sama. - Ketika digabungkan dengan
identifiersPrefix, karakter acak ditambahkan setelah awalan yang diberikan pengguna (mis.myApp+ acakaBc123→myAppaBc123). - Ketika digabungkan dengan
vmObfuscation, nilai acak menggantikan awalanvmbawaan — keacakan sudah menjamin keunikan.
ignoreImports
Type: boolean Default: false
Mencegah obfuskasi terhadap impor require. Dapat berguna dalam beberapa kasus ketika, karena suatu alasan, lingkungan runtime membutuhkan impor tersebut hanya dengan string statis.
inputFileName
Type: string Default: ''
Memungkinkan Anda mengatur nama berkas masukan yang berisi kode sumber. Nama ini akan digunakan secara internal untuk pembuatan source map.
Diperlukan saat menggunakan NodeJS API dan opsi sourceMapSourcesMode memiliki nilai sources.
log
Type: boolean Default: false
Mengaktifkan pencatatan informasi ke console.
numbersToExpressions
Type: boolean Default: false
Mengaktifkan konversi angka menjadi ekspresi
Contoh:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Memungkinkan Anda mengatur preset opsi.
Nilai yang tersedia:
vm-default;vm-low-obfuscation;vm-medium-obfuscation;vm-high-obfuscation;vm-ultra-high-obfuscation;vm-anti-llm;default;low-obfuscation;medium-obfuscation;high-obfuscation.
Semua opsi tambahan akan digabungkan dengan preset opsi yang dipilih.
parseHtml
Type: boolean Default: false
Mengaktifkan obfuskasi JavaScript di dalam tag HTML <script>.
Ketika diaktifkan, obfuscator akan:
- Mendeteksi secara otomatis apakah masukan adalah HTML (dengan memeriksa tag
<!DOCTYPE,<html>,<head>,<body>, atau<script>) - Mengekstraksi JavaScript dari tag
<script>yang ditandai dengan atributdata-javascript-obfuscator - Mengobfuskasi setiap skrip yang ditandai secara individual sambil mempertahankan struktur HTML
- Menyisipkan kembali kode hasil obfuskasi ke posisi aslinya
Penting: Hanya skrip dengan atribut data-javascript-obfuscator yang diobfuskasi. Setiap skrip yang ditandai diobfuskasi secara individual dan independen. Ini berarti:
- Kode di dalam tag skrip yang ditandai harus terisolasi - kode tersebut TIDAK boleh merujuk variabel, fungsi, atau kelas yang didefinisikan di tag skrip yang ditandai lainnya
- Skrip yang tidak ditandai tetap dapat mengakses global yang didefinisikan oleh skrip yang ditandai (melalui deklarasi
varatau penetapanglobalThiseksplisit) - Ini memberi Anda kontrol eksplisit atas skrip mana yang akan dilindungi
Diobfuskasi (harus memiliki atribut data-javascript-obfuscator):
<script data-javascript-obfuscator>- skrip biasa<script type="text/javascript" data-javascript-obfuscator>- skrip dengan tipe eksplisit- Skrip dengan atribut tambahan apa pun (
id,class,data-*lainnya, dll.)
Dilewati (dibiarkan tidak berubah):
- Skrip tanpa atribut
data-javascript-obfuscator <script type="module">- ES module (bahkan dengan atribut tersebut)<script src="...">- skrip eksternal (bahkan dengan atribut tersebut)- Tag skrip kosong
Catatan: Source map tidak dibuat ketika parseHtml diaktifkan, karena tidak akan memetakan dengan benar ke keluaran HTML.
Contoh:
// input
const html = `<!DOCTYPE html>
<html>
<body>
<!-- This script will NOT be obfuscated -->
<script>
var helper = 'utility';
</script>
<!-- This script WILL be obfuscated -->
<script data-javascript-obfuscator>
var greeting = 'Hello World';
console.log(greeting);
</script>
</body>
</html>`;
JavaScriptObfuscator.obfuscate(html, {
parseHtml: true,
stringArray: true
});
// output: HTML with only the marked script obfuscated
renameGlobals
Type: boolean Default: false
⚠️ opsi ini dapat merusak kode Anda. Aktifkan hanya jika Anda memahami cara kerjanya!
Mengaktifkan obfuskasi nama variabel dan fungsi global beserta deklarasinya.
Ketika opsi ini dinonaktifkan dan kode masukan mendeklarasikan fungsi atau kelas pada scope global (yakni kode tidak dibungkus dalam IIFE), nama-namanya dipertahankan apa adanya pada keluaran hasil obfuskasi — skrip lain dapat merujuknya berdasarkan nama. Di bawah vmObfuscation, sebuah peringatan VMGlobalFunctionNamesNotRenamed yang mencantumkan nama-nama tersebut akan dilaporkan, karena tubuh fungsi disembunyikan sebagai bytecode tetapi nama tingkat atas yang terbaca tetap mengungkap apa yang dilakukan kode (misalnya kepada LLM). Untuk menghindari paparan ini, bungkus kode dalam IIFE atau aktifkan opsi ini.
renameProperties
Type: boolean Default: false
⚠️ opsi ini MUNGKIN merusak kode Anda. Aktifkan hanya jika Anda memahami cara kerjanya!
Mengaktifkan penggantian nama properti. Semua properti DOM bawaan dan properti pada kelas inti JavaScript akan diabaikan.
Untuk beralih antara mode safe dan unsafe pada opsi ini gunakan opsi renamePropertiesMode.
Untuk mengatur format nama properti yang diganti gunakan opsi identifierNamesGenerator.
Untuk mengontrol properti mana yang akan diganti namanya gunakan opsi reservedNames.
Contoh:
// input
(function () {
const foo = {
prop1: 1,
prop2: 2,
calc: function () {
return this.prop1 + this.prop2;
}
};
console.log(foo.calc());
})();
// output
(function () {
const _0x46529b = {
'_0x10cec7': 0x1,
'_0xc1c0ca': 0x2,
'_0x4b961d': function () {
return this['_0x10cec7'] + this['_0xc1c0ca'];
}
};
console['log'](_0x46529b['_0x4b961d']());
}());
renamePropertiesMode
Type: string Default: safe
⚠️ Bahkan dalam mode safe, opsi renameProperties MUNGKIN merusak kode Anda.
Menentukan mode opsi renameProperties:
safe- perilaku bawaan setelah rilis2.11.0. Mencoba mengganti nama properti dengan cara yang lebih aman untuk mencegah error runtime. Dengan mode ini beberapa properti akan dikecualikan dari penggantian nama.unsafe- perilaku bawaan sebelum rilis2.11.0. Mengganti nama properti dengan cara yang tidak aman tanpa batasan apa pun.
Jika suatu berkas menggunakan properti dari berkas lain, gunakan opsi identifierNamesCache untuk mempertahankan nama properti yang sama di antara berkas-berkas tersebut.
reservedNames
Type: string[] Default: []
Menonaktifkan obfuskasi dan pembuatan pengenal yang cocok dengan pola RegExp yang diberikan.
Contoh:
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Menonaktifkan transformasi literal string yang cocok dengan pola RegExp yang diberikan. String yang cocok akan tetap terlihat pada keluaran hasil obfuskasi.
Saat menggunakan obfuskasi VM, reserved strings disimpan dalam larik terpisah yang tidak terenkripsi agar tetap terlihat. Hal ini berguna untuk string yang harus tetap dapat dibaca, seperti endpoint API untuk pemantauan atau pengenal pustaka.
Contoh:
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Opsi ini mengatur seed untuk generator acak. Ini berguna untuk menghasilkan hasil yang dapat diulang.
Jika seed bernilai 0 - generator acak akan bekerja tanpa seed.
selfDefending
Type: boolean Default: false
⚠️ Jangan mengubah kode hasil obfuskasi dengan cara apa pun setelah obfuskasi dengan opsi ini, karena perubahan apa pun seperti uglify pada kode dapat memicu self defending dan kode tidak akan berfungsi lagi!
⚠️ Opsi ini secara paksa mengatur nilai compact menjadi true
⚠️ Opsi ini dinonaktifkan secara diam-diam ketika vmObfuscation diaktifkan. Gunakan vmSelfDefending sebagai gantinya.
Opsi ini membuat kode keluaran tahan terhadap pemformatan dan penggantian nama variabel. Jika seseorang mencoba menggunakan JavaScript beautifier pada kode hasil obfuskasi, kode tidak akan berfungsi lagi, sehingga lebih sulit untuk dipahami dan dimodifikasi.
simplify
Type: boolean Default: true
Mengaktifkan obfuskasi kode tambahan melalui penyederhanaan.
⚠️ pada rilis mendatang obfuskasi literal boolean (true => !![]) akan dipindahkan ke bawah opsi ini.
Contoh:
// input
if (condition1) {
const foo = 1;
const bar = 2;
console.log(foo);
return bar;
} else if (condition2) {
console.log(1);
console.log(2);
console.log(3);
return 4;
} else {
return 5;
}
// output
if (condition1) {
const foo = 0x1, bar = 0x2;
return console['log'](foo), bar;
} else
return condition2 ? (console['log'](0x1), console['log'](0x2), console['log'](0x3), 0x4) : 0x5;
sourceMap
Type: boolean Default: false
Mengaktifkan pembuatan source map untuk kode hasil obfuskasi.
Source map dapat berguna untuk membantu Anda men-debug kode sumber JavaScript hasil obfuskasi. Jika Anda ingin atau perlu men-debug di lingkungan produksi, Anda dapat mengunggah berkas source map terpisah ke lokasi rahasia lalu mengarahkan peramban Anda ke sana.
sourceMapBaseUrl
Type: string Default: ``
Mengatur base url pada url impor source map ketika sourceMapMode: 'separate'.
Contoh CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Hasil:
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Mengatur nama berkas untuk source map keluaran ketika sourceMapMode: 'separate'.
Contoh CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Hasil:
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Menentukan mode pembuatan source map:
inline- menambahkan source map di akhir setiap berkas .js;separate- menghasilkan berkas '.map' terkait berisi source map. Jika Anda menjalankan obfuscator melalui CLI - menambahkan tautan ke berkas source map di akhir berkas berisi kode hasil obfuskasi//# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Memungkinkan Anda mengontrol field sources dan sourcesContent pada source map:
sources-content- menambahkan fieldsourcesdummy, menambahkan fieldsourcesContentberisi kode sumber asli;sources- menambahkan fieldsourcesdengan deskripsi sumber yang valid, tidak menambahkan fieldsourcesContent. Saat menggunakan NodeJS API, diperlukan pendefinisian opsiinputFileNameyang akan digunakan sebagai nilai fieldsources.
splitStrings
Type: boolean Default: false
Memecah literal string menjadi potongan-potongan dengan panjang sesuai nilai opsi splitStringsChunkLength.
Contoh:
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Mengatur panjang potongan untuk opsi splitStrings.
stringArray
Type: boolean Default: true
Menghapus literal string dan menempatkannya dalam sebuah larik khusus. Misalnya, string "Hello World" pada var m = "Hello World"; akan diganti dengan sesuatu seperti var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ opsi stringArray harus diaktifkan
Mengaktifkan transformasi pemanggilan ke stringArray. Semua argumen dari pemanggilan ini dapat diekstraksi ke objek yang berbeda tergantung pada nilai stringArrayCallsTransformThreshold.
Sehingga semakin sulit untuk menemukan pemanggilan ke string array secara otomatis.
Contoh:
function foo() {
var k = {
c: 0x2f2,
d: '0x396',
e: '0x397',
f: '0x39a',
g: '0x39d',
h: 0x398,
l: 0x394,
m: '0x39b',
n: '0x39f',
o: 0x395,
p: 0x395,
q: 0x399,
r: '0x399'
};
var c = i(k.d, k.e);
var d = i(k.f, k.g);
var e = i(k.h, k.l);
var f = i(k.m, k.n);
function i(c, d) {
return b(c - k.c, d);
}
var g = i(k.o, k.p);
var h = i(k.q, k.r);
}
function j(c, d) {
var l = { c: 0x14b };
return b(c - -l.c, d);
}
console[j(-'0xa6', -'0xa6')](foo());
function b(c, d) {
var e = a();
b = function (f, g) {
f = f - 0xa3;
var h = e[f];
return h;
};
return b(c, d);
}
function a() {
var m = [
'string5',
'string1',
'log',
'string3',
'string6',
'string2',
'string4'
];
a = function () {
return m;
};
return a();
}
stringArrayCallsTransformThreshold
Type: number Default: 0.5
⚠️ opsi stringArray dan stringArrayCallsTransformThreshold harus diaktifkan
Anda dapat menggunakan pengaturan ini untuk menyesuaikan probabilitas (dari 0 hingga 1) bahwa pemanggilan ke string array akan ditransformasi.
stringArrayEncoding
Type: string[] Default: []
⚠️ opsi stringArray harus diaktifkan
Opsi ini dapat memperlambat skrip Anda.
Mengenkode semua literal string dari stringArray menggunakan base64 atau rc4 dan menyisipkan kode khusus yang digunakan untuk mendekodenya kembali saat runtime.
Setiap nilai stringArray akan dienkode dengan pengodean yang dipilih secara acak dari daftar yang diberikan. Hal ini memungkinkan penggunaan beberapa pengodean.
Nilai yang tersedia:
'none'(boolean): tidak mengenkode nilaistringArray'base64'(string): mengenkode nilaistringArraymenggunakanbase64'rc4'(string): mengenkode nilaistringArraymenggunakanrc4. Sekitar 30-50% lebih lambat daripadabase64, tetapi lebih sulit untuk mendapatkan nilai awalnya.
Sebagai contoh, dengan nilai opsi berikut beberapa nilai stringArray tidak akan dienkode, dan beberapa nilai akan dienkode dengan pengodean base64 dan rc4:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ opsi stringArray harus diaktifkan
Memungkinkan Anda mengontrol tipe indeks pemanggilan string array.
Setiap indeks pemanggilan stringArray akan ditransformasi dengan tipe yang dipilih secara acak dari daftar yang diberikan. Hal ini memungkinkan penggunaan beberapa tipe.
Nilai yang tersedia:
'hexadecimal-number'(default): mentransformasi indeks pemanggilan string array sebagai angka heksadesimal'hexadecimal-numeric-string': mentransformasi indeks pemanggilan string array sebagai string numerik heksadesimal
Sebelum rilis 2.9.0, javascript-obfuscator mentransformasi semua indeks pemanggilan string array dengan tipe hexadecimal-numeric-string. Hal ini membuat sebagian deobfuskasi manual sedikit lebih sulit tetapi memungkinkan pendeteksian pemanggilan tersebut dengan mudah oleh deobfuscator otomatis.
Tipe baru hexadecimal-number berupaya mempersulit deteksi otomatis pola pemanggilan string array di dalam kode.
Lebih banyak tipe akan ditambahkan di masa mendatang.
stringArrayIndexShift
Type: boolean Default: true
⚠️ opsi stringArray harus diaktifkan
Mengaktifkan pergeseran indeks tambahan untuk semua pemanggilan string array
stringArrayRotate
Type: boolean Default: true
⚠️ stringArray harus diaktifkan
Menggeser larik stringArray sejauh sejumlah posisi yang tetap dan acak (dibuat saat obfuskasi kode). Hal ini mempersulit pencocokan urutan string yang dihapus dengan posisi aslinya.
stringArrayShuffle
Type: boolean Default: true
⚠️ stringArray harus diaktifkan
Mengacak item-item larik stringArray secara acak.
stringArrayWrappersCount
Type: number Default: 1
⚠️ opsi stringArray harus diaktifkan
Mengatur jumlah pembungkus untuk string array di dalam setiap scope root atau fungsi.
Jumlah pembungkus yang sebenarnya di dalam setiap scope dibatasi oleh jumlah node literal dalam scope tersebut.
Contoh:
// Input
const foo = 'foo';
const bar = 'bar';
function test () {
const baz = 'baz';
const bark = 'bark';
const hawk = 'hawk';
}
const eagle = 'eagle';
// Output, stringArrayWrappersCount: 5
const _0x3f6c = [
'bark',
'bar',
'foo',
'eagle',
'hawk',
'baz'
];
const _0x48f96e = _0x2e13;
const _0x4dfed8 = _0x2e13;
const _0x55e970 = _0x2e13;
function _0x2e13(_0x33c4f5, _0x3f6c62) {
_0x2e13 = function (_0x2e1388, _0x60b1e) {
_0x2e1388 = _0x2e1388 - 0xe2;
let _0x53d475 = _0x3f6c[_0x2e1388];
return _0x53d475;
};
return _0x2e13(_0x33c4f5, _0x3f6c62);
}
const foo = _0x48f96e(0xe4);
const bar = _0x4dfed8(0xe3);
function test() {
const _0x1c262f = _0x2e13;
const _0x54d7a4 = _0x2e13;
const _0x5142fe = _0x2e13;
const _0x1392b0 = _0x1c262f(0xe7);
const _0x201a58 = _0x1c262f(0xe2);
const _0xd3a7fb = _0x1c262f(0xe6);
}
const eagle = _0x48f96e(0xe5);
stringArrayWrappersChainedCalls
Type: boolean Default: true
⚠️ opsi stringArray dan stringArrayWrappersCount harus diaktifkan
Mengaktifkan pemanggilan berantai di antara pembungkus string array.
Contoh:
// Input
const foo = 'foo';
const bar = 'bar';
function test () {
const baz = 'baz';
const bark = 'bark';
function test1() {
const hawk = 'hawk';
const eagle = 'eagle';
}
}
// Output, stringArrayWrappersCount: 5, stringArrayWrappersChainedCalls: true
const _0x40c2 = [
'bar',
'bark',
'hawk',
'eagle',
'foo',
'baz'
];
const _0x31c087 = _0x3280;
const _0x31759a = _0x3280;
function _0x3280(_0x1f52ee, _0x40c2a2) {
_0x3280 = function (_0x3280a4, _0xf07b02) {
_0x3280a4 = _0x3280a4 - 0x1c4;
let _0x57a182 = _0x40c2[_0x3280a4];
return _0x57a182;
};
return _0x3280(_0x1f52ee, _0x40c2a2);
}
const foo = _0x31c087(0x1c8);
const bar = _0x31c087(0x1c4);
function test() {
const _0x848719 = _0x31759a;
const _0x2693bf = _0x31c087;
const _0x2c08e8 = _0x848719(0x1c9);
const _0x359365 = _0x2693bf(0x1c5);
function _0x175e90() {
const _0x310023 = _0x848719;
const _0x2302ef = _0x2693bf;
const _0x237437 = _0x310023(0x1c6);
const _0x56145c = _0x310023(0x1c7);
}
}
stringArrayWrappersParametersMaxCount
Type: number Default: 2
⚠️ opsi stringArray harus diaktifkan
⚠️ Saat ini opsi ini hanya memengaruhi pembungkus yang ditambahkan oleh nilai opsi function pada stringArrayWrappersType
Memungkinkan Anda mengontrol jumlah maksimum parameter pembungkus string array.
Nilai bawaan dan minimum adalah 2. Nilai yang direkomendasikan antara 2 dan 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ opsi stringArray dan stringArrayWrappersCount harus diaktifkan
Memungkinkan Anda memilih tipe pembungkus yang ditambahkan oleh opsi stringArrayWrappersCount.
Nilai yang tersedia:
'variable': menambahkan pembungkus variabel di bagian atas setiap scope. Performa cepat.'function': menambahkan pembungkus fungsi pada posisi acak di dalam setiap scope. Performa lebih lambat daripadavariabletetapi memberikan obfuskasi yang lebih ketat.
Sangat direkomendasikan untuk menggunakan pembungkus function demi obfuskasi yang lebih tinggi ketika penurunan performa tidak berdampak besar pada aplikasi hasil obfuskasi.
Contoh nilai opsi 'function':
// input
const foo = 'foo';
function test () {
const bar = 'bar';
console.log(foo, bar);
}
test();
// output
const a = [
'log',
'bar',
'foo'
];
const foo = d(0x567, 0x568);
function b(c, d) {
b = function (e, f) {
e = e - 0x185;
let g = a[e];
return g;
};
return b(c, d);
}
function test() {
const c = e(0x51c, 0x51b);
function e (c, g) {
return b(c - 0x396, g);
}
console[f(0x51b, 0x51d)](foo, c);
function f (c, g) {
return b(c - 0x396, g);
}
}
function d (c, g) {
return b(g - 0x3e1, c);
}
test();
stringArrayThreshold
Type: number Default: 0.8 Min: 0 Max: 1
⚠️ opsi stringArray harus diaktifkan
Anda dapat menggunakan pengaturan ini untuk menyesuaikan probabilitas (dari 0 hingga 1) bahwa sebuah literal string akan disisipkan ke dalam stringArray.
Pengaturan ini sangat berguna untuk ukuran kode yang besar karena berulang kali memanggil string array dan dapat memperlambat kode Anda.
stringArrayThreshold: 0 setara dengan stringArray: false.
strictMode
Type: boolean | null Default: null
Memungkinkan Anda menentukan bagaimana obfuscator harus memperlakukan kode terkait strict mode JavaScript.
Nilai yang tersedia:
null(bawaan) - mendeteksi strict mode secara otomatis dari kode. Jika kode memiliki direktif'use strict'eksplisit, sintaks ES module, atau metode kelas, kode diperlakukan sebagai strict mode. Jika tidak, sloppy mode diasumsikan.true- memaksa perlakuan strict mode untuk semua kode, bahkan tanpa direktif'use strict'eksplisit. Gunakan ini ketika kode Anda akan berjalan dalam konteks strict mode (mis. pada ES module, bundler, atau framework modern).false- hanya indikator strict mode eksplisit ('use strict', ES module, metode kelas) yang diperlakukan sebagai strict. Pewarisan dari scope induk tetap berlaku sesuai spesifikasi JS.
target
Type: string Default: browser
Memungkinkan Anda mengatur lingkungan target untuk kode hasil obfuskasi.
Nilai yang tersedia:
browser(bawaan) — lingkungan halaman web standar. Kode keluaran identik dengannode, tetapi beberapa opsi khusus peramban tidak diizinkan digunakan dengan targetnodebrowser-no-eval— sama sepertibrowser, tetapi keluaran tidak menggunakaneval(). Gunakan ketika halaman target memiliki Content Security Policy yang melarangeval/unsafe-eval.node— lingkungan Node.js. Opsi khusus peramban dinonaktifkan (opsi-opsi tersebut membutuhkanwindow/documentdan akan menjadi no-op atau melempar error di Node). Beberapa pertahananvmSelfDefendingyang bergantung pada API khusus peramban — deteksi peramban headless, pemulihan clean-realm berbasis iframe, pemeriksaan anti-inspector/DOM — tidak dikeluarkan untuk target ini.service-worker— konteks Service Worker. Tanpawindow, tanpadocument, globalselfyang berbeda.userscript— sandbox pengelola userscript (mis. Tampermonkey). PertahananvmSelfDefendingdisesuaikan sebagaimana mestinya.bytenode— kode Node.js yang akan dikompilasi dengan loader bytenode (bytecode ter-cache V8.jsc) setelah obfuskasi. Obfuscator itu sendiri tidak memanggilbytenode; ia menghasilkan JavaScript hasil obfuskasi VM yang runtime-nya disusun agar dapat bertahan melalui langkah kompilasi bytenode, dan pertahananvmSelfDefendingdisesuaikan sebagaimana mestinya. Jalankanbytenodesendiri pada keluaran hasil obfuskasi untuk menghasilkan.jscfinal.
transformObjectKeys
Type: boolean Default: false
Mengaktifkan transformasi kunci objek.
Contoh:
// input
(function(){
var object = {
foo: 'test1',
bar: {
baz: 'test2'
}
};
})();
// output
var _0x4735 = [
'foo',
'baz',
'bar',
'test1',
'test2'
];
function _0x390c(_0x33d6b6, _0x4735f4) {
_0x390c = function (_0x390c37, _0x1eed85) {
_0x390c37 = _0x390c37 - 0x198;
var _0x2275f8 = _0x4735[_0x390c37];
return _0x2275f8;
};
return _0x390c(_0x33d6b6, _0x4735f4);
}
(function () {
var _0x17d1b7 = _0x390c;
var _0xc9b6bb = {};
_0xc9b6bb[_0x17d1b7(0x199)] = _0x17d1b7(0x19c);
var _0x3d959a = {};
_0x3d959a[_0x17d1b7(0x198)] = _0x17d1b7(0x19b);
_0x3d959a[_0x17d1b7(0x19a)] = _0xc9b6bb;
var _0x41fd86 = _0x3d959a;
}());
warnings
Type: string | object Default: all
Mengontrol peringatan obfuskasi non-fatal mana yang dikeluarkan melalui metode ObfuscationResult.getWarnings().
Nilai yang tersedia:
'all'(bawaan) — setiap peringatan dikeluarkan.'none'— semua peringatan disembunyikan.- sebuah objek yang memetakan tipe peringatan ke boolean — tipe yang dipetakan ke
falsedisembunyikan; setiap tipe yang tidak ada (atau dipetakan ketrue) tetap aktif. Misalnya,{ "VMGlobalFunctionNamesNotRenamed": false }mempertahankan setiap peringatan kecuali yang satu itu.
Tipe peringatan:
VMGlobalFunctionNamesNotRenamed— di bawahvmObfuscation, nama deklarasi fungsi tingkat atas, deklarasi kelas, dan variabel yang diberi ekspresi fungsi/arrow/kelas dipertahankan apa adanya (opsirenameGlobalsdinonaktifkan dan kode tidak dibungkus dalam IIFE), sehingga tetap terbaca pada keluaran meskipun tubuhnya disembunyikan sebagai bytecode. Nama yang diekspor tidak dilaporkan.VMTopLevelInitializerNotVirtualized— inisialisasi variabel tingkat atas tetap berupa JavaScript biasa di bawah obfuskasi VM karenavmWrapTopLevelInitializersdinonaktifkan atau tidak dapat memvirtualisasinya.DynamicCodeRenameRisk— kode membangun sebuah fungsi dari string saat runtime (directeval, konstruktorFunction, ataufn.toString()yang disisipkan ke dalam<script>/Worker), yang mungkin merujuk pengenal yang telah diganti namanya oleh obfuscator.VMDynamicCodeSkipped— sebuah fungsi dilewati dari bytecoding VM karena mengandung directeval/new Functiondinamis /Function(lihatvmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— denganvmAsyncExecutordiaktifkan, sebuah fungsi yang Anda tandai secara eksplisit dalam modecommentternyata sinkron dan dilewati (hanya fungsi async yang divirtualisasi dalam mode itu).VMAsyncGeneratorSkippedInAsyncMode— denganvmAsyncExecutordan key getter async yang aktif, sebuah generator async yang ditandai tidak dapat divirtualisasi (ia harus mengembalikan iteratornya secara sinkron).BrowserTargetWithNodeStyleCode— kode tampak menargetkan Node.js (mis.require('fs'),__dirname,process.argv) sementara opsitargetdiatur ke lingkungan yang menyerupai peramban.
vmObfuscation
Type: boolean Default: false
Mengaktifkan obfuskasi bytecode berbasis VM. Ketika diaktifkan, fungsi JavaScript dikompilasi menjadi bytecode khusus yang berjalan pada virtual machine tersemat. Ini memberikan tingkat proteksi tertinggi karena logika kode asli ditransformasi sepenuhnya.
Contoh:
Kode Anda yang terbaca seperti return qty * price menjadi sederet angka seperti [0x15,0x03,0x17,...] yang hanya dapat dieksekusi oleh interpreter VM tersemat. Logika aslinya tidak lagi terlihat sebagai JavaScript.
vmTargetFunctions
Type: string[] Default: []
Menentukan secara tepat fungsi tingkat root mana yang harus mendapatkan proteksi VM berdasarkan nama.
Contoh:
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Hasil: Hanya ketiga fungsi ini yang mendapatkan proteksi VM. Selebihnya tetap sebagai JavaScript biasa (tetapi masih diobfuskasi). Cocok untuk melindungi pemeriksaan lisensi atau logika autentikasi yang sensitif sambil menjaga sisa kode Anda tetap ringan.
vmExcludeFunctions
Type: string[] Default: []
Menentukan fungsi tingkat root yang tidak boleh mendapatkan proteksi VM. Memiliki prioritas di atas pengaturan lain.
Contoh:
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Kapan digunakan: Fungsi tingkat root yang kritis terhadap performa (loop animasi, pemrosesan data real-time) dapat dikecualikan untuk menghindari overhead VM sambil tetap melindungi selebihnya.
vmTargetFunctionsMode
Type: string Default: root
Mengontrol bagaimana fungsi/metode dipilih untuk obfuskasi VM.
Contoh - Mode comment:
// Source code
function regularFunction() {
return 'not virtualized';
}
/* javascript-obfuscator:vm */
function sensitiveFunction() {
return 'this will be VM-protected';
}
function outer() {
/* javascript-obfuscator:vm */
function nestedSensitive() {
return 'nested but still VM-protected';
}
return nestedSensitive();
}
// Obfuscator options
{
vmObfuscation: true,
vmTargetFunctionsMode: 'comment'
}
Kapan digunakan: Ketika Anda memerlukan kontrol yang presisi atas fungsi mana persisnya yang mendapatkan proteksi VM, terutama fungsi bersarang yang mengandung logika sensitif. Tidak seperti vmTargetFunctions yang hanya berfungsi dengan fungsi bernama tingkat root, mode comment memungkinkan Anda melindungi fungsi apa pun di mana pun dalam kode Anda.
vmForceCompileDynamicCode
Type: boolean Default: false
Mengontrol apa yang dilakukan obfuskasi VM terhadap fungsi yang mengandung pemanggilan direct eval, new Function(...), atau Function(...).
Secara bawaan, fungsi semacam itu (dan setiap fungsi yang didefinisikan di dalamnya) dilewati dari bytecoding VM dan peringatan VMDynamicCodeSkipped dilaporkan pada result.getWarnings(). Ini karena sumber yang dibangun saat runtime mungkin merujuk pengenal dari rantai scope di sekitarnya — pengenal yang telah diganti namanya oleh obfuscator.
Ketika diatur ke true, fungsi tetap di-bytecode dan peringatan VMDynamicCodeSkipped tidak lagi dikeluarkan.
Peringatan DynamicCodeRenameRisk yang terpisah tetap muncul terlepas dari opsi ini, karena risiko penggantian nama yang dijelaskannya tidak bergantung pada pelewatan VM — mengaktifkan opsi ini tidak membuat pola yang mendasarinya menjadi lebih aman.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
Dengan opsi nonaktif (bawaan), loadConfig dibiarkan sebagai JavaScript biasa. Dengan opsi aktif, loadConfig dikompilasi menjadi bytecode VM seperti fungsi lainnya. Gunakan ini ketika Anda telah mengaudit lokasi pemanggilan dan yakin bahwa kode yang dibangun saat runtime tidak bergantung pada pengenal yang diganti namanya dalam closure.
vmWrapTopLevelInitializers
Type: boolean Default: false
Membungkus sebagian inisialisasi variabel tingkat atas dalam IIFE (Immediately Invoked Function Expression) agar dapat diobfuskasi VM.
Apa yang dilakukannya: Tanpa opsi ini, konstanta dan variabel tingkat atas tetap terlihat pada keluaran:
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
Dengan opsi ini diaktifkan, inisialisasi dibungkus dalam IIFE yang diobfuskasi VM:
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Catatan: Opsi ini hanya berfungsi ketika vmTargetFunctionsMode bernilai 'root' (bawaan).
Peringatan: Setiap kali sebuah inisialisasi tingkat atas berakhir sebagai JavaScript biasa di bawah obfuskasi VM, sebuah peringatan VMTopLevelInitializerNotVirtualized yang mencantumkan nama variabel yang terpengaruh akan dilaporkan. Itu mencakup: opsi ini dinonaktifkan, inisialisasi yang harus dilewati opsi ini (masing-masing dengan alasannya — mis. inisialisasi merujuk deklarator saudara atau mengandung top-level await), dan mode vmAsyncExecutor di mana pembungkus sinkron tidak dapat divirtualisasi sama sekali.
vmDynamicOpcodes
Type: boolean Default: false
Membuat interpreter VM lebih kecil dan unik untuk setiap build.
Apa yang dilakukannya:
- Memfilter instruksi yang tidak terpakai - Jika kode Anda tidak menggunakan kelas, instruksi terkait kelas dihapus sepenuhnya
- Mengacak struktur - Urutan handler instruksi diacak pada setiap build
Hasilnya - keluaran lebih kecil dan setiap build tampak berbeda.
vmBytecodeEncoding
Type: boolean Default: false
Mengenkode setiap instruksi bytecode. Instruksi didekode satu per satu selama eksekusi.
vmBytecodeArrayEncoding
Type: boolean Default: false
Mengenkode seluruh larik bytecode sebagai satu blok. Larik didekode sekali saat startup sebelum eksekusi dimulai. Gunakan bersama vmBytecodeEncoding untuk dua lapis proteksi.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Kunci enkripsi kustom untuk pengodean larik bytecode. Ketika diatur, kunci ini digunakan alih-alih kunci bawaan yang diturunkan dari lingkungan. Kunci harus disediakan saat runtime melalui vmBytecodeArrayEncodingKeyGetter.
Opsi ini mengeksternalisasi kunci enkripsi - kunci tidak tertanam di dalam kode hasil obfuskasi itu sendiri. Meskipun kunci tetap dapat diakses saat runtime (dan karenanya tidak benar-benar rahasia), pemisahan ini mencegah alat analisis statis menemukan kunci hanya dengan memeriksa kode saja.
Penting: Kunci harus tersedia secara sinkron saat kode hasil obfuskasi dimuat. Gunakan penyimpanan sinkron seperti cookie, localStorage, sessionStorage, variabel global, atau elemen DOM (mis. tag meta yang disisipkan server). Metode async seperti fetch() tidak dapat digunakan langsung dalam ekspresi key getter.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Ekspresi JavaScript sinkron yang mengembalikan kunci enkripsi saat runtime. Ekspresi ini dievaluasi ketika kode hasil obfuskasi dimuat, dan harus mengembalikan kunci yang sama dengan yang disediakan di vmBytecodeArrayEncodingKey. Untuk meresolusi kunci secara asinkron (sebuah Promise), aktifkan vmAsyncExecutor.
Catatan: getter yang mengembalikan Promise memerlukan vmAsyncExecutor. Hal ini tidak dapat diperiksa saat build, sehingga getter Promise dengan vmAsyncExecutor nonaktif akan gagal saat runtime — dekoder menerima Promise alih-alih kunci.
Kode hasil obfuskasi hanya akan berfungsi ketika key getter mengembalikan kunci yang persis sama dengan yang digunakan selama obfuskasi. Jika kunci tidak cocok, dekripsi akan gagal dan kode akan menghasilkan keluaran acak atau error. Jika key getter mengembalikan undefined, null, atau string kosong, kode akan melempar error: "VM decryption key not available".
Penting: Jauhkan kunci dari berkas/skrip yang sama dengan kode hasil obfuskasi — menempatkannya secara inline di sana memungkinkan bahkan pemindaian bundel yang murni statis memulihkannya. Simpan kunci di sumber terpisah: cookie yang diatur server, localStorage yang diisi oleh skrip lain, tag meta HTML yang disisipkan server, global yang diatur oleh skrip berbeda, atau (dengan vmAsyncExecutor) diambil dari backend Anda saat runtime.
Ketika kunci diambil dari backend Anda (melalui vmAsyncExecutor), tambahkan pemeriksaan berbasis sesi atau origin pada endpoint tersebut: kembalikan kunci yang benar kepada pengguna asli (sesi valid, Origin/Referer yang diharapkan) dan kunci acak kepada permintaan yang mencurigakan (mis. localhost/origin tak terduga, tanpa sesi). Pengguna asli berjalan normal; salinan yang berjalan di luar lingkungan Anda mendapatkan kunci yang tidak mendekripsi apa pun. Logika persisnya bergantung pada situs Anda.
Contoh:
// From cookie
vmBytecodeArrayEncodingKeyGetter: "document.cookie.match(/vmKey=([^;]+)/)?.[1]"
// From localStorage
vmBytecodeArrayEncodingKeyGetter: "localStorage.getItem('vmKey')"
// From global variable
vmBytecodeArrayEncodingKeyGetter: "window.__VM_KEY__"
// From meta tag (server-injected)
vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]').content"
// From nested object
vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"
// From backend, async (requires vmAsyncExecutor)
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
Contoh penggunaan:
// Build time
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
});
// Runtime - key must be set before obfuscated code runs
window.__VM_KEY__ = 'mySecretKey123';
vmAsyncExecutor
Type: boolean Default: false
Mengaktifkan executor VM asinkron, yang memungkinkan vmBytecodeArrayEncodingKeyGetter mengembalikan sebuah Promise (key getter asinkron) — sehingga kunci dekripsi dapat diambil saat runtime (permintaan jaringan, IndexedDB, dll.) alih-alih harus tersedia secara sinkron saat kode dimuat.
Sangat direkomendasikan untuk basis kode yang sepenuhnya async. Dalam mode ini hanya fungsi async yang divirtualisasi — fungsi sinkron tidak dapat dijadikan async tanpa mengubah nilai kembaliannya menjadi Promise dan merusak pemanggilnya — sehingga kode yang async sepenuhnya mendapatkan cakupan terbanyak. Mode ini tetap berfungsi ketika root-nya sinkron (mis. IIFE sinkron / pembungkus UMD): fungsi async terluar di dalamnya dilindungi, dan bagian sinkronnya dibiarkan apa adanya.
Apa yang ditransformasi: setiap fungsi async terluar, di mana pun ia muncul (termasuk yang bersarang di dalam pembungkus sinkron). Async terluar pada setiap rantai adalah unit yang dilindungi — semua yang ada di dalamnya, sinkron maupun async, ikut dikompilasi. Fungsi sinkron dan generator biasa dibiarkan tidak diobfuskasi.
function foo() { // sync — left as-is
function bar() {} // sync — left as-is
async function baz() { // transformed
// any code here, including calls to other async or sync functions
}
async function bark() { // transformed
// any code here, including calls to other async or sync functions
}
}
Pelewatan dan peringatan. Generator async juga dibiarkan tidak diobfuskasi ketika key getter asinkron aktif (sebuah generator async harus mengembalikan iteratornya secara sinkron dan tidak dapat menunggu kunci). Pada mode bawaan vmTargetFunctionsMode: 'root', pelewatan bersifat senyap (pemilihan otomatis); pada mode comment, sebuah peringatan dikeluarkan melalui ObfuscationResult.getWarnings() setiap kali sebuah fungsi yang Anda tandai secara eksplisit tidak dapat divirtualisasi — ternyata sinkron, atau merupakan generator async di bawah key getter async.
Key getter asinkron tambahannya memerlukan vmBytecodeArrayEncoding dengan sebuah vmBytecodeArrayEncodingKeyGetter.
Contoh penggunaan:
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmAsyncExecutor: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
// the key getter may now return a Promise
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
});
vmJumpsEncoding
Type: boolean Default: false
Mengenkode target lompatan (jump) dalam bytecode. Offset lompatan dihitung saat runtime, menyembunyikan struktur control flow (if/else, loop, dll.) dari analisis statis.
vmMacroOps
Type: boolean Default: false
Menggabungkan urutan instruksi umum menjadi opcode "makro" tunggal. Misalnya, LOAD + ADD + STORE dapat menjadi satu instruksi MACRO_ADD_TO_VAR. Hal ini merusak pengenalan pola dan dapat meningkatkan performa.
vmDebugProtection
Type: boolean Default: false
Menambahkan pertahanan anti-debugging, anti-analisis, dan anti-LLM berlapis ke runtime VM. Bekerja paling baik dengan target browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Menambahkan proteksi deteksi pengutakatikan (tamper), anti-hooking, dan anti-reverse-engineering berlapis ke runtime VM.
⚠️ Opsi ini secara paksa mengaktifkan vmBytecodeArrayEncoding.
⚠️ Deteksi lingkungan sensitif. Opsi ini mengikat kode hasil obfuskasi ke lingkungan runtime targetnya dan menggunakan fingerprinting peramban tingkat lanjut untuk mendeteksi alat otomasi. Kode yang dilindungi dengan opsi ini akan sengaja rusak ketika dijalankan di:
- Peramban headless (Chrome/Chromium headless, PhantomJS)
- Alat otomasi peramban (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (ketika
targetdiatur kebrowser) - jsdom atau emulasi DOM sisi server serupa
- Lingkungan di mana builtin peramban native telah di-hook atau diganti
Kode akan berfungsi dengan benar di peramban biasa (Chrome, Firefox, Safari, Edge), termasuk ketika dimuat di dalam iframe, ekstensi peramban (content script), dan Web Worker. Jika Anda perlu menjalankan pengujian otomatis terhadap kode yang dilindungi, nonaktifkan vmSelfDefending untuk build pengujian — opsi ini dirancang untuk mencegah analisis otomatis dan tidak dapat digunakan secara aman dengan framework otomasi apa pun.
Sangat direkomendasikan untuk digunakan bersama vmDebugProtection, vmBytecodeArrayEncodingKey, dan vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook menerima sebuah objek dengan dua kunci: name (wajib) dan aliases (opsional).
name adalah fungsi global yang didefinisikan oleh halaman host Anda yang dipanggil oleh sebuah pertahanan VM (vmDebugProtection / vmSelfDefending) dengan sebuah objek sinyal ketika ia mendeteksi sinyal yang bermusuhan — sebuah debugger atau inspector, peramban headless / otomasi, proses agen pengkodean AI, domain yang tidak diizinkan, dan sebagainya. Gunakan untuk melaporkan peristiwa tersebut ke backend Anda (mis. navigator.sendBeacon). Hook adalah penampung telemetri murni: nilai kembaliannya diabaikan, dan hook yang hilang atau melempar error adalah no-op senyap yang tidak akan pernah dapat menonaktifkan pertahanan. Untuk mengubah apa yang dilakukan sebuah pertahanan saat deteksi, gunakan vmDefenseReaction.
aliases secara opsional mengganti nama field dari objek sinyal tersebut — dibahas pada Mengganti nama field sinyal di bawah.
Objek sinyal. Hook menerima satu signal:
source— detektor spesifik yang memicu (lihat tabel).category— kelompok tempat ia dilaporkan:automation(peramban non-manusia),debugger(sebuah debugger/inspector aktif),sandbox(host terinstrumentasi/palsu),domain(pelanggaran domain-lock),tamper(builtin yang dipatch saat runtime), atauintegrity(kode VM itu sendiri diubah).score/threshold— seberapa kuat detektor memicu dan nilai yang harus dicapainya; hook memicu hanya setelahscore >= threshold. Sebagian besar pemeriksaan bersifat semua-atau-tidak (satu sinyal yang menentukan);headlessmenjumlahkan beberapa sinyal bentuk-peramban, sehinggascore-nya biasanya lebih tinggi daripadathreshold-nya.
Mendaftarkan hook. Definisikan sebagai global biasa sebelum bundel hasil obfuskasi dimuat — runtime VM dan pertahanannya berjalan sebelum program (yang dilindungi) Anda, sehingga banyak deteksi memicu selama startup:
// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }
Sebuah hook yang didefinisikan di dalam sumber hasil obfuskasi didaftarkan terlalu terlambat untuk menangkap deteksi saat startup, dan jika ia ter-VM-compile, ia tidak dapat dijangkau sampai program Anda berjalan. Ia tetap aman dengan cara apa pun (hook yang hilang menjadi no-op, dan penjaga re-entrancy mencegah kondisi liar apa pun), tetapi untuk cakupan lengkap daftarkan di awal. Untuk tetap melindungi logika pelaporan Anda, jaga agar hook yang didaftarkan tetap berupa buffer satu baris ((window.__vmDet = window.__vmDet || []).push(signal)) dan baca/kirim buffer tersebut dari kode hasil obfuskasi Anda.
Mengganti nama field sinyal (aliases). Nilai source/category bawaan adalah nama deskriptif, sehingga siapa pun yang menginstrumentasi callback (atau membaca keluaran) dapat mengenali proteksi tersebut dan detektor mana yang memicu. aliases mengganti nama field sinyal menjadi token buram pilihan Anda, diterapkan di dalam VM sebelum sinyal dikeluarkan, sehingga nama-nama tersebut tidak pernah muncul pada keluaran atau mencapai callback. Aplikasi Anda mengetahui pemetaannya sendiri dan meneruskan token ke backend Anda.
Alias bersifat per field, memisahkan penggantian nama kunci dan nilai: setiap field menerima sebuah key (nama properti yang diterima callback); field-nama string source dan category juga menerima peta values, sedangkan score/threshold berupa angka dan hanya menerima key. Nama-nama yang dapat Anda petakan (selain itu ditolak saat build):
- kunci field —
source,category,score,threshold - nilai
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - nilai
category—automation,debugger,sandbox,domain,tamper,integrity
vmDefenseHook: {
name: '__vmDetection',
aliases: {
source: { key: 'a8Qm', values: { headless: 'xP4m9Q' } },
category: { key: 'p3Tx', values: { automation: 'bQ7s1M' } },
score: { key: 's1' },
threshold: { key: 't1' }
}
// the callback now receives e.g. { a8Qm: 'xP4m9Q', p3Tx: 'bQ7s1M', s1: <score>, t1: <threshold> }
}
Ini adalah penghindaran fingerprint, bukan kerahasiaan — pemetaan tetap dapat disimpulkan melalui pengujian berulang — sehingga satu-satunya manfaatnya adalah tidak mengekspos nama yang stabil dan menjelaskan diri sendiri. Entri yang tidak diatur mempertahankan nama bawaannya.
Sebuah string biasa (vmDefenseHook: '__vmDetection') diterima sebagai bentuk singkat dari { name: '__vmDetection' } tetapi usang — utamakan bentuk objek.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Mengonfigurasi bagaimana setiap kategori deteksi bereaksi. Opsi ini tidak mengaktifkan apa pun — pertahanan itu sendiri diaktifkan oleh vmSelfDefending, vmDebugProtection, dan vmDomainLock; opsi ini hanya memilih bagaimana sebuah pertahanan yang aktif bereaksi. Kategori adalah unit kontrol — setiap detektor dalam sebuah kategori menjalankan reaksi kategori tersebut.
Setiap kategori mengelompokkan detektor yang mengawasi satu jenis kondisi bermusuhan. Sebuah kategori hanya bereaksi ketika opsi yang mengeluarkan detektornya diaktifkan:
Setiap kategori memetakan ke satu atau lebih dari vmSelfDefending, vmDebugProtection, dan vmDomainLock; tidak ada kategori di luar ketiga opsi tersebut, dan reaksi yang diatur untuk kategori yang opsinya nonaktif tidak berpengaruh apa pun.
Kunci adalah keenam nama kategori ini, atau default (fallback untuk kategori yang tidak ditentukan). Nilainya adalah:
break— berhenti seketikadecoy— tetap berjalan pada state yang diracuni, secara diam-diam menghasilkan hasil yang salahnone— tidak melakukan apa pun secara lokal (hanya telemetri)
Nilai bawaan per kategori ditampilkan di atas; kategori yang tidak Anda atur (atau atur ke nilai bawaannya) menggunakan nilai bawaan tersebut. default menjangkau setiap kategori, termasuk yang benar-secara-konstruksi (integrity, tamper), sehingga { default: 'none' } adalah build yang benar-benar tidak merusak dan hanya telemetri:
vmDefenseReaction: { default: 'none' } // never break — pair with vmDefenseHook
vmDefenseReaction: { automation: 'none', domain: 'break' } // tolerate automation FPs, still break on a bad domain
vmStatefulOpcodes
Type: boolean Default: false
Membuat makna opcode bergantung pada posisi dalam bytecode. Setiap posisi memiliki pemetaan opcode-ke-handler yang berbeda yang diturunkan dari sebuah seed, sehingga nomor opcode yang sama melakukan operasi yang berbeda pada posisi yang berbeda.
vmCallContextOpcodes
Type: boolean Default: false
Membuat fungsi yang dilindungi bergantung pada dari mana ia dipanggil, sehingga tidak dapat diangkat keluar dari kode lalu dijalankan atau dianalisis secara mandiri — ia hanya berperilaku benar ketika dipanggil melalui lokasi pemanggilan aslinya dalam program. Opsi ini memengaruhi performa runtime.
Saat ini hanya konstruksi berikut yang didukung:
- deklarasi fungsi (
function f() {}); - ekspresi fungsi dan arrow function yang ditetapkan ke sebuah variabel (
const f = () => {}); - metode privat instance (
this.#m()).
Dalam setiap kasus, fungsi harus selalu dijangkau melalui pemanggilan langsung (f(), this.#m()). Jika ia disimpan dalam variabel lain, diteruskan sebagai argumen, atau digunakan sebagai nilai dengan cara lain, ia dibiarkan tidak terlindungi. Fungsi async didukung; generator tidak.
Opsi ini bersifat eksperimental dan dapat merusak kode Anda, jadi uji keluaran secara menyeluruh sebelum menggunakannya.
vmStackEncoding
Type: boolean Default: false
Mengenkripsi nilai pada stack VM selama eksekusi. Nilai dienkode saat di-push dan didekode saat di-pop, sehingga inspeksi memori menampilkan data terenkripsi alih-alih nilai sebenarnya.
Opsi ini sangat memengaruhi performa.
vmCompactDispatcher
Type: boolean Default: false
Menggunakan satu executor VM alih-alih executor ganda (sync + generator). Mengurangi ukuran kode hasil obfuskasi tetapi menambah overhead performa ~20% pada kode yang banyak rekursi.
false(bawaan): executor ganda — performa optimal, keluaran lebih besartrue: executor tunggal — keluaran lebih kecil, sedikit lebih lambat
vmStringArrayBytecodeOnly
Type: boolean Default: false
Ketika diaktifkan, string array akan hanya mengekstraksi string dari data bytecode — tidak ada string lain dalam kode yang ditransformasi. Ini secara paksa mengaktifkan stringArray meskipun tidak diatur secara eksplisit.
Mengapa menggunakan ini: Mengekstraksi semua string runtime VM ke string array itu lambat. Opsi ini menargetkan hanya konten bytecode untuk ekstraksi string array, meningkatkan performa sambil tetap melindungi konstanta bytecode.
- Ketika
vmBytecodeArrayEncoding: false— string di dalam constant pool bytecode (larikc) diekstraksi - Ketika
vmBytecodeArrayEncoding: true— string bytecode terenkode base64 tingkat atas diekstraksi stringArrayThresholdtetap mengontrol berapa persen dari string bytecode tersebut yang diekstraksi
vmDomainLock
Type: string[] Default: []
⚠️ Opsi ini tidak berfungsi dengan target: 'node', target: 'service-worker', atau target: 'bytenode'
Membatasi kode hasil obfuskasi ke domain dan/atau subdomain tertentu, dan jauh lebih sulit untuk dilokasikan dan dihilangkan daripada domainLock.
Jika kode sumber tidak dijalankan pada domain yang ditentukan oleh opsi ini, peramban akan dialihkan ke URL yang diteruskan ke vmDomainLockRedirectUrl, dan pemanggilan terlindungi berikutnya akan mengembalikan hasil yang salah bahkan jika pengalihan ditekan.
Beberapa domain dan subdomain
Anda dapat mengunci kode Anda pada lebih dari satu domain atau subdomain. Misalnya, untuk menguncinya agar kode hanya berjalan pada www.example.com tambahkan www.example.com. Agar berfungsi pada domain root termasuk subdomain apa pun (example.com, sub.example.com), gunakan .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Opsi ini tidak berfungsi dengan target: 'node', target: 'service-worker', atau target: 'bytenode'
Memungkinkan peramban dialihkan ke URL yang diberikan jika kode sumber tidak dijalankan pada domain yang ditentukan oleh vmDomainLock.
Preset Options
Obfuskasi tinggi, performa rendah
Performa akan jauh lebih lambat dibandingkan tanpa obfuskasi
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
deadCodeInjection: true,
deadCodeInjectionThreshold: 1,
debugProtection: true,
debugProtectionInterval: 4000,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 1,
transformObjectKeys: true
}
Obfuskasi sedang, performa optimal
Performa akan lebih lambat dibandingkan tanpa obfuskasi
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 10,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 0.75,
stringArrayEncoding: ['base64'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 2,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 4,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.75,
transformObjectKeys: true
}
Obfuskasi rendah, performa tinggi
Performa akan berada pada tingkat yang relatif normal
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: false,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: false,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75
}
Preset bawaan, performa tinggi
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: false,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: false,
simplify: true,
splitStrings: false,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: false,
stringArrayCallsTransformThreshold: 0.5,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75
}
Obfuskasi VM Ultra High (Keamanan Maksimal)
Preset ini mengaktifkan obfuskasi bytecode berbasis VM dengan semua fitur hardening termasuk dispatch tidak langsung. Memberikan proteksi terkuat tetapi dengan ukuran keluaran yang lebih besar dan eksekusi yang jauh lebih lambat.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: true,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: true,
vmCallContextOpcodes: false,
vmStackEncoding: true,
vmCompactDispatcher: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.5,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.5,
debugProtection: true,
debugProtectionInterval: 4000,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.5,
transformObjectKeys: true
}
VM Anti-LLM (Proteksi Agen AI)
Preset ini dirancang khusus untuk mencegah agen AI dan LLM melakukan reverse-engineering terhadap kode ber-bytecode VM. Berbasis vm-default dengan self-defending dan debug protection diaktifkan. Lebih ringan daripada vm-high-obfuscation tetapi diperkeras secara khusus terhadap analisis otomatis.
{
optionsPreset: 'vm-anti-llm'
}
Mencakup:
- Obfuskasi bytecode VM dengan string array (dari
vm-default) vmSelfDefending— deteksi anti-hook, hash integritas, fingerprint sumber, verifikasi clean-realm iframe, derivasi kunci sandi ARXvmDebugProtection— pemeriksaan anti-debugging dalam loop dispatch VMdebugProtection: false— tanpa debug protection lama (debug protection VM lebih unggul)
Obfuskasi VM High (Keamanan Tertinggi)
Preset ini mengaktifkan obfuskasi bytecode berbasis VM dengan sebagian besar fitur hardening. Memberikan proteksi kuat dengan performa yang lebih baik daripada preset ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: true,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: true,
vmCallContextOpcodes: false,
vmStackEncoding: true,
vmCompactDispatcher: false
}
Obfuskasi VM Medium (Keamanan Seimbang)
Preset ini mengaktifkan obfuskasi bytecode berbasis VM dengan sekumpulan fitur hardening yang seimbang. Kompromi yang baik antara keamanan dan performa.
{
optionsPreset: 'vm-medium-obfuscation'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: false,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false
}
Obfuskasi VM Low (Keamanan Dasar, Performa Lebih Baik)
Preset ini mengaktifkan obfuskasi bytecode berbasis VM dasar tanpa fitur hardening tambahan. Keseimbangan yang baik antara keamanan dan ukuran keluaran.
{
optionsPreset: 'vm-low-obfuscation'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: false,
vmBytecodeEncoding: false,
vmBytecodeArrayEncoding: false,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: false,
vmMacroOps: false,
vmDebugProtection: false,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false
}
VM Default (Proteksi VM + String Array)
Preset ini menggabungkan obfuskasi bytecode berbasis VM dasar dengan proteksi string array. Titik awal yang baik untuk obfuskasi VM dengan proteksi string.
{
optionsPreset: 'vm-default'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: false,
vmBytecodeArrayEncoding: true,
vmStringArrayBytecodeOnly: true,
vmAsyncExecutor: false,
vmJumpsEncoding: false,
vmMacroOps: false,
vmDebugProtection: false,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false,
stringArray: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayThreshold: 1,
stringArrayIndexShift: true,
stringArrayIndexesType: ['hexadecimal-number'],
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 1,
stringArrayWrappersCount: 3,
stringArrayWrappersType: 'function',
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayEncoding: ['base64'],
splitStrings: true,
splitStringsChunkLength: 6
}
compact
Type: boolean Default: true
Keluaran kode yang ringkas dalam satu baris.
config
Type: string Default: ``
Nama berkas konfigurasi JS/JSON yang berisi opsi obfuscator. Opsi ini akan ditimpa oleh opsi yang diteruskan langsung ke CLI
controlFlowFlattening
Type: boolean Default: false
⚠️ Opsi ini sangat memengaruhi performa hingga kecepatan runtime 1,5x lebih lambat. Gunakan controlFlowFlatteningThreshold untuk mengatur persentase node yang akan terpengaruh oleh control flow flattening.
Mengaktifkan control flow flattening pada kode. Control flow flattening adalah transformasi struktur kode sumber yang mempersulit pemahaman program.
Contoh:
// input
(function(){
function foo () {
return function () {
var sum = 1 + 2;
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
console.log(6);
}
}
foo()();
})();
// output
(function () {
function _0x3bfc5c() {
return function () {
var _0x3260a5 = {
'WtABe': '4|0|6|5|3|2|1',
'GokKo': function _0xf87260(_0x427a8e, _0x43354c) {
return _0x427a8e + _0x43354c;
}
};
var _0x1ad4d6 = _0x3260a5['WtABe']['split']('|'), _0x1a7b12 = 0x0;
while (!![]) {
switch (_0x1ad4d6[_0x1a7b12++]) {
case '0':
console['log'](0x1);
continue;
case '1':
console['log'](0x6);
continue;
case '2':
console['log'](0x5);
continue;
case '3':
console['log'](0x4);
continue;
case '4':
var _0x1f2f2f = _0x3260a5['GokKo'](0x1, 0x2);
continue;
case '5':
console['log'](0x3);
continue;
case '6':
console['log'](0x2);
continue;
}
break;
}
};
}
_0x3bfc5c()();
}());
controlFlowFlatteningThreshold
Type: number Default: 0.75 Min: 0 Max: 1
Probabilitas bahwa transformasi controlFlowFlattening akan diterapkan pada suatu node.
Pengaturan ini sangat berguna untuk ukuran kode yang besar karena banyaknya transformasi control flow dapat memperlambat kode Anda dan menambah ukuran kode.
controlFlowFlatteningThreshold: 0 setara dengan controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Secara drastis meningkatkan ukuran kode hasil obfuskasi (hingga 200%), gunakan hanya jika ukuran kode hasil obfuskasi tidak menjadi masalah. Gunakan deadCodeInjectionThreshold untuk mengatur persentase node yang akan terpengaruh oleh dead code injection.
⚠️ Opsi ini secara paksa mengaktifkan opsi stringArray.
⚠️ Opsi ini dinonaktifkan secara diam-diam ketika vmObfuscation diaktifkan.
Dengan opsi ini, blok-blok kode mati (dead code) acak akan ditambahkan ke kode hasil obfuskasi.
Contoh:
// input
(function(){
if (true) {
var foo = function () {
console.log('abc');
};
var bar = function () {
console.log('def');
};
var baz = function () {
console.log('ghi');
};
var bark = function () {
console.log('jkl');
};
var hawk = function () {
console.log('mno');
};
foo();
bar();
baz();
bark();
hawk();
}
})();
// output
var _0x37b8 = [
'YBCtz',
'GlrkA',
'urPbb',
'abc',
'NMIhC',
'yZgAj',
'zrAId',
'EtyJA',
'log',
'mno',
'jkl',
'def',
'Quzya',
'IWbBa',
'ghi'
];
function _0x43a7(_0x12cf56, _0x587376) {
_0x43a7 = function (_0x2f87a8, _0x47eac2) {
_0x2f87a8 = _0x2f87a8 - (0x16a7 * 0x1 + 0x5 * 0x151 + -0x1c92);
var _0x341e03 = _0x37b8[_0x2f87a8];
return _0x341e03;
};
return _0x43a7(_0x12cf56, _0x587376);
}
(function () {
if (!![]) {
var _0xbbe28f = function () {
var _0x2fc85f = _0x43a7;
if (_0x2fc85f(0xaf) === _0x2fc85f(0xae)) {
_0x1dd94f[_0x2fc85f(0xb2)](_0x2fc85f(0xb5));
} else {
console[_0x2fc85f(0xb2)](_0x2fc85f(0xad));
}
};
var _0x5e46bc = function () {
var _0x15b472 = _0x43a7;
if (_0x15b472(0xb6) !== _0x15b472(0xaa)) {
console[_0x15b472(0xb2)](_0x15b472(0xb5));
} else {
_0x47eac2[_0x15b472(0xb2)](_0x15b472(0xad));
}
};
var _0x3669e8 = function () {
var _0x47a442 = _0x43a7;
if (_0x47a442(0xb7) !== _0x47a442(0xb0)) {
console[_0x47a442(0xb2)](_0x47a442(0xb8));
} else {
_0x24e0bf[_0x47a442(0xb2)](_0x47a442(0xb3));
}
};
var _0x28b05a = function () {
var _0x497902 = _0x43a7;
if (_0x497902(0xb1) === _0x497902(0xb1)) {
console[_0x497902(0xb2)](_0x497902(0xb4));
} else {
_0x59c9c6[_0x497902(0xb2)](_0x497902(0xb4));
}
};
var _0x402a54 = function () {
var _0x1906b7 = _0x43a7;
if (_0x1906b7(0xab) === _0x1906b7(0xac)) {
_0xb89cd0[_0x1906b7(0xb2)](_0x1906b7(0xb8));
} else {
console[_0x1906b7(0xb2)](_0x1906b7(0xb3));
}
};
_0xbbe28f();
_0x5e46bc();
_0x3669e8();
_0x28b05a();
_0x402a54();
}
}());
deadCodeInjectionThreshold
Type: number Default: 0.4 Min: 0 Max: 1
Memungkinkan Anda mengatur persentase node yang akan terpengaruh oleh deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Dapat membekukan peramban Anda jika Anda membuka Developer Tools.
⚠️ Opsi ini dinonaktifkan secara diam-diam ketika vmObfuscation diaktifkan. Gunakan vmDebugProtection sebagai gantinya.
Opsi ini membuat fungsi debugger pada Developer Tools hampir mustahil digunakan (baik pada peramban berbasis WebKit maupun Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Dapat membekukan peramban Anda! Gunakan dengan risiko Anda sendiri.
⚠️ Opsi ini dinonaktifkan secara diam-diam ketika vmObfuscation diaktifkan. Gunakan vmDebugProtection sebagai gantinya.
Jika diatur, sebuah interval dalam milidetik digunakan untuk memaksa mode debug pada tab Console, sehingga mempersulit penggunaan fitur-fitur lain dari Developer Tools. Berfungsi jika debugProtection diaktifkan. Nilai yang direkomendasikan adalah antara 2000 dan 4000 milidetik.
disableConsoleOutput
Type: boolean Default: false
⚠️ Opsi ini menonaktifkan pemanggilan console secara global untuk semua skrip
Menonaktifkan penggunaan console.log, console.info, console.error, console.warn, console.debug, console.exception, dan console.trace dengan menggantinya menjadi fungsi kosong. Hal ini mempersulit penggunaan debugger.
domainLock
Type: string[] Default: []
⚠️ Opsi ini tidak berfungsi dengan target: 'node', target: 'service-worker', atau target: 'bytenode'
Memungkinkan kode sumber hasil obfuskasi hanya berjalan pada domain dan/atau subdomain tertentu. Hal ini membuat orang lain sangat sulit untuk sekadar menyalin dan menempelkan kode sumber Anda lalu menjalankannya di tempat lain.
Jika kode sumber tidak dijalankan pada domain yang ditentukan oleh opsi ini, peramban akan dialihkan ke URL yang diteruskan pada opsi domainLockRedirectUrl.
Beberapa domain dan subdomain
Anda dapat mengunci kode Anda pada lebih dari satu domain atau subdomain. Misalnya, untuk menguncinya agar kode hanya berjalan pada www.example.com tambahkan www.example.com. Agar berfungsi pada domain root termasuk subdomain apa pun (example.com, sub.example.com), gunakan .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Opsi ini tidak berfungsi dengan target: 'node', target: 'service-worker', atau target: 'bytenode'
Memungkinkan peramban dialihkan ke URL yang diberikan jika kode sumber tidak dijalankan pada domain yang ditentukan oleh domainLock
exclude
Type: string[] Default: []
Nama berkas atau glob yang menunjukkan berkas mana yang dikecualikan dari obfuskasi.
forceTransformStrings
Type: string[] Default: []
Mengaktifkan transformasi paksa terhadap literal string yang cocok dengan pola RegExp yang diberikan.
⚠️ Opsi ini hanya memengaruhi string yang seharusnya tidak ditransformasi oleh stringArrayThreshold (atau kemungkinan threshold lain di masa mendatang)
Opsi ini memiliki prioritas di atas opsi reservedStrings tetapi tidak memiliki prioritas di atas conditional comments.
Contoh:
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
Tujuan utama opsi ini adalah kemampuan untuk menggunakan nama pengenal yang sama selama obfuskasi beberapa sumber/berkas.
Saat ini terdapat dua jenis pengenal yang didukung:
- Pengenal global:
- Semua pengenal global akan ditulis ke cache;
- Semua pengenal global yang tidak dideklarasikan yang cocok akan diganti dengan nilai dari cache.
- Pengenal properti, hanya jika opsi
renamePropertiesdiaktifkan:- Semua pengenal properti akan ditulis ke cache;
- Semua pengenal properti yang cocok akan diganti dengan nilai dari cache.
Node.js API
Jika nilai null diberikan, cache dinonaktifkan sepenuhnya.
Jika objek kosong ({}) diberikan, mengaktifkan penulisan nama pengenal ke objek-cache (tipe TIdentifierNamesCache). Objek-cache ini akan diakses melalui pemanggilan metode getIdentifierNamesCache dari objek ObfuscationResult.
Objek-cache yang dihasilkan selanjutnya dapat digunakan sebagai nilai opsi identifierNamesGenerator untuk menggunakan nama-nama ini selama obfuskasi semua nama pengenal yang cocok dari sumber berikutnya.
Contoh:
const source1ObfuscationResult = JavaScriptObfuscator.obfuscate(
`
function foo(arg) {
console.log(arg)
}
function bar() {
var bark = 2;
}
`,
{
compact: false,
identifierNamesCache: {},
renameGlobals: true
}
)
console.log(source1ObfuscationResult.getIdentifierNamesCache());
/*
{
globalIdentifiers: {
foo: '_0x5de86d',
bar: '_0x2a943b'
}
}
*/
const source2ObfuscationResult = JavaScriptObfuscator.obfuscate(
`
// Expecting that these global functions are defined in another obfuscated file
foo(1);
bar();
// Expecting that this global function is defined in third-party package
baz();
`,
{
compact: false,
identifierNamesCache: source1ObfuscationResult.getIdentifierNamesCache(),
renameGlobals: true
}
)
console.log(source2ObfuscationResult.getObfuscatedCode());
/*
_0x5de86d(0x1);
_0x2a943b();
baz();
*/
CLI
CLI memiliki opsi berbeda --identifier-names-cache-path yang memungkinkan penentuan path ke berkas .json yang sudah ada yang akan digunakan untuk membaca dan menulis cache nama pengenal.
Jika path ke berkas kosong diberikan - cache nama pengenal akan ditulis ke berkas tersebut.
Berkas dengan cache yang sudah ada ini dapat digunakan kembali sebagai nilai opsi --identifier-names-cache-path untuk menggunakan nama-nama ini selama obfuskasi semua nama pengenal yang cocok dari berkas berikutnya.
identifierNamesGenerator
Type: string Default: hexadecimal
Mengatur generator nama pengenal.
Nilai yang tersedia:
dictionary: nama pengenal dari daftaridentifiersDictionaryhexadecimal: nama pengenal seperti_0xabc123mangled: nama pengenal pendek sepertia,b,cmangled-shuffled: sama sepertimangledtetapi dengan alfabet yang diacak
identifiersDictionary
Type: string[] Default: []
Mengatur kamus pengenal untuk opsi identifierNamesGenerator: dictionary. Setiap pengenal dari kamus akan digunakan dalam beberapa varian dengan penggunaan huruf besar/kecil yang berbeda pada setiap karakter. Oleh karena itu, jumlah pengenal dalam kamus sebaiknya bergantung pada jumlah pengenal pada kode sumber asli.
identifiersPrefix
Type: string Default: ''
Mengatur awalan untuk semua pengenal global.
Gunakan opsi ini saat Anda ingin mengobfuskasi beberapa berkas. Opsi ini membantu menghindari konflik antar-pengenal global dari berkas-berkas tersebut. Awalan harus berbeda untuk setiap berkas.
randomIdentifiersPrefix
Type: boolean Default: false
Menambahkan awalan acak berbasis seed (6 karakter alfanumerik) ke semua pengenal global. Gunakan opsi ini untuk menghindari tabrakan antara bundel yang diobfuskasi secara terpisah yang dimuat ke dalam scope global yang sama — opsi ini menghilangkan kebutuhan memilih identifiersPrefix unik untuk setiap bundel secara manual.
- Nilai acak diturunkan dari opsi
seeddan hash kode sumber, sehingga build yang dapat direproduksi dengan seed yang sama menghasilkan awalan yang sama. - Ketika digabungkan dengan
identifiersPrefix, karakter acak ditambahkan setelah awalan yang diberikan pengguna (mis.myApp+ acakaBc123→myAppaBc123). - Ketika digabungkan dengan
vmObfuscation, nilai acak menggantikan awalanvmbawaan — keacakan sudah menjamin keunikan.
ignoreImports
Type: boolean Default: false
Mencegah obfuskasi terhadap impor require. Dapat berguna dalam beberapa kasus ketika, karena suatu alasan, lingkungan runtime membutuhkan impor tersebut hanya dengan string statis.
inputFileName
Type: string Default: ''
Memungkinkan Anda mengatur nama berkas masukan yang berisi kode sumber. Nama ini akan digunakan secara internal untuk pembuatan source map.
Diperlukan saat menggunakan NodeJS API dan opsi sourceMapSourcesMode memiliki nilai sources.
log
Type: boolean Default: false
Mengaktifkan pencatatan informasi ke console.
numbersToExpressions
Type: boolean Default: false
Mengaktifkan konversi angka menjadi ekspresi
Contoh:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Memungkinkan Anda mengatur preset opsi.
Nilai yang tersedia:
vm-default;vm-low-obfuscation;vm-medium-obfuscation;vm-high-obfuscation;vm-ultra-high-obfuscation;vm-anti-llm;default;low-obfuscation;medium-obfuscation;high-obfuscation.
Semua opsi tambahan akan digabungkan dengan preset opsi yang dipilih.
parseHtml
Type: boolean Default: false
Mengaktifkan obfuskasi JavaScript di dalam tag HTML <script>.
Ketika diaktifkan, obfuscator akan:
- Mendeteksi secara otomatis apakah masukan adalah HTML (dengan memeriksa tag
<!DOCTYPE,<html>,<head>,<body>, atau<script>) - Mengekstraksi JavaScript dari tag
<script>yang ditandai dengan atributdata-javascript-obfuscator - Mengobfuskasi setiap skrip yang ditandai secara individual sambil mempertahankan struktur HTML
- Menyisipkan kembali kode hasil obfuskasi ke posisi aslinya
Penting: Hanya skrip dengan atribut data-javascript-obfuscator yang diobfuskasi. Setiap skrip yang ditandai diobfuskasi secara individual dan independen. Ini berarti:
- Kode di dalam tag skrip yang ditandai harus terisolasi - kode tersebut TIDAK boleh merujuk variabel, fungsi, atau kelas yang didefinisikan di tag skrip yang ditandai lainnya
- Skrip yang tidak ditandai tetap dapat mengakses global yang didefinisikan oleh skrip yang ditandai (melalui deklarasi
varatau penetapanglobalThiseksplisit) - Ini memberi Anda kontrol eksplisit atas skrip mana yang akan dilindungi
Diobfuskasi (harus memiliki atribut data-javascript-obfuscator):
<script data-javascript-obfuscator>- skrip biasa<script type="text/javascript" data-javascript-obfuscator>- skrip dengan tipe eksplisit- Skrip dengan atribut tambahan apa pun (
id,class,data-*lainnya, dll.)
Dilewati (dibiarkan tidak berubah):
- Skrip tanpa atribut
data-javascript-obfuscator <script type="module">- ES module (bahkan dengan atribut tersebut)<script src="...">- skrip eksternal (bahkan dengan atribut tersebut)- Tag skrip kosong
Catatan: Source map tidak dibuat ketika parseHtml diaktifkan, karena tidak akan memetakan dengan benar ke keluaran HTML.
Contoh:
// input
const html = `<!DOCTYPE html>
<html>
<body>
<!-- This script will NOT be obfuscated -->
<script>
var helper = 'utility';
</script>
<!-- This script WILL be obfuscated -->
<script data-javascript-obfuscator>
var greeting = 'Hello World';
console.log(greeting);
</script>
</body>
</html>`;
JavaScriptObfuscator.obfuscate(html, {
parseHtml: true,
stringArray: true
});
// output: HTML with only the marked script obfuscated
renameGlobals
Type: boolean Default: false
⚠️ opsi ini dapat merusak kode Anda. Aktifkan hanya jika Anda memahami cara kerjanya!
Mengaktifkan obfuskasi nama variabel dan fungsi global beserta deklarasinya.
Ketika opsi ini dinonaktifkan dan kode masukan mendeklarasikan fungsi atau kelas pada scope global (yakni kode tidak dibungkus dalam IIFE), nama-namanya dipertahankan apa adanya pada keluaran hasil obfuskasi — skrip lain dapat merujuknya berdasarkan nama. Di bawah vmObfuscation, sebuah peringatan VMGlobalFunctionNamesNotRenamed yang mencantumkan nama-nama tersebut akan dilaporkan, karena tubuh fungsi disembunyikan sebagai bytecode tetapi nama tingkat atas yang terbaca tetap mengungkap apa yang dilakukan kode (misalnya kepada LLM). Untuk menghindari paparan ini, bungkus kode dalam IIFE atau aktifkan opsi ini.
renameProperties
Type: boolean Default: false
⚠️ opsi ini MUNGKIN merusak kode Anda. Aktifkan hanya jika Anda memahami cara kerjanya!
Mengaktifkan penggantian nama properti. Semua properti DOM bawaan dan properti pada kelas inti JavaScript akan diabaikan.
Untuk beralih antara mode safe dan unsafe pada opsi ini gunakan opsi renamePropertiesMode.
Untuk mengatur format nama properti yang diganti gunakan opsi identifierNamesGenerator.
Untuk mengontrol properti mana yang akan diganti namanya gunakan opsi reservedNames.
Contoh:
// input
(function () {
const foo = {
prop1: 1,
prop2: 2,
calc: function () {
return this.prop1 + this.prop2;
}
};
console.log(foo.calc());
})();
// output
(function () {
const _0x46529b = {
'_0x10cec7': 0x1,
'_0xc1c0ca': 0x2,
'_0x4b961d': function () {
return this['_0x10cec7'] + this['_0xc1c0ca'];
}
};
console['log'](_0x46529b['_0x4b961d']());
}());
renamePropertiesMode
Type: string Default: safe
⚠️ Bahkan dalam mode safe, opsi renameProperties MUNGKIN merusak kode Anda.
Menentukan mode opsi renameProperties:
safe- perilaku bawaan setelah rilis2.11.0. Mencoba mengganti nama properti dengan cara yang lebih aman untuk mencegah error runtime. Dengan mode ini beberapa properti akan dikecualikan dari penggantian nama.unsafe- perilaku bawaan sebelum rilis2.11.0. Mengganti nama properti dengan cara yang tidak aman tanpa batasan apa pun.
Jika suatu berkas menggunakan properti dari berkas lain, gunakan opsi identifierNamesCache untuk mempertahankan nama properti yang sama di antara berkas-berkas tersebut.
reservedNames
Type: string[] Default: []
Menonaktifkan obfuskasi dan pembuatan pengenal yang cocok dengan pola RegExp yang diberikan.
Contoh:
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Menonaktifkan transformasi literal string yang cocok dengan pola RegExp yang diberikan. String yang cocok akan tetap terlihat pada keluaran hasil obfuskasi.
Saat menggunakan obfuskasi VM, reserved strings disimpan dalam larik terpisah yang tidak terenkripsi agar tetap terlihat. Hal ini berguna untuk string yang harus tetap dapat dibaca, seperti endpoint API untuk pemantauan atau pengenal pustaka.
Contoh:
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Opsi ini mengatur seed untuk generator acak. Ini berguna untuk menghasilkan hasil yang dapat diulang.
Jika seed bernilai 0 - generator acak akan bekerja tanpa seed.
selfDefending
Type: boolean Default: false
⚠️ Jangan mengubah kode hasil obfuskasi dengan cara apa pun setelah obfuskasi dengan opsi ini, karena perubahan apa pun seperti uglify pada kode dapat memicu self defending dan kode tidak akan berfungsi lagi!
⚠️ Opsi ini secara paksa mengatur nilai compact menjadi true
⚠️ Opsi ini dinonaktifkan secara diam-diam ketika vmObfuscation diaktifkan. Gunakan vmSelfDefending sebagai gantinya.
Opsi ini membuat kode keluaran tahan terhadap pemformatan dan penggantian nama variabel. Jika seseorang mencoba menggunakan JavaScript beautifier pada kode hasil obfuskasi, kode tidak akan berfungsi lagi, sehingga lebih sulit untuk dipahami dan dimodifikasi.
simplify
Type: boolean Default: true
Mengaktifkan obfuskasi kode tambahan melalui penyederhanaan.
⚠️ pada rilis mendatang obfuskasi literal boolean (true => !![]) akan dipindahkan ke bawah opsi ini.
Contoh:
// input
if (condition1) {
const foo = 1;
const bar = 2;
console.log(foo);
return bar;
} else if (condition2) {
console.log(1);
console.log(2);
console.log(3);
return 4;
} else {
return 5;
}
// output
if (condition1) {
const foo = 0x1, bar = 0x2;
return console['log'](foo), bar;
} else
return condition2 ? (console['log'](0x1), console['log'](0x2), console['log'](0x3), 0x4) : 0x5;
sourceMap
Type: boolean Default: false
Mengaktifkan pembuatan source map untuk kode hasil obfuskasi.
Source map dapat berguna untuk membantu Anda men-debug kode sumber JavaScript hasil obfuskasi. Jika Anda ingin atau perlu men-debug di lingkungan produksi, Anda dapat mengunggah berkas source map terpisah ke lokasi rahasia lalu mengarahkan peramban Anda ke sana.
sourceMapBaseUrl
Type: string Default: ``
Mengatur base url pada url impor source map ketika sourceMapMode: 'separate'.
Contoh CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Hasil:
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Mengatur nama berkas untuk source map keluaran ketika sourceMapMode: 'separate'.
Contoh CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Hasil:
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Menentukan mode pembuatan source map:
inline- menambahkan source map di akhir setiap berkas .js;separate- menghasilkan berkas '.map' terkait berisi source map. Jika Anda menjalankan obfuscator melalui CLI - menambahkan tautan ke berkas source map di akhir berkas berisi kode hasil obfuskasi//# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Memungkinkan Anda mengontrol field sources dan sourcesContent pada source map:
sources-content- menambahkan fieldsourcesdummy, menambahkan fieldsourcesContentberisi kode sumber asli;sources- menambahkan fieldsourcesdengan deskripsi sumber yang valid, tidak menambahkan fieldsourcesContent. Saat menggunakan NodeJS API, diperlukan pendefinisian opsiinputFileNameyang akan digunakan sebagai nilai fieldsources.
splitStrings
Type: boolean Default: false
Memecah literal string menjadi potongan-potongan dengan panjang sesuai nilai opsi splitStringsChunkLength.
Contoh:
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Mengatur panjang potongan untuk opsi splitStrings.
stringArray
Type: boolean Default: true
Menghapus literal string dan menempatkannya dalam sebuah larik khusus. Misalnya, string "Hello World" pada var m = "Hello World"; akan diganti dengan sesuatu seperti var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ opsi stringArray harus diaktifkan
Mengaktifkan transformasi pemanggilan ke stringArray. Semua argumen dari pemanggilan ini dapat diekstraksi ke objek yang berbeda tergantung pada nilai stringArrayCallsTransformThreshold.
Sehingga semakin sulit untuk menemukan pemanggilan ke string array secara otomatis.
Contoh:
function foo() {
var k = {
c: 0x2f2,
d: '0x396',
e: '0x397',
f: '0x39a',
g: '0x39d',
h: 0x398,
l: 0x394,
m: '0x39b',
n: '0x39f',
o: 0x395,
p: 0x395,
q: 0x399,
r: '0x399'
};
var c = i(k.d, k.e);
var d = i(k.f, k.g);
var e = i(k.h, k.l);
var f = i(k.m, k.n);
function i(c, d) {
return b(c - k.c, d);
}
var g = i(k.o, k.p);
var h = i(k.q, k.r);
}
function j(c, d) {
var l = { c: 0x14b };
return b(c - -l.c, d);
}
console[j(-'0xa6', -'0xa6')](foo());
function b(c, d) {
var e = a();
b = function (f, g) {
f = f - 0xa3;
var h = e[f];
return h;
};
return b(c, d);
}
function a() {
var m = [
'string5',
'string1',
'log',
'string3',
'string6',
'string2',
'string4'
];
a = function () {
return m;
};
return a();
}
stringArrayCallsTransformThreshold
Type: number Default: 0.5
⚠️ opsi stringArray dan stringArrayCallsTransformThreshold harus diaktifkan
Anda dapat menggunakan pengaturan ini untuk menyesuaikan probabilitas (dari 0 hingga 1) bahwa pemanggilan ke string array akan ditransformasi.
stringArrayEncoding
Type: string[] Default: []
⚠️ opsi stringArray harus diaktifkan
Opsi ini dapat memperlambat skrip Anda.
Mengenkode semua literal string dari stringArray menggunakan base64 atau rc4 dan menyisipkan kode khusus yang digunakan untuk mendekodenya kembali saat runtime.
Setiap nilai stringArray akan dienkode dengan pengodean yang dipilih secara acak dari daftar yang diberikan. Hal ini memungkinkan penggunaan beberapa pengodean.
Nilai yang tersedia:
'none'(boolean): tidak mengenkode nilaistringArray'base64'(string): mengenkode nilaistringArraymenggunakanbase64'rc4'(string): mengenkode nilaistringArraymenggunakanrc4. Sekitar 30-50% lebih lambat daripadabase64, tetapi lebih sulit untuk mendapatkan nilai awalnya.
Sebagai contoh, dengan nilai opsi berikut beberapa nilai stringArray tidak akan dienkode, dan beberapa nilai akan dienkode dengan pengodean base64 dan rc4:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ opsi stringArray harus diaktifkan
Memungkinkan Anda mengontrol tipe indeks pemanggilan string array.
Setiap indeks pemanggilan stringArray akan ditransformasi dengan tipe yang dipilih secara acak dari daftar yang diberikan. Hal ini memungkinkan penggunaan beberapa tipe.
Nilai yang tersedia:
'hexadecimal-number'(default): mentransformasi indeks pemanggilan string array sebagai angka heksadesimal'hexadecimal-numeric-string': mentransformasi indeks pemanggilan string array sebagai string numerik heksadesimal
Sebelum rilis 2.9.0, javascript-obfuscator mentransformasi semua indeks pemanggilan string array dengan tipe hexadecimal-numeric-string. Hal ini membuat sebagian deobfuskasi manual sedikit lebih sulit tetapi memungkinkan pendeteksian pemanggilan tersebut dengan mudah oleh deobfuscator otomatis.
Tipe baru hexadecimal-number berupaya mempersulit deteksi otomatis pola pemanggilan string array di dalam kode.
Lebih banyak tipe akan ditambahkan di masa mendatang.
stringArrayIndexShift
Type: boolean Default: true
⚠️ opsi stringArray harus diaktifkan
Mengaktifkan pergeseran indeks tambahan untuk semua pemanggilan string array
stringArrayRotate
Type: boolean Default: true
⚠️ stringArray harus diaktifkan
Menggeser larik stringArray sejauh sejumlah posisi yang tetap dan acak (dibuat saat obfuskasi kode). Hal ini mempersulit pencocokan urutan string yang dihapus dengan posisi aslinya.
stringArrayShuffle
Type: boolean Default: true
⚠️ stringArray harus diaktifkan
Mengacak item-item larik stringArray secara acak.
stringArrayWrappersCount
Type: number Default: 1
⚠️ opsi stringArray harus diaktifkan
Mengatur jumlah pembungkus untuk string array di dalam setiap scope root atau fungsi.
Jumlah pembungkus yang sebenarnya di dalam setiap scope dibatasi oleh jumlah node literal dalam scope tersebut.
Contoh:
// Input
const foo = 'foo';
const bar = 'bar';
function test () {
const baz = 'baz';
const bark = 'bark';
const hawk = 'hawk';
}
const eagle = 'eagle';
// Output, stringArrayWrappersCount: 5
const _0x3f6c = [
'bark',
'bar',
'foo',
'eagle',
'hawk',
'baz'
];
const _0x48f96e = _0x2e13;
const _0x4dfed8 = _0x2e13;
const _0x55e970 = _0x2e13;
function _0x2e13(_0x33c4f5, _0x3f6c62) {
_0x2e13 = function (_0x2e1388, _0x60b1e) {
_0x2e1388 = _0x2e1388 - 0xe2;
let _0x53d475 = _0x3f6c[_0x2e1388];
return _0x53d475;
};
return _0x2e13(_0x33c4f5, _0x3f6c62);
}
const foo = _0x48f96e(0xe4);
const bar = _0x4dfed8(0xe3);
function test() {
const _0x1c262f = _0x2e13;
const _0x54d7a4 = _0x2e13;
const _0x5142fe = _0x2e13;
const _0x1392b0 = _0x1c262f(0xe7);
const _0x201a58 = _0x1c262f(0xe2);
const _0xd3a7fb = _0x1c262f(0xe6);
}
const eagle = _0x48f96e(0xe5);
stringArrayWrappersChainedCalls
Type: boolean Default: true
⚠️ opsi stringArray dan stringArrayWrappersCount harus diaktifkan
Mengaktifkan pemanggilan berantai di antara pembungkus string array.
Contoh:
// Input
const foo = 'foo';
const bar = 'bar';
function test () {
const baz = 'baz';
const bark = 'bark';
function test1() {
const hawk = 'hawk';
const eagle = 'eagle';
}
}
// Output, stringArrayWrappersCount: 5, stringArrayWrappersChainedCalls: true
const _0x40c2 = [
'bar',
'bark',
'hawk',
'eagle',
'foo',
'baz'
];
const _0x31c087 = _0x3280;
const _0x31759a = _0x3280;
function _0x3280(_0x1f52ee, _0x40c2a2) {
_0x3280 = function (_0x3280a4, _0xf07b02) {
_0x3280a4 = _0x3280a4 - 0x1c4;
let _0x57a182 = _0x40c2[_0x3280a4];
return _0x57a182;
};
return _0x3280(_0x1f52ee, _0x40c2a2);
}
const foo = _0x31c087(0x1c8);
const bar = _0x31c087(0x1c4);
function test() {
const _0x848719 = _0x31759a;
const _0x2693bf = _0x31c087;
const _0x2c08e8 = _0x848719(0x1c9);
const _0x359365 = _0x2693bf(0x1c5);
function _0x175e90() {
const _0x310023 = _0x848719;
const _0x2302ef = _0x2693bf;
const _0x237437 = _0x310023(0x1c6);
const _0x56145c = _0x310023(0x1c7);
}
}
stringArrayWrappersParametersMaxCount
Type: number Default: 2
⚠️ opsi stringArray harus diaktifkan
⚠️ Saat ini opsi ini hanya memengaruhi pembungkus yang ditambahkan oleh nilai opsi function pada stringArrayWrappersType
Memungkinkan Anda mengontrol jumlah maksimum parameter pembungkus string array.
Nilai bawaan dan minimum adalah 2. Nilai yang direkomendasikan antara 2 dan 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ opsi stringArray dan stringArrayWrappersCount harus diaktifkan
Memungkinkan Anda memilih tipe pembungkus yang ditambahkan oleh opsi stringArrayWrappersCount.
Nilai yang tersedia:
'variable': menambahkan pembungkus variabel di bagian atas setiap scope. Performa cepat.'function': menambahkan pembungkus fungsi pada posisi acak di dalam setiap scope. Performa lebih lambat daripadavariabletetapi memberikan obfuskasi yang lebih ketat.
Sangat direkomendasikan untuk menggunakan pembungkus function demi obfuskasi yang lebih tinggi ketika penurunan performa tidak berdampak besar pada aplikasi hasil obfuskasi.
Contoh nilai opsi 'function':
// input
const foo = 'foo';
function test () {
const bar = 'bar';
console.log(foo, bar);
}
test();
// output
const a = [
'log',
'bar',
'foo'
];
const foo = d(0x567, 0x568);
function b(c, d) {
b = function (e, f) {
e = e - 0x185;
let g = a[e];
return g;
};
return b(c, d);
}
function test() {
const c = e(0x51c, 0x51b);
function e (c, g) {
return b(c - 0x396, g);
}
console[f(0x51b, 0x51d)](foo, c);
function f (c, g) {
return b(c - 0x396, g);
}
}
function d (c, g) {
return b(g - 0x3e1, c);
}
test();
stringArrayThreshold
Type: number Default: 0.8 Min: 0 Max: 1
⚠️ opsi stringArray harus diaktifkan
Anda dapat menggunakan pengaturan ini untuk menyesuaikan probabilitas (dari 0 hingga 1) bahwa sebuah literal string akan disisipkan ke dalam stringArray.
Pengaturan ini sangat berguna untuk ukuran kode yang besar karena berulang kali memanggil string array dan dapat memperlambat kode Anda.
stringArrayThreshold: 0 setara dengan stringArray: false.
strictMode
Type: boolean | null Default: null
Memungkinkan Anda menentukan bagaimana obfuscator harus memperlakukan kode terkait strict mode JavaScript.
Nilai yang tersedia:
null(bawaan) - mendeteksi strict mode secara otomatis dari kode. Jika kode memiliki direktif'use strict'eksplisit, sintaks ES module, atau metode kelas, kode diperlakukan sebagai strict mode. Jika tidak, sloppy mode diasumsikan.true- memaksa perlakuan strict mode untuk semua kode, bahkan tanpa direktif'use strict'eksplisit. Gunakan ini ketika kode Anda akan berjalan dalam konteks strict mode (mis. pada ES module, bundler, atau framework modern).false- hanya indikator strict mode eksplisit ('use strict', ES module, metode kelas) yang diperlakukan sebagai strict. Pewarisan dari scope induk tetap berlaku sesuai spesifikasi JS.
target
Type: string Default: browser
Memungkinkan Anda mengatur lingkungan target untuk kode hasil obfuskasi.
Nilai yang tersedia:
browser(bawaan) — lingkungan halaman web standar. Kode keluaran identik dengannode, tetapi beberapa opsi khusus peramban tidak diizinkan digunakan dengan targetnodebrowser-no-eval— sama sepertibrowser, tetapi keluaran tidak menggunakaneval(). Gunakan ketika halaman target memiliki Content Security Policy yang melarangeval/unsafe-eval.node— lingkungan Node.js. Opsi khusus peramban dinonaktifkan (opsi-opsi tersebut membutuhkanwindow/documentdan akan menjadi no-op atau melempar error di Node). Beberapa pertahananvmSelfDefendingyang bergantung pada API khusus peramban — deteksi peramban headless, pemulihan clean-realm berbasis iframe, pemeriksaan anti-inspector/DOM — tidak dikeluarkan untuk target ini.service-worker— konteks Service Worker. Tanpawindow, tanpadocument, globalselfyang berbeda.userscript— sandbox pengelola userscript (mis. Tampermonkey). PertahananvmSelfDefendingdisesuaikan sebagaimana mestinya.bytenode— kode Node.js yang akan dikompilasi dengan loader bytenode (bytecode ter-cache V8.jsc) setelah obfuskasi. Obfuscator itu sendiri tidak memanggilbytenode; ia menghasilkan JavaScript hasil obfuskasi VM yang runtime-nya disusun agar dapat bertahan melalui langkah kompilasi bytenode, dan pertahananvmSelfDefendingdisesuaikan sebagaimana mestinya. Jalankanbytenodesendiri pada keluaran hasil obfuskasi untuk menghasilkan.jscfinal.
transformObjectKeys
Type: boolean Default: false
Mengaktifkan transformasi kunci objek.
Contoh:
// input
(function(){
var object = {
foo: 'test1',
bar: {
baz: 'test2'
}
};
})();
// output
var _0x4735 = [
'foo',
'baz',
'bar',
'test1',
'test2'
];
function _0x390c(_0x33d6b6, _0x4735f4) {
_0x390c = function (_0x390c37, _0x1eed85) {
_0x390c37 = _0x390c37 - 0x198;
var _0x2275f8 = _0x4735[_0x390c37];
return _0x2275f8;
};
return _0x390c(_0x33d6b6, _0x4735f4);
}
(function () {
var _0x17d1b7 = _0x390c;
var _0xc9b6bb = {};
_0xc9b6bb[_0x17d1b7(0x199)] = _0x17d1b7(0x19c);
var _0x3d959a = {};
_0x3d959a[_0x17d1b7(0x198)] = _0x17d1b7(0x19b);
_0x3d959a[_0x17d1b7(0x19a)] = _0xc9b6bb;
var _0x41fd86 = _0x3d959a;
}());
warnings
Type: string | object Default: all
Mengontrol peringatan obfuskasi non-fatal mana yang dikeluarkan melalui metode ObfuscationResult.getWarnings().
Nilai yang tersedia:
'all'(bawaan) — setiap peringatan dikeluarkan.'none'— semua peringatan disembunyikan.- sebuah objek yang memetakan tipe peringatan ke boolean — tipe yang dipetakan ke
falsedisembunyikan; setiap tipe yang tidak ada (atau dipetakan ketrue) tetap aktif. Misalnya,{ "VMGlobalFunctionNamesNotRenamed": false }mempertahankan setiap peringatan kecuali yang satu itu.
Tipe peringatan:
VMGlobalFunctionNamesNotRenamed— di bawahvmObfuscation, nama deklarasi fungsi tingkat atas, deklarasi kelas, dan variabel yang diberi ekspresi fungsi/arrow/kelas dipertahankan apa adanya (opsirenameGlobalsdinonaktifkan dan kode tidak dibungkus dalam IIFE), sehingga tetap terbaca pada keluaran meskipun tubuhnya disembunyikan sebagai bytecode. Nama yang diekspor tidak dilaporkan.VMTopLevelInitializerNotVirtualized— inisialisasi variabel tingkat atas tetap berupa JavaScript biasa di bawah obfuskasi VM karenavmWrapTopLevelInitializersdinonaktifkan atau tidak dapat memvirtualisasinya.DynamicCodeRenameRisk— kode membangun sebuah fungsi dari string saat runtime (directeval, konstruktorFunction, ataufn.toString()yang disisipkan ke dalam<script>/Worker), yang mungkin merujuk pengenal yang telah diganti namanya oleh obfuscator.VMDynamicCodeSkipped— sebuah fungsi dilewati dari bytecoding VM karena mengandung directeval/new Functiondinamis /Function(lihatvmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— denganvmAsyncExecutordiaktifkan, sebuah fungsi yang Anda tandai secara eksplisit dalam modecommentternyata sinkron dan dilewati (hanya fungsi async yang divirtualisasi dalam mode itu).VMAsyncGeneratorSkippedInAsyncMode— denganvmAsyncExecutordan key getter async yang aktif, sebuah generator async yang ditandai tidak dapat divirtualisasi (ia harus mengembalikan iteratornya secara sinkron).BrowserTargetWithNodeStyleCode— kode tampak menargetkan Node.js (mis.require('fs'),__dirname,process.argv) sementara opsitargetdiatur ke lingkungan yang menyerupai peramban.
vmObfuscation
Type: boolean Default: false
Mengaktifkan obfuskasi bytecode berbasis VM. Ketika diaktifkan, fungsi JavaScript dikompilasi menjadi bytecode khusus yang berjalan pada virtual machine tersemat. Ini memberikan tingkat proteksi tertinggi karena logika kode asli ditransformasi sepenuhnya.
Contoh:
Kode Anda yang terbaca seperti return qty * price menjadi sederet angka seperti [0x15,0x03,0x17,...] yang hanya dapat dieksekusi oleh interpreter VM tersemat. Logika aslinya tidak lagi terlihat sebagai JavaScript.
vmTargetFunctions
Type: string[] Default: []
Menentukan secara tepat fungsi tingkat root mana yang harus mendapatkan proteksi VM berdasarkan nama.
Contoh:
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Hasil: Hanya ketiga fungsi ini yang mendapatkan proteksi VM. Selebihnya tetap sebagai JavaScript biasa (tetapi masih diobfuskasi). Cocok untuk melindungi pemeriksaan lisensi atau logika autentikasi yang sensitif sambil menjaga sisa kode Anda tetap ringan.
vmExcludeFunctions
Type: string[] Default: []
Menentukan fungsi tingkat root yang tidak boleh mendapatkan proteksi VM. Memiliki prioritas di atas pengaturan lain.
Contoh:
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Kapan digunakan: Fungsi tingkat root yang kritis terhadap performa (loop animasi, pemrosesan data real-time) dapat dikecualikan untuk menghindari overhead VM sambil tetap melindungi selebihnya.
vmTargetFunctionsMode
Type: string Default: root
Mengontrol bagaimana fungsi/metode dipilih untuk obfuskasi VM.
Contoh - Mode comment:
// Source code
function regularFunction() {
return 'not virtualized';
}
/* javascript-obfuscator:vm */
function sensitiveFunction() {
return 'this will be VM-protected';
}
function outer() {
/* javascript-obfuscator:vm */
function nestedSensitive() {
return 'nested but still VM-protected';
}
return nestedSensitive();
}
// Obfuscator options
{
vmObfuscation: true,
vmTargetFunctionsMode: 'comment'
}
Kapan digunakan: Ketika Anda memerlukan kontrol yang presisi atas fungsi mana persisnya yang mendapatkan proteksi VM, terutama fungsi bersarang yang mengandung logika sensitif. Tidak seperti vmTargetFunctions yang hanya berfungsi dengan fungsi bernama tingkat root, mode comment memungkinkan Anda melindungi fungsi apa pun di mana pun dalam kode Anda.
vmForceCompileDynamicCode
Type: boolean Default: false
Mengontrol apa yang dilakukan obfuskasi VM terhadap fungsi yang mengandung pemanggilan direct eval, new Function(...), atau Function(...).
Secara bawaan, fungsi semacam itu (dan setiap fungsi yang didefinisikan di dalamnya) dilewati dari bytecoding VM dan peringatan VMDynamicCodeSkipped dilaporkan pada result.getWarnings(). Ini karena sumber yang dibangun saat runtime mungkin merujuk pengenal dari rantai scope di sekitarnya — pengenal yang telah diganti namanya oleh obfuscator.
Ketika diatur ke true, fungsi tetap di-bytecode dan peringatan VMDynamicCodeSkipped tidak lagi dikeluarkan.
Peringatan DynamicCodeRenameRisk yang terpisah tetap muncul terlepas dari opsi ini, karena risiko penggantian nama yang dijelaskannya tidak bergantung pada pelewatan VM — mengaktifkan opsi ini tidak membuat pola yang mendasarinya menjadi lebih aman.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
Dengan opsi nonaktif (bawaan), loadConfig dibiarkan sebagai JavaScript biasa. Dengan opsi aktif, loadConfig dikompilasi menjadi bytecode VM seperti fungsi lainnya. Gunakan ini ketika Anda telah mengaudit lokasi pemanggilan dan yakin bahwa kode yang dibangun saat runtime tidak bergantung pada pengenal yang diganti namanya dalam closure.
vmWrapTopLevelInitializers
Type: boolean Default: false
Membungkus sebagian inisialisasi variabel tingkat atas dalam IIFE (Immediately Invoked Function Expression) agar dapat diobfuskasi VM.
Apa yang dilakukannya: Tanpa opsi ini, konstanta dan variabel tingkat atas tetap terlihat pada keluaran:
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
Dengan opsi ini diaktifkan, inisialisasi dibungkus dalam IIFE yang diobfuskasi VM:
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Catatan: Opsi ini hanya berfungsi ketika vmTargetFunctionsMode bernilai 'root' (bawaan).
Peringatan: Setiap kali sebuah inisialisasi tingkat atas berakhir sebagai JavaScript biasa di bawah obfuskasi VM, sebuah peringatan VMTopLevelInitializerNotVirtualized yang mencantumkan nama variabel yang terpengaruh akan dilaporkan. Itu mencakup: opsi ini dinonaktifkan, inisialisasi yang harus dilewati opsi ini (masing-masing dengan alasannya — mis. inisialisasi merujuk deklarator saudara atau mengandung top-level await), dan mode vmAsyncExecutor di mana pembungkus sinkron tidak dapat divirtualisasi sama sekali.
vmDynamicOpcodes
Type: boolean Default: false
Membuat interpreter VM lebih kecil dan unik untuk setiap build.
Apa yang dilakukannya:
- Memfilter instruksi yang tidak terpakai - Jika kode Anda tidak menggunakan kelas, instruksi terkait kelas dihapus sepenuhnya
- Mengacak struktur - Urutan handler instruksi diacak pada setiap build
Hasilnya - keluaran lebih kecil dan setiap build tampak berbeda.
vmBytecodeEncoding
Type: boolean Default: false
Mengenkode setiap instruksi bytecode. Instruksi didekode satu per satu selama eksekusi.
vmBytecodeArrayEncoding
Type: boolean Default: false
Mengenkode seluruh larik bytecode sebagai satu blok. Larik didekode sekali saat startup sebelum eksekusi dimulai. Gunakan bersama vmBytecodeEncoding untuk dua lapis proteksi.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Kunci enkripsi kustom untuk pengodean larik bytecode. Ketika diatur, kunci ini digunakan alih-alih kunci bawaan yang diturunkan dari lingkungan. Kunci harus disediakan saat runtime melalui vmBytecodeArrayEncodingKeyGetter.
Opsi ini mengeksternalisasi kunci enkripsi - kunci tidak tertanam di dalam kode hasil obfuskasi itu sendiri. Meskipun kunci tetap dapat diakses saat runtime (dan karenanya tidak benar-benar rahasia), pemisahan ini mencegah alat analisis statis menemukan kunci hanya dengan memeriksa kode saja.
Penting: Kunci harus tersedia secara sinkron saat kode hasil obfuskasi dimuat. Gunakan penyimpanan sinkron seperti cookie, localStorage, sessionStorage, variabel global, atau elemen DOM (mis. tag meta yang disisipkan server). Metode async seperti fetch() tidak dapat digunakan langsung dalam ekspresi key getter.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Ekspresi JavaScript sinkron yang mengembalikan kunci enkripsi saat runtime. Ekspresi ini dievaluasi ketika kode hasil obfuskasi dimuat, dan harus mengembalikan kunci yang sama dengan yang disediakan di vmBytecodeArrayEncodingKey. Untuk meresolusi kunci secara asinkron (sebuah Promise), aktifkan vmAsyncExecutor.
Catatan: getter yang mengembalikan Promise memerlukan vmAsyncExecutor. Hal ini tidak dapat diperiksa saat build, sehingga getter Promise dengan vmAsyncExecutor nonaktif akan gagal saat runtime — dekoder menerima Promise alih-alih kunci.
Kode hasil obfuskasi hanya akan berfungsi ketika key getter mengembalikan kunci yang persis sama dengan yang digunakan selama obfuskasi. Jika kunci tidak cocok, dekripsi akan gagal dan kode akan menghasilkan keluaran acak atau error. Jika key getter mengembalikan undefined, null, atau string kosong, kode akan melempar error: "VM decryption key not available".
Penting: Jauhkan kunci dari berkas/skrip yang sama dengan kode hasil obfuskasi — menempatkannya secara inline di sana memungkinkan bahkan pemindaian bundel yang murni statis memulihkannya. Simpan kunci di sumber terpisah: cookie yang diatur server, localStorage yang diisi oleh skrip lain, tag meta HTML yang disisipkan server, global yang diatur oleh skrip berbeda, atau (dengan vmAsyncExecutor) diambil dari backend Anda saat runtime.
Ketika kunci diambil dari backend Anda (melalui vmAsyncExecutor), tambahkan pemeriksaan berbasis sesi atau origin pada endpoint tersebut: kembalikan kunci yang benar kepada pengguna asli (sesi valid, Origin/Referer yang diharapkan) dan kunci acak kepada permintaan yang mencurigakan (mis. localhost/origin tak terduga, tanpa sesi). Pengguna asli berjalan normal; salinan yang berjalan di luar lingkungan Anda mendapatkan kunci yang tidak mendekripsi apa pun. Logika persisnya bergantung pada situs Anda.
Contoh:
// From cookie
vmBytecodeArrayEncodingKeyGetter: "document.cookie.match(/vmKey=([^;]+)/)?.[1]"
// From localStorage
vmBytecodeArrayEncodingKeyGetter: "localStorage.getItem('vmKey')"
// From global variable
vmBytecodeArrayEncodingKeyGetter: "window.__VM_KEY__"
// From meta tag (server-injected)
vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]').content"
// From nested object
vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"
// From backend, async (requires vmAsyncExecutor)
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
Contoh penggunaan:
// Build time
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
});
// Runtime - key must be set before obfuscated code runs
window.__VM_KEY__ = 'mySecretKey123';
vmAsyncExecutor
Type: boolean Default: false
Mengaktifkan executor VM asinkron, yang memungkinkan vmBytecodeArrayEncodingKeyGetter mengembalikan sebuah Promise (key getter asinkron) — sehingga kunci dekripsi dapat diambil saat runtime (permintaan jaringan, IndexedDB, dll.) alih-alih harus tersedia secara sinkron saat kode dimuat.
Sangat direkomendasikan untuk basis kode yang sepenuhnya async. Dalam mode ini hanya fungsi async yang divirtualisasi — fungsi sinkron tidak dapat dijadikan async tanpa mengubah nilai kembaliannya menjadi Promise dan merusak pemanggilnya — sehingga kode yang async sepenuhnya mendapatkan cakupan terbanyak. Mode ini tetap berfungsi ketika root-nya sinkron (mis. IIFE sinkron / pembungkus UMD): fungsi async terluar di dalamnya dilindungi, dan bagian sinkronnya dibiarkan apa adanya.
Apa yang ditransformasi: setiap fungsi async terluar, di mana pun ia muncul (termasuk yang bersarang di dalam pembungkus sinkron). Async terluar pada setiap rantai adalah unit yang dilindungi — semua yang ada di dalamnya, sinkron maupun async, ikut dikompilasi. Fungsi sinkron dan generator biasa dibiarkan tidak diobfuskasi.
function foo() { // sync — left as-is
function bar() {} // sync — left as-is
async function baz() { // transformed
// any code here, including calls to other async or sync functions
}
async function bark() { // transformed
// any code here, including calls to other async or sync functions
}
}
Pelewatan dan peringatan. Generator async juga dibiarkan tidak diobfuskasi ketika key getter asinkron aktif (sebuah generator async harus mengembalikan iteratornya secara sinkron dan tidak dapat menunggu kunci). Pada mode bawaan vmTargetFunctionsMode: 'root', pelewatan bersifat senyap (pemilihan otomatis); pada mode comment, sebuah peringatan dikeluarkan melalui ObfuscationResult.getWarnings() setiap kali sebuah fungsi yang Anda tandai secara eksplisit tidak dapat divirtualisasi — ternyata sinkron, atau merupakan generator async di bawah key getter async.
Key getter asinkron tambahannya memerlukan vmBytecodeArrayEncoding dengan sebuah vmBytecodeArrayEncodingKeyGetter.
Contoh penggunaan:
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmAsyncExecutor: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
// the key getter may now return a Promise
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
});
vmJumpsEncoding
Type: boolean Default: false
Mengenkode target lompatan (jump) dalam bytecode. Offset lompatan dihitung saat runtime, menyembunyikan struktur control flow (if/else, loop, dll.) dari analisis statis.
vmMacroOps
Type: boolean Default: false
Menggabungkan urutan instruksi umum menjadi opcode "makro" tunggal. Misalnya, LOAD + ADD + STORE dapat menjadi satu instruksi MACRO_ADD_TO_VAR. Hal ini merusak pengenalan pola dan dapat meningkatkan performa.
vmDebugProtection
Type: boolean Default: false
Menambahkan pertahanan anti-debugging, anti-analisis, dan anti-LLM berlapis ke runtime VM. Bekerja paling baik dengan target browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Menambahkan proteksi deteksi pengutakatikan (tamper), anti-hooking, dan anti-reverse-engineering berlapis ke runtime VM.
⚠️ Opsi ini secara paksa mengaktifkan vmBytecodeArrayEncoding.
⚠️ Deteksi lingkungan sensitif. Opsi ini mengikat kode hasil obfuskasi ke lingkungan runtime targetnya dan menggunakan fingerprinting peramban tingkat lanjut untuk mendeteksi alat otomasi. Kode yang dilindungi dengan opsi ini akan sengaja rusak ketika dijalankan di:
- Peramban headless (Chrome/Chromium headless, PhantomJS)
- Alat otomasi peramban (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (ketika
targetdiatur kebrowser) - jsdom atau emulasi DOM sisi server serupa
- Lingkungan di mana builtin peramban native telah di-hook atau diganti
Kode akan berfungsi dengan benar di peramban biasa (Chrome, Firefox, Safari, Edge), termasuk ketika dimuat di dalam iframe, ekstensi peramban (content script), dan Web Worker. Jika Anda perlu menjalankan pengujian otomatis terhadap kode yang dilindungi, nonaktifkan vmSelfDefending untuk build pengujian — opsi ini dirancang untuk mencegah analisis otomatis dan tidak dapat digunakan secara aman dengan framework otomasi apa pun.
Sangat direkomendasikan untuk digunakan bersama vmDebugProtection, vmBytecodeArrayEncodingKey, dan vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook menerima sebuah objek dengan dua kunci: name (wajib) dan aliases (opsional).
name adalah fungsi global yang didefinisikan oleh halaman host Anda yang dipanggil oleh sebuah pertahanan VM (vmDebugProtection / vmSelfDefending) dengan sebuah objek sinyal ketika ia mendeteksi sinyal yang bermusuhan — sebuah debugger atau inspector, peramban headless / otomasi, proses agen pengkodean AI, domain yang tidak diizinkan, dan sebagainya. Gunakan untuk melaporkan peristiwa tersebut ke backend Anda (mis. navigator.sendBeacon). Hook adalah penampung telemetri murni: nilai kembaliannya diabaikan, dan hook yang hilang atau melempar error adalah no-op senyap yang tidak akan pernah dapat menonaktifkan pertahanan. Untuk mengubah apa yang dilakukan sebuah pertahanan saat deteksi, gunakan vmDefenseReaction.
aliases secara opsional mengganti nama field dari objek sinyal tersebut — dibahas pada Mengganti nama field sinyal di bawah.
Objek sinyal. Hook menerima satu signal:
source— detektor spesifik yang memicu (lihat tabel).category— kelompok tempat ia dilaporkan:automation(peramban non-manusia),debugger(sebuah debugger/inspector aktif),sandbox(host terinstrumentasi/palsu),domain(pelanggaran domain-lock),tamper(builtin yang dipatch saat runtime), atauintegrity(kode VM itu sendiri diubah).score/threshold— seberapa kuat detektor memicu dan nilai yang harus dicapainya; hook memicu hanya setelahscore >= threshold. Sebagian besar pemeriksaan bersifat semua-atau-tidak (satu sinyal yang menentukan);headlessmenjumlahkan beberapa sinyal bentuk-peramban, sehinggascore-nya biasanya lebih tinggi daripadathreshold-nya.
Mendaftarkan hook. Definisikan sebagai global biasa sebelum bundel hasil obfuskasi dimuat — runtime VM dan pertahanannya berjalan sebelum program (yang dilindungi) Anda, sehingga banyak deteksi memicu selama startup:
// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }
Sebuah hook yang didefinisikan di dalam sumber hasil obfuskasi didaftarkan terlalu terlambat untuk menangkap deteksi saat startup, dan jika ia ter-VM-compile, ia tidak dapat dijangkau sampai program Anda berjalan. Ia tetap aman dengan cara apa pun (hook yang hilang menjadi no-op, dan penjaga re-entrancy mencegah kondisi liar apa pun), tetapi untuk cakupan lengkap daftarkan di awal. Untuk tetap melindungi logika pelaporan Anda, jaga agar hook yang didaftarkan tetap berupa buffer satu baris ((window.__vmDet = window.__vmDet || []).push(signal)) dan baca/kirim buffer tersebut dari kode hasil obfuskasi Anda.
Mengganti nama field sinyal (aliases). Nilai source/category bawaan adalah nama deskriptif, sehingga siapa pun yang menginstrumentasi callback (atau membaca keluaran) dapat mengenali proteksi tersebut dan detektor mana yang memicu. aliases mengganti nama field sinyal menjadi token buram pilihan Anda, diterapkan di dalam VM sebelum sinyal dikeluarkan, sehingga nama-nama tersebut tidak pernah muncul pada keluaran atau mencapai callback. Aplikasi Anda mengetahui pemetaannya sendiri dan meneruskan token ke backend Anda.
Alias bersifat per field, memisahkan penggantian nama kunci dan nilai: setiap field menerima sebuah key (nama properti yang diterima callback); field-nama string source dan category juga menerima peta values, sedangkan score/threshold berupa angka dan hanya menerima key. Nama-nama yang dapat Anda petakan (selain itu ditolak saat build):
- kunci field —
source,category,score,threshold - nilai
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - nilai
category—automation,debugger,sandbox,domain,tamper,integrity
vmDefenseHook: {
name: '__vmDetection',
aliases: {
source: { key: 'a8Qm', values: { headless: 'xP4m9Q' } },
category: { key: 'p3Tx', values: { automation: 'bQ7s1M' } },
score: { key: 's1' },
threshold: { key: 't1' }
}
// the callback now receives e.g. { a8Qm: 'xP4m9Q', p3Tx: 'bQ7s1M', s1: <score>, t1: <threshold> }
}
Ini adalah penghindaran fingerprint, bukan kerahasiaan — pemetaan tetap dapat disimpulkan melalui pengujian berulang — sehingga satu-satunya manfaatnya adalah tidak mengekspos nama yang stabil dan menjelaskan diri sendiri. Entri yang tidak diatur mempertahankan nama bawaannya.
Sebuah string biasa (vmDefenseHook: '__vmDetection') diterima sebagai bentuk singkat dari { name: '__vmDetection' } tetapi usang — utamakan bentuk objek.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Mengonfigurasi bagaimana setiap kategori deteksi bereaksi. Opsi ini tidak mengaktifkan apa pun — pertahanan itu sendiri diaktifkan oleh vmSelfDefending, vmDebugProtection, dan vmDomainLock; opsi ini hanya memilih bagaimana sebuah pertahanan yang aktif bereaksi. Kategori adalah unit kontrol — setiap detektor dalam sebuah kategori menjalankan reaksi kategori tersebut.
Setiap kategori mengelompokkan detektor yang mengawasi satu jenis kondisi bermusuhan. Sebuah kategori hanya bereaksi ketika opsi yang mengeluarkan detektornya diaktifkan:
Setiap kategori memetakan ke satu atau lebih dari vmSelfDefending, vmDebugProtection, dan vmDomainLock; tidak ada kategori di luar ketiga opsi tersebut, dan reaksi yang diatur untuk kategori yang opsinya nonaktif tidak berpengaruh apa pun.
Kunci adalah keenam nama kategori ini, atau default (fallback untuk kategori yang tidak ditentukan). Nilainya adalah:
break— berhenti seketikadecoy— tetap berjalan pada state yang diracuni, secara diam-diam menghasilkan hasil yang salahnone— tidak melakukan apa pun secara lokal (hanya telemetri)
Nilai bawaan per kategori ditampilkan di atas; kategori yang tidak Anda atur (atau atur ke nilai bawaannya) menggunakan nilai bawaan tersebut. default menjangkau setiap kategori, termasuk yang benar-secara-konstruksi (integrity, tamper), sehingga { default: 'none' } adalah build yang benar-benar tidak merusak dan hanya telemetri:
vmDefenseReaction: { default: 'none' } // never break — pair with vmDefenseHook
vmDefenseReaction: { automation: 'none', domain: 'break' } // tolerate automation FPs, still break on a bad domain
vmStatefulOpcodes
Type: boolean Default: false
Membuat makna opcode bergantung pada posisi dalam bytecode. Setiap posisi memiliki pemetaan opcode-ke-handler yang berbeda yang diturunkan dari sebuah seed, sehingga nomor opcode yang sama melakukan operasi yang berbeda pada posisi yang berbeda.
vmCallContextOpcodes
Type: boolean Default: false
Membuat fungsi yang dilindungi bergantung pada dari mana ia dipanggil, sehingga tidak dapat diangkat keluar dari kode lalu dijalankan atau dianalisis secara mandiri — ia hanya berperilaku benar ketika dipanggil melalui lokasi pemanggilan aslinya dalam program. Opsi ini memengaruhi performa runtime.
Saat ini hanya konstruksi berikut yang didukung:
- deklarasi fungsi (
function f() {}); - ekspresi fungsi dan arrow function yang ditetapkan ke sebuah variabel (
const f = () => {}); - metode privat instance (
this.#m()).
Dalam setiap kasus, fungsi harus selalu dijangkau melalui pemanggilan langsung (f(), this.#m()). Jika ia disimpan dalam variabel lain, diteruskan sebagai argumen, atau digunakan sebagai nilai dengan cara lain, ia dibiarkan tidak terlindungi. Fungsi async didukung; generator tidak.
Opsi ini bersifat eksperimental dan dapat merusak kode Anda, jadi uji keluaran secara menyeluruh sebelum menggunakannya.
vmStackEncoding
Type: boolean Default: false
Mengenkripsi nilai pada stack VM selama eksekusi. Nilai dienkode saat di-push dan didekode saat di-pop, sehingga inspeksi memori menampilkan data terenkripsi alih-alih nilai sebenarnya.
Opsi ini sangat memengaruhi performa.
vmCompactDispatcher
Type: boolean Default: false
Menggunakan satu executor VM alih-alih executor ganda (sync + generator). Mengurangi ukuran kode hasil obfuskasi tetapi menambah overhead performa ~20% pada kode yang banyak rekursi.
false(bawaan): executor ganda — performa optimal, keluaran lebih besartrue: executor tunggal — keluaran lebih kecil, sedikit lebih lambat
vmStringArrayBytecodeOnly
Type: boolean Default: false
Ketika diaktifkan, string array akan hanya mengekstraksi string dari data bytecode — tidak ada string lain dalam kode yang ditransformasi. Ini secara paksa mengaktifkan stringArray meskipun tidak diatur secara eksplisit.
Mengapa menggunakan ini: Mengekstraksi semua string runtime VM ke string array itu lambat. Opsi ini menargetkan hanya konten bytecode untuk ekstraksi string array, meningkatkan performa sambil tetap melindungi konstanta bytecode.
- Ketika
vmBytecodeArrayEncoding: false— string di dalam constant pool bytecode (larikc) diekstraksi - Ketika
vmBytecodeArrayEncoding: true— string bytecode terenkode base64 tingkat atas diekstraksi stringArrayThresholdtetap mengontrol berapa persen dari string bytecode tersebut yang diekstraksi
vmDomainLock
Type: string[] Default: []
⚠️ Opsi ini tidak berfungsi dengan target: 'node', target: 'service-worker', atau target: 'bytenode'
Membatasi kode hasil obfuskasi ke domain dan/atau subdomain tertentu, dan jauh lebih sulit untuk dilokasikan dan dihilangkan daripada domainLock.
Jika kode sumber tidak dijalankan pada domain yang ditentukan oleh opsi ini, peramban akan dialihkan ke URL yang diteruskan ke vmDomainLockRedirectUrl, dan pemanggilan terlindungi berikutnya akan mengembalikan hasil yang salah bahkan jika pengalihan ditekan.
Beberapa domain dan subdomain
Anda dapat mengunci kode Anda pada lebih dari satu domain atau subdomain. Misalnya, untuk menguncinya agar kode hanya berjalan pada www.example.com tambahkan www.example.com. Agar berfungsi pada domain root termasuk subdomain apa pun (example.com, sub.example.com), gunakan .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Opsi ini tidak berfungsi dengan target: 'node', target: 'service-worker', atau target: 'bytenode'
Memungkinkan peramban dialihkan ke URL yang diberikan jika kode sumber tidak dijalankan pada domain yang ditentukan oleh vmDomainLock.
Preset Options
Obfuskasi tinggi, performa rendah
Performa akan jauh lebih lambat dibandingkan tanpa obfuskasi
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
deadCodeInjection: true,
deadCodeInjectionThreshold: 1,
debugProtection: true,
debugProtectionInterval: 4000,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 1,
transformObjectKeys: true
}
Obfuskasi sedang, performa optimal
Performa akan lebih lambat dibandingkan tanpa obfuskasi
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 10,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 0.75,
stringArrayEncoding: ['base64'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 2,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 4,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.75,
transformObjectKeys: true
}
Obfuskasi rendah, performa tinggi
Performa akan berada pada tingkat yang relatif normal
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: false,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: false,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75
}
Preset bawaan, performa tinggi
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: false,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: false,
simplify: true,
splitStrings: false,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: false,
stringArrayCallsTransformThreshold: 0.5,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75
}
Obfuskasi VM Ultra High (Keamanan Maksimal)
Preset ini mengaktifkan obfuskasi bytecode berbasis VM dengan semua fitur hardening termasuk dispatch tidak langsung. Memberikan proteksi terkuat tetapi dengan ukuran keluaran yang lebih besar dan eksekusi yang jauh lebih lambat.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: true,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: true,
vmCallContextOpcodes: false,
vmStackEncoding: true,
vmCompactDispatcher: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.5,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.5,
debugProtection: true,
debugProtectionInterval: 4000,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.5,
transformObjectKeys: true
}
VM Anti-LLM (Proteksi Agen AI)
Preset ini dirancang khusus untuk mencegah agen AI dan LLM melakukan reverse-engineering terhadap kode ber-bytecode VM. Berbasis vm-default dengan self-defending dan debug protection diaktifkan. Lebih ringan daripada vm-high-obfuscation tetapi diperkeras secara khusus terhadap analisis otomatis.
{
optionsPreset: 'vm-anti-llm'
}
Mencakup:
- Obfuskasi bytecode VM dengan string array (dari
vm-default) vmSelfDefending— deteksi anti-hook, hash integritas, fingerprint sumber, verifikasi clean-realm iframe, derivasi kunci sandi ARXvmDebugProtection— pemeriksaan anti-debugging dalam loop dispatch VMdebugProtection: false— tanpa debug protection lama (debug protection VM lebih unggul)
Obfuskasi VM High (Keamanan Tertinggi)
Preset ini mengaktifkan obfuskasi bytecode berbasis VM dengan sebagian besar fitur hardening. Memberikan proteksi kuat dengan performa yang lebih baik daripada preset ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: true,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: true,
vmCallContextOpcodes: false,
vmStackEncoding: true,
vmCompactDispatcher: false
}
Obfuskasi VM Medium (Keamanan Seimbang)
Preset ini mengaktifkan obfuskasi bytecode berbasis VM dengan sekumpulan fitur hardening yang seimbang. Kompromi yang baik antara keamanan dan performa.
{
optionsPreset: 'vm-medium-obfuscation'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: false,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false
}
Obfuskasi VM Low (Keamanan Dasar, Performa Lebih Baik)
Preset ini mengaktifkan obfuskasi bytecode berbasis VM dasar tanpa fitur hardening tambahan. Keseimbangan yang baik antara keamanan dan ukuran keluaran.
{
optionsPreset: 'vm-low-obfuscation'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: false,
vmBytecodeEncoding: false,
vmBytecodeArrayEncoding: false,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: false,
vmMacroOps: false,
vmDebugProtection: false,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false
}
VM Default (Proteksi VM + String Array)
Preset ini menggabungkan obfuskasi bytecode berbasis VM dasar dengan proteksi string array. Titik awal yang baik untuk obfuskasi VM dengan proteksi string.
{
optionsPreset: 'vm-default'
}
Atau konfigurasikan secara individual:
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: false,
vmBytecodeArrayEncoding: true,
vmStringArrayBytecodeOnly: true,
vmAsyncExecutor: false,
vmJumpsEncoding: false,
vmMacroOps: false,
vmDebugProtection: false,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false,
stringArray: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayThreshold: 1,
stringArrayIndexShift: true,
stringArrayIndexesType: ['hexadecimal-number'],
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 1,
stringArrayWrappersCount: 3,
stringArrayWrappersType: 'function',
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayEncoding: ['base64'],
splitStrings: true,
splitStringsChunkLength: 6
}
