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 renameProperties diaktifkan:
    • 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 daftar identifiersDictionary
  • hexadecimal: nama pengenal seperti _0xabc123
  • mangled: nama pengenal pendek seperti a, b, c
  • mangled-shuffled: sama seperti mangled tetapi 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 seed dan 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 + acak aBc123myAppaBc123).
  • Ketika digabungkan dengan vmObfuscation, nilai acak menggantikan awalan vm bawaan — 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 atribut data-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 var atau penetapan globalThis eksplisit)
  • 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 rilis 2.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 rilis 2.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 field sources dummy, menambahkan field sourcesContent berisi kode sumber asli;
  • sources - menambahkan field sources dengan deskripsi sumber yang valid, tidak menambahkan field sourcesContent. Saat menggunakan NodeJS API, diperlukan pendefinisian opsi inputFileName yang akan digunakan sebagai nilai field sources.

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 nilai stringArray
  • 'base64' (string): mengenkode nilai stringArray menggunakan base64
  • 'rc4' (string): mengenkode nilai stringArray menggunakan rc4. Sekitar 30-50% lebih lambat daripada base64, 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 daripada variable tetapi 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 dengan node, tetapi beberapa opsi khusus peramban tidak diizinkan digunakan dengan target node
  • browser-no-eval — sama seperti browser, tetapi keluaran tidak menggunakan eval(). Gunakan ketika halaman target memiliki Content Security Policy yang melarang eval/unsafe-eval.
  • node — lingkungan Node.js. Opsi khusus peramban dinonaktifkan (opsi-opsi tersebut membutuhkan window/document dan akan menjadi no-op atau melempar error di Node). Beberapa pertahanan vmSelfDefending yang 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. Tanpa window, tanpa document, global self yang berbeda.
  • userscript — sandbox pengelola userscript (mis. Tampermonkey). Pertahanan vmSelfDefending disesuaikan sebagaimana mestinya.
  • bytenode — kode Node.js yang akan dikompilasi dengan loader bytenode (bytecode ter-cache V8 .jsc) setelah obfuskasi. Obfuscator itu sendiri tidak memanggil bytenode; ia menghasilkan JavaScript hasil obfuskasi VM yang runtime-nya disusun agar dapat bertahan melalui langkah kompilasi bytenode, dan pertahanan vmSelfDefending disesuaikan sebagaimana mestinya. Jalankan bytenode sendiri pada keluaran hasil obfuskasi untuk menghasilkan .jsc final.

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 false disembunyikan; setiap tipe yang tidak ada (atau dipetakan ke true) tetap aktif. Misalnya, { "VMGlobalFunctionNamesNotRenamed": false } mempertahankan setiap peringatan kecuali yang satu itu.

Tipe peringatan:

  • VMGlobalFunctionNamesNotRenamed — di bawah vmObfuscation, nama deklarasi fungsi tingkat atas, deklarasi kelas, dan variabel yang diberi ekspresi fungsi/arrow/kelas dipertahankan apa adanya (opsi renameGlobals dinonaktifkan 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 karena vmWrapTopLevelInitializers dinonaktifkan atau tidak dapat memvirtualisasinya.
  • DynamicCodeRenameRisk — kode membangun sebuah fungsi dari string saat runtime (direct eval, konstruktor Function, atau fn.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 direct eval / new Function dinamis / Function (lihat vmForceCompileDynamicCode).
  • VMSyncFunctionSkippedInAsyncMode — dengan vmAsyncExecutor diaktifkan, sebuah fungsi yang Anda tandai secara eksplisit dalam mode comment ternyata sinkron dan dilewati (hanya fungsi async yang divirtualisasi dalam mode itu).
  • VMAsyncGeneratorSkippedInAsyncMode — dengan vmAsyncExecutor dan 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 opsi target diatur 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.

ModeDeskripsi
rootPerilaku bawaan. Hanya fungsi tingkat root yang dipertimbangkan untuk obfuskasi VM. Menggunakan allow-list vmTargetFunctions dan deny-list vmExcludeFunctions untuk memfilter.
commentHanya fungsi/metode yang ditandai dengan komentar /* javascript-obfuscator:vm */ yang diobfuskasi VM. Berfungsi dengan fungsi/metode pada tingkat nesting mana pun.

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:

  1. Memfilter instruksi yang tidak terpakai - Jika kode Anda tidak menggunakan kelas, instruksi terkait kelas dihapus sepenuhnya
  2. 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 target diatur ke browser)
  • 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), atau integrity (kode VM itu sendiri diubah).
  • score / threshold — seberapa kuat detektor memicu dan nilai yang harus dicapainya; hook memicu hanya setelah score >= threshold. Sebagian besar pemeriksaan bersifat semua-atau-tidak (satu sinyal yang menentukan); headless menjumlahkan beberapa sinyal bentuk-peramban, sehingga score-nya biasanya lebih tinggi daripada threshold-nya.
sourcemendeteksicategory
integritykode VM hasil obfuskasi itu sendiri telah dimodifikasiintegrity
nodekode yang menargetkan peramban berjalan di bawah Node.jsdebugger
debuggersesi debugger atau inspector yang terpasang atau aktif, atau lingkungan debugdebugger
headlessperamban headless digunakan untuk menjalankan kodeautomation
agentagen pengkodean AI menjalankan kodeautomation
timingjeda eksekusi yang mengindikasikan breakpoint atau debugger yang melangkahdebugger
sandboxkode berjalan dalam sandbox atau lingkungan host palsusandbox
domainorigin halaman tidak ada dalam allow-list vmDomainLockdomain
nativeHooksebuah fungsi builtin native telah diganti atau di-hooktamper

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 fieldsource, category, score, threshold
  • nilai sourceheadless, agent, node, debugger, timing, sandbox, domain, nativeHook, integrity
  • nilai categoryautomation, 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:

KategoriDiaktifkan olehBereaksi ketika
automationvmSelfDefending atau vmDebugProtectionKode dikendalikan oleh perangkat lunak alih-alih manusia: peramban headless atau otomatis, framework scraping / pengujian, atau agen pengkodean AI yang melangkahi halaman.
debuggervmDebugProtection atau vmSelfDefendingSeseorang membuka debugger atau inspector developer-tools peramban dan melangkah menelusuri kode yang berjalan untuk memahaminya.
sandboxvmDebugProtectionKode sama sekali tidak berjalan di peramban asli — kode telah dipindahkan ke lingkungan JavaScript yang diemulasi atau diskrip untuk dieksekusi dan dipelajari secara offline.
domainvmDomainLockKode berjalan di situs yang tidak Anda otorisasi: host yang tidak ada dalam allow-list vmDomainLock Anda (misalnya, bundel Anda disalin ke domain orang lain).
tampervmSelfDefendingLingkungan JavaScript di sekitar VM telah dimodifikasi untuk mengawasi atau membajaknya, seperti builtin peramban native yang ditukar dengan versi terinstrumentasi.
integrityvmSelfDefendingKode bundel yang dilindungi itu sendiri telah diedit atau dipatch sejak Anda membuatnya.

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 seketika
  • decoy — tetap berjalan pada state yang diracuni, secara diam-diam menghasilkan hasil yang salah
  • none — 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 besar
  • true: 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 (larik c) diekstraksi
  • Ketika vmBytecodeArrayEncoding: true — string bytecode terenkode base64 tingkat atas diekstraksi
  • stringArrayThreshold tetap 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 ARX
  • vmDebugProtection — pemeriksaan anti-debugging dalam loop dispatch VM
  • debugProtection: 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 renameProperties diaktifkan:
    • 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 daftar identifiersDictionary
  • hexadecimal: nama pengenal seperti _0xabc123
  • mangled: nama pengenal pendek seperti a, b, c
  • mangled-shuffled: sama seperti mangled tetapi 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 seed dan 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 + acak aBc123myAppaBc123).
  • Ketika digabungkan dengan vmObfuscation, nilai acak menggantikan awalan vm bawaan — 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 atribut data-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 var atau penetapan globalThis eksplisit)
  • 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 rilis 2.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 rilis 2.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 field sources dummy, menambahkan field sourcesContent berisi kode sumber asli;
  • sources - menambahkan field sources dengan deskripsi sumber yang valid, tidak menambahkan field sourcesContent. Saat menggunakan NodeJS API, diperlukan pendefinisian opsi inputFileName yang akan digunakan sebagai nilai field sources.

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 nilai stringArray
  • 'base64' (string): mengenkode nilai stringArray menggunakan base64
  • 'rc4' (string): mengenkode nilai stringArray menggunakan rc4. Sekitar 30-50% lebih lambat daripada base64, 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 daripada variable tetapi 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 dengan node, tetapi beberapa opsi khusus peramban tidak diizinkan digunakan dengan target node
  • browser-no-eval — sama seperti browser, tetapi keluaran tidak menggunakan eval(). Gunakan ketika halaman target memiliki Content Security Policy yang melarang eval/unsafe-eval.
  • node — lingkungan Node.js. Opsi khusus peramban dinonaktifkan (opsi-opsi tersebut membutuhkan window/document dan akan menjadi no-op atau melempar error di Node). Beberapa pertahanan vmSelfDefending yang 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. Tanpa window, tanpa document, global self yang berbeda.
  • userscript — sandbox pengelola userscript (mis. Tampermonkey). Pertahanan vmSelfDefending disesuaikan sebagaimana mestinya.
  • bytenode — kode Node.js yang akan dikompilasi dengan loader bytenode (bytecode ter-cache V8 .jsc) setelah obfuskasi. Obfuscator itu sendiri tidak memanggil bytenode; ia menghasilkan JavaScript hasil obfuskasi VM yang runtime-nya disusun agar dapat bertahan melalui langkah kompilasi bytenode, dan pertahanan vmSelfDefending disesuaikan sebagaimana mestinya. Jalankan bytenode sendiri pada keluaran hasil obfuskasi untuk menghasilkan .jsc final.

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 false disembunyikan; setiap tipe yang tidak ada (atau dipetakan ke true) tetap aktif. Misalnya, { "VMGlobalFunctionNamesNotRenamed": false } mempertahankan setiap peringatan kecuali yang satu itu.

Tipe peringatan:

  • VMGlobalFunctionNamesNotRenamed — di bawah vmObfuscation, nama deklarasi fungsi tingkat atas, deklarasi kelas, dan variabel yang diberi ekspresi fungsi/arrow/kelas dipertahankan apa adanya (opsi renameGlobals dinonaktifkan 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 karena vmWrapTopLevelInitializers dinonaktifkan atau tidak dapat memvirtualisasinya.
  • DynamicCodeRenameRisk — kode membangun sebuah fungsi dari string saat runtime (direct eval, konstruktor Function, atau fn.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 direct eval / new Function dinamis / Function (lihat vmForceCompileDynamicCode).
  • VMSyncFunctionSkippedInAsyncMode — dengan vmAsyncExecutor diaktifkan, sebuah fungsi yang Anda tandai secara eksplisit dalam mode comment ternyata sinkron dan dilewati (hanya fungsi async yang divirtualisasi dalam mode itu).
  • VMAsyncGeneratorSkippedInAsyncMode — dengan vmAsyncExecutor dan 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 opsi target diatur 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.

ModeDeskripsi
rootPerilaku bawaan. Hanya fungsi tingkat root yang dipertimbangkan untuk obfuskasi VM. Menggunakan allow-list vmTargetFunctions dan deny-list vmExcludeFunctions untuk memfilter.
commentHanya fungsi/metode yang ditandai dengan komentar /* javascript-obfuscator:vm */ yang diobfuskasi VM. Berfungsi dengan fungsi/metode pada tingkat nesting mana pun.

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:

  1. Memfilter instruksi yang tidak terpakai - Jika kode Anda tidak menggunakan kelas, instruksi terkait kelas dihapus sepenuhnya
  2. 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 target diatur ke browser)
  • 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), atau integrity (kode VM itu sendiri diubah).
  • score / threshold — seberapa kuat detektor memicu dan nilai yang harus dicapainya; hook memicu hanya setelah score >= threshold. Sebagian besar pemeriksaan bersifat semua-atau-tidak (satu sinyal yang menentukan); headless menjumlahkan beberapa sinyal bentuk-peramban, sehingga score-nya biasanya lebih tinggi daripada threshold-nya.
sourcemendeteksicategory
integritykode VM hasil obfuskasi itu sendiri telah dimodifikasiintegrity
nodekode yang menargetkan peramban berjalan di bawah Node.jsdebugger
debuggersesi debugger atau inspector yang terpasang atau aktif, atau lingkungan debugdebugger
headlessperamban headless digunakan untuk menjalankan kodeautomation
agentagen pengkodean AI menjalankan kodeautomation
timingjeda eksekusi yang mengindikasikan breakpoint atau debugger yang melangkahdebugger
sandboxkode berjalan dalam sandbox atau lingkungan host palsusandbox
domainorigin halaman tidak ada dalam allow-list vmDomainLockdomain
nativeHooksebuah fungsi builtin native telah diganti atau di-hooktamper

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 fieldsource, category, score, threshold
  • nilai sourceheadless, agent, node, debugger, timing, sandbox, domain, nativeHook, integrity
  • nilai categoryautomation, 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:

KategoriDiaktifkan olehBereaksi ketika
automationvmSelfDefending atau vmDebugProtectionKode dikendalikan oleh perangkat lunak alih-alih manusia: peramban headless atau otomatis, framework scraping / pengujian, atau agen pengkodean AI yang melangkahi halaman.
debuggervmDebugProtection atau vmSelfDefendingSeseorang membuka debugger atau inspector developer-tools peramban dan melangkah menelusuri kode yang berjalan untuk memahaminya.
sandboxvmDebugProtectionKode sama sekali tidak berjalan di peramban asli — kode telah dipindahkan ke lingkungan JavaScript yang diemulasi atau diskrip untuk dieksekusi dan dipelajari secara offline.
domainvmDomainLockKode berjalan di situs yang tidak Anda otorisasi: host yang tidak ada dalam allow-list vmDomainLock Anda (misalnya, bundel Anda disalin ke domain orang lain).
tampervmSelfDefendingLingkungan JavaScript di sekitar VM telah dimodifikasi untuk mengawasi atau membajaknya, seperti builtin peramban native yang ditukar dengan versi terinstrumentasi.
integrityvmSelfDefendingKode bundel yang dilindungi itu sendiri telah diedit atau dipatch sejak Anda membuatnya.

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 seketika
  • decoy — tetap berjalan pada state yang diracuni, secara diam-diam menghasilkan hasil yang salah
  • none — 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 besar
  • true: 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 (larik c) diekstraksi
  • Ketika vmBytecodeArrayEncoding: true — string bytecode terenkode base64 tingkat atas diekstraksi
  • stringArrayThreshold tetap 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 ARX
  • vmDebugProtection — pemeriksaan anti-debugging dalam loop dispatch VM
  • debugProtection: 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
}